adaptive-concurrency 0.9.0 → 0.10.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/Limiter.d.ts CHANGED
@@ -121,6 +121,8 @@ export declare class Limiter<Context = void> {
121
121
  private readonly acquireFailedCounter;
122
122
  private readonly acquireBypassedCounter;
123
123
  private readonly limitGauge;
124
+ private readonly acquireTimeOnSuccessDistribution;
125
+ private readonly acquireTimeOnUnavailableDistribution;
124
126
  static makeDefaultLimit(): AdaptiveLimit;
125
127
  constructor(options?: LimiterOptions<Context>);
126
128
  acquire(options?: AcquireOptions<Context>): AcquireResult;
@@ -1 +1 @@
1
- {"version":3,"file":"Limiter.d.ts","sourceRoot":"","sources":["../src/Limiter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Limiter.d.ts","sourceRoot":"","sources":["../src/Limiter.ts"],"names":[],"mappings":"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"}
package/dist/Limiter.js CHANGED
@@ -28,6 +28,8 @@ export class Limiter {
28
28
  acquireFailedCounter;
29
29
  acquireBypassedCounter;
30
30
  limitGauge;
31
+ acquireTimeOnSuccessDistribution;
32
+ acquireTimeOnUnavailableDistribution;
31
33
  static makeDefaultLimit() {
32
34
  return new GradientLimit();
33
35
  }
@@ -66,6 +68,8 @@ export class Limiter {
66
68
  this.acquireSucceededCounter = registry.counter(MetricIds.ACQUIRE_ATTEMPT_NAME, { id: limiterName, status: "succeeded" });
67
69
  this.acquireFailedCounter = registry.counter(MetricIds.ACQUIRE_ATTEMPT_NAME, { id: limiterName, status: "failed" });
68
70
  this.acquireBypassedCounter = registry.counter(MetricIds.ACQUIRE_ATTEMPT_NAME, { id: limiterName, status: "bypassed" });
71
+ this.acquireTimeOnSuccessDistribution = registry.distribution(MetricIds.ACQUIRE_TIME_NAME, { id: limiterName, status: "success" });
72
+ this.acquireTimeOnUnavailableDistribution = registry.distribution(MetricIds.ACQUIRE_TIME_NAME, { id: limiterName, status: "unavailable" });
69
73
  this.acquireBypassedAllotment = {
70
74
  releaseAndRecordSuccess: async () => {
71
75
  this.successCounter.increment();
@@ -77,6 +81,8 @@ export class Limiter {
77
81
  this.droppedCounter.increment();
78
82
  },
79
83
  };
84
+ // Emit metric for initial limit.
85
+ this.limitGauge.record(this._limit);
80
86
  }
81
87
  async acquire(options) {
82
88
  if (options?.signal?.aborted)
@@ -86,6 +92,7 @@ export class Limiter {
86
92
  this.acquireBypassedCounter.increment();
87
93
  return this.acquireBypassedAllotment;
88
94
  }
95
+ const acquireStart = this.clock();
89
96
  const state = {
90
97
  limit: this._limit,
91
98
  inflight: this._inflight,
@@ -93,21 +100,32 @@ export class Limiter {
93
100
  if (!(await this.acquireStrategy.tryAcquireAllotment(ctx, state))) {
94
101
  this.acquireFailedCounter.increment();
95
102
  if (!this.rejectionStrategy) {
103
+ this.acquireTimeOnUnavailableDistribution.addSample(this.clock() - acquireStart);
96
104
  return undefined;
97
105
  }
98
- // if signal aborted here, nothing to cleanup, as we didn't acquire anything.
106
+ // if signal aborted here, nothing to cleanup, as we didn't acquire
107
+ // anything. Also, don't try to record the acquire time, as we aborted
108
+ // mid-way (didn't invoke the rejection strategy).
99
109
  if (options?.signal?.aborted) {
100
110
  return undefined;
101
111
  }
102
- return this.rejectionStrategy.onAllotmentUnavailable(ctx, async (retryCtx) => {
112
+ const result = await this.rejectionStrategy.onAllotmentUnavailable(ctx, async (retryCtx) => {
103
113
  if (options?.signal?.aborted) {
104
114
  return undefined;
105
115
  }
106
116
  return this.tryAcquireCore(retryCtx);
107
117
  }, options?.signal);
118
+ const distribution = result
119
+ ? this.acquireTimeOnSuccessDistribution
120
+ : this.acquireTimeOnUnavailableDistribution;
121
+ distribution.addSample(this.clock() - acquireStart);
122
+ return result;
108
123
  }
109
124
  this.acquireSucceededCounter.increment();
110
125
  const allotment = this.createAllotment(ctx);
126
+ // Record the acquire time as a success, since we did actually succeed even
127
+ // if we abort below.
128
+ this.acquireTimeOnSuccessDistribution.addSample(this.clock() - acquireStart);
111
129
  if (options?.signal?.aborted) {
112
130
  // here, we did acquire, so we need to try to cleanup.
113
131
  await allotment.releaseAndIgnore();
@@ -15,6 +15,7 @@ export declare const MetricIds: {
15
15
  readonly MIN_RTT_NAME: "min_rtt";
16
16
  readonly WINDOW_MIN_RTT_NAME: "min_window_rtt";
17
17
  readonly WINDOW_QUEUE_SIZE_NAME: "queue_size";
18
+ readonly ACQUIRE_TIME_NAME: "acquire_time";
18
19
  };
19
20
  /**
20
21
  * Listener to receive samples for a distribution.
@@ -1 +1 @@
1
- {"version":3,"file":"MetricRegistry.d.ts","sourceRoot":"","sources":["../src/MetricRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS;;;;;;;;;CASZ,CAAC;AAEX;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,SAAS,IAAI,IAAI,CAAC;CACnB;AAED,0FAA0F;AAC1F,MAAM,WAAW,KAAK;IACpB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;;;OAQG;IACH,YAAY,CACV,EAAE,EAAE,MAAM,EACV,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,kBAAkB,CAAC;IAEtB;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC;IAE9D;;;;;OAKG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC;CACnE;AAMD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,cAUhC,CAAC"}
1
+ {"version":3,"file":"MetricRegistry.d.ts","sourceRoot":"","sources":["../src/MetricRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;CAUZ,CAAC;AAEX;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,SAAS,IAAI,IAAI,CAAC;CACnB;AAED,0FAA0F;AAC1F,MAAM,WAAW,KAAK;IACpB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;;;OAQG;IACH,YAAY,CACV,EAAE,EAAE,MAAM,EACV,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,kBAAkB,CAAC;IAEtB;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC;IAE9D;;;;;OAKG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC;CACnE;AAMD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,cAUhC,CAAC"}
@@ -15,6 +15,7 @@ export const MetricIds = {
15
15
  MIN_RTT_NAME: "min_rtt",
16
16
  WINDOW_MIN_RTT_NAME: "min_window_rtt",
17
17
  WINDOW_QUEUE_SIZE_NAME: "queue_size",
18
+ ACQUIRE_TIME_NAME: "acquire_time",
18
19
  };
19
20
  const NOOP_SAMPLE_LISTENER = { addSample() { } };
20
21
  const NOOP_COUNTER = { increment() { } };
@@ -0,0 +1,30 @@
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
+ };
15
+ /**
16
+ * Rejection strategy that blocks the caller in a FIFO queue when the limit
17
+ * has been reached, waiting for a slot to open up. This strategy favors
18
+ * fairness: callers are served in the order they arrived.
19
+ *
20
+ * Because JavaScript is single-threaded, "blocking" means awaiting a promise
21
+ * that resolves when a token becomes available.
22
+ */
23
+ export declare class FifoBlockingRejection<ContextT> implements AllotmentUnavailableStrategy<ContextT> {
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;
29
+ }
30
+ //# sourceMappingURL=FifoBlockingRejection.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,29 @@
1
+ import { LinkedWaiterQueue } from "../../utils/LinkedWaiterQueue.js";
2
+ import { BlockingBacklogRejection, MAX_TIMEOUT, } from "./BlockingBacklogRejection.js";
3
+ /**
4
+ * Rejection strategy that blocks the caller in a FIFO queue when the limit
5
+ * has been reached, waiting for a slot to open up. This strategy favors
6
+ * fairness: callers are served in the order they arrived.
7
+ *
8
+ * Because JavaScript is single-threaded, "blocking" means awaiting a promise
9
+ * that resolves when a token becomes available.
10
+ */
11
+ export class FifoBlockingRejection {
12
+ delegate;
13
+ constructor(options = {}) {
14
+ this.delegate = new BlockingBacklogRejection({
15
+ backlogSize: options.backlogSize ?? Number.POSITIVE_INFINITY,
16
+ backlogTimeout: options.backlogTimeout ?? MAX_TIMEOUT,
17
+ queue: new LinkedWaiterQueue("back"),
18
+ });
19
+ }
20
+ onAllotmentUnavailable(context, retry, signal) {
21
+ return this.delegate.onAllotmentUnavailable(context, retry, signal);
22
+ }
23
+ onAllotmentReleased() {
24
+ return this.delegate.onAllotmentReleased();
25
+ }
26
+ onLimitChanged(oldLimit, newLimit) {
27
+ this.delegate.onLimitChanged(oldLimit, newLimit);
28
+ }
29
+ }
@@ -0,0 +1,27 @@
1
+ import type { AcquireResult, AllotmentUnavailableStrategy } from "../../Limiter.js";
2
+ export interface LifoBlockingRejectionOptions<ContextT> {
3
+ /**
4
+ * Maximum number of blocked callers in the backlog. Default: 100
5
+ */
6
+ backlogSize?: number | undefined;
7
+ /**
8
+ * Maximum timeout for callers blocked on the limiter, in milliseconds.
9
+ * Can be a fixed number or a function that derives the timeout from the
10
+ * request context (e.g. from a deadline). Default: 1000
11
+ */
12
+ backlogTimeout?: number | ((context: ContextT) => number) | undefined;
13
+ }
14
+ /**
15
+ * Rejection strategy that blocks the caller in a LIFO queue when the limit
16
+ * has been reached. This strategy favors availability over latency by
17
+ * processing the most recently blocked request first, keeping success
18
+ * latencies low and minimizing timeouts.
19
+ */
20
+ export declare class LifoBlockingRejection<ContextT> implements AllotmentUnavailableStrategy<ContextT> {
21
+ private readonly delegate;
22
+ constructor(options?: LifoBlockingRejectionOptions<ContextT>);
23
+ onAllotmentUnavailable(context: ContextT, retry: (context: ContextT) => AcquireResult, signal?: AbortSignal): Promise<import("../../LimitAllotment.js").LimitAllotment | undefined>;
24
+ onAllotmentReleased(): Promise<void>;
25
+ onLimitChanged(oldLimit: number, newLimit: number): void;
26
+ }
27
+ //# sourceMappingURL=LifoBlockingRejection.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,27 @@
1
+ import { LinkedWaiterQueue } from "../../utils/LinkedWaiterQueue.js";
2
+ import { BlockingBacklogRejection, } from "./BlockingBacklogRejection.js";
3
+ /**
4
+ * Rejection strategy that blocks the caller in a LIFO queue when the limit
5
+ * has been reached. This strategy favors availability over latency by
6
+ * processing the most recently blocked request first, keeping success
7
+ * latencies low and minimizing timeouts.
8
+ */
9
+ export class LifoBlockingRejection {
10
+ delegate;
11
+ constructor(options = {}) {
12
+ this.delegate = new BlockingBacklogRejection({
13
+ backlogSize: options.backlogSize ?? 100,
14
+ backlogTimeout: options.backlogTimeout ?? 1_000,
15
+ queue: new LinkedWaiterQueue("front"),
16
+ });
17
+ }
18
+ onAllotmentUnavailable(context, retry, signal) {
19
+ return this.delegate.onAllotmentUnavailable(context, retry, signal);
20
+ }
21
+ onAllotmentReleased() {
22
+ return this.delegate.onAllotmentReleased();
23
+ }
24
+ onLimitChanged(oldLimit, newLimit) {
25
+ this.delegate.onLimitChanged(oldLimit, newLimit);
26
+ }
27
+ }
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "dynamic rate limiting"
10
10
  ],
11
11
  "author": "Ethan Resnick <ethan.resnick@gmail.com>",
12
- "version": "0.9.0",
12
+ "version": "0.10.0",
13
13
  "type": "module",
14
14
  "exports": {
15
15
  ".": {