dynamic-throttled-queue 3.0.0-rc.1d87d99 → 3.0.0-rc.6e88a00

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -437,7 +437,7 @@ Strategies must return a finite integer `nextRate` and a boolean `shouldBackOff`
437
437
 
438
438
  `cooldownFor(delay)` stops the queue from starting anything new for `delay` milliseconds. See [Honour `Retry-After` on HTTP 429](#honour-retry-after-on-http-429) for a full example.
439
439
 
440
- - **Scheduling.** Pending work, newly queued work, and retries are kept and do not start. Active callbacks keep running and settle normally. When the cooldown ends, starts resume without new work being queued; the first one is due one spacing later, as after any fresh start. Delayed retries keep counting down and join the queue when due.
440
+ - **Scheduling.** Pending work, newly queued work, and retries are kept and do not start. Active callbacks keep running and settle normally. When the cooldown ends, starts resume without new work being queued; the first one is due one spacing later, as after any fresh start. Delayed retries keep counting down and join the queue when due. While nothing is queued, the cooldown holds no timer, so it does not keep a Node.js process alive after `waitForIdle()` resolves.
441
441
  - **Overlaps.** Each call asks for "nothing before now + `delay`". A later deadline replaces the current one; an earlier one is ignored. Two 60-second hints that arrive together give one 60-second cooldown, not two.
442
442
  - **Validation.** `NaN`, negative, and infinite delays throw a `RangeError` in every lifecycle state, including after `abort()` or a strategy failure. Delays above `maxCooldown` are clamped to it. `0` does nothing.
443
443
  - **Lifecycle.** `pause()` and cooldown are separate: a cooldown keeps elapsing while paused, its end does not resume a paused queue, and `resume()` does not end it. `stop()` clears the cooldown timer but keeps the deadline, so the work that restarts the queue still waits for it. `abort()` and a strategy failure clear the cooldown; later valid calls do nothing.
@@ -450,6 +450,12 @@ Strategies must return a finite integer `nextRate` and a boolean `shouldBackOff`
450
450
 
451
451
  - The `pending` property is removed. Read `getState().pending` instead.
452
452
  - The `RateFailureOutcome` type is renamed to `FailureOutcome`.
453
+ - `QueueLifecycleState` gains `"failed"`. An exhaustive `switch` on `getState().state` needs a case for it.
454
+ - When `rateStrategy` throws or returns a malformed decision, the queue now reports `state: "failed"`, discards pending work, rejects `waitForIdle()` with the strategy error, and throws that error from later enqueues. In v2 it kept reporting `"running"`, kept the pending work, and `waitForIdle()` never settled.
455
+ - An unknown `retryBackoff.strategy` now throws `retryBackoff.strategy must be fixed, linear, or exponential` at creation. v2 silently used the fixed delay.
456
+ - Settled timing now matches the documented contract: the window collected right after a backoff holds the rate steady, an empty collection interval makes no rate decision, and a backoff that ends with nothing queued no longer stops later callbacks from starting.
457
+ - Exported types gained required members: `ExecutionContext.attempt`; `QueueState.canceled`, `cooldownRemaining`, `cooldowns` and `cooldownTotal`; `ThrottleHandle.submit` and `cooldownFor`. Code that reads them is unaffected. Hand-built contexts, state objects and handle test doubles need the new members.
458
+ - `ThrottleCallback` now returns `unknown`, so any callback type-checks. Code that calls a `ThrottleCallback` itself gets `unknown` back instead of `boolean | void | Promise<boolean | void>`.
453
459
 
454
460
  ### From v1
455
461
 
@@ -63,7 +63,8 @@ export type AdaptiveRate = {
63
63
  /**
64
64
  * Ends a pause, then begins observing if idle and work is pending. While starts are open and no start
65
65
  * is scheduled (concurrency was full), makes starts due now once a spacing has passed since the last
66
- * start, or schedules them for when it has. During `startsDue`, the batch's own follow-up covers it.
66
+ * start, or schedules them for when it has; with nothing pending then, drains instead. During
67
+ * `startsDue`, the batch's own follow-up covers it.
67
68
  */
68
69
  start: () => void;
69
70
  /** Ends observation. Settled timing discards its in-progress window. */
@@ -301,11 +301,16 @@ export function createAdaptiveRate(options, host) {
301
301
  },
302
302
  start() {
303
303
  ignoringSettlements = false;
304
- if (!host.hasPendingWork())
304
+ const waitingForSlot = pacing === "open" && startTimer === undefined && !dispatching;
305
+ if (!host.hasPendingWork()) {
306
+ // Work removed while every slot was busy (a cancel) never reaches `startDue`, which drains.
307
+ if (waitingForSlot)
308
+ timing.drained();
305
309
  return;
310
+ }
306
311
  if (pacing === "idle")
307
312
  timing.start();
308
- else if (pacing === "open" && startTimer === undefined && !dispatching)
313
+ else if (waitingForSlot)
309
314
  startDue();
310
315
  },
311
316
  stop() {
@@ -1 +1 @@
1
- {"version":3,"file":"adaptive-rate.js","sourceRoot":"","sources":["../src/adaptive-rate.ts"],"names":[],"mappings":"AA+BA,MAAM,CAAC,MAAM,MAAM,GAAiB,CAAC,EACnC,OAAO,EACP,OAAO,EACP,WAAW,EACX,UAAU,EACV,cAAc,EACd,cAAc,EACd,YAAY,GACb,EAAE,EAAE;IACH,IAAI,UAAU,IAAI,cAAc,EAAE,CAAC;QACjC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IAC/E,CAAC;IACD,IAAI,CAAC,YAAY,IAAI,UAAU,KAAK,CAAC,IAAI,cAAc,EAAE,CAAC;QACxD,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;IAChF,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;AACzD,CAAC,CAAC;AAEF,MAAM,UAAU,IAAI,CAAC,EAAE,UAAU,GAAG,CAAC,EAAE,cAAc,GAAG,GAAG,KAAkB,EAAE;IAC7E,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,cAAc,IAAI,CAAC,IAAI,cAAc,IAAI,CAAC,EAAE,CAAC;QACnF,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACpF,CAAC;IACD,OAAO,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,EAAE,EAAE;QACnF,IAAI,UAAU,IAAI,cAAc,EAAE,CAAC;YACjC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,cAAc,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;QACrF,CAAC;QACD,IAAI,CAAC,YAAY,IAAI,UAAU,KAAK,CAAC,IAAI,cAAc,EAAE,CAAC;YACxD,OAAO,EAAE,QAAQ,EAAE,WAAW,GAAG,UAAU,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;QACtE,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;IACzD,CAAC,CAAC;AACJ,CAAC;AAuFD,MAAM,gBAAgB,GAAuB,GAAG,EAAE,GAAE,CAAC,CAAC;AAEtD,SAAS,gBAAgB,CAAC,QAAiB;IACzC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtD,MAAM,IAAI,SAAS,CAAC,6CAA6C,CAAC,CAAC;IACrE,CAAC;IACD,MAAM,SAAS,GAAG,QAAgC,CAAC;IACnD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClF,MAAM,IAAI,SAAS,CAAC,qDAAqD,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,OAAO,SAAS,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QACjD,MAAM,IAAI,SAAS,CAAC,mDAAmD,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,yGAAyG;AACzG,SAAS,cAAc,CAAC,OAAsB;IAC5C,IAAI,IAA+C,CAAC;IACpD,IAAI,GAAG,GAAG,CAAC,CAAC;IAEZ,SAAS,MAAM;QACb,IAAI,GAAG,SAAS,CAAC;QACjB,MAAM,OAAO,GAAG,GAAG,CAAC;QACpB,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;QAC9B,IAAI,OAAO,KAAK,GAAG;YAAE,OAAO;QAC5B,IAAI,IAAI;YAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;aACpC,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM;YAAE,OAAO,CAAC,MAAM,EAAE,CAAC;QACrD,IAAI,GAAG,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED,SAAS,IAAI;QACX,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,IAAI,GAAG,SAAS,CAAC;QACjB,GAAG,EAAE,CAAC;QACN,OAAO,CAAC,IAAI,EAAE,CAAC;IACjB,CAAC;IAED,OAAO;QACL,KAAK;YACH,OAAO,CAAC,MAAM,EAAE,CAAC;YACjB,IAAI,GAAG,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM;QAC7B,OAAO,EAAE,IAAI;QACb,IAAI;QACJ,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED,2FAA2F;AAC3F,SAAS,aAAa,CAAC,OAAsB;IAC3C,IAAI,KAAgD,CAAC;IACrD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,iGAAiG;IACjG,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,yEAAyE;IACzE,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,SAAS,IAAI;QACX,KAAK,GAAG,SAAS,CAAC;QAClB,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QACD,MAAM,EAAE,CAAC;QACT,UAAU,GAAG,IAAI,CAAC;QAClB,MAAM,GAAG,KAAK,CAAC;QACf,MAAM,GAAG,CAAC,CAAC;QACX,WAAW,GAAG,CAAC,CAAC;QAChB,OAAO,CAAC,MAAM,EAAE,CAAC;QACjB,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED,SAAS,KAAK;QACZ,KAAK,GAAG,SAAS,CAAC;QAClB,qGAAqG;QACrG,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;YACjB,IAAI,EAAE,CAAC;YACP,OAAO;QACT,CAAC;QACD,UAAU,GAAG,KAAK,CAAC;QACnB,MAAM,GAAG,IAAI,CAAC;QACd,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,IAAI,WAAW,KAAK,CAAC;YAAE,MAAM,EAAE,CAAC;IAClC,CAAC;IAED,SAAS,MAAM;QACb,MAAM,GAAG,KAAK,CAAC;QACf,MAAM,OAAO,GAAG,MAAM,CAAC;QACvB,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;QAC9B,IAAI,OAAO,KAAK,MAAM;YAAE,OAAO;QAC/B,IAAI,IAAI;YAAE,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;;YAChD,IAAI,EAAE,CAAC;IACd,CAAC;IAED,OAAO;QACL,KAAK;YACH,SAAS,GAAG,KAAK,CAAC;YAClB,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,IAAI,EAAE,CAAC;gBACP,OAAO;YACT,CAAC;YACD,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,WAAW,KAAK,CAAC;gBAAE,MAAM,EAAE,CAAC;QAClC,CAAC;QACD,OAAO;YACL,IAAI,CAAC,UAAU;gBAAE,OAAO,gBAAgB,CAAC;YACzC,MAAM,SAAS,GAAG,MAAM,CAAC;YACzB,MAAM,EAAE,CAAC;YACT,WAAW,EAAE,CAAC;YACd,OAAO,OAAO,CAAC,EAAE;gBACf,IAAI,SAAS,KAAK,MAAM;oBAAE,OAAO;gBACjC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBACxB,WAAW,EAAE,CAAC;gBACd,IAAI,MAAM,IAAI,CAAC,SAAS,IAAI,WAAW,KAAK,CAAC;oBAAE,MAAM,EAAE,CAAC;YAC1D,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,KAAI,CAAC;QACZ,IAAI;YACF,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,KAAK,GAAG,SAAS,CAAC;YAClB,UAAU,GAAG,KAAK,CAAC;YACnB,MAAM,GAAG,KAAK,CAAC;YACf,SAAS,GAAG,KAAK,CAAC;YAClB,MAAM,EAAE,CAAC;YACT,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,CAAC;QACD,OAAO;YACL,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,KAAK,GAAG,SAAS,CAAC;YAClB,IAAI,UAAU,EAAE,CAAC;gBACf,UAAU,GAAG,KAAK,CAAC;gBACnB,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC;YACtB,CAAC;YACD,SAAS,GAAG,IAAI,CAAC;YACjB,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAA4B,EAAE,IAAsB;IACrF,MAAM,EACJ,OAAO,EACP,OAAO,EACP,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,OAAO,EACP,YAAY,EACZ,qBAAqB,EACrB,YAAY,GACb,GAAG,OAAO,CAAC;IACZ,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9C,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,IAAI,mBAAmB,GAAG,KAAK,CAAC;IAChC,IAAI,MAAM,GAAW,MAAM,CAAC;IAC5B,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,UAAqD,CAAC;IAC1D,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,SAAS,cAAc,CAAC,OAAuB;QAC7C,IAAI,CAAC;YACH,OAAO,qBAAqB,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;QAClD,CAAC;QACD,MAAM,CAAC;YACL,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,SAAS,SAAS,CAAC,IAAY;QAC7B,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO;QAC1B,IAAI,IAAI,GAAG,IAAI;YAAE,aAAa,EAAE,CAAC;;YAC5B,aAAa,EAAE,CAAC;QACrB,IAAI,GAAG,IAAI,CAAC;QACZ,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;IAED,SAAS,MAAM;QACb,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;YAChC,WAAW,EAAE,IAAI;YACjB,OAAO;YACP,OAAO;YACP,UAAU;YACV,cAAc;YACd,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE;YACrC,YAAY;SACb,CAAC,CAAC;QACH,IAAI,QAA8B,CAAC;QACnC,IAAI,CAAC;YACH,QAAQ,GAAG,gBAAgB,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACnB,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,IAAI,GAAG,OAAO,IAAI,QAAQ,CAAC,aAAa,CAAC;QAC/C,UAAU,GAAG,CAAC,CAAC;QACf,YAAY,GAAG,IAAI,CAAC;QACpB,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACnE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,OAAO;QACd,OAAO,YAAY,CAAC,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;IACnD,CAAC;IAED,SAAS,aAAa,CAAC,KAAa;QAClC,YAAY,CAAC,UAAU,CAAC,CAAC;QACzB,UAAU,GAAG,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;IAED,SAAS,WAAW;QAClB,YAAY,CAAC,UAAU,CAAC,CAAC;QACzB,UAAU,GAAG,SAAS,CAAC;IACzB,CAAC;IAED,oFAAoF;IACpF,SAAS,QAAQ;QACf,UAAU,GAAG,SAAS,CAAC;QACvB,MAAM,IAAI,GAAG,SAAS,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAChD,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;YACb,aAAa,CAAC,IAAI,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QACD,WAAW,GAAG,IAAI,CAAC;QACnB,WAAW,GAAG,CAAC,CAAC;QAChB,IAAI,QAAiB,CAAC;QACtB,IAAI,CAAC;YACH,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACrD,CAAC;gBACO,CAAC;YACP,WAAW,GAAG,KAAK,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;YAAE,MAAM,CAAC,OAAO,EAAE,CAAC;QAC7C,IAAI,MAAM,KAAK,MAAM,IAAI,QAAQ;YAAE,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,OAAO,GAAkB;QAC7B,QAAQ;QACR,IAAI,MAAM;YACR,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,MAAM,CAAC,OAAO;YACZ,IAAI,CAAC,mBAAmB,IAAI,OAAO,IAAI,cAAc,CAAC,OAAO,CAAC;gBAAE,UAAU,EAAE,CAAC;QAC/E,CAAC;QACD,MAAM;QACN,MAAM;YACJ,MAAM,GAAG,MAAM,CAAC;YAChB,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,OAAO;YACV,MAAM,GAAG,MAAM,CAAC;YAChB,IAAI,OAAO,KAAK,SAAS;gBAAE,WAAW,EAAE,CAAC;;gBACpC,aAAa,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC;QAC1C,CAAC;QACD,MAAM;YACJ,MAAM,GAAG,MAAM,CAAC;QAClB,CAAC;QACD,IAAI;YACF,YAAY,GAAG,KAAK,CAAC;YACrB,MAAM,GAAG,MAAM,CAAC;YAChB,WAAW,EAAE,CAAC;QAChB,CAAC;KACF,CAAC;IACF,MAAM,MAAM,GAAG,OAAO,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAEzG,OAAO;QACL,IAAI,IAAI;YACN,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,aAAa;YACf,OAAO,aAAa,CAAC;QACvB,CAAC;QACD,IAAI,aAAa;YACf,OAAO,aAAa,CAAC;QACvB,CAAC;QACD,KAAK;YACH,mBAAmB,GAAG,KAAK,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;gBAAE,OAAO;YACnC,IAAI,MAAM,KAAK,MAAM;gBAAE,MAAM,CAAC,KAAK,EAAE,CAAC;iBACjC,IAAI,MAAM,KAAK,MAAM,IAAI,UAAU,KAAK,SAAS,IAAI,CAAC,WAAW;gBAAE,QAAQ,EAAE,CAAC;QACrF,CAAC;QACD,IAAI;YACF,mBAAmB,GAAG,KAAK,CAAC;YAC5B,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,CAAC;QACD,KAAK;YACH,MAAM,CAAC,IAAI,EAAE,CAAC;YACd,UAAU,GAAG,CAAC,CAAC;YACf,mBAAmB,GAAG,IAAI,CAAC;QAC7B,CAAC;QACD,OAAO;YACL,mBAAmB,GAAG,KAAK,CAAC;YAC5B,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC;QACD,OAAO;YACL,IAAI,WAAW,IAAI,WAAW,EAAE,KAAK,CAAC;gBAAE,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC/D,OAAO,MAAM,CAAC,OAAO,EAAE,CAAC;QAC1B,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"adaptive-rate.js","sourceRoot":"","sources":["../src/adaptive-rate.ts"],"names":[],"mappings":"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"}
package/dist/scheduler.js CHANGED
@@ -21,7 +21,7 @@ export function createScheduler(options, adaptiveRateOptions, retryPolicy) {
21
21
  let cooldownTotal = 0;
22
22
  /** Monotonic (`performance.now()`) time before which nothing starts; `undefined` when no cooldown is active. */
23
23
  let cooldownDeadline;
24
- /** Fires at the deadline. Cleared while stopped, which keeps the deadline for the restart. */
24
+ /** Fires at the deadline, armed only while queued work waits on it; `start()` arms it when work arrives. */
25
25
  let cooldownTimer;
26
26
  const abortController = new AbortController();
27
27
  /** Submitted items whose result has not settled. */
@@ -52,12 +52,12 @@ export function createScheduler(options, adaptiveRateOptions, retryPolicy) {
52
52
  switch (next) {
53
53
  case "running":
54
54
  work.thaw();
55
- if (cooldownDeadline === undefined) {
56
- adaptiveRate.start();
55
+ if (coolingDown()) {
56
+ armCooldown();
57
+ adaptiveRate.suspend();
57
58
  return;
58
59
  }
59
- armCooldown(cooldownDeadline);
60
- adaptiveRate.suspend();
60
+ adaptiveRate.start();
61
61
  return;
62
62
  case "paused":
63
63
  // A cooldown keeps elapsing while paused: its deadline is the server's, not the queue's.
@@ -84,20 +84,27 @@ export function createScheduler(options, adaptiveRateOptions, retryPolicy) {
84
84
  rejectTasks(error);
85
85
  }
86
86
  }
87
- function armCooldown(deadline) {
87
+ /** Re-arms the expiry timer for the current deadline, or leaves it unarmed while nothing is queued. */
88
+ function armCooldown() {
88
89
  clearTimeout(cooldownTimer);
89
- cooldownTimer = setTimeout(expireCooldown, Math.max(0, deadline - performance.now()));
90
+ cooldownTimer = cooldownDeadline !== undefined && work.queued > 0
91
+ ? setTimeout(expireCooldown, Math.max(0, cooldownDeadline - performance.now()))
92
+ : undefined;
90
93
  }
91
94
  function expireCooldown() {
92
- // A timer can fire slightly before the monotonic deadline; wait out the remainder.
93
- if (cooldownDeadline !== undefined && performance.now() < cooldownDeadline) {
94
- armCooldown(cooldownDeadline);
95
- return;
96
- }
97
95
  cooldownTimer = undefined;
98
- cooldownDeadline = undefined;
96
+ // A timer can fire slightly before the monotonic deadline; `start()` then waits out the remainder.
99
97
  start();
100
98
  }
99
+ /** Ends a cooldown whose deadline has passed; returns whether one still holds starts. */
100
+ function coolingDown() {
101
+ if (cooldownDeadline === undefined)
102
+ return false;
103
+ if (performance.now() < cooldownDeadline)
104
+ return true;
105
+ cooldownDeadline = undefined;
106
+ return false;
107
+ }
101
108
  function clearCooldown() {
102
109
  clearTimeout(cooldownTimer);
103
110
  cooldownTimer = undefined;
@@ -181,9 +188,14 @@ export function createScheduler(options, adaptiveRateOptions, retryPolicy) {
181
188
  }
182
189
  handleSettlement(item, returnedOutcome(item, result), result, reportSettlement);
183
190
  }
191
+ /** Lets due work start; during a cooldown, keeps the expiry timer armed exactly while work is queued. */
184
192
  function start() {
185
- if (lifecycle.state === "running" && cooldownDeadline === undefined)
193
+ if (lifecycle.state !== "running")
194
+ return;
195
+ if (!coolingDown())
186
196
  adaptiveRate.start();
197
+ else if (cooldownTimer === undefined || work.queued === 0)
198
+ armCooldown();
187
199
  }
188
200
  /** Admits `item` or throws: the queue is terminal or every capacity reservation is taken. */
189
201
  function accept(item) {
@@ -217,10 +229,14 @@ export function createScheduler(options, adaptiveRateOptions, retryPolicy) {
217
229
  if (!tasks.delete(task))
218
230
  return;
219
231
  cnt_canceled++;
220
- if (!task.active)
232
+ const queued = !task.active;
233
+ if (queued)
221
234
  work.remove(item);
222
235
  task.controller.abort(reason);
223
236
  task.reject(task.controller.signal.reason);
237
+ // The removed item may have been the last queued: pacing can drain and a cooldown timer unarm.
238
+ if (queued)
239
+ start();
224
240
  },
225
241
  };
226
242
  };
@@ -234,19 +250,19 @@ export function createScheduler(options, adaptiveRateOptions, retryPolicy) {
234
250
  if (lifecycle.state === "aborted" || lifecycle.state === "failed")
235
251
  return;
236
252
  const now = performance.now();
253
+ const beginning = !coolingDown();
237
254
  const latest = Math.max(now, cooldownDeadline ?? now);
238
255
  const deadline = now + Math.min(delay, maxCooldown);
239
256
  // Hints are absolute ("not before now + delay"), so overlapping ones keep the later deadline, never add up.
240
257
  if (deadline <= latest)
241
258
  return;
242
- const beginning = cooldownDeadline === undefined;
243
259
  cnt_cooldowns++;
244
260
  cooldownTotal += deadline - latest;
245
261
  cooldownDeadline = deadline;
246
262
  // Stopped: the restart arms the timer for whatever remains.
247
263
  if (lifecycle.state === "stopped")
248
264
  return;
249
- armCooldown(deadline);
265
+ armCooldown();
250
266
  // Paused: adaptive rate is already stopped; `resume()` suspends it instead of starting it.
251
267
  if (beginning && lifecycle.state === "running")
252
268
  adaptiveRate.suspend();
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "dynamic-throttled-queue",
3
- "version": "3.0.0-rc.1d87d99",
3
+ "version": "3.0.0-rc.6e88a00",
4
4
  "type": "module",
5
5
  "description": "Dynamically throttles arbitrary code to execute between a minimum and maximum number of times per interval. Best for making throttled API requests.",
6
6
  "files": [
7
- "dist"
7
+ "dist",
8
+ "skills/configure-throttled-queue"
8
9
  ],
9
10
  "zshy": {
10
11
  "exports": {
@@ -22,7 +23,8 @@
22
23
  "queue",
23
24
  "throttle",
24
25
  "throttled",
25
- "request"
26
+ "request",
27
+ "tanstack-intent"
26
28
  ],
27
29
  "author": "Adrian Elton-Browning <gingacodemonkey@gmail.com>",
28
30
  "license": "MIT",
@@ -33,6 +35,7 @@
33
35
  "@commitlint/cli": "21.2.3",
34
36
  "@commitlint/config-conventional": "20.0.0",
35
37
  "@gingacodemonkey/config": "^0.0.38",
38
+ "@tanstack/intent": "0.5.0",
36
39
  "@types/node": "^24.13.3",
37
40
  "@varlock/bumpy": "^1.18.1",
38
41
  "eslint": "^9.39.5",
@@ -40,7 +43,6 @@
40
43
  "jscpd": "^4.2.5",
41
44
  "knip": "5.70.1",
42
45
  "lint-staged": "17.6.0",
43
- "only-allow": "^1.2.2",
44
46
  "typescript": "^6.0.3",
45
47
  "vitest": "^5.0.2",
46
48
  "zshy": "^0.8.0"
@@ -70,8 +72,8 @@
70
72
  "lint:jscpd": "jscpd .",
71
73
  "lint": "pnpm lint:ts && pnpm lint:esl",
72
74
  "lint:e18e": "pnpm dlx @e18e/cli analyze",
73
- "preinstall": "only-allow pnpm",
74
75
  "bump": "bumpy add",
75
- "bump:status": "bumpy status"
76
+ "bump:status": "bumpy status",
77
+ "skills:check": "intent maintainer check"
76
78
  }
77
79
  }
@@ -0,0 +1,343 @@
1
+ ---
2
+ name: configure-throttled-queue
3
+ description: >
4
+ Use when creating, configuring, or debugging a dynamic-throttled-queue
5
+ (createThrottledQueue): pacing calls to a rate-limited API, choosing
6
+ min_rpi/max_rpi/interval/concurrency, adapting the rate to errors or HTTP
7
+ 429s, retrying failed work, honoring Retry-After, getting results back with
8
+ submit() and cancelling them, or pausing, stopping, aborting, and draining
9
+ the queue.
10
+ metadata:
11
+ purpose: >
12
+ Teach agents to configure dynamic-throttled-queue correctly: start-rate
13
+ pacing versus async concurrency, adaptive-rate outcome classification
14
+ versus retry eligibility, server-directed cooldowns, task handles, and the
15
+ pause/resume/stop/abort/failed lifecycle semantics.
16
+ type: core
17
+ library: dynamic-throttled-queue
18
+ library_version: 3.0.0
19
+ sources:
20
+ - src/*.ts
21
+ - src/__tests__/*.test.ts
22
+ # Keep the literal directory prefix at 15 characters or fewer. With Intent's
23
+ # ":(exclude)**/node_modules/**" pathspec, git ls-files (seen on 2.39 and
24
+ # 2.55) lists nothing under most longer prefixes, so review loses the fixtures.
25
+ - tests/skills/configure-throttled-queue*/*
26
+ - README.md
27
+ ---
28
+
29
+ # Configure a dynamic-throttled-queue
30
+
31
+ `createThrottledQueue(options)` returns a function that enqueues callbacks, plus
32
+ control methods. Work through the steps in order; each ends with a check.
33
+
34
+ ## Setup
35
+
36
+ ```ts
37
+ import { createThrottledQueue } from "dynamic-throttled-queue";
38
+
39
+ // At most 5 request starts per second, spread evenly (one every 200 ms).
40
+ const queue = createThrottledQueue({ min_rpi: 5, interval: 1000 });
41
+
42
+ queue(async ({ signal }) => {
43
+ const response = await fetch("https://api.example.com/data", { signal });
44
+ if (!response.ok) return false; // fire-and-forget failure signal
45
+ });
46
+ ```
47
+
48
+ The package is ESM-only and requires Node.js 24 or later.
49
+
50
+ ## 1. Pick the start rate
51
+
52
+ The rate counts **callback starts per `interval` milliseconds**. It says nothing
53
+ about how long a callback runs.
54
+
55
+ | Option | Meaning | Rule |
56
+ | --- | --- | --- |
57
+ | `min_rpi` | Lowest starts per interval | Required positive integer |
58
+ | `max_rpi` | Highest starts per interval | Integer `>= min_rpi`; defaults to `min_rpi` |
59
+ | `interval` | Window length in ms | Required positive number |
60
+ | `evenly_spaced` | `true` (default): one start every `interval / rate` ms. `false`: up to `rate` starts at once per interval | |
61
+
62
+ - A provider limit of "100 requests per minute" is `{ min_rpi: 100, interval: 60_000 }`.
63
+ Use `evenly_spaced: false` only when bursts are allowed.
64
+ - With `max_rpi === min_rpi` the rate is fixed. With a range, the queue starts at
65
+ `Math.ceil((min_rpi + max_rpi) / 2)` and adapts between the bounds (step 3).
66
+ - Set `max_rpi` to the provider's documented ceiling, never above it: the default
67
+ strategy raises the rate after every clean interval that has pending work.
68
+
69
+ Check: `createThrottledQueue` throws synchronously on invalid numbers, and
70
+ `queue.getState().rate` shows the starting rate.
71
+
72
+ ## 2. Bound in-flight work separately
73
+
74
+ `concurrency` caps callbacks still awaiting asynchronous settlement. It is
75
+ independent of the start rate; omitting it allows unlimited in-flight work.
76
+ Use both when the provider limits requests per window **and** simultaneous
77
+ connections:
78
+
79
+ ```ts
80
+ import { createThrottledQueue } from "dynamic-throttled-queue";
81
+
82
+ const queue = createThrottledQueue({
83
+ min_rpi: 10,
84
+ interval: 1000,
85
+ concurrency: 3, // never more than 3 unsettled callbacks
86
+ maxQueueSize: 1000, // bound accepted, not-yet-terminal work
87
+ });
88
+ ```
89
+
90
+ When `maxQueueSize` is reached, `queue(...)` and `submit(...)` **throw
91
+ synchronously** (`Cannot enqueue work: maxQueueSize has been reached`). Capacity covers
92
+ pending, active, and retrying work until each item is terminal.
93
+
94
+ Check: `getState().active` never exceeds `concurrency`.
95
+
96
+ ## 3. Decide which failures adapt the rate
97
+
98
+ A failure is a callback that returns `false`, throws, or rejects. By default
99
+ every failure counts toward `errors_per_interval` (default `5`). When the count
100
+ reaches the threshold, the default `linear` strategy lowers the rate by 1; an
101
+ interval with zero errors and pending work raises it by 1. `back_off: true`
102
+ also skips one full interval after the threshold is hit.
103
+
104
+ Count only capacity signals with `rateOutcomeClassifier`. It receives
105
+ `{ kind: "returned-false" }`, `{ kind: "thrown", error }`, or
106
+ `{ kind: "rejected", error }` and returns whether the failure reduces the rate:
107
+
108
+ ```ts
109
+ import { createThrottledQueue, type FailureOutcome } from "dynamic-throttled-queue";
110
+
111
+ class HttpError extends Error {
112
+ constructor(readonly status: number) {
113
+ super(`HTTP ${status}`);
114
+ }
115
+ }
116
+
117
+ function isCapacitySignal(outcome: FailureOutcome): boolean {
118
+ if (outcome.kind === "returned-false") return false;
119
+ const { error } = outcome;
120
+ return error instanceof HttpError && (error.status === 429 || error.status >= 500);
121
+ }
122
+
123
+ const queue = createThrottledQueue({
124
+ min_rpi: 1,
125
+ max_rpi: 20,
126
+ interval: 1000,
127
+ errors_per_interval: 3,
128
+ back_off: true,
129
+ rateOutcomeClassifier: isCapacitySignal,
130
+ onRateChange: rate => console.log(`rate is now ${rate}/s`),
131
+ });
132
+ ```
133
+
134
+ If the classifier throws, the failure counts as rate-reducing. To change how
135
+ the rate moves (for example AIMD), read
136
+ [rate strategies and timing](references/rate-strategies.md).
137
+
138
+ Check: `getState().rateDecreases` grows only for the failures you classify as
139
+ capacity signals.
140
+
141
+ ## 4. Configure retries independently
142
+
143
+ `retry` is the hard cap on extra attempts (default `0`). `retryClassifier`
144
+ decides eligibility per failure and must return literal `true` to retry.
145
+ `retryBackoff` delays retries; without it they are immediate.
146
+
147
+ ```ts
148
+ import { createThrottledQueue } from "dynamic-throttled-queue";
149
+
150
+ const queue = createThrottledQueue({
151
+ min_rpi: 5,
152
+ interval: 1000,
153
+ retry: 3,
154
+ retryClassifier: (outcome, attempt) => outcome.kind !== "returned-false" && attempt <= 3,
155
+ retryBackoff: { strategy: "exponential", baseDelay: 250, maxDelay: 10_000, jitter: 0.2 },
156
+ });
157
+ ```
158
+
159
+ Retry and rate decisions are separate: a failure can be retryable,
160
+ rate-reducing, both, or neither. Every retry is a new attempt that obeys normal
161
+ pacing. For backoff formulas and validation, read
162
+ [retry details](references/retries.md).
163
+
164
+ Check: `getState().retried` counts scheduled retries; the callback's
165
+ `attempt` (1-based) counts up across retries.
166
+
167
+ ## 5. Honor server cooldowns
168
+
169
+ When a server says when capacity returns (HTTP 429 with `Retry-After`), call
170
+ `cooldownFor(ms)`. The queue starts nothing new until then, keeps pending
171
+ work, and makes no rate decision meanwhile. It does not retry or lower the rate
172
+ on its own; combine it with steps 3 and 4.
173
+
174
+ ```ts
175
+ import { createThrottledQueue } from "dynamic-throttled-queue";
176
+
177
+ const queue = createThrottledQueue({ min_rpi: 1, max_rpi: 10, interval: 1000, retry: 2, maxCooldown: 60_000 });
178
+
179
+ const task = queue.submit(async ({ signal }) => {
180
+ const response = await fetch("https://api.example.com/data", { signal });
181
+ if (response.status === 429) {
182
+ const seconds = Number(response.headers.get("Retry-After"));
183
+ if (Number.isFinite(seconds) && seconds >= 0) queue.cooldownFor(seconds * 1000);
184
+ throw new Error("rate limited");
185
+ }
186
+ return response.json() as Promise<unknown>;
187
+ });
188
+ ```
189
+
190
+ Convert the header yourself and clamp past dates to `0`: `NaN`, negative, and
191
+ infinite delays throw `RangeError`. Delays above `maxCooldown` are clamped. A
192
+ later deadline replaces an earlier one; overlapping hints do not add up.
193
+
194
+ Check: `getState().cooldownRemaining` is non-zero during the cooldown.
195
+
196
+ ## 6. Get results with task handles
197
+
198
+ Use `submit()` when the caller needs the value. Its semantics differ from the
199
+ fire-and-forget form:
200
+
201
+ - Every returned value, **including `false`**, is a successful result. Only a
202
+ throw or rejection fails, retries, and counts for the rate.
203
+ - `result` settles once: the final value, the last attempt's error, or the
204
+ cancel reason.
205
+ - `cancel(reason?)` rejects `result` immediately (an `AbortError` by default).
206
+ A pending item is removed; an active one has only its own signal aborted and
207
+ keeps its concurrency slot until the callback returns. Cancelled work never
208
+ retries and never counts as success, failure, or a rate error.
209
+
210
+ ```ts
211
+ import { createThrottledQueue } from "dynamic-throttled-queue";
212
+
213
+ const queue = createThrottledQueue({ min_rpi: 5, interval: 1000, retry: 2 });
214
+
215
+ const task = queue.submit(async ({ signal, attempt }) => {
216
+ const response = await fetch("https://api.example.com/item", { signal });
217
+ if (!response.ok) throw new Error(`HTTP ${response.status} on attempt ${attempt}`);
218
+ return (await response.json()) as { id: string };
219
+ });
220
+
221
+ setTimeout(() => task.cancel(), 5000);
222
+ const item = await task.result.catch(() => undefined);
223
+ ```
224
+
225
+ Check: every `result` you cancel or abort has a rejection handler.
226
+
227
+ ## 7. Control the lifecycle
228
+
229
+ | Call | Effect | Reversible |
230
+ | --- | --- | --- |
231
+ | `pause()` | No new starts; keeps work; active callbacks finish | `resume()` |
232
+ | `stop()` | Clears timers; keeps work | The next enqueue restarts it |
233
+ | `abort()` | Discards pending work, aborts the shared signal, later enqueues throw | No |
234
+
235
+ A throwing or malformed `rateStrategy` moves the queue to `failed`: terminal,
236
+ pending work discarded, enqueues throw the strategy error, and `waitForIdle()`
237
+ promises reject with it.
238
+ Create a new queue to continue. For per-state rules, read
239
+ [lifecycle details](references/lifecycle.md) before writing shutdown,
240
+ pause, or error-recovery code.
241
+
242
+ Drain and inspect:
243
+
244
+ ```ts
245
+ import { createThrottledQueue } from "dynamic-throttled-queue";
246
+
247
+ const queue = createThrottledQueue({ min_rpi: 5, interval: 1000 });
248
+ for (const id of ["a", "b", "c"]) {
249
+ queue(async ({ signal }) => {
250
+ await fetch(`https://api.example.com/items/${id}`, { signal });
251
+ });
252
+ }
253
+
254
+ await queue.waitForIdle(); // pending, active, and delayed retries all terminal
255
+ const { succeeded, failed, state } = queue.getState();
256
+ console.log({ succeeded, failed, state });
257
+ ```
258
+
259
+ For every `getState()` field and `waitForIdle()` edge case, read
260
+ [state and idle](references/state-and-idle.md).
261
+
262
+ Check: `waitForIdle()` resolves and `getState().pending` and `.active` are `0`.
263
+
264
+ ## Common Mistakes
265
+
266
+ ### CRITICAL: Ignoring the signal and expecting abort or cancel to stop work
267
+
268
+ ```ts
269
+ import { createThrottledQueue } from "dynamic-throttled-queue";
270
+
271
+ const queue = createThrottledQueue({ min_rpi: 5, interval: 1000 });
272
+ // Wrong: abort() cannot stop this request
273
+ queue(async () => { await fetch("https://api.example.com/data"); });
274
+ // Right
275
+ queue(async ({ signal }) => { await fetch("https://api.example.com/data", { signal }); });
276
+ ```
277
+
278
+ Cancellation is cooperative. A callback that ignores `signal` keeps running
279
+ after `abort()` or `cancel()`; only its outcome is discarded. Source: README
280
+ "Lifecycle"; `src/scheduler.ts`.
281
+
282
+ ### CRITICAL: Starting a promise without returning or awaiting it
283
+
284
+ ```ts
285
+ import { createThrottledQueue } from "dynamic-throttled-queue";
286
+
287
+ const queue = createThrottledQueue({ min_rpi: 5, interval: 1000, concurrency: 2, retry: 2 });
288
+ // Wrong: the queue sees a synchronous success; no retry, no concurrency slot
289
+ queue(({ signal }) => { void fetch("https://api.example.com/data", { signal }).catch(() => {}); });
290
+ // Right: return (or await) the work
291
+ queue(({ signal }) => fetch("https://api.example.com/data", { signal }));
292
+ ```
293
+
294
+ The queue only tracks what the callback returns. An unreturned promise cannot
295
+ fail, retry, hold a `concurrency` slot, or delay `waitForIdle()`. Source: README
296
+ "Queuing work".
297
+
298
+ ### HIGH: Using the rate to limit simultaneous requests
299
+
300
+ `min_rpi: 3` allows 3 starts per interval; slow callbacks pile up without
301
+ bound. Add `concurrency` for an in-flight cap. Source: `ThrottleOptions.concurrency`.
302
+
303
+ ### HIGH: Returning `false` from `submit()` to signal failure
304
+
305
+ In `submit()`, `false` is a successful result: no retry, no rate reduction.
306
+ Throw instead. Fire-and-forget callbacks still treat `false` as failure; any
307
+ other returned value is success. Source: `TaskCallback` and `ThrottleCallback`
308
+ in `src/scheduler.ts`.
309
+
310
+ ### HIGH: Expecting `retryClassifier` or cooldowns to change the rate
311
+
312
+ Retry eligibility, rate counting (`rateOutcomeClassifier`), and `cooldownFor`
313
+ are three independent decisions. Configure each one you need. Source: README
314
+ "Failure classification" and "Server-directed cooldown".
315
+
316
+ ### HIGH: Unhandled rejections from cancelled or aborted tasks
317
+
318
+ `cancel()` and `abort()` reject `task.result`. Attach a handler such as
319
+ `task.result.catch(() => {})` if you do not await it.
320
+
321
+ ### MEDIUM: Treating `stop()` as shutdown
322
+
323
+ `stop()` keeps pending work and the next enqueue restarts processing. Use
324
+ `abort()` for terminal shutdown.
325
+
326
+ ### MEDIUM: Catching the `maxQueueSize` overflow as a return value
327
+
328
+ A full queue throws from `queue(...)` and `submit(...)`. Wrap enqueue
329
+ calls in `try`/`catch` when `maxQueueSize` is set.
330
+
331
+ ## Completion
332
+
333
+ The configuration is complete when:
334
+
335
+ 1. The start rate matches the provider limit and `max_rpi` does not exceed it.
336
+ 2. `concurrency` is set when the provider limits simultaneous requests.
337
+ 3. Each failure type is deliberately classified for rate reduction and retry.
338
+ 4. Every async callback passes `signal` to its I/O.
339
+ 5. Every `submit()` result is awaited or has a rejection handler.
340
+ 6. Shutdown uses `abort()` or `waitForIdle()`, not `stop()`.
341
+
342
+ If the queue reports `state: "failed"`, fix the custom `rateStrategy` and
343
+ create a new queue.
@@ -0,0 +1,46 @@
1
+ # Lifecycle details
2
+
3
+ Read this before writing shutdown, pause/resume, or error-recovery code, or
4
+ when a queue stops starting work unexpectedly.
5
+
6
+ | State | Pending work and enqueue | Active work | Lifecycle calls |
7
+ | --- | --- | --- | --- |
8
+ | `running` | Starts normally; enqueues accepted | Runs | `pause()` retains work and stops starts. `stop()` retains work and clears timers. `abort()` is terminal. A strategy failure moves to `failed`. |
9
+ | `paused` | Pending work, new enqueues, and retries are kept but do not start | Continues and settles | `resume()` restarts pacing at the current rate with a fresh observation window. `pause()` is idempotent. `stop()` clears the paused state. |
10
+ | `stopped` | Pending work kept; the next enqueue restarts scheduling | Continues and settles | `pause()` and `resume()` do nothing. `stop()` is idempotent. |
11
+ | `aborted` | Pending work discarded; enqueues throw | Receives the aborted shared signal and may finish cooperatively | Nothing restarts scheduling. `abort()` is idempotent. |
12
+ | `failed` | Pending work and delayed retries discarded; enqueues throw the strategy error | Continues and settles without retries or accounting; the shared signal is **not** aborted | Terminal. All lifecycle calls do nothing. |
13
+
14
+ ## Rules that are easy to miss
15
+
16
+ - While paused, outcomes do not adjust the rate. A failure can still create a
17
+ retry, which waits for `resume()`.
18
+ - `stop()` cannot cancel an active callback, and that callback settling does not
19
+ restart scheduling. Only a new enqueue does, and it also resumes frozen
20
+ delayed retries.
21
+ - `abort()` aborts one shared signal for fire-and-forget callbacks; `submit()`
22
+ callbacks get a per-item signal that `abort()` also aborts. Late outcomes are
23
+ discarded and never retry.
24
+ - On `failed`, the strategy error is rethrown where the decision ran: as an
25
+ uncaught exception from the adaptive-rate timer, or as an unhandled rejection
26
+ when a slow async callback completes a settled-timing window. Pending and
27
+ later `waitForIdle()` calls reject with it. Create a new queue to resume.
28
+
29
+ ## Cooldown interaction
30
+
31
+ - `pause()` and `cooldownFor()` are separate. A cooldown keeps elapsing while
32
+ paused, its end does not resume a paused queue, and `resume()` does not end it.
33
+ - `stop()` clears the cooldown timer but keeps the deadline, so the restarting
34
+ enqueue still waits for it.
35
+ - `abort()` and a strategy failure clear the cooldown; later valid
36
+ `cooldownFor()` calls do nothing, but invalid delays still throw `RangeError`.
37
+ - A cooldown replaces any adaptive-rate backoff in progress. Failures that
38
+ settle during a cooldown count toward the first decision after it.
39
+
40
+ ## Task handles across the lifecycle
41
+
42
+ - `pause()` and `stop()` leave `result` pending.
43
+ - `abort()` rejects every unsettled `result` with the queue signal's
44
+ `AbortError`; a strategy failure rejects them with the strategy error.
45
+ - `submit()` throws synchronously and returns no handle when the queue is full,
46
+ aborted, or failed.
@@ -0,0 +1,68 @@
1
+ # Rate strategies and adjustment timing
2
+
3
+ Read this when the default one-step `linear` adaptation is too slow or too
4
+ fast, when writing a custom `RateStrategy`, or when slow callbacks make rate
5
+ decisions land in the wrong interval.
6
+
7
+ ## Built-in strategies
8
+
9
+ | Strategy | Threshold reached | Clean interval with pending work | Otherwise |
10
+ | --- | --- | --- | --- |
11
+ | `linear` (default) | `currentRate - 1`, request backoff | `currentRate + 1` | hold |
12
+ | `aimd({ increaseBy = 1, decreaseFactor = 0.5 })` | `Math.floor(currentRate * decreaseFactor)`, request backoff | `currentRate + increaseBy` | hold |
13
+
14
+ A backoff request (`shouldBackOff: true`) skips an interval only when the queue
15
+ has `back_off: true`.
16
+
17
+ "Clean" means zero counted errors and the previous window was not a backoff.
18
+ Partial-error, empty, and immediately-post-backoff windows hold the rate. The
19
+ queue clamps every `nextRate` to `[min_rpi, max_rpi]`. `aimd()` throws unless
20
+ `increaseBy` is a positive integer and `0 < decreaseFactor < 1`.
21
+
22
+ ```ts
23
+ import { aimd, createThrottledQueue } from "dynamic-throttled-queue";
24
+
25
+ const queue = createThrottledQueue({
26
+ min_rpi: 1,
27
+ max_rpi: 100,
28
+ interval: 1000,
29
+ rateStrategy: aimd({ increaseBy: 2, decreaseFactor: 0.5 }),
30
+ });
31
+ ```
32
+
33
+ ## Custom strategies
34
+
35
+ A `RateStrategy` is a pure function. It receives a frozen observation
36
+ `{ currentRate, minRate, maxRate, errorCount, errorThreshold, hasPendingWork, wasBackedOff }`
37
+ and returns `{ nextRate, shouldBackOff }`.
38
+
39
+ ```ts
40
+ import { createThrottledQueue, type RateStrategy } from "dynamic-throttled-queue";
41
+
42
+ const decreaseOnly: RateStrategy = ({ currentRate, minRate, errorCount, errorThreshold }) => ({
43
+ nextRate: errorCount >= errorThreshold ? Math.max(minRate, currentRate - 1) : currentRate,
44
+ shouldBackOff: errorCount >= errorThreshold,
45
+ });
46
+
47
+ const queue = createThrottledQueue({ min_rpi: 1, max_rpi: 10, interval: 1000, rateStrategy: decreaseOnly });
48
+ ```
49
+
50
+ - `nextRate` must be a finite integer and `shouldBackOff` a boolean. Anything
51
+ else, or a thrown error, **fails the queue permanently** (see
52
+ [lifecycle](lifecycle.md)). Never return `NaN`, fractions, or `undefined`.
53
+ - `shouldBackOff` only pauses scheduling when the queue has `back_off: true`.
54
+
55
+ ## Adjustment timing
56
+
57
+ - `adjustmentTiming: "interval"` (default): each interval decides from the
58
+ outcomes that have settled so far. A slow callback can settle after its start
59
+ interval and affect a later decision.
60
+ - `adjustmentTiming: "settled"`: a window holds every attempt started during one
61
+ interval. When collection closes, no further callbacks start until every
62
+ attempt in the window settles, then exactly one decision is made. Use it when
63
+ callbacks run longer than `interval` and decisions must reflect complete
64
+ windows. A callback that never settles blocks later windows until it settles
65
+ or the queue is aborted, so give callbacks timeouts.
66
+
67
+ While paused, settled outcomes do not count toward the rate. In settled timing,
68
+ `pause()` discards the open window.
@@ -0,0 +1,52 @@
1
+ # Retry details
2
+
3
+ Read this when choosing a `retryBackoff` policy, when `createThrottledQueue`
4
+ rejects retry options, or when retry counts in `getState()` look wrong.
5
+
6
+ ## Eligibility
7
+
8
+ 1. A failure (`false` in fire-and-forget form, a throw, or a rejection) is
9
+ eligible only while `retry` budget remains. `retry` must be a non-negative
10
+ integer.
11
+ 2. If `retryClassifier` is set, it is called with the normalized outcome and the
12
+ one-based attempt that just failed. Only literal `true` retries; any other
13
+ value makes the failure permanent. It is not called once the budget is spent.
14
+ 3. If the classifier throws, the queue retries within the remaining budget.
15
+
16
+ Cancelled tasks, and outcomes that settle after `abort()` or a strategy
17
+ failure, never retry.
18
+
19
+ ## Backoff
20
+
21
+ `retryBackoff` is
22
+ `{ strategy: "fixed" | "linear" | "exponential"; baseDelay: number; maxDelay?: number; jitter?: number; random?: () => number }`.
23
+
24
+ For retry index `n` (first retry is `1`):
25
+
26
+ | Strategy | Delay before cap |
27
+ | --- | --- |
28
+ | `fixed` | `baseDelay` |
29
+ | `linear` | `baseDelay × n` |
30
+ | `exponential` | `baseDelay × 2^(n - 1)` |
31
+
32
+ The delay is capped at `maxDelay`, symmetric percentage `jitter` (`0`–`1`) is
33
+ applied, then it is capped again. `baseDelay` and `maxDelay` must be finite and
34
+ non-negative; an unknown `strategy` throws. Pass `random` to make jitter
35
+ deterministic in tests; a throwing or out-of-range `random` falls back to no
36
+ jitter.
37
+
38
+ Backoff starts when the failed attempt settles. It is independent of the
39
+ adaptive-rate `back_off` option.
40
+
41
+ ## Scheduling
42
+
43
+ Delayed retries count as pending work and occupy `maxQueueSize` capacity. When
44
+ due, they rejoin the tail of the queue and obey normal pacing; equal due times
45
+ keep their scheduling order. While paused or stopped, their remaining delay
46
+ freezes. `abort()` discards them.
47
+
48
+ ## Counters
49
+
50
+ `started`, `succeeded`, and `failed` count attempts: a failure is counted even
51
+ when a later retry succeeds. `retried` increments only when another attempt is
52
+ actually scheduled.
@@ -0,0 +1,38 @@
1
+ # State and idle
2
+
3
+ Read this when reporting queue metrics, asserting on queue state in tests, or
4
+ waiting for work to finish.
5
+
6
+ ## `getState()`
7
+
8
+ Returns a frozen snapshot; mutating it does not affect the queue.
9
+
10
+ | Field | Meaning |
11
+ | --- | --- |
12
+ | `rate` | Current starts per interval |
13
+ | `pending` | Queued items plus delayed retries |
14
+ | `active` | Callbacks currently executing |
15
+ | `state` | `"running"`, `"paused"`, `"stopped"`, `"aborted"`, or `"failed"` |
16
+ | `cooldownRemaining` | Ms until the cooldown ends, rounded up; `0` when none |
17
+ | `started`, `succeeded`, `failed` | Attempts; a retry is a new attempt |
18
+ | `retried` | Retries actually scheduled |
19
+ | `canceled` | Submitted items whose `result` `cancel()` rejected |
20
+ | `rateIncreases`, `rateDecreases` | Applied rate changes; match `onRateChange` calls exactly |
21
+ | `cooldowns`, `cooldownTotal` | `cooldownFor()` calls that moved the deadline later, and the ms they added |
22
+
23
+ Counters are monotonic and stop changing after `abort()` or a strategy failure.
24
+ A cancelled active attempt counts as neither succeeded nor failed.
25
+
26
+ ## `waitForIdle()`
27
+
28
+ Resolves once pending work, active callbacks, and delayed retries are all
29
+ terminal; immediately if already idle.
30
+
31
+ - One-shot: a later enqueue does not affect a resolved promise. Concurrent
32
+ callers resolve together.
33
+ - A failure that schedules a retry never produces a transient idle.
34
+ - After `stop()`, waiters stay pending until a later enqueue lets the work
35
+ finish. Do not use `stop()` + `waitForIdle()` as shutdown.
36
+ - After `abort()`, waiters resolve as soon as no callback is active.
37
+ - While paused, waiters resolve only when pending and active are both `0`.
38
+ - On `failed`, every waiter rejects with the strategy error at once.