@mondart/nestjs-common-module-bottleneck 3.2.11 → 3.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -52,6 +52,46 @@ To share limits across instances instead of throttling each process
52
52
  independently, set `useRedis: true` and provide `redis: { host, port, ... }`
53
53
  — it's passed straight through to Bottleneck's `ioredis` datastore.
54
54
 
55
+ ### When Redis is unreachable
56
+
57
+ Throttling is best-effort; the work is not. If a limiter fails because Redis
58
+ cannot be reached (`ECONNREFUSED`, a closed connection, retries exhausted) or
59
+ because it answered but cannot serve the write (`READONLY` during a failover,
60
+ `LOADING`, `OOM`, `CLUSTERDOWN`), the task runs **unthrottled** instead of
61
+ failing the caller, and Redis is skipped entirely for the next 5 seconds so an
62
+ outage costs one timeout rather than one per request. Each window opens with
63
+ an `ERROR` log naming the cause. Limits are not enforced while it is open — if
64
+ a route must fail closed instead, throttle it outside this service.
65
+
66
+ Commands default to `maxRetriesPerRequest: 2` (ioredis' own default of 20
67
+ leaves a request hanging ~30s before it fails); override it with
68
+ `redis.maxRetriesPerRequest`.
69
+
70
+ A limiter whose Redis state went stale — `SETTINGS_KEY_NOT_FOUND` when its
71
+ settings key expired, `UNKNOWN_CLIENT` when another replica swept its client —
72
+ is dropped and rebuilt once, then the task is retried. The retry cannot
73
+ duplicate the callback: the script that fails runs before the job is
74
+ registered.
75
+
76
+ ### Job expiration
77
+
78
+ Every job gets `expiration: 60000` by default. This is not optional
79
+ bookkeeping: Bottleneck reclaims a slot for a dead client only through
80
+ `job_expirations` (`register.lua`), and its unresponsive-client sweep skips
81
+ any client whose running weight is still above zero (`process_tick.lua`). So
82
+ without an expiration, a process killed mid-job (SIGKILL, OOM, crash) never
83
+ releases its slot, and with `maxConcurrent: 1` that key stays wedged **for
84
+ every replica** — indefinitely, because each new request refreshes the key's
85
+ TTL.
86
+
87
+ Set `expiration` above the slowest throttled handler, or `null` to disable it.
88
+ A job that overruns is rejected with a `BottleneckError` and its slot is
89
+ freed; the handler itself keeps running, Bottleneck just stops waiting for it.
90
+
91
+ Set it through this module's options or `@ConfigBottleneckDecorator()`, never
92
+ through raw Bottleneck `ConstructorOptions` — Bottleneck reads `expiration`
93
+ only from its job defaults, so it is silently ignored there.
94
+
55
95
  ## Throttling HTTP routes
56
96
 
57
97
  `BottleneckInterceptor` runs on every HTTP request but only queues one that
