feat: add throttle — distributed throttle primitive#63
Closed
freshlogic wants to merge 1 commit intomainfrom
Closed
feat: add throttle — distributed throttle primitive#63freshlogic wants to merge 1 commit intomainfrom
freshlogic wants to merge 1 commit intomainfrom
Conversation
Coalesces calls for the same key across multiple processes via Redis so that fn runs at most once per ttl window. The first caller in a window wins the claim and fn runs to completion; subsequent calls are no-ops. Errors thrown by fn propagate to the caller — useful for callers that need to know whether the work succeeded so they can NACK upstream messages, etc. Implementation is a single SETNX with PX TTL: claim succeeds, fn runs; claim fails, return immediately. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Coverage Report for CI Build 24945751484Coverage decreased (-0.2%) to 99.812%Details
Uncovered Changes
Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
Member
Author
|
Closing — this was just a thin sugar wrapper over pettyCache.mutex.lock. Caller can use mutex.lock directly with try/catch on the throw-on-contention path; the extra primitive doesn't earn its keep. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
pettyCache.throttle(key, { ttl }, fn)— a distributed throttle primitive backed by Redis. Async/await only.The pattern: first caller for a given key in a
ttlwindow wins the claim andfnruns to completion; subsequent calls within the window are no-ops (return immediately without invoking fn). After the window expires, the next caller can claim again.Errors thrown by
fnpropagate to the caller — useful for callers that need to know whether the work succeeded so they can NACK upstream messages, retry, etc.Why
The first concrete use case is Stores.com's segmentation-service rollup pipeline — many upstream Service Bus events signal "refresh accountId X." We want at most one refresh-message-publish per ~5-min window per account, and we need the publishing caller to know if the publish succeeded (so they can NACK their upstream message on failure).
API
First caller in a 5-min window: schedules the deferred message, errors propagate. Subsequent callers: no-op return.
Implementation
Single SETNX with PX TTL:
No mutex, no setTimeout, no UUID, no retries. ~15 lines.
Test plan
Relationship to PR #62 (debounce)
PR #62 adds a similar debounce primitive (timer-reset semantics, fire-and-forget). This throttle is a different shape — first-call-wins, awaitable, errors propagate. The two have different use-case fits; we may end up keeping both, or closing one. Open here so segmentation can move forward independently.
🤖 Generated with Claude Code