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 +26 -2
- package/dist/dynamic-throttled-queue.d.ts +1 -1
- package/dist/pending-work.d.ts +2 -0
- package/dist/pending-work.js +31 -13
- package/dist/pending-work.js.map +1 -1
- package/dist/scheduler.d.ts +17 -0
- package/dist/scheduler.js +92 -21
- package/dist/scheduler.js.map +1 -1
- package/package.json +1 -1
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 `
|
|
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;
|
package/dist/pending-work.d.ts
CHANGED
|
@@ -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`
|
package/dist/pending-work.js
CHANGED
|
@@ -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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
|
|
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--;
|
package/dist/pending-work.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pending-work.js","sourceRoot":"","sources":["../src/pending-work.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pending-work.js","sourceRoot":"","sources":["../src/pending-work.ts"],"names":[],"mappings":"AA2DA,MAAM,UAAU,iBAAiB,CAAI,OAA2B,EAAE,IAAqB;IACrF,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC;IAC/C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,mGAAmG;IACnG,MAAM,OAAO,GAAG,IAAI,GAAG,EAAK,CAAC;IAC7B,MAAM,IAAI,GAAwB,EAAE,CAAC;IACrC,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,iGAAiG;IACjG,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,MAAM,WAAW,GAAsC,EAAE,CAAC;IAE1D,SAAS,MAAM;QACb,OAAO,KAAK,CAAC,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC5C,CAAC;IAED,SAAS,OAAO;QACd,OAAO,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;IAChC,CAAC;IAED,SAAS,MAAM;QACb,OAAO,MAAM,KAAK,CAAC,IAAI,OAAO,EAAE,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,SAAS,UAAU;QACjB,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO;QACtB,KAAK,MAAM,MAAM,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;YAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IAC/D,CAAC;IAED,SAAS,WAAW,CAAC,KAAmB;QACtC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAED,SAAS,SAAS,CAAC,KAAmB;QACpC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC;QACzC,KAAK,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IACxE,CAAC;IAED,SAAS,IAAI,CAAC,IAAO,EAAE,KAAa;QAClC,MAAM,KAAK,GAAiB,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;QAC/D,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjB,IAAI,CAAC,MAAM;YAAE,SAAS,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAED,SAAS,IAAI;QACX,KAAK,MAAM,KAAK,IAAI,IAAI;YAAE,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAChB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QACjB,IAAI,GAAG,CAAC,CAAC;QACT,OAAO,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;IAED,SAAS,OAAO;QACd,IAAI,IAAI,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;YAC1B,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YACjB,IAAI,GAAG,CAAC,CAAC;QACX,CAAC;aACI,IAAI,IAAI,GAAG,gBAAgB,IAAI,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5D,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YACtB,IAAI,GAAG,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,MAAM;YACR,OAAO,MAAM,EAAE,CAAC;QAClB,CAAC;QACD,IAAI,OAAO;YACT,OAAO,OAAO,EAAE,CAAC;QACnB,CAAC;QACD,IAAI,MAAM;YACR,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM,CAAC,IAAI;YACT,IAAI,OAAO,EAAE,GAAG,MAAM,GAAG,QAAQ,IAAI,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;YACrH,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;QACD,IAAI;YACF,OAAO,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAE,CAAC;gBAC5B,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;oBAAE,SAAS;gBACnC,MAAM,EAAE,CAAC;gBACT,OAAO,EAAE,CAAC;gBACV,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,EAAE,CAAC;YACV,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,CAAC,IAAI;YACT,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;YAC3D,IAAI,KAAK,KAAK,CAAC,CAAC;gBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;;gBAC/B,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,CAAC;YACrD,UAAU,EAAE,CAAC;QACf,CAAC;QACD,MAAM,CAAC,MAAM,EAAE,OAAO;YACpB,MAAM,EAAE,CAAC;YACT,QAAQ,EAAE,CAAC;YACX,IAAI,KAA2B,CAAC;YAChC,IAAI,CAAC;gBACH,KAAK,GAAG,MAAM,EAAE,EAAE,CAAC;YACrB,CAAC;oBACO,CAAC;gBACP,QAAQ,EAAE,CAAC;YACb,CAAC;YACD,IAAI,KAAK,EAAE,KAAK,KAAK,SAAS;gBAAE,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;iBACzD,IAAI,KAAK,EAAE,CAAC;gBACf,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACvB,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,CAAC;YACD,OAAO,EAAE,EAAE,CAAC;YACZ,UAAU,EAAE,CAAC;QACf,CAAC;QACD,MAAM;YACJ,MAAM,GAAG,IAAI,CAAC;YACd,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;gBACzB,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;oBAAE,SAAS;gBAC1C,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAC5B,KAAK,CAAC,OAAO,GAAG,SAAS,CAAC;gBAC1B,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;QACD,IAAI;YACF,MAAM,GAAG,KAAK,CAAC;YACf,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;gBACzB,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;oBAAE,SAAS,CAAC,KAAK,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;QACD,OAAO;YACL,IAAI,EAAE,CAAC;YACP,UAAU,EAAE,CAAC;QACf,CAAC;QACD,IAAI,CAAC,KAAK;YACR,IAAI,EAAE,CAAC;YACP,KAAK,MAAM,MAAM,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;gBAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnE,CAAC;QACD,KAAK,CAAC,QAAQ;YACZ,IAAI,MAAM,EAAE;gBAAE,OAAO;YACrB,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,EAAQ,CAAC;YAC7C,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACzB,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/scheduler.d.ts
CHANGED
|
@@ -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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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(
|
|
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
|
});
|
package/dist/scheduler.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,2BAA2B;AAExD,OAAO,EAAE,iBAAiB,EAAE,0BAA0B;
|
|
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.
|
|
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": [
|