@@ -1 +1 @@
1
- {"version":3,"file":"bottleneck.interceptor.d.ts","sourceRoot":"","sources":["../../src/interceptors/bottleneck.interceptor.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,gBAAgB,EAIhB,eAAe,EAEhB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAOzC,OAAO,EAEL,uBAAuB,EACxB,MAAM,4CAA4C,CAAC;AAUpD,qBACa,qBAAsB,YAAW,eAAe;IAKzD,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAN5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkD;gBAItD,OAAO,EAAE,uBAAuB,EAChC,iBAAiB,EAAE,iBAAiB,EACpC,SAAS,EAAE,SAAS;IAQvC,SAAS,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW;CA6FnD"}
1
+ {"version":3,"file":"bottleneck.interceptor.d.ts","sourceRoot":"","sources":["../../src/interceptors/bottleneck.interceptor.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,gBAAgB,EAIhB,eAAe,EAEhB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAOzC,OAAO,EAEL,uBAAuB,EACxB,MAAM,4CAA4C,CAAC;AAUpD,qBACa,qBAAsB,YAAW,eAAe;IAKzD,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAN5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkD;gBAItD,OAAO,EAAE,uBAAuB,EAChC,iBAAiB,EAAE,iBAAiB,EACpC,SAAS,EAAE,SAAS;IAQvC,SAAS,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW;CAyGnD"}
@@ -63,9 +63,14 @@ let BottleneckInterceptor = BottleneckInterceptor_1 = class BottleneckIntercepto
63
63
  return (0, rxjs_1.from)(this.bottleneckService
64
64
  .scheduleForKey(key, async () => (0, rxjs_1.lastValueFrom)(next.handle()), bottleneckOptions)
65
65
  .catch((err) => {
66
- if (String(err?.message || '').includes('This limiter is at max capacity')) {
66
+ const message = String(err?.message || '');
67
+ if (message.includes('This limiter is at max capacity')) {
67
68
  throw new common_1.ServiceUnavailableException('Too many requests queued for this order. Try again soon.');
68
69
  }
70
+ if (message.includes('This job timed out after')) {
71
+ this.logger.warn(`⏱️ [Bottleneck] Job outran its expiration for key="${key}" method=${method} url=${url}; the handler is still running`);
72
+ throw new common_1.ServiceUnavailableException('This request took too long to complete. Check its result before retrying.');
73
+ }
69
74
  throw err;
70
75
  })
71
76
  .finally(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"bottleneck.interceptor.js","sourceRoot":"","sources":["../../src/interceptors/bottleneck.interceptor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bottleneck.interceptor.js","sourceRoot":"","sources":["../../src/interceptors/bottleneck.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AACA,2CAQwB;AACxB,+BAA2C;AAC3C,uEAAmE;AACnE,uCAAyC;AACzC,oEAIuC;AAEvC,6FAGoD;AAW7C,IAAM,qBAAqB,6BAA3B,MAAM,qBAAqB;IAGhC,YAEE,OAAiD,EAChC,iBAAoC,EACpC,SAAoB;QAFpB,YAAO,GAAP,OAAO,CAAyB;QAChC,sBAAiB,GAAjB,iBAAiB,CAAmB;QACpC,cAAS,GAAT,SAAS,CAAW;QANtB,WAAM,GAAW,IAAI,eAAM,CAAC,uBAAqB,CAAC,IAAI,CAAC,CAAC;IAOtE,CAAC;IAOJ,SAAS,CAAC,GAAqB,EAAE,IAAiB;QAChD,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;QAE3B,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAC3C,2CAAwB,EACxB,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CACnC,CAAC;QACF,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CACpD,0CAAuB,EACvB,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CACnC,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAC7C,6CAA0B,EAC1B,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CACnC,CAAC;QAEF,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GACxE;YACE,GAAG,IAAI,CAAC,OAAO;YACf,GAAG,MAAM;SACV,CAAC;QAEJ,MAAM,GAAG,GAAG,GAAG,EAAE,YAAY,EAAE,EAAE,UAAU,EAAE,EAAE,GAAG,CAAC;QACnD,IAAI,IAAI,IAAI,CAAC,CAAC,aAAa,IAAI,SAAS,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uCAAuC,GAAG,EAAE,CAAC,CAAC;YAChE,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,CAAC;QAED,MAAM,GAAG,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QAC5C,MAAM,kBAAkB,GAAG,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,eAAe,GAAuB,kBAAkB,EAAE,KAAK,CAAC;QAEtE,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,MAAM,IAAI,oCAA2B,CACnC,GAAG,kBAAkB,EAAE,GAAG,4BAA4B,GAAG,EAAE,CAC5D,CAAC;QACJ,CAAC;QAED,MAAM,GAAG,GAAG,GAAG,QAAQ,IAAI,kBAAkB,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QAIxE,MAAM,iBAAiB,GAAkC;YAKvD,YAAY,EAAE,GAAG;YAEjB,aAAa,EAAE,aAAa,IAAI,CAAC;YACjC,OAAO,EAAE,OAAO,IAAI,CAAC;YACrB,GAAG,IAAI;SACR,CAAC;QACF,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,SAAS,CAAC;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEzB,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,2CAA2C,GAAG,YAAY,MAAM,QAAQ,GAAG,EAAE,CAC9E,CAAC;QAEF,OAAO,IAAA,WAAI,EACT,IAAI,CAAC,iBAAiB;aACnB,cAAc,CACb,GAAG,EACH,KAAK,IAAI,EAAE,CAAC,IAAA,oBAAa,EAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EACxC,iBAAiB,CAClB;aACA,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACb,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;YAG3C,IAAI,OAAO,CAAC,QAAQ,CAAC,iCAAiC,CAAC,EAAE,CAAC;gBACxD,MAAM,IAAI,oCAA2B,CACnC,0DAA0D,CAC3D,CAAC;YACJ,CAAC;YAMD,IAAI,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAC,EAAE,CAAC;gBACjD,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,sDAAsD,GAAG,YAAY,MAAM,QAAQ,GAAG,gCAAgC,CACvH,CAAC;gBACF,MAAM,IAAI,oCAA2B,CACnC,2EAA2E,CAC5E,CAAC;YACJ,CAAC;YAED,MAAM,GAAG,CAAC;QACZ,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE;YACZ,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,wCAAwC,GAAG,YAAY,MAAM,QAAQ,GAAG,aAAa,QAAQ,IAAI,CAClG,CAAC;QACJ,CAAC,CAAC,CACL,CAAC;IACJ,CAAC;CACF,CAAA;AAxHY,sDAAqB;gCAArB,qBAAqB;IADjC,IAAA,mBAAU,GAAE;IAKR,WAAA,IAAA,eAAM,EAAC,wDAAyB,CAAC,CAAA;6CAEE,sCAAiB;QACzB,gBAAS;GAP5B,qBAAqB,CAwHjC"}
@@ -19,6 +19,7 @@ export interface BottleneckModuleOptions {
19
19
  reservoirIncreaseAmount?: number | null;
20
20
  reservoirIncreaseInterval?: number | null;
21
21
  reservoirIncreaseMaximum?: number | null;
22
+ expiration?: number | null;
22
23
  rejectOnDrop?: boolean | null;
23
24
  trackDoneStatus?: boolean | null;
24
25
  useRedis?: boolean;
@@ -30,6 +31,7 @@ export interface BottleneckModuleOptions {
30
31
  database?: number;
31
32
  ttl?: number;
32
33
  tls?: boolean;
34
+ maxRetriesPerRequest?: number;
33
35
  };
34
36
  }
35
37
  export interface BottleneckModuleFactory {
@@ -1 +1 @@
1
- {"version":3,"file":"bottleneck-options.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/bottleneck-options.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtD,eAAO,MAAM,yBAAyB,8BAA8B,CAAC;AAOrE,MAAM,WAAW,uBAAuB;IAEtC,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAOlB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAEjE,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,yBAAyB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,YAAY,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,eAAe,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAEjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,OAAO,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,EAAE,MACnB,OAAO,CAAC,uBAAuB,CAAC,GAAG,uBAAuB,CAAC;CAC9D;AAED,MAAM,WAAW,4BAA6B,SAAQ,IAAI,CACxD,cAAc,EACd,SAAS,CACV;IACC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,QAAQ,CAAC,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACzC,WAAW,CAAC,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAC5C,UAAU,CAAC,EAAE,CACX,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,OAAO,CAAC,uBAAuB,CAAC,GAAG,uBAAuB,CAAC;CACjE"}
1
+ {"version":3,"file":"bottleneck-options.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/bottleneck-options.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEtD,eAAO,MAAM,yBAAyB,8BAA8B,CAAC;AAOrE,MAAM,WAAW,uBAAuB;IAEtC,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAOlB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAEjE,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,yBAAyB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAWzC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,eAAe,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAEjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,OAAO,CAAC;QAQd,oBAAoB,CAAC,EAAE,MAAM,CAAC;KAC/B,CAAC;CACH;AAED,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,EAAE,MACnB,OAAO,CAAC,uBAAuB,CAAC,GAAG,uBAAuB,CAAC;CAC9D;AAED,MAAM,WAAW,4BAA6B,SAAQ,IAAI,CACxD,cAAc,EACd,SAAS,CACV;IACC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,QAAQ,CAAC,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACzC,WAAW,CAAC,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAC5C,UAAU,CAAC,EAAE,CACX,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,OAAO,CAAC,uBAAuB,CAAC,GAAG,uBAAuB,CAAC;CACjE"}
@@ -6,10 +6,16 @@ export declare class BottleneckService implements OnModuleDestroy {
6
6
  private readonly logger;
7
7
  private readonly group;
8
8
  private readonly cache;
9
+ private readonly usesRedis;
10
+ private readonly expiration;
11
+ private bypassRedisUntil;
9
12
  constructor(options: BottleneckModuleOptions);
10
13
  private getLimiter;
11
- private isMissingSettingsKeyError;
14
+ private isStaleLimiterError;
15
+ private isRedisUnavailableError;
16
+ private jobOptions;
12
17
  private scheduleWithSettingsRecovery;
18
+ private bypassRedis;
13
19
  scheduleForKey<T>(key: string, task: () => Promise<T>, opts?: Bottleneck.ConstructorOptions): Promise<T>;
14
20
  runQueuedTask<T>(key: string, fn: () => Promise<T>): Promise<T>;
15
21
  onModuleDestroy(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"bottleneck.service.d.ts","sourceRoot":"","sources":["../../src/services/bottleneck.service.ts"],"names":[],"mappings":"AACA,OAAO,EAA8B,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAEL,uBAAuB,EACxB,MAAM,4CAA4C,CAAC;AAWpD,qBACa,iBAAkB,YAAW,eAAe;IASrD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAR1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAEpB;IACH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmC;gBAItC,OAAO,EAAE,uBAAuB;YAwCrC,UAAU;IAsBxB,OAAO,CAAC,yBAAyB;YAOnB,4BAA4B;IAwBpC,cAAc,CAAC,CAAC,EACpB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACtB,IAAI,CAAC,EAAE,UAAU,CAAC,kBAAkB,GACnC,OAAO,CAAC,CAAC,CAAC;IAWP,aAAa,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAmB/D,eAAe;CAGtB"}
1
+ {"version":3,"file":"bottleneck.service.d.ts","sourceRoot":"","sources":["../../src/services/bottleneck.service.ts"],"names":[],"mappings":"AACA,OAAO,EAA8B,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAEL,uBAAuB,EACxB,MAAM,4CAA4C,CAAC;AA6FpD,qBACa,iBAAkB,YAAW,eAAe;IAerD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAd1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAEpB;IACH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmC;IACzD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAU;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgB;IAI3C,OAAO,CAAC,gBAAgB,CAAK;gBAIV,OAAO,EAAE,uBAAuB;YAwDrC,UAAU;IA0BxB,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,uBAAuB;IAe/B,OAAO,CAAC,UAAU;YAMJ,4BAA4B;IAkD1C,OAAO,CAAC,WAAW;IAgBb,cAAc,CAAC,CAAC,EACpB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACtB,IAAI,CAAC,EAAE,UAAU,CAAC,kBAAkB,GACnC,OAAO,CAAC,CAAC,CAAC;IAWP,aAAa,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAmB/D,eAAe;CAGtB"}
@@ -21,6 +21,28 @@ const common_1 = require("@nestjs/common");
21
21
  const bottleneck_1 = __importDefault(require("bottleneck"));
22
22
  const bottleneck_options_interface_1 = require("../interfaces/bottleneck-options.interface");
23
23
  const ioredis_1 = __importDefault(require("ioredis"));
24
+ const REDIS_RECOVERY_SIGNAL = /^ERR (UNKNOWN_CLIENT|SETTINGS_KEY_NOT_FOUND)$/;
25
+ const REDIS_UNAVAILABLE = /ECONNREFUSED|ECONNRESET|ETIMEDOUT|ENOTFOUND|EHOSTUNREACH|EPIPE|Connection is closed|Stream isn't writeable|max retries per request|Command timed out|Connection is already closed/i;
26
+ const REDIS_BYPASS_MS = 5_000;
27
+ const REDIS_NOT_WRITABLE = /^(READONLY|LOADING|OOM|CLUSTERDOWN|MISCONF|TRYAGAIN|NOREPLICAS)\b/;
28
+ const DEFAULT_MAX_RETRIES_PER_REQUEST = 2;
29
+ const DEFAULT_EXPIRATION_MS = 60_000;
30
+ class BottleneckRedis extends ioredis_1.default {
31
+ sendCommand(...args) {
32
+ const [command] = args;
33
+ const reject = command?.reject;
34
+ if (typeof reject === 'function') {
35
+ command.reject = (error) => {
36
+ if (error instanceof Error &&
37
+ REDIS_RECOVERY_SIGNAL.test(error.message)) {
38
+ error.message = error.message.slice(4);
39
+ }
40
+ reject.call(command, error);
41
+ };
42
+ }
43
+ return super.sendCommand(...args);
44
+ }
45
+ }
24
46
  let BottleneckService = BottleneckService_1 = class BottleneckService {
25
47
  constructor(options) {
26
48
  this.options = options;
@@ -28,11 +50,12 @@ let BottleneckService = BottleneckService_1 = class BottleneckService {
28
50
  timestamp: true,
29
51
  });
30
52
  this.cache = new Map();
31
- const { useRedis, redis, appName, clearDatastore = false, ...rest } = this.options;
53
+ this.bypassRedisUntil = 0;
54
+ const { useRedis, redis, appName, clearDatastore = false, expiration, ...rest } = this.options;
32
55
  const redisOptions = useRedis && redis
33
56
  ? {
34
57
  datastore: 'ioredis',
35
- Redis: ioredis_1.default,
58
+ Redis: BottleneckRedis,
36
59
  clientOptions: {
37
60
  host: redis.host,
38
61
  port: redis.port,
@@ -40,6 +63,7 @@ let BottleneckService = BottleneckService_1 = class BottleneckService {
40
63
  password: redis.password,
41
64
  db: redis.database,
42
65
  tls: redis.tls ? {} : undefined,
66
+ maxRetriesPerRequest: redis.maxRetriesPerRequest ?? DEFAULT_MAX_RETRIES_PER_REQUEST,
43
67
  },
44
68
  timeout: redis.ttl,
45
69
  }
@@ -52,6 +76,11 @@ let BottleneckService = BottleneckService_1 = class BottleneckService {
52
76
  ...redisOptions,
53
77
  ...rest,
54
78
  });
79
+ this.expiration = expiration === undefined ? DEFAULT_EXPIRATION_MS : expiration;
80
+ this.usesRedis = Boolean(redisOptions);
81
+ if (this.usesRedis) {
82
+ this.group.on('error', (error) => this.logger.error('Bottleneck datastore error', error instanceof Error ? error.stack : String(error)));
83
+ }
55
84
  }
56
85
  async getLimiter(key, opts) {
57
86
  const limiter = this.group.key(key);
@@ -61,24 +90,67 @@ let BottleneckService = BottleneckService_1 = class BottleneckService {
61
90
  }
62
91
  return limiter;
63
92
  }
64
- isMissingSettingsKeyError(error) {
93
+ isStaleLimiterError(error) {
65
94
  return (error instanceof Error &&
66
- /(?:^|\s)SETTINGS_KEY_NOT_FOUND$/.test(error.message));
95
+ /(?:^|\s)(SETTINGS_KEY_NOT_FOUND|UNKNOWN_CLIENT)$/.test(error.message));
96
+ }
97
+ isRedisUnavailableError(error) {
98
+ if (!(error instanceof Error))
99
+ return false;
100
+ const code = error.code;
101
+ return (REDIS_UNAVAILABLE.test(error.message) ||
102
+ REDIS_NOT_WRITABLE.test(error.message) ||
103
+ (code !== undefined && REDIS_UNAVAILABLE.test(code)));
104
+ }
105
+ jobOptions(opts) {
106
+ const expiration = opts?.expiration === undefined ? this.expiration : opts.expiration;
107
+ return expiration === null ? {} : { expiration };
67
108
  }
68
109
  async scheduleWithSettingsRecovery(key, task, opts) {
110
+ if (this.usesRedis && Date.now() < this.bypassRedisUntil) {
111
+ this.logger.debug(`Running key ${key} unthrottled; Redis still down`);
112
+ return task();
113
+ }
114
+ let taskStarted = false;
115
+ const guardedTask = () => {
116
+ taskStarted = true;
117
+ return task();
118
+ };
69
119
  try {
70
120
  const limiter = await this.getLimiter(key, opts);
71
- return await limiter.schedule(task);
121
+ return await limiter.schedule(this.jobOptions(opts), guardedTask);
72
122
  }
73
123
  catch (error) {
74
- if (!this.isMissingSettingsKeyError(error))
124
+ if (taskStarted)
75
125
  throw error;
76
- this.logger.warn(`Recreating limiter for key ${key} after its Redis settings key disappeared`);
77
- await this.group.deleteKey(key);
78
- const limiter = await this.getLimiter(key, opts);
79
- return limiter.schedule(task);
126
+ if (this.usesRedis && this.isRedisUnavailableError(error)) {
127
+ return this.bypassRedis(key, error, task);
128
+ }
129
+ if (!this.isStaleLimiterError(error))
130
+ throw error;
131
+ this.logger.warn(`Recreating limiter for key ${key} after its Redis state went stale: ${error.message}`);
132
+ let retryStarted = false;
133
+ try {
134
+ await this.group.deleteKey(key);
135
+ const limiter = await this.getLimiter(key, opts);
136
+ return await limiter.schedule(this.jobOptions(opts), () => {
137
+ retryStarted = true;
138
+ return task();
139
+ });
140
+ }
141
+ catch (retryError) {
142
+ if (retryStarted || !this.isRedisUnavailableError(retryError)) {
143
+ throw retryError;
144
+ }
145
+ return this.bypassRedis(key, retryError, task);
146
+ }
80
147
  }
81
148
  }
149
+ bypassRedis(key, error, task) {
150
+ this.bypassRedisUntil = Date.now() + REDIS_BYPASS_MS;
151
+ this.logger.error(`Redis unavailable; running tasks unthrottled for the next ${REDIS_BYPASS_MS}ms (key ${key})`, error instanceof Error ? error.stack : String(error));
152
+ return task();
153
+ }
82
154
  async scheduleForKey(key, task, opts) {
83
155
  this.logger.debug(`Scheduling task for key ${key}`);
84
156
  return this.scheduleWithSettingsRecovery(key, task, opts);
@@ -1 +1 @@
1
- {"version":3,"file":"bottleneck.service.js","sourceRoot":"","sources":["../../src/services/bottleneck.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bottleneck.service.js","sourceRoot":"","sources":["../../src/services/bottleneck.service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mondart/nestjs-common-module-bottleneck",
3
- "version": "3.2.11",
3
+ "version": "3.2.13",
4
4
  "description": "Bottleneck throttling and queue utilities for NestJS.",
5
5
  "author": {
6
6
  "name": "Mondart"
@@ -17,7 +17,7 @@
17
17
  "build": "tsc -p tsconfig.json"
18
18
  },
19
19
  "dependencies": {
20
- "@mondart/nestjs-common-module-core": "3.2.9",
20
+ "@mondart/nestjs-common-module-core": "3.2.11",
21
21
  "@nestjs/cqrs": "^11.0.1",
22
22
  "bottleneck": "^2.19.5",
23
23
  "ioredis": "^5.11.1"