adaptive-concurrency 0.1.0 → 0.2.0
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/dist/LimitAllotment.d.ts +4 -4
- package/dist/LimitAllotment.d.ts.map +1 -1
- package/dist/Limiter.d.ts +20 -37
- package/dist/Limiter.d.ts.map +1 -1
- package/dist/Limiter.js +28 -50
- package/dist/RunResult.d.ts +1 -1
- package/dist/RunResult.js +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -6
- package/dist/limiter/{PartitionedStrategy.d.ts → acquire-strategies/PartitionedStrategy.d.ts} +2 -2
- package/dist/limiter/acquire-strategies/PartitionedStrategy.d.ts.map +1 -0
- package/dist/limiter/{PartitionedStrategy.js → acquire-strategies/PartitionedStrategy.js} +1 -1
- package/dist/limiter/{DelayedRejectStrategy.d.ts → allocation-unavailable-strategies/DelayedRejectStrategy.d.ts} +5 -5
- package/dist/limiter/allocation-unavailable-strategies/DelayedRejectStrategy.d.ts.map +1 -0
- package/dist/limiter/{DelayedThenBlockingRejection.d.ts → allocation-unavailable-strategies/DelayedThenBlockingRejection.d.ts} +6 -6
- package/dist/limiter/allocation-unavailable-strategies/DelayedThenBlockingRejection.d.ts.map +1 -0
- package/dist/limiter/{DelayedThenBlockingRejection.js → allocation-unavailable-strategies/DelayedThenBlockingRejection.js} +4 -4
- package/dist/limiter/{FifoBlockingRejection.d.ts → allocation-unavailable-strategies/FifoBlockingRejection.d.ts} +4 -4
- package/dist/limiter/allocation-unavailable-strategies/FifoBlockingRejection.d.ts.map +1 -0
- package/dist/limiter/{FifoBlockingRejection.js → allocation-unavailable-strategies/FifoBlockingRejection.js} +1 -1
- package/dist/limiter/{LifoBlockingRejection.d.ts → allocation-unavailable-strategies/LifoBlockingRejection.d.ts} +5 -5
- package/dist/limiter/allocation-unavailable-strategies/LifoBlockingRejection.d.ts.map +1 -0
- package/dist/limiter/{LifoBlockingRejection.js → allocation-unavailable-strategies/LifoBlockingRejection.js} +2 -2
- package/dist/limiter/factories/makeBlockingLimiter.d.ts +3 -3
- package/dist/limiter/factories/makeBlockingLimiter.d.ts.map +1 -1
- package/dist/limiter/factories/makeBlockingLimiter.js +4 -2
- package/dist/limiter/factories/makeLifoBlockingLimiter.d.ts +4 -4
- package/dist/limiter/factories/makeLifoBlockingLimiter.d.ts.map +1 -1
- package/dist/limiter/factories/makeLifoBlockingLimiter.js +3 -7
- package/dist/limiter/factories/makePartitionedBlockingLimiter.d.ts +4 -4
- package/dist/limiter/factories/makePartitionedBlockingLimiter.d.ts.map +1 -1
- package/dist/limiter/factories/makePartitionedBlockingLimiter.js +17 -16
- package/dist/limiter/factories/makePartitionedLifoBlockingLimiter.d.ts +5 -5
- package/dist/limiter/factories/makePartitionedLifoBlockingLimiter.d.ts.map +1 -1
- package/dist/limiter/factories/makePartitionedLifoBlockingLimiter.js +13 -14
- package/dist/limiter/factories/makePartitionedLimiter.d.ts +4 -4
- package/dist/limiter/factories/makePartitionedLimiter.d.ts.map +1 -1
- package/dist/limiter/factories/makePartitionedLimiter.js +12 -13
- package/dist/limiter/factories/makeSimpleLimiter.d.ts +2 -2
- package/dist/limiter/factories/makeSimpleLimiter.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/Limit.d.ts +0 -29
- package/dist/Limit.d.ts.map +0 -1
- package/dist/Limit.js +0 -1
- package/dist/Listener.d.ts +0 -23
- package/dist/Listener.d.ts.map +0 -1
- package/dist/Listener.js +0 -1
- package/dist/MetricIds.d.ts +0 -13
- package/dist/MetricIds.d.ts.map +0 -1
- package/dist/MetricIds.js +0 -12
- package/dist/StreamingLimit.d.ts +0 -26
- package/dist/StreamingLimit.d.ts.map +0 -1
- package/dist/StreamingLimit.js +0 -1
- package/dist/executors/AdaptiveExecutor.d.ts +0 -50
- package/dist/executors/AdaptiveExecutor.d.ts.map +0 -1
- package/dist/executors/AdaptiveExecutor.js +0 -80
- package/dist/limit/Gradient2Limit.d.ts +0 -122
- package/dist/limit/Gradient2Limit.d.ts.map +0 -1
- package/dist/limit/Gradient2Limit.js +0 -107
- package/dist/limit/statistics/ExpMovingAverage.d.ts +0 -21
- package/dist/limit/statistics/ExpMovingAverage.d.ts.map +0 -1
- package/dist/limit/statistics/ExpMovingAverage.js +0 -43
- package/dist/limit/statistics/Minimum.d.ts +0 -12
- package/dist/limit/statistics/Minimum.d.ts.map +0 -1
- package/dist/limit/statistics/Minimum.js +0 -22
- package/dist/limit/statistics/MinimumValue.d.ts +0 -12
- package/dist/limit/statistics/MinimumValue.d.ts.map +0 -1
- package/dist/limit/statistics/MinimumValue.js +0 -22
- package/dist/limit/statistics/SingleMeasurement.d.ts +0 -12
- package/dist/limit/statistics/SingleMeasurement.d.ts.map +0 -1
- package/dist/limit/statistics/SingleMeasurement.js +0 -21
- package/dist/limit/statistics/StreamingStatistic.d.ts +0 -29
- package/dist/limit/statistics/StreamingStatistic.d.ts.map +0 -1
- package/dist/limit/statistics/StreamingStatistic.js +0 -1
- package/dist/limit/utils/index.d.ts +0 -10
- package/dist/limit/utils/index.d.ts.map +0 -1
- package/dist/limit/utils/index.js +0 -19
- package/dist/limiter/AbstractLimiter.d.ts +0 -48
- package/dist/limiter/AbstractLimiter.d.ts.map +0 -1
- package/dist/limiter/AbstractLimiter.js +0 -78
- package/dist/limiter/AbstractPartitionedLimiter.d.ts +0 -66
- package/dist/limiter/AbstractPartitionedLimiter.d.ts.map +0 -1
- package/dist/limiter/AbstractPartitionedLimiter.js +0 -209
- package/dist/limiter/BlockingLimiter.d.ts +0 -55
- package/dist/limiter/BlockingLimiter.d.ts.map +0 -1
- package/dist/limiter/BlockingLimiter.js +0 -111
- package/dist/limiter/DelayedRejectStrategy.d.ts.map +0 -1
- package/dist/limiter/DelayedThenBlockingRejection.d.ts.map +0 -1
- package/dist/limiter/FifoBlockingRejection.d.ts.map +0 -1
- package/dist/limiter/LifoBlockingLimiter.d.ts +0 -53
- package/dist/limiter/LifoBlockingLimiter.d.ts.map +0 -1
- package/dist/limiter/LifoBlockingLimiter.js +0 -108
- package/dist/limiter/LifoBlockingRejection.d.ts.map +0 -1
- package/dist/limiter/PartitionedStrategy.d.ts.map +0 -1
- package/dist/limiter/SimpleLimiter.d.ts +0 -31
- package/dist/limiter/SimpleLimiter.d.ts.map +0 -1
- package/dist/limiter/SimpleLimiter.js +0 -119
- package/dist/limiter/factories.d.ts +0 -31
- package/dist/limiter/factories.d.ts.map +0 -1
- package/dist/limiter/factories.js +0 -74
- /package/dist/limiter/{DelayedRejectStrategy.js → allocation-unavailable-strategies/DelayedRejectStrategy.js} +0 -0
package/dist/LimitAllotment.d.ts
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Handle returned when a concurrency slot is acquired. The caller must invoke
|
|
3
|
-
* exactly one of the
|
|
3
|
+
* exactly one of the release-and-record methods when the operation completes.
|
|
4
4
|
*/
|
|
5
5
|
export interface LimitAllotment {
|
|
6
6
|
/**
|
|
7
7
|
* The operation succeeded and internally measured latency should be used as
|
|
8
8
|
* an RTT sample.
|
|
9
9
|
*/
|
|
10
|
-
|
|
10
|
+
releaseAndRecordSuccess(): Promise<void>;
|
|
11
11
|
/**
|
|
12
12
|
* The operation failed before any meaningful RTT measurement could be made
|
|
13
13
|
* and should be ignored so it does not introduce an artificially low RTT.
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
releaseAndIgnore(): Promise<void>;
|
|
16
16
|
/**
|
|
17
17
|
* The request failed and was dropped due to being rejected by an external
|
|
18
18
|
* limit or hitting a timeout. Loss based StreamingLimit implementations will
|
|
19
19
|
* likely do an aggressive reduction in limit when this happens.
|
|
20
20
|
*/
|
|
21
|
-
|
|
21
|
+
releaseAndRecordDropped(): Promise<void>;
|
|
22
22
|
}
|
|
23
23
|
//# sourceMappingURL=LimitAllotment.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LimitAllotment.d.ts","sourceRoot":"","sources":["../src/LimitAllotment.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,
|
|
1
|
+
{"version":3,"file":"LimitAllotment.d.ts","sourceRoot":"","sources":["../src/LimitAllotment.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzC;;;OAGG;IACH,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAElC;;;;OAIG;IACH,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C"}
|
package/dist/Limiter.d.ts
CHANGED
|
@@ -2,13 +2,11 @@ import type { AdaptiveLimit } from "./limit/StreamingLimit.js";
|
|
|
2
2
|
import type { LimitAllotment } from "./LimitAllotment.js";
|
|
3
3
|
import type { MetricRegistry } from "./MetricRegistry.js";
|
|
4
4
|
import { QuotaNotAvailable, type RunResult } from "./RunResult.js";
|
|
5
|
-
export type
|
|
6
|
-
export type AsyncAcquireResult = Promise<LimitAllotment | undefined>;
|
|
5
|
+
export type MaybePromise<T> = T | Promise<T>;
|
|
7
6
|
/**
|
|
8
|
-
*
|
|
9
|
-
* both sync and async limiters generically.
|
|
7
|
+
* Acquire is async-only.
|
|
10
8
|
*/
|
|
11
|
-
export type AcquireResult =
|
|
9
|
+
export type AcquireResult = Promise<LimitAllotment | undefined>;
|
|
12
10
|
export interface AcquireOptions<ContextT = void> {
|
|
13
11
|
context?: ContextT;
|
|
14
12
|
signal?: AbortSignal;
|
|
@@ -32,17 +30,17 @@ export interface AcquireStrategy<ContextT> {
|
|
|
32
30
|
* When `true`, the strategy has reserved capacity for one inflight unit; when
|
|
33
31
|
* `false`, an allotment was not available.
|
|
34
32
|
*/
|
|
35
|
-
tryAcquireAllotment(context: ContextT, state: LimiterState): boolean
|
|
33
|
+
tryAcquireAllotment(context: ContextT, state: LimiterState): MaybePromise<boolean>;
|
|
36
34
|
/**
|
|
37
35
|
* Called when an acquired allotment completes (success, ignore, or drop).
|
|
38
36
|
* Perform any cleanup (e.g. increment permits, release a partition slot).
|
|
39
37
|
*/
|
|
40
|
-
onAllotmentReleased(context: ContextT): void
|
|
38
|
+
onAllotmentReleased(context: ContextT): MaybePromise<void>;
|
|
41
39
|
/**
|
|
42
40
|
* Called when the adaptive limit changes. The strategy can react
|
|
43
41
|
* (e.g. adjust available permits by the delta, update partition sub-limits).
|
|
44
42
|
*/
|
|
45
|
-
onLimitChanged?(oldLimit: number, newLimit: number): void
|
|
43
|
+
onLimitChanged?(oldLimit: number, newLimit: number): MaybePromise<void>;
|
|
46
44
|
}
|
|
47
45
|
/**
|
|
48
46
|
* Determines what happens when a request is rejected by the
|
|
@@ -50,7 +48,7 @@ export interface AcquireStrategy<ContextT> {
|
|
|
50
48
|
* {@link Limiter.acquire}'s return type, enabling the type system to
|
|
51
49
|
* distinguish sync limiters (no promise) from async/blocking ones.
|
|
52
50
|
*/
|
|
53
|
-
export interface AllotmentUnavailableStrategy<ContextT
|
|
51
|
+
export interface AllotmentUnavailableStrategy<ContextT> {
|
|
54
52
|
/**
|
|
55
53
|
* Called when the acquire strategy cannot allocate an allotment for a
|
|
56
54
|
* request.
|
|
@@ -62,14 +60,14 @@ export interface AllotmentUnavailableStrategy<ContextT, ResultT extends SyncAcqu
|
|
|
62
60
|
* ready-to-use allotment with all required wrapping.
|
|
63
61
|
* @param signal Optional abort signal from the caller.
|
|
64
62
|
*/
|
|
65
|
-
onAllotmentUnavailable(context: ContextT, retry: (context: ContextT) =>
|
|
63
|
+
onAllotmentUnavailable(context: ContextT, retry: (context: ContextT) => AcquireResult, signal?: AbortSignal): AcquireResult;
|
|
66
64
|
/**
|
|
67
65
|
* Called whenever any allotment is released (success, ignore, or drop).
|
|
68
66
|
* Blocking strategies use this to wake queued waiters.
|
|
69
67
|
*/
|
|
70
|
-
onAllotmentReleased(): void
|
|
68
|
+
onAllotmentReleased(): MaybePromise<void>;
|
|
71
69
|
}
|
|
72
|
-
export interface LimiterOptions<ContextT
|
|
70
|
+
export interface LimiterOptions<ContextT> {
|
|
73
71
|
limit?: AdaptiveLimit;
|
|
74
72
|
/**
|
|
75
73
|
* Clock function returning the current time in fractional milliseconds
|
|
@@ -93,20 +91,17 @@ export interface LimiterOptions<ContextT, RejResultT extends SyncAcquireResult |
|
|
|
93
91
|
* Strategy that decides what happens when the acquire strategy rejects a
|
|
94
92
|
* request. When omitted, rejected requests immediately receive `undefined`.
|
|
95
93
|
*/
|
|
96
|
-
allotmentUnavailableStrategy?: AllotmentUnavailableStrategy<ContextT
|
|
94
|
+
allotmentUnavailableStrategy?: AllotmentUnavailableStrategy<ContextT>;
|
|
97
95
|
}
|
|
98
96
|
/**
|
|
99
97
|
* Concurrency limiter with pluggable strategies for gating decisions and
|
|
100
98
|
* rejection handling.
|
|
101
99
|
*
|
|
102
|
-
*
|
|
103
|
-
* (`LimitAllotment | undefined`). When a blocking rejection strategy is
|
|
104
|
-
* configured, `acquire()` may also return a `Promise`.
|
|
100
|
+
* `acquire()` always returns a `Promise<LimitAllotment | undefined>`.
|
|
105
101
|
*
|
|
106
102
|
* @typeParam ContextT Request context type (e.g. partition key).
|
|
107
|
-
* @typeParam RejResultT The result type produced by the rejection strategy.
|
|
108
103
|
*/
|
|
109
|
-
export declare class Limiter<Context = void
|
|
104
|
+
export declare class Limiter<Context = void> {
|
|
110
105
|
private _inflight;
|
|
111
106
|
private _limit;
|
|
112
107
|
private readonly clock;
|
|
@@ -120,8 +115,8 @@ export declare class Limiter<Context = void, AcquireResult extends SyncAcquireRe
|
|
|
120
115
|
private readonly rejectedCounter;
|
|
121
116
|
private readonly bypassCounter;
|
|
122
117
|
static makeDefaultLimit(): AdaptiveLimit;
|
|
123
|
-
constructor(options?: LimiterOptions<Context
|
|
124
|
-
acquire(options?: AcquireOptions<Context>):
|
|
118
|
+
constructor(options?: LimiterOptions<Context>);
|
|
119
|
+
acquire(options?: AcquireOptions<Context>): AcquireResult;
|
|
125
120
|
private tryAcquireCore;
|
|
126
121
|
private createAllotment;
|
|
127
122
|
getLimit(): number;
|
|
@@ -139,11 +134,6 @@ export declare class SemaphoreStrategy {
|
|
|
139
134
|
onAllotmentReleased(): void;
|
|
140
135
|
onLimitChanged(oldLimit: number, newLimit: number): void;
|
|
141
136
|
}
|
|
142
|
-
/**
|
|
143
|
-
* Run a callback when an acquire result is ready. If the result is a Promise,
|
|
144
|
-
* waits asynchronously; otherwise invokes the callback synchronously.
|
|
145
|
-
*/
|
|
146
|
-
export declare function whenAcquireSettled(result: AcquireResult, callback: (allotment: LimitAllotment | undefined) => void): void;
|
|
147
137
|
export type RunCallbackArgs<ContextT> = {
|
|
148
138
|
context: ContextT | undefined;
|
|
149
139
|
signal: AbortSignal | undefined;
|
|
@@ -158,18 +148,11 @@ export interface LimitedFunction<ContextT> {
|
|
|
158
148
|
* - If {@link Limiter.acquire} yields no allotment, returns
|
|
159
149
|
* {@link QuotaNotAvailable} without invoking `fn`.
|
|
160
150
|
* - On {@link RunResult} `success` / `ignore`, returns the carried value after
|
|
161
|
-
*
|
|
162
|
-
* - On `dropped`,
|
|
163
|
-
* - On uncaught exceptions from `fn`,
|
|
164
|
-
* {@link AdaptiveTimeoutError}, which
|
|
151
|
+
* recording success/ignore to the allotment.
|
|
152
|
+
* - On `dropped`, records drop and throws the carried error.
|
|
153
|
+
* - On uncaught exceptions from `fn`, records ignore and rethrows, except for
|
|
154
|
+
* {@link AdaptiveTimeoutError}, which records drop and rethrows.
|
|
165
155
|
* - Callback receives `{ context, signal }` from acquire options.
|
|
166
156
|
*/
|
|
167
|
-
export declare function withLimiter<ContextT
|
|
168
|
-
/**
|
|
169
|
-
* Synchronous try-acquire interface. A `Limiter<Ctx>` (with default sync
|
|
170
|
-
* rejection) is structurally compatible with this interface.
|
|
171
|
-
*/
|
|
172
|
-
export interface SyncLimiter<ContextT = void> {
|
|
173
|
-
acquire(options?: AcquireOptions<ContextT>): LimitAllotment | undefined;
|
|
174
|
-
}
|
|
157
|
+
export declare function withLimiter<ContextT>(limiter: Limiter<ContextT>): LimitedFunction<ContextT>;
|
|
175
158
|
//# sourceMappingURL=Limiter.d.ts.map
|
package/dist/Limiter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Limiter.d.ts","sourceRoot":"","sources":["../src/Limiter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAW,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAEnE,OAAO,EAEL,iBAAiB,EACjB,KAAK,SAAS,EACf,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"Limiter.d.ts","sourceRoot":"","sources":["../src/Limiter.ts"],"names":[],"mappings":"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"}
|
package/dist/Limiter.js
CHANGED
|
@@ -5,21 +5,18 @@ import { isAdaptiveTimeoutError, QuotaNotAvailable, } from "./RunResult.js";
|
|
|
5
5
|
// Limiter options
|
|
6
6
|
// ---------------------------------------------------------------------------
|
|
7
7
|
const NOOP_ALLOTMENT = {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
async releaseAndRecordSuccess() { },
|
|
9
|
+
async releaseAndIgnore() { },
|
|
10
|
+
async releaseAndRecordDropped() { },
|
|
11
11
|
};
|
|
12
12
|
let idCounter = 0;
|
|
13
13
|
/**
|
|
14
14
|
* Concurrency limiter with pluggable strategies for gating decisions and
|
|
15
15
|
* rejection handling.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
* (`LimitAllotment | undefined`). When a blocking rejection strategy is
|
|
19
|
-
* configured, `acquire()` may also return a `Promise`.
|
|
17
|
+
* `acquire()` always returns a `Promise<LimitAllotment | undefined>`.
|
|
20
18
|
*
|
|
21
19
|
* @typeParam ContextT Request context type (e.g. partition key).
|
|
22
|
-
* @typeParam RejResultT The result type produced by the rejection strategy.
|
|
23
20
|
*/
|
|
24
21
|
export class Limiter {
|
|
25
22
|
_inflight = 0;
|
|
@@ -48,7 +45,7 @@ export class Limiter {
|
|
|
48
45
|
this.limitAlgorithm.subscribe((newLimit) => {
|
|
49
46
|
const oldLimit = this._limit;
|
|
50
47
|
this._limit = newLimit;
|
|
51
|
-
this.acquireStrategy.onLimitChanged?.(oldLimit, newLimit);
|
|
48
|
+
void Promise.resolve(this.acquireStrategy.onLimitChanged?.(oldLimit, newLimit));
|
|
52
49
|
});
|
|
53
50
|
const registry = options.metricRegistry ?? NoopMetricRegistry;
|
|
54
51
|
const limiterName = options.name ?? `unnamed-${++idCounter}`;
|
|
@@ -74,7 +71,7 @@ export class Limiter {
|
|
|
74
71
|
status: "bypassed",
|
|
75
72
|
});
|
|
76
73
|
}
|
|
77
|
-
acquire(options) {
|
|
74
|
+
async acquire(options) {
|
|
78
75
|
if (options?.signal?.aborted)
|
|
79
76
|
return undefined;
|
|
80
77
|
const ctx = (options?.context ?? undefined);
|
|
@@ -86,7 +83,7 @@ export class Limiter {
|
|
|
86
83
|
limit: this._limit,
|
|
87
84
|
inflight: this._inflight,
|
|
88
85
|
};
|
|
89
|
-
if (!this.acquireStrategy.tryAcquireAllotment(ctx, state)) {
|
|
86
|
+
if (!(await this.acquireStrategy.tryAcquireAllotment(ctx, state))) {
|
|
90
87
|
this.rejectedCounter.increment();
|
|
91
88
|
if (this.rejectionStrategy) {
|
|
92
89
|
return this.rejectionStrategy.onAllotmentUnavailable(ctx, (retryCtx) => this.tryAcquireCore(retryCtx), options?.signal);
|
|
@@ -95,12 +92,12 @@ export class Limiter {
|
|
|
95
92
|
}
|
|
96
93
|
return this.createAllotment(ctx);
|
|
97
94
|
}
|
|
98
|
-
tryAcquireCore(ctx) {
|
|
95
|
+
async tryAcquireCore(ctx) {
|
|
99
96
|
const state = {
|
|
100
97
|
limit: this._limit,
|
|
101
98
|
inflight: this._inflight,
|
|
102
99
|
};
|
|
103
|
-
if (!this.acquireStrategy.tryAcquireAllotment(ctx, state)) {
|
|
100
|
+
if (!(await this.acquireStrategy.tryAcquireAllotment(ctx, state))) {
|
|
104
101
|
return undefined;
|
|
105
102
|
}
|
|
106
103
|
return this.createAllotment(ctx);
|
|
@@ -109,25 +106,25 @@ export class Limiter {
|
|
|
109
106
|
const startTime = this.clock();
|
|
110
107
|
const currentInflight = ++this._inflight;
|
|
111
108
|
return {
|
|
112
|
-
|
|
109
|
+
releaseAndRecordSuccess: async () => {
|
|
113
110
|
this._inflight--;
|
|
114
|
-
this.acquireStrategy.onAllotmentReleased(ctx);
|
|
111
|
+
await this.acquireStrategy.onAllotmentReleased(ctx);
|
|
115
112
|
this.successCounter.increment();
|
|
116
113
|
this.limitAlgorithm.addSample(startTime, this.clock() - startTime, currentInflight, false);
|
|
117
|
-
this.rejectionStrategy?.onAllotmentReleased();
|
|
114
|
+
await this.rejectionStrategy?.onAllotmentReleased();
|
|
118
115
|
},
|
|
119
|
-
|
|
116
|
+
releaseAndIgnore: async () => {
|
|
120
117
|
this._inflight--;
|
|
121
|
-
this.acquireStrategy.onAllotmentReleased(ctx);
|
|
118
|
+
await this.acquireStrategy.onAllotmentReleased(ctx);
|
|
122
119
|
this.ignoredCounter.increment();
|
|
123
|
-
this.rejectionStrategy?.onAllotmentReleased();
|
|
120
|
+
await this.rejectionStrategy?.onAllotmentReleased();
|
|
124
121
|
},
|
|
125
|
-
|
|
122
|
+
releaseAndRecordDropped: async () => {
|
|
126
123
|
this._inflight--;
|
|
127
|
-
this.acquireStrategy.onAllotmentReleased(ctx);
|
|
124
|
+
await this.acquireStrategy.onAllotmentReleased(ctx);
|
|
128
125
|
this.droppedCounter.increment();
|
|
129
126
|
this.limitAlgorithm.addSample(startTime, this.clock() - startTime, currentInflight, true);
|
|
130
|
-
this.rejectionStrategy?.onAllotmentReleased();
|
|
127
|
+
await this.rejectionStrategy?.onAllotmentReleased();
|
|
131
128
|
},
|
|
132
129
|
};
|
|
133
130
|
}
|
|
@@ -164,35 +161,16 @@ export class SemaphoreStrategy {
|
|
|
164
161
|
this.permits += newLimit - oldLimit;
|
|
165
162
|
}
|
|
166
163
|
}
|
|
167
|
-
// ---------------------------------------------------------------------------
|
|
168
|
-
// Helper: whenAcquireSettled
|
|
169
|
-
// ---------------------------------------------------------------------------
|
|
170
|
-
/**
|
|
171
|
-
* Run a callback when an acquire result is ready. If the result is a Promise,
|
|
172
|
-
* waits asynchronously; otherwise invokes the callback synchronously.
|
|
173
|
-
*/
|
|
174
|
-
export function whenAcquireSettled(result, callback) {
|
|
175
|
-
if (result !== null &&
|
|
176
|
-
typeof result === "object" &&
|
|
177
|
-
"then" in result &&
|
|
178
|
-
typeof result.then ===
|
|
179
|
-
"function") {
|
|
180
|
-
void result.then(callback);
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
callback(result);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
164
|
/**
|
|
187
165
|
* Creates a helper that runs callbacks under acquired limiter allotments.
|
|
188
166
|
*
|
|
189
167
|
* - If {@link Limiter.acquire} yields no allotment, returns
|
|
190
168
|
* {@link QuotaNotAvailable} without invoking `fn`.
|
|
191
169
|
* - On {@link RunResult} `success` / `ignore`, returns the carried value after
|
|
192
|
-
*
|
|
193
|
-
* - On `dropped`,
|
|
194
|
-
* - On uncaught exceptions from `fn`,
|
|
195
|
-
* {@link AdaptiveTimeoutError}, which
|
|
170
|
+
* recording success/ignore to the allotment.
|
|
171
|
+
* - On `dropped`, records drop and throws the carried error.
|
|
172
|
+
* - On uncaught exceptions from `fn`, records ignore and rethrows, except for
|
|
173
|
+
* {@link AdaptiveTimeoutError}, which records drop and rethrows.
|
|
196
174
|
* - Callback receives `{ context, signal }` from acquire options.
|
|
197
175
|
*/
|
|
198
176
|
export function withLimiter(limiter) {
|
|
@@ -204,7 +182,7 @@ export function withLimiter(limiter) {
|
|
|
204
182
|
const fn = hasOptions
|
|
205
183
|
? maybeFn
|
|
206
184
|
: optionsOrFn;
|
|
207
|
-
const allotment = await
|
|
185
|
+
const allotment = await limiter.acquire(options);
|
|
208
186
|
if (!allotment) {
|
|
209
187
|
return QuotaNotAvailable;
|
|
210
188
|
}
|
|
@@ -216,23 +194,23 @@ export function withLimiter(limiter) {
|
|
|
216
194
|
]);
|
|
217
195
|
if (result.status === "rejected") {
|
|
218
196
|
if (isAdaptiveTimeoutError(result.reason)) {
|
|
219
|
-
allotment.
|
|
197
|
+
await allotment.releaseAndRecordDropped();
|
|
220
198
|
}
|
|
221
199
|
else {
|
|
222
|
-
allotment.
|
|
200
|
+
await allotment.releaseAndIgnore();
|
|
223
201
|
}
|
|
224
202
|
throw result.reason;
|
|
225
203
|
}
|
|
226
204
|
const outcome = result.value;
|
|
227
205
|
switch (outcome.kind) {
|
|
228
206
|
case "success":
|
|
229
|
-
allotment.
|
|
207
|
+
await allotment.releaseAndRecordSuccess();
|
|
230
208
|
return outcome.value;
|
|
231
209
|
case "ignore":
|
|
232
|
-
allotment.
|
|
210
|
+
await allotment.releaseAndIgnore();
|
|
233
211
|
return outcome.value;
|
|
234
212
|
case "dropped":
|
|
235
|
-
allotment.
|
|
213
|
+
await allotment.releaseAndRecordDropped();
|
|
236
214
|
throw outcome.error;
|
|
237
215
|
}
|
|
238
216
|
}
|
package/dist/RunResult.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export declare const QuotaNotAvailable: unique symbol;
|
|
|
7
7
|
/**
|
|
8
8
|
* Error type that signals the operation was dropped due to timeout or external
|
|
9
9
|
* load shedding. When thrown from {@link Limiter.run}'s callback, run treats
|
|
10
|
-
* it as dropped (calls `
|
|
10
|
+
* it as dropped (calls `releaseAndRecordDropped`) and then rethrows it.
|
|
11
11
|
*/
|
|
12
12
|
export declare class AdaptiveTimeoutError extends Error {
|
|
13
13
|
readonly code: "ADAPTIVE_TIMEOUT";
|
package/dist/RunResult.js
CHANGED
|
@@ -8,7 +8,7 @@ export const QuotaNotAvailable = Symbol("QuotaNotAvailable");
|
|
|
8
8
|
/**
|
|
9
9
|
* Error type that signals the operation was dropped due to timeout or external
|
|
10
10
|
* load shedding. When thrown from {@link Limiter.run}'s callback, run treats
|
|
11
|
-
* it as dropped (calls `
|
|
11
|
+
* it as dropped (calls `releaseAndRecordDropped`) and then rethrows it.
|
|
12
12
|
*/
|
|
13
13
|
export class AdaptiveTimeoutError extends Error {
|
|
14
14
|
code = ADAPTIVE_TIMEOUT_ERROR_CODE;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { AdaptiveLimit } from "./limit/StreamingLimit.js";
|
|
2
2
|
export type { LimitAllotment } from "./LimitAllotment.js";
|
|
3
|
-
export { Limiter, SemaphoreStrategy,
|
|
3
|
+
export { Limiter, SemaphoreStrategy, withLimiter, type AcquireOptions, type AcquireResult, type AcquireStrategy, type AllotmentUnavailableStrategy, type LimitedFunction, type LimiterOptions, type LimiterState, type RunCallbackArgs, type MaybePromise, } from "./Limiter.js";
|
|
4
4
|
export { ListenerSet } from "./ListenerSet.js";
|
|
5
5
|
export { MetricIds, NoopMetricRegistry, type Counter, type DistributionMetric, type GaugeMetric, type MetricRegistry, } from "./MetricRegistry.js";
|
|
6
6
|
export { AdaptiveTimeoutError, dropped, ignore, isAdaptiveTimeoutError, QuotaNotAvailable, success, type RunDropped, type RunIgnore, type RunResult, type RunSuccess, } from "./RunResult.js";
|
|
@@ -19,9 +19,9 @@ export { createPercentileSampleWindow } from "./limit/window/PercentileSampleWin
|
|
|
19
19
|
export type { SampleWindow } from "./limit/window/SampleWindow.js";
|
|
20
20
|
export { squareRoot, squareRootWithBaseline } from "./utils/index.js";
|
|
21
21
|
export * from "./limiter/factories/index.js";
|
|
22
|
-
export { PartitionedStrategy, type PartitionConfig, } from "./limiter/PartitionedStrategy.js";
|
|
23
|
-
export { DelayedRejectStrategy, type DelayedRejectStrategyOptions, } from "./limiter/DelayedRejectStrategy.js";
|
|
24
|
-
export { DelayedThenBlockingRejection } from "./limiter/DelayedThenBlockingRejection.js";
|
|
25
|
-
export { FifoBlockingRejection } from "./limiter/FifoBlockingRejection.js";
|
|
26
|
-
export { LifoBlockingRejection, type LifoBlockingRejectionOptions, } from "./limiter/LifoBlockingRejection.js";
|
|
22
|
+
export { PartitionedStrategy, type PartitionConfig, } from "./limiter/acquire-strategies/PartitionedStrategy.js";
|
|
23
|
+
export { DelayedRejectStrategy, type DelayedRejectStrategyOptions, } from "./limiter/allocation-unavailable-strategies/DelayedRejectStrategy.js";
|
|
24
|
+
export { DelayedThenBlockingRejection } from "./limiter/allocation-unavailable-strategies/DelayedThenBlockingRejection.js";
|
|
25
|
+
export { FifoBlockingRejection } from "./limiter/allocation-unavailable-strategies/FifoBlockingRejection.js";
|
|
26
|
+
export { LifoBlockingRejection, type LifoBlockingRejectionOptions, } from "./limiter/allocation-unavailable-strategies/LifoBlockingRejection.js";
|
|
27
27
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,WAAW,EACX,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,4BAA4B,EACjC,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,YAAY,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,KAAK,OAAO,EACZ,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,cAAc,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,OAAO,EACP,MAAM,EACN,sBAAsB,EACtB,iBAAiB,EACjB,OAAO,EACP,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,UAAU,GAChB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EACL,aAAa,EACb,KAAK,qBAAqB,GAC3B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EACL,UAAU,EACV,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,GAC1B,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,YAAY,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAG7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,4BAA4B,EAAE,MAAM,0CAA0C,CAAC;AACxF,YAAY,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAGnE,OAAO,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAGtE,cAAc,8BAA8B,CAAC;AAC7C,OAAO,EACL,mBAAmB,EACnB,KAAK,eAAe,GACrB,MAAM,qDAAqD,CAAC;AAG7D,OAAO,EACL,qBAAqB,EACrB,KAAK,4BAA4B,GAClC,MAAM,sEAAsE,CAAC;AAC9E,OAAO,EAAE,4BAA4B,EAAE,MAAM,6EAA6E,CAAC;AAC3H,OAAO,EAAE,qBAAqB,EAAE,MAAM,sEAAsE,CAAC;AAC7G,OAAO,EACL,qBAAqB,EACrB,KAAK,4BAA4B,GAClC,MAAM,sEAAsE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Limiter, SemaphoreStrategy,
|
|
1
|
+
export { Limiter, SemaphoreStrategy, withLimiter, } from "./Limiter.js";
|
|
2
2
|
export { ListenerSet } from "./ListenerSet.js";
|
|
3
3
|
export { MetricIds, NoopMetricRegistry, } from "./MetricRegistry.js";
|
|
4
4
|
export { AdaptiveTimeoutError, dropped, ignore, isAdaptiveTimeoutError, QuotaNotAvailable, success, } from "./RunResult.js";
|
|
@@ -20,9 +20,9 @@ export { createPercentileSampleWindow } from "./limit/window/PercentileSampleWin
|
|
|
20
20
|
export { squareRoot, squareRootWithBaseline } from "./utils/index.js";
|
|
21
21
|
// Acquire strategies
|
|
22
22
|
export * from "./limiter/factories/index.js";
|
|
23
|
-
export { PartitionedStrategy, } from "./limiter/PartitionedStrategy.js";
|
|
23
|
+
export { PartitionedStrategy, } from "./limiter/acquire-strategies/PartitionedStrategy.js";
|
|
24
24
|
// Rejection strategies
|
|
25
|
-
export { DelayedRejectStrategy, } from "./limiter/DelayedRejectStrategy.js";
|
|
26
|
-
export { DelayedThenBlockingRejection } from "./limiter/DelayedThenBlockingRejection.js";
|
|
27
|
-
export { FifoBlockingRejection } from "./limiter/FifoBlockingRejection.js";
|
|
28
|
-
export { LifoBlockingRejection, } from "./limiter/LifoBlockingRejection.js";
|
|
25
|
+
export { DelayedRejectStrategy, } from "./limiter/allocation-unavailable-strategies/DelayedRejectStrategy.js";
|
|
26
|
+
export { DelayedThenBlockingRejection } from "./limiter/allocation-unavailable-strategies/DelayedThenBlockingRejection.js";
|
|
27
|
+
export { FifoBlockingRejection } from "./limiter/allocation-unavailable-strategies/FifoBlockingRejection.js";
|
|
28
|
+
export { LifoBlockingRejection, } from "./limiter/allocation-unavailable-strategies/LifoBlockingRejection.js";
|
package/dist/limiter/{PartitionedStrategy.d.ts → acquire-strategies/PartitionedStrategy.d.ts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { AcquireStrategy, LimiterState } from "
|
|
2
|
-
import type { MetricRegistry } from "
|
|
1
|
+
import type { AcquireStrategy, LimiterState } from "../../Limiter.js";
|
|
2
|
+
import type { MetricRegistry } from "../../MetricRegistry.js";
|
|
3
3
|
export type PartitionConfig = {
|
|
4
4
|
/**
|
|
5
5
|
* Percentage of the total limit guaranteed to this partition. Must be in
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PartitionedStrategy.d.ts","sourceRoot":"","sources":["../../../src/limiter/acquire-strategies/PartitionedStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,KAAK,EAGV,cAAc,EACf,MAAM,yBAAyB,CAAC;AAKjC,MAAM,MAAM,eAAe,GAAG;IAC5B;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,qBAAa,mBAAmB,CAC9B,QAAQ,EACR,aAAa,SAAS,MAAM,GAAG,MAAM,CACrC,YAAW,eAAe,CAAC,QAAQ,CAAC;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAG9B;IACF,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAuB;IACxD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAEH;gBAEnB,OAAO,EAAE;QACnB;;;WAGG;QACH,YAAY,EAAE,MAAM,CAAC;QAErB;;;;;WAKG;QACH,iBAAiB,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,aAAa,GAAG,SAAS,CAAC;QACpE,UAAU,EAAE,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;QAEnD,cAAc,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;KAC7C;IAkDD,mBAAmB,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO;IAUpE,mBAAmB,CAAC,OAAO,EAAE,QAAQ,GAAG,IAAI;IAI5C,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAMzD;;;OAGG;IACH,YAAY,CAAC,IAAI,EAAE,aAAa;;;;;;;IAehC,OAAO,CAAC,gBAAgB;CAUzB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { LimitAllotment } from "
|
|
2
|
-
import type { AllotmentUnavailableStrategy,
|
|
1
|
+
import type { LimitAllotment } from "../../LimitAllotment.js";
|
|
2
|
+
import type { AllotmentUnavailableStrategy, AcquireResult } from "../../Limiter.js";
|
|
3
3
|
export interface DelayedRejectStrategyOptions<ContextT> {
|
|
4
4
|
/**
|
|
5
5
|
* Milliseconds to wait before resolving with no allotment. Return 0 to reject
|
|
@@ -11,7 +11,7 @@ export interface DelayedRejectStrategyOptions<ContextT> {
|
|
|
11
11
|
* Maximum number of acquire attempts that may be waiting on a delay at once.
|
|
12
12
|
* When exceeded, new rejections skip the delay (immediate `undefined`).
|
|
13
13
|
*/
|
|
14
|
-
maxConcurrentDelays?: number;
|
|
14
|
+
maxConcurrentDelays?: number | undefined;
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* When the acquire strategy rejects, waits up to `delayMsForContext(context)`,
|
|
@@ -20,12 +20,12 @@ export interface DelayedRejectStrategyOptions<ContextT> {
|
|
|
20
20
|
* reject," not "wait for capacity." Compose with `PartitionedStrategy` via
|
|
21
21
|
* `Limiter.rejectionStrategy`; partition delays are not fields on `PartitionConfig`.
|
|
22
22
|
*/
|
|
23
|
-
export declare class DelayedRejectStrategy<ContextT> implements AllotmentUnavailableStrategy<ContextT
|
|
23
|
+
export declare class DelayedRejectStrategy<ContextT> implements AllotmentUnavailableStrategy<ContextT> {
|
|
24
24
|
private readonly delayMsForContext;
|
|
25
25
|
private readonly maxConcurrentDelays;
|
|
26
26
|
private concurrentDelays;
|
|
27
27
|
constructor(options: DelayedRejectStrategyOptions<ContextT>);
|
|
28
|
-
onAllotmentUnavailable(context: ContextT, _retry: (context: ContextT) =>
|
|
28
|
+
onAllotmentUnavailable(context: ContextT, _retry: (context: ContextT) => AcquireResult, signal?: AbortSignal): Promise<LimitAllotment | undefined>;
|
|
29
29
|
onAllotmentReleased(): void;
|
|
30
30
|
private run;
|
|
31
31
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DelayedRejectStrategy.d.ts","sourceRoot":"","sources":["../../../src/limiter/allocation-unavailable-strategies/DelayedRejectStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EACV,4BAA4B,EAC5B,aAAa,EACd,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,4BAA4B,CAAC,QAAQ;IACpD;;;;OAIG;IACH,iBAAiB,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,MAAM,CAAC;IAEjD;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C;AAED;;;;;;GAMG;AACH,qBAAa,qBAAqB,CAChC,QAAQ,CACR,YAAW,4BAA4B,CAAC,QAAQ,CAAC;IACjD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAgC;IAClE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,gBAAgB,CAAK;gBAEjB,OAAO,EAAE,4BAA4B,CAAC,QAAQ,CAAC;IAS3D,sBAAsB,CACpB,OAAO,EAAE,QAAQ,EACjB,MAAM,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,aAAa,EAC5C,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAItC,mBAAmB,IAAI,IAAI;YAIb,GAAG;CA0BlB"}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import type { LimitAllotment } from "
|
|
2
|
-
import type { AllotmentUnavailableStrategy,
|
|
1
|
+
import type { LimitAllotment } from "../../LimitAllotment.js";
|
|
2
|
+
import type { AllotmentUnavailableStrategy, AcquireResult } from "../../Limiter.js";
|
|
3
3
|
import type { DelayedRejectStrategy } from "./DelayedRejectStrategy.js";
|
|
4
4
|
/**
|
|
5
5
|
* Composes "delay then reject" backoff with blocking behavior. On rejection:
|
|
6
6
|
* first applies delayed-reject semantics, then delegates to a blocking strategy
|
|
7
7
|
* (FIFO/LIFO) to await capacity.
|
|
8
8
|
*/
|
|
9
|
-
export declare class DelayedThenBlockingRejection<ContextT> implements AllotmentUnavailableStrategy<ContextT
|
|
9
|
+
export declare class DelayedThenBlockingRejection<ContextT> implements AllotmentUnavailableStrategy<ContextT> {
|
|
10
10
|
private readonly delayStrategy;
|
|
11
11
|
private readonly blockingStrategy;
|
|
12
12
|
constructor(options: {
|
|
13
13
|
delayStrategy: DelayedRejectStrategy<ContextT>;
|
|
14
|
-
blockingStrategy: AllotmentUnavailableStrategy<ContextT
|
|
14
|
+
blockingStrategy: AllotmentUnavailableStrategy<ContextT>;
|
|
15
15
|
});
|
|
16
|
-
onAllotmentUnavailable(context: ContextT, retry: (context: ContextT) =>
|
|
17
|
-
onAllotmentReleased(): void
|
|
16
|
+
onAllotmentUnavailable(context: ContextT, retry: (context: ContextT) => AcquireResult, signal?: AbortSignal): Promise<LimitAllotment | undefined>;
|
|
17
|
+
onAllotmentReleased(): Promise<void>;
|
|
18
18
|
}
|
|
19
19
|
//# sourceMappingURL=DelayedThenBlockingRejection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DelayedThenBlockingRejection.d.ts","sourceRoot":"","sources":["../../../src/limiter/allocation-unavailable-strategies/DelayedThenBlockingRejection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EACV,4BAA4B,EAC5B,aAAa,EACd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAExE;;;;GAIG;AACH,qBAAa,4BAA4B,CACvC,QAAQ,CACR,YAAW,4BAA4B,CAAC,QAAQ,CAAC;IACjD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkC;IAChE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAyC;gBAE9D,OAAO,EAAE;QACnB,aAAa,EAAE,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QAC/C,gBAAgB,EAAE,4BAA4B,CAAC,QAAQ,CAAC,CAAC;KAC1D;IAKK,sBAAsB,CAC1B,OAAO,EAAE,QAAQ,EACjB,KAAK,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,aAAa,EAC3C,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAYhC,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;CAI3C"}
|
|
@@ -15,12 +15,12 @@ export class DelayedThenBlockingRejection {
|
|
|
15
15
|
if (signal?.aborted) {
|
|
16
16
|
return undefined;
|
|
17
17
|
}
|
|
18
|
-
const allotment = retry(context);
|
|
18
|
+
const allotment = await retry(context);
|
|
19
19
|
return (allotment ??
|
|
20
20
|
this.blockingStrategy.onAllotmentUnavailable(context, retry, signal));
|
|
21
21
|
}
|
|
22
|
-
onAllotmentReleased() {
|
|
23
|
-
this.delayStrategy.onAllotmentReleased();
|
|
24
|
-
this.blockingStrategy.onAllotmentReleased();
|
|
22
|
+
async onAllotmentReleased() {
|
|
23
|
+
await this.delayStrategy.onAllotmentReleased();
|
|
24
|
+
await this.blockingStrategy.onAllotmentReleased();
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { LimitAllotment } from "
|
|
2
|
-
import type { AllotmentUnavailableStrategy,
|
|
1
|
+
import type { LimitAllotment } from "../../LimitAllotment.js";
|
|
2
|
+
import type { AllotmentUnavailableStrategy, AcquireResult } from "../../Limiter.js";
|
|
3
3
|
/**
|
|
4
4
|
* Rejection strategy that blocks the caller in a FIFO queue when the limit
|
|
5
5
|
* has been reached, waiting for a slot to open up. This strategy favors
|
|
@@ -8,7 +8,7 @@ import type { AllotmentUnavailableStrategy, AsyncAcquireResult, SyncAcquireResul
|
|
|
8
8
|
* Because JavaScript is single-threaded, "blocking" means awaiting a promise
|
|
9
9
|
* that resolves when a token becomes available.
|
|
10
10
|
*/
|
|
11
|
-
export declare class FifoBlockingRejection<ContextT> implements AllotmentUnavailableStrategy<ContextT
|
|
11
|
+
export declare class FifoBlockingRejection<ContextT> implements AllotmentUnavailableStrategy<ContextT> {
|
|
12
12
|
private readonly timeout;
|
|
13
13
|
private readonly waiters;
|
|
14
14
|
constructor(options?: {
|
|
@@ -18,7 +18,7 @@ export declare class FifoBlockingRejection<ContextT> implements AllotmentUnavail
|
|
|
18
18
|
*/
|
|
19
19
|
timeout?: number | undefined;
|
|
20
20
|
});
|
|
21
|
-
onAllotmentUnavailable(_context: ContextT, retry: (context: ContextT) =>
|
|
21
|
+
onAllotmentUnavailable(_context: ContextT, retry: (context: ContextT) => AcquireResult, signal?: AbortSignal): Promise<LimitAllotment | undefined>;
|
|
22
22
|
onAllotmentReleased(): void;
|
|
23
23
|
private acquireAsync;
|
|
24
24
|
private waitForRelease;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FifoBlockingRejection.d.ts","sourceRoot":"","sources":["../../../src/limiter/allocation-unavailable-strategies/FifoBlockingRejection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EACV,4BAA4B,EAC5B,aAAa,EACd,MAAM,kBAAkB,CAAC;AAM1B;;;;;;;GAOG;AACH,qBAAa,qBAAqB,CAChC,QAAQ,CACR,YAAW,4BAA4B,CAAC,QAAQ,CAAC;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAG3C,OAAO,GAAE;QACP;;;WAGG;QACH,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KACzB;IASR,sBAAsB,CACpB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,aAAa,EAC3C,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAItC,mBAAmB,IAAI,IAAI;YAOb,YAAY;IA6B1B,OAAO,CAAC,cAAc;CAoCvB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { LimitAllotment } from "
|
|
2
|
-
import type { AllotmentUnavailableStrategy,
|
|
1
|
+
import type { LimitAllotment } from "../../LimitAllotment.js";
|
|
2
|
+
import type { AllotmentUnavailableStrategy, AcquireResult } from "../../Limiter.js";
|
|
3
3
|
export interface LifoBlockingRejectionOptions<ContextT> {
|
|
4
4
|
/**
|
|
5
5
|
* Maximum number of blocked callers in the backlog. Default: 100
|
|
@@ -18,14 +18,14 @@ export interface LifoBlockingRejectionOptions<ContextT> {
|
|
|
18
18
|
* processing the most recently blocked request first, keeping success
|
|
19
19
|
* latencies low and minimizing timeouts.
|
|
20
20
|
*/
|
|
21
|
-
export declare class LifoBlockingRejection<ContextT> implements AllotmentUnavailableStrategy<ContextT
|
|
21
|
+
export declare class LifoBlockingRejection<ContextT> implements AllotmentUnavailableStrategy<ContextT> {
|
|
22
22
|
private readonly backlogSize;
|
|
23
23
|
private readonly getBacklogTimeout;
|
|
24
24
|
private readonly backlog;
|
|
25
25
|
private retry;
|
|
26
26
|
constructor(options?: LifoBlockingRejectionOptions<ContextT>);
|
|
27
|
-
onAllotmentUnavailable(context: ContextT, retry: (context: ContextT) =>
|
|
28
|
-
onAllotmentReleased(): void
|
|
27
|
+
onAllotmentUnavailable(context: ContextT, retry: (context: ContextT) => AcquireResult, signal?: AbortSignal): Promise<LimitAllotment | undefined>;
|
|
28
|
+
onAllotmentReleased(): Promise<void>;
|
|
29
29
|
private waitForBacklog;
|
|
30
30
|
}
|
|
31
31
|
//# sourceMappingURL=LifoBlockingRejection.d.ts.map
|