adaptive-concurrency 0.7.0 → 0.9.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
@@ -113,11 +113,14 @@ export declare class Limiter<Context = void> {
113
113
  private readonly acquireStrategy;
114
114
  private readonly rejectionStrategy;
115
115
  private readonly bypassResolver;
116
+ private readonly acquireBypassedAllotment;
116
117
  private readonly successCounter;
117
118
  private readonly droppedCounter;
118
119
  private readonly ignoredCounter;
119
- private readonly rejectedCounter;
120
- private readonly bypassCounter;
120
+ private readonly acquireSucceededCounter;
121
+ private readonly acquireFailedCounter;
122
+ private readonly acquireBypassedCounter;
123
+ private readonly limitGauge;
121
124
  static makeDefaultLimit(): AdaptiveLimit;
122
125
  constructor(options?: LimiterOptions<Context>);
123
126
  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
@@ -5,11 +5,6 @@ import { isAdaptiveTimeoutError, isRunResult, QuotaNotAvailable, } from "./RunRe
5
5
  // ---------------------------------------------------------------------------
6
6
  // Limiter options
7
7
  // ---------------------------------------------------------------------------
8
- const NOOP_ALLOTMENT = {
9
- async releaseAndRecordSuccess() { },
10
- async releaseAndIgnore() { },
11
- async releaseAndRecordDropped() { },
12
- };
13
8
  let idCounter = 0;
14
9
  /**
15
10
  * Concurrency limiter with pluggable strategies for gating decisions and
@@ -25,11 +20,14 @@ export class Limiter {
25
20
  acquireStrategy;
26
21
  rejectionStrategy;
27
22
  bypassResolver;
23
+ acquireBypassedAllotment;
28
24
  successCounter;
29
25
  droppedCounter;
30
26
  ignoredCounter;
31
- rejectedCounter;
32
- bypassCounter;
27
+ acquireSucceededCounter;
28
+ acquireFailedCounter;
29
+ acquireBypassedCounter;
30
+ limitGauge;
33
31
  static makeDefaultLimit() {
34
32
  return new GradientLimit();
35
33
  }
@@ -44,12 +42,15 @@ export class Limiter {
44
42
  this.limitAlgorithm.subscribe((newLimit) => {
45
43
  const oldLimit = this._limit;
46
44
  this._limit = newLimit;
45
+ this.limitGauge.record(newLimit);
47
46
  this.acquireStrategy.onLimitChanged?.(oldLimit, newLimit);
48
47
  void this.rejectionStrategy?.onLimitChanged?.(oldLimit, newLimit);
49
48
  });
50
49
  const registry = options.metricRegistry ?? NoopMetricRegistry;
51
50
  const limiterName = options.name ?? `unnamed-${++idCounter}`;
52
- registry.gauge(MetricIds.LIMIT_NAME, () => this._limit);
51
+ this.limitGauge = registry.gauge(MetricIds.LIMIT_NAME, {
52
+ id: limiterName,
53
+ });
53
54
  this.successCounter = registry.counter(MetricIds.CALL_NAME, {
54
55
  id: limiterName,
55
56
  status: "success",
@@ -62,29 +63,35 @@ export class Limiter {
62
63
  id: limiterName,
63
64
  status: "ignored",
64
65
  });
65
- this.rejectedCounter = registry.counter(MetricIds.CALL_NAME, {
66
- id: limiterName,
67
- status: "rejected",
68
- });
69
- this.bypassCounter = registry.counter(MetricIds.CALL_NAME, {
70
- id: limiterName,
71
- status: "bypassed",
72
- });
66
+ this.acquireSucceededCounter = registry.counter(MetricIds.ACQUIRE_ATTEMPT_NAME, { id: limiterName, status: "succeeded" });
67
+ this.acquireFailedCounter = registry.counter(MetricIds.ACQUIRE_ATTEMPT_NAME, { id: limiterName, status: "failed" });
68
+ this.acquireBypassedCounter = registry.counter(MetricIds.ACQUIRE_ATTEMPT_NAME, { id: limiterName, status: "bypassed" });
69
+ this.acquireBypassedAllotment = {
70
+ releaseAndRecordSuccess: async () => {
71
+ this.successCounter.increment();
72
+ },
73
+ releaseAndIgnore: async () => {
74
+ this.ignoredCounter.increment();
75
+ },
76
+ releaseAndRecordDropped: async () => {
77
+ this.droppedCounter.increment();
78
+ },
79
+ };
73
80
  }
74
81
  async acquire(options) {
75
82
  if (options?.signal?.aborted)
76
83
  return undefined;
77
84
  const ctx = (options?.context ?? undefined);
78
85
  if (this.bypassResolver?.(ctx)) {
79
- this.bypassCounter.increment();
80
- return NOOP_ALLOTMENT;
86
+ this.acquireBypassedCounter.increment();
87
+ return this.acquireBypassedAllotment;
81
88
  }
82
89
  const state = {
83
90
  limit: this._limit,
84
91
  inflight: this._inflight,
85
92
  };
86
93
  if (!(await this.acquireStrategy.tryAcquireAllotment(ctx, state))) {
87
- this.rejectedCounter.increment();
94
+ this.acquireFailedCounter.increment();
88
95
  if (!this.rejectionStrategy) {
89
96
  return undefined;
90
97
  }
@@ -99,6 +106,7 @@ export class Limiter {
99
106
  return this.tryAcquireCore(retryCtx);
100
107
  }, options?.signal);
101
108
  }
109
+ this.acquireSucceededCounter.increment();
102
110
  const allotment = this.createAllotment(ctx);
103
111
  if (options?.signal?.aborted) {
104
112
  // here, we did acquire, so we need to try to cleanup.
@@ -113,8 +121,10 @@ export class Limiter {
113
121
  inflight: this._inflight,
114
122
  };
115
123
  if (!(await this.acquireStrategy.tryAcquireAllotment(ctx, state))) {
124
+ this.acquireFailedCounter.increment();
116
125
  return undefined;
117
126
  }
127
+ this.acquireSucceededCounter.increment();
118
128
  return this.createAllotment(ctx);
119
129
  }
120
130
  createAllotment(ctx) {
@@ -1,9 +1,15 @@
1
1
  /**
2
2
  * Common metric ids used by the limiters and limit algorithms.
3
+ *
4
+ * `CALL_NAME` records outcomes for work that actually executed under a limiter
5
+ * (status: `success`, `ignored`, `dropped`). `ACQUIRE_ATTEMPT_NAME` records
6
+ * acquire outcomes (status: `succeeded`, `failed`, `bypassed`), including
7
+ * failures from retry attempts.
3
8
  */
4
9
  export declare const MetricIds: {
5
10
  readonly LIMIT_NAME: "limit";
6
11
  readonly CALL_NAME: "call";
12
+ readonly ACQUIRE_ATTEMPT_NAME: "acquire_attempt";
7
13
  readonly INFLIGHT_NAME: "inflight";
8
14
  readonly PARTITION_LIMIT_NAME: "limit.partition";
9
15
  readonly MIN_RTT_NAME: "min_rtt";
@@ -24,7 +30,8 @@ export interface Counter {
24
30
  increment(): void;
25
31
  }
26
32
  /** Opaque handle for a registered gauge (supplier is polled by the registry on flush). */
27
- export interface GaugeMetric {
33
+ export interface Gauge {
34
+ record(value: number): void;
28
35
  }
29
36
  /**
30
37
  * Simple abstraction for tracking metrics in the limiters.
@@ -39,7 +46,7 @@ export interface MetricRegistry {
39
46
  * @param tagNameValuePairs Pairs of tag name and tag value
40
47
  * @returns SampleListener for the caller to add samples
41
48
  */
42
- distribution(id: string, ...tagNameValuePairs: string[]): DistributionMetric;
49
+ distribution(id: string, attributes?: Record<string, string>): DistributionMetric;
43
50
  /**
44
51
  * Register a gauge using the provided supplier. The supplier will be polled
45
52
  * whenever the gauge value is flushed by the registry.
@@ -49,14 +56,14 @@ export interface MetricRegistry {
49
56
  * @param tagNameValuePairs Pairs of tag name and tag value
50
57
  * @returns Registration handle for the gauge
51
58
  */
52
- gauge(id: string, supplier: () => number, ...tagNameValuePairs: string[]): GaugeMetric;
59
+ gauge(id: string, attributes?: Record<string, string>): Gauge;
53
60
  /**
54
61
  * Create a counter that will be incremented when an event occurs.
55
62
  *
56
63
  * @param id Metric identifier
57
64
  * @param attributes Counter attributes/tags
58
65
  */
59
- counter(id: string, attributes: Record<string, string>): Counter;
66
+ counter(id: string, attributes?: Record<string, string>): Counter;
60
67
  }
61
68
  /**
62
69
  * No-op MetricRegistry that discards all metrics. Used as the default when
@@ -1 +1 @@
1
- {"version":3,"file":"MetricRegistry.d.ts","sourceRoot":"","sources":["../src/MetricRegistry.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,SAAS;;;;;;;;CAQZ,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,WAAW;CAAG;AAE/B;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,iBAAiB,EAAE,MAAM,EAAE,GAAG,kBAAkB,CAAC;IAE7E;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,MAAM,EAAE,GAAG,iBAAiB,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC;IAEvF;;;;;OAKG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC;CAClE;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;;;;;;;;;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,9 +1,15 @@
1
1
  /**
2
2
  * Common metric ids used by the limiters and limit algorithms.
3
+ *
4
+ * `CALL_NAME` records outcomes for work that actually executed under a limiter
5
+ * (status: `success`, `ignored`, `dropped`). `ACQUIRE_ATTEMPT_NAME` records
6
+ * acquire outcomes (status: `succeeded`, `failed`, `bypassed`), including
7
+ * failures from retry attempts.
3
8
  */
4
9
  export const MetricIds = {
5
10
  LIMIT_NAME: "limit",
6
11
  CALL_NAME: "call",
12
+ ACQUIRE_ATTEMPT_NAME: "acquire_attempt",
7
13
  INFLIGHT_NAME: "inflight",
8
14
  PARTITION_LIMIT_NAME: "limit.partition",
9
15
  MIN_RTT_NAME: "min_rtt",
@@ -12,7 +18,7 @@ export const MetricIds = {
12
18
  };
13
19
  const NOOP_SAMPLE_LISTENER = { addSample() { } };
14
20
  const NOOP_COUNTER = { increment() { } };
15
- const NOOP_GAUGE = {};
21
+ const NOOP_GAUGE = { record() { } };
16
22
  /**
17
23
  * No-op MetricRegistry that discards all metrics. Used as the default when
18
24
  * no registry is configured.
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export type { AdaptiveLimit } from "./limit/StreamingLimit.js";
2
2
  export type { LimitAllotment } from "./LimitAllotment.js";
3
3
  export { Limiter, withLimiter, type AcquireOptions, type AcquireResult, type AcquireStrategy, type AllotmentUnavailableStrategy, type LimitedFunction, type LimiterOptions, type LimiterState, type MaybePromise, type RunCallbackArgs, } from "./Limiter.js";
4
4
  export { ListenerSet } from "./ListenerSet.js";
5
- export { MetricIds, NoopMetricRegistry, type Counter, type DistributionMetric, type GaugeMetric, type MetricRegistry, } from "./MetricRegistry.js";
5
+ export { MetricIds, NoopMetricRegistry, type Counter, type DistributionMetric, type Gauge, type MetricRegistry, } from "./MetricRegistry.js";
6
6
  export { AdaptiveTimeoutError, dropped, ignore, isAdaptiveTimeoutError, isRunResult, QuotaNotAvailable, success, type RunDropped, type RunIgnore, type RunResult, type RunSuccess, } from "./RunResult.js";
7
7
  export { AIMDLimit, type AIMDLimitOptions } from "./limit/AIMDLimit.js";
8
8
  export { FixedLimit } from "./limit/FixedLimit.js";
@@ -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,WAAW,EACX,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,4BAA4B,EACjC,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,eAAe,GACrB,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,WAAW,EACX,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;AAEnE,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAE1B,cAAc,8BAA8B,CAAC;AAG7C,OAAO,EACL,mBAAmB,EACnB,KAAK,eAAe,GACrB,MAAM,qDAAqD,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mDAAmD,CAAC;AAGtF,OAAO,EACL,wBAAwB,EACxB,WAAW,EACX,KAAK,+BAA+B,EACpC,KAAK,WAAW,GACjB,MAAM,yEAAyE,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,KAAK,4BAA4B,GAClC,MAAM,sEAAsE,CAAC;AAC9E,OAAO,EAAE,4BAA4B,EAAE,MAAM,6EAA6E,CAAC"}
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,WAAW,EACX,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,4BAA4B,EACjC,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,eAAe,GACrB,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,KAAK,EACV,KAAK,cAAc,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,OAAO,EACP,MAAM,EACN,sBAAsB,EACtB,WAAW,EACX,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;AAEnE,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAE1B,cAAc,8BAA8B,CAAC;AAG7C,OAAO,EACL,mBAAmB,EACnB,KAAK,eAAe,GACrB,MAAM,qDAAqD,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mDAAmD,CAAC;AAGtF,OAAO,EACL,wBAAwB,EACxB,WAAW,EACX,KAAK,+BAA+B,EACpC,KAAK,WAAW,GACjB,MAAM,yEAAyE,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,KAAK,4BAA4B,GAClC,MAAM,sEAAsE,CAAC;AAC9E,OAAO,EAAE,4BAA4B,EAAE,MAAM,6EAA6E,CAAC"}
@@ -150,8 +150,10 @@ class Partition {
150
150
  throw new Error("maxBurstMultiplier must be >= 1.0");
151
151
  }
152
152
  const registry = init.registry;
153
- this.inflightDistribution = registry.distribution(MetricIds.INFLIGHT_NAME, PARTITION_TAG_NAME, this.name);
154
- this.limitAtGlobalSaturationGauge = registry.gauge(MetricIds.PARTITION_LIMIT_NAME, () => this._limitAtGlobalSaturation, PARTITION_TAG_NAME, this.name);
153
+ this.inflightDistribution = registry.distribution(MetricIds.INFLIGHT_NAME, {
154
+ [PARTITION_TAG_NAME]: this.name,
155
+ });
156
+ this.limitAtGlobalSaturationGauge = registry.gauge(MetricIds.PARTITION_LIMIT_NAME, { [PARTITION_TAG_NAME]: this.name });
155
157
  }
156
158
  /**
157
159
  * Recompute this partition's limitAtGlobalSaturation from global limit.
@@ -161,6 +163,7 @@ class Partition {
161
163
  */
162
164
  updateLimitAtGlobalSaturation(totalGlobalLimit) {
163
165
  this._limitAtGlobalSaturation = partitionLimitAtGlobalSaturationForGlobal(totalGlobalLimit, this.percent);
166
+ this.limitAtGlobalSaturationGauge.record(this._limitAtGlobalSaturation);
164
167
  }
165
168
  get limitAtGlobalSaturation() {
166
169
  return this._limitAtGlobalSaturation;
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.7.0",
12
+ "version": "0.9.0",
13
13
  "type": "module",
14
14
  "exports": {
15
15
  ".": {
@@ -26,6 +26,7 @@
26
26
  "prepublishOnly": "pnpm build"
27
27
  },
28
28
  "devDependencies": {
29
+ "@types/node": "^25.5.0",
29
30
  "tsx": "^4.19.0",
30
31
  "type-fest": "^5.5.0",
31
32
  "type-party": "^0.7.3",
@@ -1,30 +0,0 @@
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
@@ -1 +0,0 @@
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,29 +0,0 @@
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
- }
@@ -1,27 +0,0 @@
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
@@ -1 +0,0 @@
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,27 +0,0 @@
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
- }