Skip to content

feat: add external storage concurrency limiter APIs - #615

Open
jmaeagle99 wants to merge 1 commit into
mainfrom
extstore-foundation
Open

jmaeagle99 wants to merge 1 commit into
mainfrom
extstore-foundation

Conversation

@jmaeagle99

@jmaeagle99 jmaeagle99 commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

What was changed

Adds the concurrency contract for external storage drivers:

  • StorageDriverLimiter, with permit(item) { ... } holding a permit for the block.
  • ExternalStorageConcurrency, carrying the two budgets: max_driver_operations (64, shared
    across the configuration) and max_operations_per_message (8, per activation/task/request).
  • The limiter is now on StorageDriverStoreContext and StorageDriverRetrieveContext, and
    ExternalStorage takes a concurrency:.

Why?

A driver is handed a whole batch and decides for itself how many requests to make of it, so the SDK can only bound that fan out cooperatively by handing the driver something to take a permit from. The spec puts the limiter on the store and retrieve contexts and the budgets on the storage configuration.

Ruby's block form is the counterpart of Python's async with limiter.permit(item): — both hold the permit for a lexical scope and release it on exit, including when the body raises. Field names and defaults match Python's ExternalStorageConcurrency exactly. No cancellation parameter is needed because the Ruby contexts already carry a Cancellation.

Checklist

  1. How was this tested: New unit tests cover the defaults (64 / 8), rejection of non-positive and non-Integer budgets, and that permit runs the block and returns its value.

  2. Any docs updates needed? Not yet. Everything here is @!visibility private and experimental.

@jmaeagle99
jmaeagle99 requested a review from a team as a code owner October 12, 2026 18:00
@jmaeagle99 jmaeagle99 added the skip-changelog PR changes do not require changelog updates label Oct 12, 2026

@chris-olszewski chris-olszewski left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just small questions around some doc comment language

Comment on lines +20 to +21
# Take one permit per request rather than one around a whole batch. Wrapping an entire fan out in a single
# permit satisfies this signature while defeating the limit it exists to impose. Taking a permit while already

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the second sentence explaining why to take a permit per request is there for consistency with other SDKs, that seems fine, but otherwise I think the first sentence is all that is necessary.

# waiting when the SDK abandons the operation stops waiting.
#
# @param item [Api::Common::V1::Payload, StorageDriverClaim] What this one request covers: a payload when
# storing, a claim when retrieving. A limiter may price a permit by it; one that does not may ignore it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be a me thing, but "price a permit" is not language I've seen before.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changelog PR changes do not require changelog updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants