dynamic-throttled-queue 2.3.0-rc.477ab9c → 2.3.0-rc.63bc2b5

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
@@ -28,7 +28,7 @@ throttle(() => {
28
28
 
29
29
  Callbacks can return `false` to signal a failure (used for dynamic rate adjustment and retry). Async callbacks (returning a Promise) are also supported — rejections and `false` resolutions count as failures. By default, every failure reduces the adaptive rate; use `rateOutcomeClassifier` when only selected failures should do so. Use `retryClassifier` to separately decide whether a failure is eligible for retry.
30
30
 
31
- Each callback receives an execution context containing the queue-owned `AbortSignal`. Existing zero-argument callbacks remain supported. Use the signal to cooperatively cancel in-flight work:
31
+ Each callback receives an execution context containing an `AbortSignal` and the one-based `attempt` number (retries count up from 1). Fire-and-forget callbacks get the queue-owned signal, which only `abort()` aborts. Callbacks passed to [`submit()`](#task-handles) get a signal scoped to their item instead. Existing zero-argument callbacks remain supported. Use the signal to cooperatively cancel in-flight work:
32
32
 
33
33
  ```ts
34
34
  throttle(async ({ signal }) => {
@@ -41,6 +41,29 @@ Set `concurrency` to bound callbacks that are still awaiting asynchronous comple
41
41
 
42
42
  Set `maxQueueSize` to bound accepted work. Capacity is reserved from enqueue through terminal success or failure, including pending callbacks, active callbacks, and retries. A full queue makes `enqueue()` throw synchronously in v2; unlimited capacity remains the default. In v3, a full queue will return `false` instead.
43
43
 
44
+ ### Task handles
45
+
46
+ `submit()` accepts a callback like the fire-and-forget form, but returns a handle for that one item, covering every attempt it makes:
47
+
48
+ ```ts
49
+ const task = queue.submit(async ({ signal, attempt }) => {
50
+ const response = await fetch("/api/data", { signal });
51
+ if (!response.ok) throw new Error(`HTTP ${response.status} on attempt ${attempt}`);
52
+ return response.json();
53
+ });
54
+
55
+ task.cancel();
56
+ const data = await task.result;
57
+ ```
58
+
59
+ - **Results.** Every value the callback returns or resolves, including `false`, is the result. Only a throw or a rejection is a failure, and it goes through `retry`, `retryClassifier`, and `rateOutcomeClassifier` the same as any other failure. `result` fulfills once, with the final successful value, or rejects once, with the final attempt's error after retries end.
60
+ - **Cancellation.** `cancel(reason?)` rejects `result` immediately with `reason`, or with an `AbortError` when no reason is given. A canceled item that has not started (including one waiting on a delayed retry) is removed: it never starts, frees its `maxQueueSize` slot, and does not use a start slot. A canceled active item has its own signal aborted, and only that signal; other work and the queue signal are unaffected. It keeps its concurrency slot until the callback returns, and `waitForIdle()` waits for it. Its outcome never retries and never counts as a success, a failure, or a rate-reducing error. Calling `cancel()` again, or after `result` has settled, does nothing.
61
+ - **Queue termination.** `abort()` rejects every unsettled item at once with the queue signal's `AbortError` and aborts each item's signal. A strategy failure (see [Lifecycle](#lifecycle)) does the same with the strategy error. Values that arrive later are discarded.
62
+ - **Retained work.** `pause()` and `stop()` keep items and leave their results pending.
63
+ - **Admission.** `submit()` throws synchronously and returns no handle when `enqueue()` would throw: the queue is full, aborted, or failed.
64
+
65
+ `result` is an ordinary promise. If you cancel or abort without awaiting it, attach a handler (for example `task.result.catch(() => {})`) so the rejection is not reported as unhandled.
66
+
44
67
  ## Options
45
68
 
46
69
  | Param | Type | Default | Description |
@@ -78,6 +101,7 @@ With `adjustmentTiming: "settled"`, an observation window contains every callbac
78
101
 
79
102
  | Property | Type | Description |
80
103
  | -------- | ---- | ----------- |
104
+ | `submit(callback)` | `<T>(callback) => TaskHandle<T>` | Enqueue one item and return its `{ result, cancel }` handle; see [Task handles](#task-handles) |
81
105
  | `pause()` | `() => void` | Temporarily prevent new callback starts while retaining accepted work |
82
106
  | `resume()` | `() => void` | Resume a paused queue with a fresh pacing and observation window |
83
107
  | `stop()` | `() => void` | Stop processing the queue immediately |
@@ -115,7 +139,7 @@ In settled timing, `pause()` discards the in-progress observation window rather
115
139
 
116
140
  A queue fails when `rateStrategy` throws or returns a malformed decision. The queue clears its timers, discards pending callbacks and delayed retries, and reports `state: "failed"`. The original error is still rethrown where the decision ran: an uncaught exception from the adaptive-rate timer, or an unhandled rejection when a slow asynchronous callback completes a settled-timing window. Pending `waitForIdle()` promises reject with that error immediately, even while callbacks are still active; later `waitForIdle()` calls reject with it and later enqueues throw it. Unlike `abort()`, failure does not wait for active callbacks to settle. Create a new queue to resume work.
117
141
 
118
- `getState()` returns a frozen `QueueState` snapshot. Each call is independent; mutations to the returned object do not affect the queue. Fields: `rate` (current rate), `pending` (queued + delayed retries), `active` (callbacks executing), `state` (`"running"` | `"paused"` | `"stopped"` | `"aborted"` | `"failed"`), and monotonic lifetime counters `started`, `succeeded`, `failed`, `retried`, `rateIncreases`, `rateDecreases`. `started`/`succeeded`/`failed` count callback attempts: a retry is a new attempt; a failure is counted even when a later retry succeeds. `retried` increments only when another attempt is actually scheduled. Rate-direction counters match applied rate changes and `onRateChange` notifications exactly. Counters do not change for settlements after `abort()` or a strategy failure.
142
+ `getState()` returns a frozen `QueueState` snapshot. Each call is independent; mutations to the returned object do not affect the queue. Fields: `rate` (current rate), `pending` (queued + delayed retries), `active` (callbacks executing), `state` (`"running"` | `"paused"` | `"stopped"` | `"aborted"` | `"failed"`), and monotonic lifetime counters `started`, `succeeded`, `failed`, `retried`, `canceled`, `rateIncreases`, `rateDecreases`. `started`/`succeeded`/`failed` count callback attempts: a retry is a new attempt; a failure is counted even when a later retry succeeds. `retried` increments only when another attempt is actually scheduled. `canceled` counts submitted items whose result `cancel()` rejected; a canceled active attempt counts as neither succeeded nor failed. Rate-direction counters match applied rate changes and `onRateChange` notifications exactly. Counters do not change for settlements after `abort()` or a strategy failure.
119
143
 
120
144
  `waitForIdle()` returns a `Promise<void>` that resolves once all pending callbacks, active executions, and delayed retries have reached a terminal outcome. If the queue is already idle the promise resolves immediately. Each call is one-shot: a later enqueue does not affect a promise that has already resolved. Multiple simultaneous callers all resolve at the same idle transition without retaining waiter state. A callback failure that triggers a retry never exposes a transient idle transition between the failed attempt and the retry. `stop()` retains pending work, so existing waiters remain pending until that work completes after a later enqueue resumes the queue. `abort()` discards pending work, so waiters resolve as soon as no callback is active: immediately when none is running, otherwise when the last active callback settles. Post-abort settlements do not create new retry work. A paused queue resolves waiters only when both pending and active work are zero. A failed queue rejects every waiter with the strategy error at once, without waiting for active callbacks.
121
145
 
@@ -4,7 +4,7 @@ import type { ThrottleHandle } from "./scheduler.js";
4
4
  export { aimd, linear } from "./adaptive-rate.js";
5
5
  export type { AdjustmentTiming, AimdOptions, RateFailureOutcome, RateOutcomeClassifier, RateStrategy, RateStrategyDecision, RateStrategyObservation } from "./adaptive-rate.js";
6
6
  export type { RetryBackoff, RetryClassifier } from "./retry-policy.js";
7
- export type { ExecutionContext, QueueLifecycleState, QueueState, ThrottleCallback, ThrottleFn, ThrottleHandle } from "./scheduler.js";
7
+ export type { ExecutionContext, QueueLifecycleState, QueueState, TaskCallback, TaskHandle, ThrottleCallback, ThrottleFn, ThrottleHandle } from "./scheduler.js";
8
8
  export type ThrottleOptions = {
9
9
  min_rpi: number;
10
10
  interval: number;
@@ -29,6 +29,8 @@ export type PendingWork<T> = {
29
29
  accept: (item: T) => void;
30
30
  /** Makes the oldest queued item active and returns it, or `undefined` when nothing is queued. */
31
31
  take: () => T | undefined;
32
+ /** Drops `item`, which must be queued or held, and releases its reservation. */
33
+ remove: (item: T) => void;
32
34
  /**
33
35
  * Ends one active item. `decide` runs once the item no longer counts as active but still holds its
34
36
  * reservation; returning a retry keeps that reservation, returning nothing releases it. `observe`
@@ -2,6 +2,8 @@ export function createPendingWork(options, host) {
2
2
  const { capacity, compactThreshold } = options;
3
3
  const queue = [];
4
4
  let head = 0;
5
+ /** Queued items that were removed but still sit between `head` and the tail; `take` skips them. */
6
+ const removed = new Set();
5
7
  const held = [];
6
8
  let frozen = false;
7
9
  let active = 0;
@@ -9,7 +11,7 @@ export function createPendingWork(options, host) {
9
11
  let deciding = 0;
10
12
  const idleWaiters = [];
11
13
  function queued() {
12
- return queue.length - head;
14
+ return queue.length - head - removed.size;
13
15
  }
14
16
  function pending() {
15
17
  return queued() + held.length;
@@ -44,6 +46,17 @@ export function createPendingWork(options, host) {
44
46
  held.length = 0;
45
47
  queue.length = 0;
46
48
  head = 0;
49
+ removed.clear();
50
+ }
51
+ function compact() {
52
+ if (head === queue.length) {
53
+ queue.length = 0;
54
+ head = 0;
55
+ }
56
+ else if (head > compactThreshold && head > queue.length / 2) {
57
+ queue.splice(0, head);
58
+ head = 0;
59
+ }
47
60
  }
48
61
  return {
49
62
  get queued() {
@@ -61,19 +74,24 @@ export function createPendingWork(options, host) {
61
74
  queue.push(item);
62
75
  },
63
76
  take() {
64
- if (head === queue.length)
65
- return undefined;
66
- const item = queue[head++];
67
- active++;
68
- if (head === queue.length) {
69
- queue.length = 0;
70
- head = 0;
71
- }
72
- else if (head > compactThreshold && head > queue.length / 2) {
73
- queue.splice(0, head);
74
- head = 0;
77
+ while (head < queue.length) {
78
+ const item = queue[head++];
79
+ if (removed.delete(item))
80
+ continue;
81
+ active++;
82
+ compact();
83
+ return item;
75
84
  }
76
- return item;
85
+ compact();
86
+ return undefined;
87
+ },
88
+ remove(item) {
89
+ const index = held.findIndex(retry => retry.item === item);
90
+ if (index === -1)
91
+ removed.add(item);
92
+ else
93
+ clearTimeout(held.splice(index, 1)[0].timeout);
94
+ notifyIdle();
77
95
  },
78
96
  settle(decide, observe) {
79
97
  active--;
@@ -1 +1 @@
1
- {"version":3,"file":"pending-work.js","sourceRoot":"","sources":["../src/pending-work.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pending-work.js","sourceRoot":"","sources":["../src/pending-work.ts"],"names":[],"mappings":"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"}
@@ -3,10 +3,24 @@ import type { PendingWorkOptions } from "./pending-work.js";
3
3
  import type { RetryPolicy } from "./retry-policy.js";
4
4
  export type ExecutionContext = Readonly<{
5
5
  signal: AbortSignal;
6
+ /** One-based attempt number; retries of the same item count up from 1. */
7
+ attempt: number;
6
8
  }>;
7
9
  /** Return `false` to signal failure (increments error count, triggers retry if configured). */
8
10
  export type ThrottleCallback = (context: ExecutionContext) => boolean | void | Promise<boolean | void>;
9
11
  export type ThrottleFn = (callback: ThrottleCallback) => void;
12
+ /** Submitted work. Every returned value, including `false`, is a result; only a throw or rejection fails. */
13
+ export type TaskCallback<T> = (context: ExecutionContext) => T | Promise<T>;
14
+ /** One accepted logical item across all of its attempts. */
15
+ export type TaskHandle<T> = Readonly<{
16
+ /** Settles once: the final value, the final failure, or the cancellation reason. */
17
+ result: Promise<T>;
18
+ /**
19
+ * Rejects `result` with `reason` (an `AbortError` by default) unless it already settled. A pending
20
+ * item is removed; an active one has its signal aborted and is never retried. Repeat calls do nothing.
21
+ */
22
+ cancel: (reason?: unknown) => void;
23
+ }>;
10
24
  export type QueueLifecycleState = "running" | "paused" | "stopped" | "aborted" | "failed";
11
25
  export type QueueState = Readonly<{
12
26
  rate: number;
@@ -17,10 +31,13 @@ export type QueueState = Readonly<{
17
31
  succeeded: number;
18
32
  failed: number;
19
33
  retried: number;
34
+ /** Submitted items whose result was rejected by `cancel()`. */
35
+ canceled: number;
20
36
  rateIncreases: number;
21
37
  rateDecreases: number;
22
38
  }>;
23
39
  export type ThrottleHandle = ThrottleFn & {
40
+ submit: <T>(callback: TaskCallback<T>) => TaskHandle<T>;
24
41
  pause: () => void;
25
42
  resume: () => void;
26
43
  stop: () => void;
package/dist/scheduler.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { createAdaptiveRate } from "./adaptive-rate.js";
2
2
  import { createPendingWork } from "./pending-work.js";
3
+ const returnedFalse = Object.freeze({ kind: "returned-false" });
3
4
  /** The state each event leads to. An event missing from the current state's row is a no-op. */
4
5
  const lifecycleTransitions = {
5
6
  running: { pause: "paused", stop: "stopped", abort: "aborted", fail: "failed" },
@@ -15,7 +16,10 @@ export function createScheduler(options, adaptiveRateOptions, retryPolicy) {
15
16
  let cnt_succeeded = 0;
16
17
  let cnt_failed = 0;
17
18
  let cnt_retried = 0;
19
+ let cnt_canceled = 0;
18
20
  const abortController = new AbortController();
21
+ /** Submitted items whose result has not settled. */
22
+ const tasks = new Set();
19
23
  const work = createPendingWork(pendingWorkOptions, { retryQueued: start });
20
24
  const adaptiveRate = createAdaptiveRate(adaptiveRateOptions, {
21
25
  hasPendingWork: () => work.queued > 0,
@@ -56,69 +60,135 @@ export function createScheduler(options, adaptiveRateOptions, retryPolicy) {
56
60
  adaptiveRate.stop();
57
61
  work.discard();
58
62
  abortController.abort();
63
+ rejectTasks(abortController.signal.reason);
59
64
  return;
60
65
  case "failed":
61
66
  adaptiveRate.stop();
62
67
  work.fail(error);
68
+ rejectTasks(error);
63
69
  }
64
70
  }
65
- function nextAttempt(item, outcome) {
66
- if (!outcome)
67
- return undefined;
68
- const decision = retryPolicy.decide(outcome, item.attempt);
69
- if (!decision)
70
- return undefined;
71
- cnt_retried++;
72
- return { item: { fn: item.fn, attempt: item.attempt + 1 }, ...decision };
71
+ /** Rejects every unsettled submitted item with `reason` and aborts its signal. */
72
+ function rejectTasks(reason) {
73
+ // Snapshot first: abort listeners run synchronously and may re-enter the queue.
74
+ const affected = [...tasks];
75
+ tasks.clear();
76
+ for (const task of affected) {
77
+ task.controller.abort(reason);
78
+ task.reject(reason);
79
+ }
80
+ }
81
+ function nextAttempt(item, outcome, value) {
82
+ const { task } = item;
83
+ if (outcome) {
84
+ const decision = retryPolicy.decide(outcome, item.attempt);
85
+ if (decision && (task === undefined || tasks.has(task))) {
86
+ cnt_retried++;
87
+ item.attempt++;
88
+ if (task)
89
+ task.active = false;
90
+ return { item, ...decision };
91
+ }
92
+ }
93
+ if (task && tasks.delete(task)) {
94
+ // Submitted items never return-false, so a failure always carries its error.
95
+ if (outcome)
96
+ task.reject("error" in outcome ? outcome.error : undefined);
97
+ else
98
+ task.resolve(value);
99
+ }
100
+ return undefined;
73
101
  }
74
- function handleSettlement(item, outcome, reportSettlement, resume = false) {
102
+ function handleSettlement(item, outcome, value, reportSettlement, resume = false) {
75
103
  if (lifecycle.state === "aborted" || lifecycle.state === "failed") {
76
104
  work.settle();
77
105
  return;
78
106
  }
79
- if (outcome)
80
- cnt_failed++;
81
- else
82
- cnt_succeeded++;
83
- work.settle(() => nextAttempt(item, outcome), () => {
107
+ const observe = () => {
84
108
  reportSettlement(outcome);
85
109
  // An async settlement frees a slot; a start may be due if concurrency held one back.
86
110
  if (resume)
87
111
  start();
88
- });
112
+ };
113
+ if (item.task && !tasks.has(item.task)) {
114
+ // Canceled: the attempt's outcome neither counts nor retries, but the observation window still closes.
115
+ outcome = undefined;
116
+ work.settle(undefined, observe);
117
+ return;
118
+ }
119
+ if (outcome)
120
+ cnt_failed++;
121
+ else
122
+ cnt_succeeded++;
123
+ work.settle(() => nextAttempt(item, outcome, value), observe);
124
+ }
125
+ /** Only fire-and-forget callbacks report failure by returning `false`. */
126
+ function returnedOutcome(item, value) {
127
+ return value === false && item.task === undefined ? returnedFalse : undefined;
89
128
  }
90
129
  function execute(item) {
91
130
  const reportSettlement = adaptiveRate.started();
92
131
  cnt_started++;
132
+ const { task } = item;
133
+ if (task)
134
+ task.active = true;
93
135
  let result;
94
136
  try {
95
- result = item.fn({ signal: abortController.signal });
137
+ result = item.fn({ signal: task?.controller.signal ?? abortController.signal, attempt: item.attempt });
96
138
  }
97
139
  catch (error) {
98
- handleSettlement(item, { kind: "thrown", error }, reportSettlement);
140
+ handleSettlement(item, { kind: "thrown", error }, undefined, reportSettlement);
99
141
  return;
100
142
  }
101
143
  if (result instanceof Promise) {
102
- void result.then(value => handleSettlement(item, value === false ? { kind: "returned-false" } : undefined, reportSettlement, true), (error) => handleSettlement(item, { kind: "rejected", error }, reportSettlement, true));
144
+ void result.then((value) => handleSettlement(item, returnedOutcome(item, value), value, reportSettlement, true), (error) => handleSettlement(item, { kind: "rejected", error }, undefined, reportSettlement, true));
103
145
  return;
104
146
  }
105
- handleSettlement(item, result === false ? { kind: "returned-false" } : undefined, reportSettlement);
147
+ handleSettlement(item, returnedOutcome(item, result), result, reportSettlement);
106
148
  }
107
149
  function start() {
108
150
  if (lifecycle.state === "running")
109
151
  adaptiveRate.start();
110
152
  }
111
- function enqueue(callback) {
153
+ /** Admits `item` or throws: the queue is terminal or every capacity reservation is taken. */
154
+ function accept(item) {
112
155
  if (lifecycle.state === "aborted")
113
156
  throw new Error("Cannot enqueue work after the queue has been aborted");
114
157
  if (lifecycle.state === "failed")
115
158
  throw lifecycle.error;
116
- work.accept({ fn: callback, attempt: 1 });
159
+ work.accept(item);
160
+ }
161
+ /** Schedules newly accepted work. */
162
+ function schedule() {
117
163
  if (lifecycle.state === "stopped")
118
164
  transition("restart");
119
165
  else
120
166
  start();
121
167
  }
168
+ function enqueue(callback) {
169
+ accept({ fn: callback, attempt: 1 });
170
+ schedule();
171
+ }
172
+ enqueue.submit = (callback) => {
173
+ const { promise, resolve, reject } = Promise.withResolvers();
174
+ const task = { controller: new AbortController(), resolve: resolve, reject, active: false };
175
+ const item = { fn: callback, attempt: 1, task };
176
+ accept(item);
177
+ tasks.add(task);
178
+ schedule();
179
+ return {
180
+ result: promise,
181
+ cancel(reason) {
182
+ if (!tasks.delete(task))
183
+ return;
184
+ cnt_canceled++;
185
+ if (!task.active)
186
+ work.remove(item);
187
+ task.controller.abort(reason);
188
+ task.reject(task.controller.signal.reason);
189
+ },
190
+ };
191
+ };
122
192
  enqueue.pause = () => transition("pause");
123
193
  enqueue.resume = () => transition("resume");
124
194
  enqueue.stop = () => transition("stop");
@@ -137,6 +207,7 @@ export function createScheduler(options, adaptiveRateOptions, retryPolicy) {
137
207
  succeeded: cnt_succeeded,
138
208
  failed: cnt_failed,
139
209
  retried: cnt_retried,
210
+ canceled: cnt_canceled,
140
211
  rateIncreases: adaptiveRate.rateIncreases,
141
212
  rateDecreases: adaptiveRate.rateDecreases,
142
213
  });
@@ -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,6 +1,6 @@
1
1
  {
2
2
  "name": "dynamic-throttled-queue",
3
- "version": "2.3.0-rc.477ab9c",
3
+ "version": "2.3.0-rc.63bc2b5",
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": [