adaptive-concurrency 0.3.2 → 0.3.3
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 +7 -1
- package/dist/LimitAllotment.d.ts.map +1 -1
- package/dist/Limiter.d.ts +14 -21
- package/dist/Limiter.d.ts.map +1 -1
- package/dist/Limiter.js +31 -47
- package/dist/RunResult.d.ts +12 -6
- package/dist/RunResult.d.ts.map +1 -1
- package/dist/RunResult.js +10 -3
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/limiter/acquire-strategies/PartitionedStrategy.d.ts +34 -5
- package/dist/limiter/acquire-strategies/PartitionedStrategy.d.ts.map +1 -1
- package/dist/limiter/acquire-strategies/PartitionedStrategy.js +34 -9
- package/dist/limiter/acquire-strategies/SemaphoreStrategy.d.ts +13 -0
- package/dist/limiter/acquire-strategies/SemaphoreStrategy.d.ts.map +1 -0
- package/dist/limiter/acquire-strategies/SemaphoreStrategy.js +23 -0
- package/dist/limiter/allocation-unavailable-strategies/BlockingBacklogRejection.d.ts +51 -0
- package/dist/limiter/allocation-unavailable-strategies/BlockingBacklogRejection.d.ts.map +1 -0
- package/dist/limiter/allocation-unavailable-strategies/BlockingBacklogRejection.js +176 -0
- package/dist/limiter/allocation-unavailable-strategies/DelayedThenBlockingRejection.d.ts +1 -1
- package/dist/limiter/allocation-unavailable-strategies/DelayedThenBlockingRejection.d.ts.map +1 -1
- package/dist/limiter/allocation-unavailable-strategies/DelayedThenBlockingRejection.js +6 -0
- package/dist/limiter/allocation-unavailable-strategies/FifoBlockingRejection.d.ts +19 -15
- package/dist/limiter/allocation-unavailable-strategies/FifoBlockingRejection.d.ts.map +1 -1
- package/dist/limiter/allocation-unavailable-strategies/FifoBlockingRejection.js +12 -61
- package/dist/limiter/allocation-unavailable-strategies/LifoBlockingRejection.d.ts +4 -8
- package/dist/limiter/allocation-unavailable-strategies/LifoBlockingRejection.d.ts.map +1 -1
- package/dist/limiter/allocation-unavailable-strategies/LifoBlockingRejection.js +12 -49
- package/dist/limiter/factories/makeBlockingLimiter.d.ts +3 -1
- package/dist/limiter/factories/makeBlockingLimiter.d.ts.map +1 -1
- package/dist/limiter/factories/makeBlockingLimiter.js +3 -2
- package/dist/limiter/factories/makeLifoBlockingLimiter.d.ts +1 -1
- package/dist/limiter/factories/makeLifoBlockingLimiter.d.ts.map +1 -1
- package/dist/limiter/factories/makeLifoBlockingLimiter.js +1 -1
- package/dist/limiter/factories/makePartitionedBlockingLimiter.d.ts +3 -1
- package/dist/limiter/factories/makePartitionedBlockingLimiter.d.ts.map +1 -1
- package/dist/limiter/factories/makePartitionedBlockingLimiter.js +5 -4
- package/dist/limiter/factories/makeSimpleLimiter.d.ts.map +1 -1
- package/dist/limiter/factories/makeSimpleLimiter.js +2 -1
- package/package.json +3 -2
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { LimitAllotment } from "../../LimitAllotment.js";
|
|
2
|
+
import type { AcquireResult, AllotmentUnavailableStrategy } from "../../Limiter.js";
|
|
3
|
+
type Waiter<ContextT> = {
|
|
4
|
+
context: ContextT;
|
|
5
|
+
retry: (context: ContextT) => AcquireResult;
|
|
6
|
+
handle: WaiterHandle;
|
|
7
|
+
resolve: (allotment: LimitAllotment | undefined) => void;
|
|
8
|
+
};
|
|
9
|
+
export declare const MAX_TIMEOUT: number;
|
|
10
|
+
export type BlockingBacklogRejectionOptions<ContextT> = {
|
|
11
|
+
backlogSize: number;
|
|
12
|
+
backlogTimeout: number | ((context: ContextT) => number);
|
|
13
|
+
queue: WaiterQueue<Waiter<ContextT>>;
|
|
14
|
+
};
|
|
15
|
+
export type WaiterQueue<WaiterT extends Waiter<any>> = {
|
|
16
|
+
enqueue: (waiter: Omit<WaiterT, "handle">) => WaiterT;
|
|
17
|
+
peekHead: () => WaiterT | undefined;
|
|
18
|
+
removeByHandle: (handle: WaiterHandle) => boolean;
|
|
19
|
+
size: () => number;
|
|
20
|
+
};
|
|
21
|
+
export type WaiterHandle = {
|
|
22
|
+
key: symbol;
|
|
23
|
+
};
|
|
24
|
+
export declare class BlockingBacklogRejection<ContextT> implements AllotmentUnavailableStrategy<ContextT> {
|
|
25
|
+
private readonly backlogSize;
|
|
26
|
+
private readonly getBacklogTimeout;
|
|
27
|
+
private readonly queue;
|
|
28
|
+
private drainInProgress;
|
|
29
|
+
constructor(options: BlockingBacklogRejectionOptions<ContextT>);
|
|
30
|
+
onAllotmentUnavailable(context: ContextT, retry: (context: ContextT) => AcquireResult, signal?: AbortSignal): Promise<LimitAllotment | undefined>;
|
|
31
|
+
onAllotmentReleased(): Promise<void>;
|
|
32
|
+
onLimitChanged(oldLimit: number, newLimit: number): void;
|
|
33
|
+
private waitInBacklog;
|
|
34
|
+
private assertTimeoutWithinBounds;
|
|
35
|
+
}
|
|
36
|
+
export declare class ArrayWaiterQueue<WaiterT extends Waiter<any>> implements WaiterQueue<WaiterT> {
|
|
37
|
+
private head;
|
|
38
|
+
private tail;
|
|
39
|
+
private readonly nodes;
|
|
40
|
+
private readonly enqueueDirection;
|
|
41
|
+
private length;
|
|
42
|
+
constructor(enqueueDirection: "front" | "back");
|
|
43
|
+
enqueue(waiterWithoutHandle: Omit<WaiterT, "handle">): WaiterT;
|
|
44
|
+
peekHead(): WaiterT | undefined;
|
|
45
|
+
removeByHandle(handle: WaiterHandle): boolean;
|
|
46
|
+
size(): number;
|
|
47
|
+
private pushFront;
|
|
48
|
+
private pushBack;
|
|
49
|
+
}
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=BlockingBacklogRejection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlockingBacklogRejection.d.ts","sourceRoot":"","sources":["../../../src/limiter/allocation-unavailable-strategies/BlockingBacklogRejection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,KAAK,EACV,aAAa,EACb,4BAA4B,EAC7B,MAAM,kBAAkB,CAAC;AAE1B,KAAK,MAAM,CAAC,QAAQ,IAAI;IACtB,OAAO,EAAE,QAAQ,CAAC;IAClB,KAAK,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,aAAa,CAAC;IAC5C,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,CAAC,SAAS,EAAE,cAAc,GAAG,SAAS,KAAK,IAAI,CAAC;CAC1D,CAAC;AAEF,eAAO,MAAM,WAAW,QAAiB,CAAC;AAE1C,MAAM,MAAM,+BAA+B,CAAC,QAAQ,IAAI;IACtD,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,QAAQ,KAAK,MAAM,CAAC,CAAC;IACzD,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,OAAO,SAAS,MAAM,CAAC,GAAG,CAAC,IAAI;IACrD,OAAO,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,OAAO,CAAC;IACtD,QAAQ,EAAE,MAAM,OAAO,GAAG,SAAS,CAAC;IACpC,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC;IAClD,IAAI,EAAE,MAAM,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,qBAAa,wBAAwB,CACnC,QAAQ,CACR,YAAW,4BAA4B,CAAC,QAAQ,CAAC;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAgC;IAClE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;IACtD,OAAO,CAAC,eAAe,CAAS;gBAEpB,OAAO,EAAE,+BAA+B,CAAC,QAAQ,CAAC;IAmB9D,sBAAsB,CACpB,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;IAgC1C,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAQxD,OAAO,CAAC,aAAa;IAmCrB,OAAO,CAAC,yBAAyB;CAKlC;AAED,qBAAa,gBAAgB,CAC3B,OAAO,SAAS,MAAM,CAAC,GAAG,CAAC,CAC3B,YAAW,WAAW,CAAC,OAAO,CAAC;IAC/B,OAAO,CAAC,IAAI,CAAkC;IAC9C,OAAO,CAAC,IAAI,CAAkC;IAC9C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0C;IAChE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,MAAM,CAAK;gBAEP,gBAAgB,EAAE,OAAO,GAAG,MAAM;IAI9C,OAAO,CAAC,mBAAmB,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,OAAO;IAuB9D,QAAQ,IAAI,OAAO,GAAG,SAAS;IAI/B,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO;IAuB7C,IAAI,IAAI,MAAM;IAId,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,QAAQ;CAWjB"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
export const MAX_TIMEOUT = 60 * 60 * 1000; // 1 hour
|
|
2
|
+
export class BlockingBacklogRejection {
|
|
3
|
+
backlogSize;
|
|
4
|
+
getBacklogTimeout;
|
|
5
|
+
queue;
|
|
6
|
+
drainInProgress = false;
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.backlogSize = options.backlogSize;
|
|
9
|
+
this.queue = options.queue;
|
|
10
|
+
const backlogTimeout = options.backlogTimeout;
|
|
11
|
+
if (typeof backlogTimeout === "number") {
|
|
12
|
+
this.assertTimeoutWithinBounds(backlogTimeout);
|
|
13
|
+
this.getBacklogTimeout = () => backlogTimeout;
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
this.getBacklogTimeout = (context) => {
|
|
17
|
+
const contextTimeout = backlogTimeout(context);
|
|
18
|
+
this.assertTimeoutWithinBounds(contextTimeout);
|
|
19
|
+
return contextTimeout;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
onAllotmentUnavailable(context, retry, signal) {
|
|
23
|
+
if (signal?.aborted) {
|
|
24
|
+
return Promise.resolve(undefined);
|
|
25
|
+
}
|
|
26
|
+
if (this.queue.size() >= this.backlogSize) {
|
|
27
|
+
return Promise.resolve(undefined);
|
|
28
|
+
}
|
|
29
|
+
return this.waitInBacklog(context, retry, signal);
|
|
30
|
+
}
|
|
31
|
+
async onAllotmentReleased() {
|
|
32
|
+
if (this.drainInProgress || this.queue.size() === 0) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
this.drainInProgress = true;
|
|
36
|
+
try {
|
|
37
|
+
while (this.queue.size() > 0) {
|
|
38
|
+
const waiter = this.queue.peekHead();
|
|
39
|
+
if (!waiter) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const allotment = await waiter.retry(waiter.context);
|
|
43
|
+
if (!allotment) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (!this.queue.removeByHandle(waiter.handle)) {
|
|
47
|
+
// Waiter expired while retry was in-flight. Release the acquired slot
|
|
48
|
+
// so future retries can serve active queued waiters.
|
|
49
|
+
await allotment.releaseAndIgnore();
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
waiter.resolve(allotment);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
this.drainInProgress = false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
onLimitChanged(oldLimit, newLimit) {
|
|
60
|
+
if (newLimit > oldLimit) {
|
|
61
|
+
queueMicrotask(() => {
|
|
62
|
+
void this.onAllotmentReleased();
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
waitInBacklog(context, retry, signal) {
|
|
67
|
+
return new Promise((resolve) => {
|
|
68
|
+
let settled = false;
|
|
69
|
+
const settle = (allotment) => {
|
|
70
|
+
if (settled)
|
|
71
|
+
return;
|
|
72
|
+
settled = true;
|
|
73
|
+
cleanup();
|
|
74
|
+
resolve(allotment);
|
|
75
|
+
};
|
|
76
|
+
const waiter = this.queue.enqueue({
|
|
77
|
+
context,
|
|
78
|
+
retry,
|
|
79
|
+
resolve: (allotment) => settle(allotment),
|
|
80
|
+
});
|
|
81
|
+
const timer = setTimeout(() => settle(undefined), this.getBacklogTimeout(context));
|
|
82
|
+
const onAbort = () => settle(undefined);
|
|
83
|
+
const cleanup = () => {
|
|
84
|
+
clearTimeout(timer);
|
|
85
|
+
signal?.removeEventListener("abort", onAbort);
|
|
86
|
+
this.queue.removeByHandle(waiter.handle);
|
|
87
|
+
};
|
|
88
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
assertTimeoutWithinBounds(timeout) {
|
|
92
|
+
if (timeout > MAX_TIMEOUT) {
|
|
93
|
+
throw new Error(`Timeout cannot be greater than ${MAX_TIMEOUT} ms`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export class ArrayWaiterQueue {
|
|
98
|
+
head;
|
|
99
|
+
tail;
|
|
100
|
+
nodes = new Map();
|
|
101
|
+
enqueueDirection;
|
|
102
|
+
length = 0;
|
|
103
|
+
constructor(enqueueDirection) {
|
|
104
|
+
this.enqueueDirection = enqueueDirection;
|
|
105
|
+
}
|
|
106
|
+
enqueue(waiterWithoutHandle) {
|
|
107
|
+
const handle = { key: Symbol("waiter-node") };
|
|
108
|
+
const waiter = {
|
|
109
|
+
...waiterWithoutHandle,
|
|
110
|
+
handle,
|
|
111
|
+
};
|
|
112
|
+
const node = {
|
|
113
|
+
handle,
|
|
114
|
+
value: waiter,
|
|
115
|
+
prev: undefined,
|
|
116
|
+
next: undefined,
|
|
117
|
+
};
|
|
118
|
+
this.nodes.set(handle.key, node);
|
|
119
|
+
if (this.enqueueDirection === "front") {
|
|
120
|
+
this.pushFront(node);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
this.pushBack(node);
|
|
124
|
+
}
|
|
125
|
+
this.length += 1;
|
|
126
|
+
return waiter;
|
|
127
|
+
}
|
|
128
|
+
peekHead() {
|
|
129
|
+
return this.head?.value;
|
|
130
|
+
}
|
|
131
|
+
removeByHandle(handle) {
|
|
132
|
+
const node = this.nodes.get(handle.key);
|
|
133
|
+
if (!node)
|
|
134
|
+
return false;
|
|
135
|
+
this.nodes.delete(handle.key);
|
|
136
|
+
if (node.prev) {
|
|
137
|
+
node.prev.next = node.next;
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
this.head = node.next;
|
|
141
|
+
}
|
|
142
|
+
if (node.next) {
|
|
143
|
+
node.next.prev = node.prev;
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
this.tail = node.prev;
|
|
147
|
+
}
|
|
148
|
+
node.prev = undefined;
|
|
149
|
+
node.next = undefined;
|
|
150
|
+
this.length -= 1;
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
size() {
|
|
154
|
+
return this.length;
|
|
155
|
+
}
|
|
156
|
+
pushFront(node) {
|
|
157
|
+
if (!this.head) {
|
|
158
|
+
this.head = node;
|
|
159
|
+
this.tail = node;
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
node.next = this.head;
|
|
163
|
+
this.head.prev = node;
|
|
164
|
+
this.head = node;
|
|
165
|
+
}
|
|
166
|
+
pushBack(node) {
|
|
167
|
+
if (!this.tail) {
|
|
168
|
+
this.head = node;
|
|
169
|
+
this.tail = node;
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
node.prev = this.tail;
|
|
173
|
+
this.tail.next = node;
|
|
174
|
+
this.tail = node;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { LimitAllotment } from "../../LimitAllotment.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { AcquireResult, AllotmentUnavailableStrategy } 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:
|
package/dist/limiter/allocation-unavailable-strategies/DelayedThenBlockingRejection.d.ts.map
CHANGED
|
@@ -1 +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,
|
|
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,aAAa,EACb,4BAA4B,EAC7B,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;IAqBhC,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;CAI3C"}
|
|
@@ -16,6 +16,12 @@ export class DelayedThenBlockingRejection {
|
|
|
16
16
|
return undefined;
|
|
17
17
|
}
|
|
18
18
|
const allotment = await retry(context);
|
|
19
|
+
if (allotment) {
|
|
20
|
+
return allotment;
|
|
21
|
+
}
|
|
22
|
+
if (signal?.aborted) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
19
25
|
return (allotment ??
|
|
20
26
|
this.blockingStrategy.onAllotmentUnavailable(context, retry, signal));
|
|
21
27
|
}
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type { AcquireResult, AllotmentUnavailableStrategy } from "../../Limiter.js";
|
|
2
|
+
export type FifoBlockingRejectionOptions<ContextT> = {
|
|
3
|
+
/**
|
|
4
|
+
* Maximum number of blocked callers in the backlog.
|
|
5
|
+
* Default: unbounded
|
|
6
|
+
*/
|
|
7
|
+
backlogSize?: number | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Maximum timeout for callers blocked on the limiter, in milliseconds.
|
|
10
|
+
* Can be a fixed number or a function that derives the timeout from the
|
|
11
|
+
* request context (e.g. from a deadline). Default: 3_600_000 (1 hour).
|
|
12
|
+
*/
|
|
13
|
+
backlogTimeout?: number | ((context: ContextT) => number) | undefined;
|
|
14
|
+
};
|
|
3
15
|
/**
|
|
4
16
|
* Rejection strategy that blocks the caller in a FIFO queue when the limit
|
|
5
17
|
* has been reached, waiting for a slot to open up. This strategy favors
|
|
@@ -9,18 +21,10 @@ import type { AllotmentUnavailableStrategy, AcquireResult } from "../../Limiter.
|
|
|
9
21
|
* that resolves when a token becomes available.
|
|
10
22
|
*/
|
|
11
23
|
export declare class FifoBlockingRejection<ContextT> implements AllotmentUnavailableStrategy<ContextT> {
|
|
12
|
-
private readonly
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
* Default: 3_600_000 (1 hour).
|
|
18
|
-
*/
|
|
19
|
-
timeout?: number | undefined;
|
|
20
|
-
});
|
|
21
|
-
onAllotmentUnavailable(_context: ContextT, retry: (context: ContextT) => AcquireResult, signal?: AbortSignal): Promise<LimitAllotment | undefined>;
|
|
22
|
-
onAllotmentReleased(): void;
|
|
23
|
-
private acquireAsync;
|
|
24
|
-
private waitForRelease;
|
|
24
|
+
private readonly delegate;
|
|
25
|
+
constructor(options?: FifoBlockingRejectionOptions<ContextT>);
|
|
26
|
+
onAllotmentUnavailable(context: ContextT, retry: (context: ContextT) => AcquireResult, signal?: AbortSignal): Promise<import("../../LimitAllotment.js").LimitAllotment | undefined>;
|
|
27
|
+
onAllotmentReleased(): Promise<void>;
|
|
28
|
+
onLimitChanged(oldLimit: number, newLimit: number): void;
|
|
25
29
|
}
|
|
26
30
|
//# sourceMappingURL=FifoBlockingRejection.d.ts.map
|
|
@@ -1 +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,
|
|
1
|
+
{"version":3,"file":"FifoBlockingRejection.d.ts","sourceRoot":"","sources":["../../../src/limiter/allocation-unavailable-strategies/FifoBlockingRejection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,4BAA4B,EAC7B,MAAM,kBAAkB,CAAC;AAO1B,MAAM,MAAM,4BAA4B,CAAC,QAAQ,IAAI;IACnD;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEjC;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,QAAQ,KAAK,MAAM,CAAC,GAAG,SAAS,CAAC;CACvE,CAAC;AAEF;;;;;;;GAOG;AACH,qBAAa,qBAAqB,CAChC,QAAQ,CACR,YAAW,4BAA4B,CAAC,QAAQ,CAAC;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;gBAElD,OAAO,GAAE,4BAA4B,CAAC,QAAQ,CAAM;IAQhE,sBAAsB,CACpB,OAAO,EAAE,QAAQ,EACjB,KAAK,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,aAAa,EAC3C,MAAM,CAAC,EAAE,WAAW;IAKtB,mBAAmB;IAInB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;CAGzD"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { ArrayWaiterQueue, BlockingBacklogRejection, MAX_TIMEOUT, } from "./BlockingBacklogRejection.js";
|
|
2
2
|
/**
|
|
3
3
|
* Rejection strategy that blocks the caller in a FIFO queue when the limit
|
|
4
4
|
* has been reached, waiting for a slot to open up. This strategy favors
|
|
@@ -8,70 +8,21 @@ const MAX_TIMEOUT = 60 * 60 * 1000; // 1 hour
|
|
|
8
8
|
* that resolves when a token becomes available.
|
|
9
9
|
*/
|
|
10
10
|
export class FifoBlockingRejection {
|
|
11
|
-
|
|
12
|
-
waiters = [];
|
|
11
|
+
delegate;
|
|
13
12
|
constructor(options = {}) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
this.delegate = new BlockingBacklogRejection({
|
|
14
|
+
backlogSize: options.backlogSize ?? Number.POSITIVE_INFINITY,
|
|
15
|
+
backlogTimeout: options.backlogTimeout ?? MAX_TIMEOUT,
|
|
16
|
+
queue: new ArrayWaiterQueue("back"),
|
|
17
|
+
});
|
|
19
18
|
}
|
|
20
|
-
onAllotmentUnavailable(
|
|
21
|
-
return this.
|
|
19
|
+
onAllotmentUnavailable(context, retry, signal) {
|
|
20
|
+
return this.delegate.onAllotmentUnavailable(context, retry, signal);
|
|
22
21
|
}
|
|
23
22
|
onAllotmentReleased() {
|
|
24
|
-
|
|
25
|
-
for (const waiter of waiters) {
|
|
26
|
-
waiter();
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
async acquireAsync(context, retry, signal) {
|
|
30
|
-
const deadline = performance.now() + this.timeout;
|
|
31
|
-
while (true) {
|
|
32
|
-
const remaining = deadline - performance.now();
|
|
33
|
-
if (remaining <= 0) {
|
|
34
|
-
return undefined;
|
|
35
|
-
}
|
|
36
|
-
if (signal?.aborted) {
|
|
37
|
-
return undefined;
|
|
38
|
-
}
|
|
39
|
-
const allotment = await retry(context);
|
|
40
|
-
if (allotment) {
|
|
41
|
-
return allotment;
|
|
42
|
-
}
|
|
43
|
-
const acquired = await this.waitForRelease(remaining, signal);
|
|
44
|
-
if (!acquired) {
|
|
45
|
-
return undefined;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
23
|
+
return this.delegate.onAllotmentReleased();
|
|
48
24
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return Promise.resolve(false);
|
|
52
|
-
}
|
|
53
|
-
return new Promise((resolve) => {
|
|
54
|
-
let settled = false;
|
|
55
|
-
const settle = (acquired) => {
|
|
56
|
-
if (settled)
|
|
57
|
-
return;
|
|
58
|
-
settled = true;
|
|
59
|
-
cleanup();
|
|
60
|
-
resolve(acquired);
|
|
61
|
-
};
|
|
62
|
-
const waiter = () => settle(true);
|
|
63
|
-
this.waiters.push(waiter);
|
|
64
|
-
const timer = setTimeout(() => settle(false), timeoutMs);
|
|
65
|
-
const onAbort = () => settle(false);
|
|
66
|
-
const cleanup = () => {
|
|
67
|
-
clearTimeout(timer);
|
|
68
|
-
signal?.removeEventListener("abort", onAbort);
|
|
69
|
-
const idx = this.waiters.indexOf(waiter);
|
|
70
|
-
if (idx !== -1) {
|
|
71
|
-
this.waiters.splice(idx, 1);
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
75
|
-
});
|
|
25
|
+
onLimitChanged(oldLimit, newLimit) {
|
|
26
|
+
this.delegate.onLimitChanged(oldLimit, newLimit);
|
|
76
27
|
}
|
|
77
28
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { AllotmentUnavailableStrategy, AcquireResult } from "../../Limiter.js";
|
|
1
|
+
import type { AcquireResult, AllotmentUnavailableStrategy } from "../../Limiter.js";
|
|
3
2
|
export interface LifoBlockingRejectionOptions<ContextT> {
|
|
4
3
|
/**
|
|
5
4
|
* Maximum number of blocked callers in the backlog. Default: 100
|
|
@@ -19,13 +18,10 @@ export interface LifoBlockingRejectionOptions<ContextT> {
|
|
|
19
18
|
* latencies low and minimizing timeouts.
|
|
20
19
|
*/
|
|
21
20
|
export declare class LifoBlockingRejection<ContextT> implements AllotmentUnavailableStrategy<ContextT> {
|
|
22
|
-
private readonly
|
|
23
|
-
private readonly getBacklogTimeout;
|
|
24
|
-
private readonly backlog;
|
|
25
|
-
private retry;
|
|
21
|
+
private readonly delegate;
|
|
26
22
|
constructor(options?: LifoBlockingRejectionOptions<ContextT>);
|
|
27
|
-
onAllotmentUnavailable(context: ContextT, retry: (context: ContextT) => AcquireResult, signal?: AbortSignal): Promise<LimitAllotment | undefined>;
|
|
23
|
+
onAllotmentUnavailable(context: ContextT, retry: (context: ContextT) => AcquireResult, signal?: AbortSignal): Promise<import("../../LimitAllotment.js").LimitAllotment | undefined>;
|
|
28
24
|
onAllotmentReleased(): Promise<void>;
|
|
29
|
-
|
|
25
|
+
onLimitChanged(oldLimit: number, newLimit: number): void;
|
|
30
26
|
}
|
|
31
27
|
//# sourceMappingURL=LifoBlockingRejection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LifoBlockingRejection.d.ts","sourceRoot":"","sources":["../../../src/limiter/allocation-unavailable-strategies/LifoBlockingRejection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"LifoBlockingRejection.d.ts","sourceRoot":"","sources":["../../../src/limiter/allocation-unavailable-strategies/LifoBlockingRejection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,4BAA4B,EAC7B,MAAM,kBAAkB,CAAC;AAM1B,MAAM,WAAW,4BAA4B,CAAC,QAAQ;IACpD;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEjC;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,QAAQ,KAAK,MAAM,CAAC,GAAG,SAAS,CAAC;CACvE;AAED;;;;;GAKG;AACH,qBAAa,qBAAqB,CAChC,QAAQ,CACR,YAAW,4BAA4B,CAAC,QAAQ,CAAC;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;gBAElD,OAAO,GAAE,4BAA4B,CAAC,QAAQ,CAAM;IAQhE,sBAAsB,CACpB,OAAO,EAAE,QAAQ,EACjB,KAAK,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,aAAa,EAC3C,MAAM,CAAC,EAAE,WAAW;IAKtB,mBAAmB;IAInB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;CAGzD"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ArrayWaiterQueue, BlockingBacklogRejection, } from "./BlockingBacklogRejection.js";
|
|
1
2
|
/**
|
|
2
3
|
* Rejection strategy that blocks the caller in a LIFO queue when the limit
|
|
3
4
|
* has been reached. This strategy favors availability over latency by
|
|
@@ -5,59 +6,21 @@
|
|
|
5
6
|
* latencies low and minimizing timeouts.
|
|
6
7
|
*/
|
|
7
8
|
export class LifoBlockingRejection {
|
|
8
|
-
|
|
9
|
-
getBacklogTimeout;
|
|
10
|
-
backlog = [];
|
|
11
|
-
retry;
|
|
9
|
+
delegate;
|
|
12
10
|
constructor(options = {}) {
|
|
13
|
-
this.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
this.delegate = new BlockingBacklogRejection({
|
|
12
|
+
backlogSize: options.backlogSize ?? 100,
|
|
13
|
+
backlogTimeout: options.backlogTimeout ?? 1_000,
|
|
14
|
+
queue: new ArrayWaiterQueue("front"),
|
|
15
|
+
});
|
|
17
16
|
}
|
|
18
17
|
onAllotmentUnavailable(context, retry, signal) {
|
|
19
|
-
this.retry
|
|
20
|
-
if (this.backlog.length >= this.backlogSize) {
|
|
21
|
-
return Promise.resolve(undefined);
|
|
22
|
-
}
|
|
23
|
-
return this.waitForBacklog(context, signal);
|
|
18
|
+
return this.delegate.onAllotmentUnavailable(context, retry, signal);
|
|
24
19
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return;
|
|
28
|
-
const waiter = this.backlog[0];
|
|
29
|
-
const allotment = await this.retry(waiter.context);
|
|
30
|
-
if (allotment) {
|
|
31
|
-
this.backlog.shift();
|
|
32
|
-
waiter.resolve(allotment);
|
|
33
|
-
}
|
|
20
|
+
onAllotmentReleased() {
|
|
21
|
+
return this.delegate.onAllotmentReleased();
|
|
34
22
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
let settled = false;
|
|
38
|
-
const settle = (allotment) => {
|
|
39
|
-
if (settled)
|
|
40
|
-
return;
|
|
41
|
-
settled = true;
|
|
42
|
-
cleanup();
|
|
43
|
-
resolve(allotment);
|
|
44
|
-
};
|
|
45
|
-
const waiter = {
|
|
46
|
-
context,
|
|
47
|
-
resolve: (allotment) => settle(allotment),
|
|
48
|
-
};
|
|
49
|
-
this.backlog.unshift(waiter);
|
|
50
|
-
const timer = setTimeout(() => settle(undefined), this.getBacklogTimeout(context));
|
|
51
|
-
const onAbort = () => settle(undefined);
|
|
52
|
-
const cleanup = () => {
|
|
53
|
-
clearTimeout(timer);
|
|
54
|
-
signal?.removeEventListener("abort", onAbort);
|
|
55
|
-
const idx = this.backlog.indexOf(waiter);
|
|
56
|
-
if (idx !== -1) {
|
|
57
|
-
this.backlog.splice(idx, 1);
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
61
|
-
});
|
|
23
|
+
onLimitChanged(oldLimit, newLimit) {
|
|
24
|
+
this.delegate.onLimitChanged(oldLimit, newLimit);
|
|
62
25
|
}
|
|
63
26
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Limiter, type LimiterOptions } from "../../Limiter.js";
|
|
2
|
+
import { type FifoBlockingRejectionOptions } from "../allocation-unavailable-strategies/FifoBlockingRejection.js";
|
|
2
3
|
export declare function makeBlockingLimiter<ContextT = void>(options?: {
|
|
3
|
-
|
|
4
|
+
backlogSize?: number;
|
|
5
|
+
backlogTimeout?: FifoBlockingRejectionOptions<ContextT>["backlogTimeout"];
|
|
4
6
|
limiter?: Omit<LimiterOptions<ContextT>, "allotmentUnavailableStrategy">;
|
|
5
7
|
}): Limiter<ContextT>;
|
|
6
8
|
//# sourceMappingURL=makeBlockingLimiter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makeBlockingLimiter.d.ts","sourceRoot":"","sources":["../../../src/limiter/factories/makeBlockingLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"makeBlockingLimiter.d.ts","sourceRoot":"","sources":["../../../src/limiter/factories/makeBlockingLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,KAAK,4BAA4B,EAClC,MAAM,+DAA+D,CAAC;AAEvE,wBAAgB,mBAAmB,CAAC,QAAQ,GAAG,IAAI,EACjD,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,4BAA4B,CAAC,QAAQ,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAC1E,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,8BAA8B,CAAC,CAAC;CACrE,GACL,OAAO,CAAC,QAAQ,CAAC,CAQnB"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Limiter, } from "../../Limiter.js";
|
|
2
|
-
import { FifoBlockingRejection } from "../allocation-unavailable-strategies/FifoBlockingRejection.js";
|
|
2
|
+
import { FifoBlockingRejection, } from "../allocation-unavailable-strategies/FifoBlockingRejection.js";
|
|
3
3
|
export function makeBlockingLimiter(options = {}) {
|
|
4
4
|
return new Limiter({
|
|
5
5
|
...options.limiter,
|
|
6
6
|
allotmentUnavailableStrategy: new FifoBlockingRejection({
|
|
7
|
-
|
|
7
|
+
backlogSize: options.backlogSize,
|
|
8
|
+
backlogTimeout: options.backlogTimeout,
|
|
8
9
|
}),
|
|
9
10
|
});
|
|
10
11
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Limiter, type LimiterOptions } from "../../Limiter.js";
|
|
2
2
|
import { type LifoBlockingRejectionOptions } from "../allocation-unavailable-strategies/LifoBlockingRejection.js";
|
|
3
3
|
export declare function makeLifoBlockingLimiter<ContextT = void>(options?: {
|
|
4
|
-
backlogSize?:
|
|
4
|
+
backlogSize?: LifoBlockingRejectionOptions<ContextT>["backlogSize"];
|
|
5
5
|
backlogTimeout?: LifoBlockingRejectionOptions<ContextT>["backlogTimeout"];
|
|
6
6
|
limiter?: Omit<LimiterOptions<ContextT>, "allotmentUnavailableStrategy">;
|
|
7
7
|
}): Limiter<ContextT>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makeLifoBlockingLimiter.d.ts","sourceRoot":"","sources":["../../../src/limiter/factories/makeLifoBlockingLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"makeLifoBlockingLimiter.d.ts","sourceRoot":"","sources":["../../../src/limiter/factories/makeLifoBlockingLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAEL,KAAK,4BAA4B,EAClC,MAAM,+DAA+D,CAAC;AAEvE,wBAAgB,uBAAuB,CAAC,QAAQ,GAAG,IAAI,EACrD,OAAO,GAAE;IACP,WAAW,CAAC,EAAE,4BAA4B,CAAC,QAAQ,CAAC,CAAC,aAAa,CAAC,CAAC;IACpE,cAAc,CAAC,EAAE,4BAA4B,CAAC,QAAQ,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAC1E,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,8BAA8B,CAAC,CAAC;CACrE,GACL,OAAO,CAAC,QAAQ,CAAC,CAQnB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Limiter
|
|
1
|
+
import { Limiter } from "../../Limiter.js";
|
|
2
2
|
import { LifoBlockingRejection, } from "../allocation-unavailable-strategies/LifoBlockingRejection.js";
|
|
3
3
|
export function makeLifoBlockingLimiter(options = {}) {
|
|
4
4
|
return new Limiter({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Limiter, type LimiterOptions } from "../../Limiter.js";
|
|
2
2
|
import { type PartitionConfig } from "../acquire-strategies/PartitionedStrategy.js";
|
|
3
|
+
import { type FifoBlockingRejectionOptions } from "../allocation-unavailable-strategies/FifoBlockingRejection.js";
|
|
3
4
|
export declare function makePartitionedBlockingLimiter<ContextT, PartitionName extends string = string>(options: {
|
|
4
5
|
partitionResolver: (context: ContextT) => PartitionName | undefined;
|
|
5
6
|
partitions: Record<PartitionName, PartitionConfig & {
|
|
@@ -7,6 +8,7 @@ export declare function makePartitionedBlockingLimiter<ContextT, PartitionName e
|
|
|
7
8
|
}>;
|
|
8
9
|
limiter?: Omit<LimiterOptions<ContextT>, "acquireStrategy">;
|
|
9
10
|
maxConcurrentDelays?: number;
|
|
10
|
-
|
|
11
|
+
backlogSize?: FifoBlockingRejectionOptions<ContextT>["backlogSize"];
|
|
12
|
+
backlogTimeout?: FifoBlockingRejectionOptions<ContextT>["backlogTimeout"];
|
|
11
13
|
}): Limiter<ContextT>;
|
|
12
14
|
//# sourceMappingURL=makePartitionedBlockingLimiter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makePartitionedBlockingLimiter.d.ts","sourceRoot":"","sources":["../../../src/limiter/factories/makePartitionedBlockingLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"makePartitionedBlockingLimiter.d.ts","sourceRoot":"","sources":["../../../src/limiter/factories/makePartitionedBlockingLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,8CAA8C,CAAC;AAGtD,OAAO,EAEL,KAAK,4BAA4B,EAClC,MAAM,+DAA+D,CAAC;AAEvE,wBAAgB,8BAA8B,CAC5C,QAAQ,EACR,aAAa,SAAS,MAAM,GAAG,MAAM,EACrC,OAAO,EAAE;IACT,iBAAiB,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,aAAa,GAAG,SAAS,CAAC;IACpE,UAAU,EAAE,MAAM,CAAC,aAAa,EAAE,eAAe,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1E,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC,CAAC;IAC5D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,4BAA4B,CAAC,QAAQ,CAAC,CAAC,aAAa,CAAC,CAAC;IACpE,cAAc,CAAC,EAAE,4BAA4B,CAAC,QAAQ,CAAC,CAAC,gBAAgB,CAAC,CAAC;CAC3E,GAAG,OAAO,CAAC,QAAQ,CAAC,CAiCpB"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Limiter
|
|
1
|
+
import { Limiter } from "../../Limiter.js";
|
|
2
|
+
import { PartitionedStrategy, } from "../acquire-strategies/PartitionedStrategy.js";
|
|
2
3
|
import { DelayedRejectStrategy } from "../allocation-unavailable-strategies/DelayedRejectStrategy.js";
|
|
3
4
|
import { DelayedThenBlockingRejection } from "../allocation-unavailable-strategies/DelayedThenBlockingRejection.js";
|
|
4
|
-
import { FifoBlockingRejection } from "../allocation-unavailable-strategies/FifoBlockingRejection.js";
|
|
5
|
-
import { PartitionedStrategy, } from "../acquire-strategies/PartitionedStrategy.js";
|
|
5
|
+
import { FifoBlockingRejection, } from "../allocation-unavailable-strategies/FifoBlockingRejection.js";
|
|
6
6
|
export function makePartitionedBlockingLimiter(options) {
|
|
7
7
|
const limit = options.limiter?.limit ?? Limiter.makeDefaultLimit();
|
|
8
8
|
const delayByPartition = new Map(Object.entries(options.partitions).map(([name, cfg]) => [
|
|
@@ -29,7 +29,8 @@ export function makePartitionedBlockingLimiter(options) {
|
|
|
29
29
|
maxConcurrentDelays: options.maxConcurrentDelays,
|
|
30
30
|
}),
|
|
31
31
|
blockingStrategy: new FifoBlockingRejection({
|
|
32
|
-
|
|
32
|
+
backlogSize: options.backlogSize,
|
|
33
|
+
backlogTimeout: options.backlogTimeout,
|
|
33
34
|
}),
|
|
34
35
|
}),
|
|
35
36
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makeSimpleLimiter.d.ts","sourceRoot":"","sources":["../../../src/limiter/factories/makeSimpleLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"makeSimpleLimiter.d.ts","sourceRoot":"","sources":["../../../src/limiter/factories/makeSimpleLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGhE,wBAAgB,iBAAiB,CAAC,QAAQ,GAAG,IAAI,EAC/C,OAAO,GAAE,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAM,GAC9D,OAAO,CAAC,QAAQ,CAAC,CAOnB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Limiter
|
|
1
|
+
import { Limiter } from "../../Limiter.js";
|
|
2
|
+
import { SemaphoreStrategy } from "../acquire-strategies/SemaphoreStrategy.js";
|
|
2
3
|
export function makeSimpleLimiter(options = {}) {
|
|
3
4
|
const limit = options.limit ?? Limiter.makeDefaultLimit();
|
|
4
5
|
return new Limiter({
|