apcore-js 0.21.1 → 0.23.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/README.md +37 -3
- package/dist/acl-handlers.d.ts.map +1 -1
- package/dist/acl-handlers.js +5 -0
- package/dist/acl-handlers.js.map +1 -1
- package/dist/async-task.d.ts +49 -14
- package/dist/async-task.d.ts.map +1 -1
- package/dist/async-task.js +134 -39
- package/dist/async-task.js.map +1 -1
- package/dist/bindings.d.ts +13 -1
- package/dist/bindings.d.ts.map +1 -1
- package/dist/bindings.js +21 -5
- package/dist/bindings.js.map +1 -1
- package/dist/browser/index.d.ts +2 -2
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +2 -2
- package/dist/browser/index.js.map +1 -1
- package/dist/builtin-steps.d.ts +14 -12
- package/dist/builtin-steps.d.ts.map +1 -1
- package/dist/builtin-steps.js +99 -30
- package/dist/builtin-steps.js.map +1 -1
- package/dist/cancel.d.ts +23 -2
- package/dist/cancel.d.ts.map +1 -1
- package/dist/cancel.js +31 -6
- package/dist/cancel.js.map +1 -1
- package/dist/client.d.ts +3 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +7 -3
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +31 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +108 -14
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +36 -3
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +111 -20
- package/dist/context.js.map +1 -1
- package/dist/errors.d.ts +74 -2
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +158 -11
- package/dist/errors.js.map +1 -1
- package/dist/events/emitter.d.ts +54 -16
- package/dist/events/emitter.d.ts.map +1 -1
- package/dist/events/emitter.js +162 -73
- package/dist/events/emitter.js.map +1 -1
- package/dist/events/index.d.ts +2 -1
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +1 -1
- package/dist/events/index.js.map +1 -1
- package/dist/events/retry.d.ts +35 -0
- package/dist/events/retry.d.ts.map +1 -0
- package/dist/events/retry.js +52 -0
- package/dist/events/retry.js.map +1 -0
- package/dist/events/subscribers.d.ts +54 -9
- package/dist/events/subscribers.d.ts.map +1 -1
- package/dist/events/subscribers.js +109 -67
- package/dist/events/subscribers.js.map +1 -1
- package/dist/executor.d.ts +4 -1
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +157 -21
- package/dist/executor.js.map +1 -1
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/dist/index.d.ts +8 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/middleware/circuit-breaker.d.ts +10 -4
- package/dist/middleware/circuit-breaker.d.ts.map +1 -1
- package/dist/middleware/circuit-breaker.js +49 -24
- package/dist/middleware/circuit-breaker.js.map +1 -1
- package/dist/middleware/index.d.ts +2 -2
- package/dist/middleware/index.d.ts.map +1 -1
- package/dist/middleware/index.js +2 -2
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/manager.d.ts +6 -2
- package/dist/middleware/manager.d.ts.map +1 -1
- package/dist/middleware/manager.js +36 -1
- package/dist/middleware/manager.js.map +1 -1
- package/dist/middleware/platform-notify.d.ts +2 -3
- package/dist/middleware/platform-notify.d.ts.map +1 -1
- package/dist/middleware/platform-notify.js +5 -6
- package/dist/middleware/platform-notify.js.map +1 -1
- package/dist/middleware/retry.d.ts +33 -15
- package/dist/middleware/retry.d.ts.map +1 -1
- package/dist/middleware/retry.js +48 -23
- package/dist/middleware/retry.js.map +1 -1
- package/dist/observability/context-logger.d.ts +15 -11
- package/dist/observability/context-logger.d.ts.map +1 -1
- package/dist/observability/context-logger.js +40 -14
- package/dist/observability/context-logger.js.map +1 -1
- package/dist/pipeline.d.ts +1 -1
- package/dist/pipeline.js +11 -11
- package/dist/pipeline.js.map +1 -1
- package/dist/registry/multi-class.js +6 -17
- package/dist/registry/multi-class.js.map +1 -1
- package/dist/registry/registry.d.ts +46 -2
- package/dist/registry/registry.d.ts.map +1 -1
- package/dist/registry/registry.js +276 -36
- package/dist/registry/registry.js.map +1 -1
- package/dist/registry/version.d.ts.map +1 -1
- package/dist/registry/version.js +9 -2
- package/dist/registry/version.js.map +1 -1
- package/dist/schema/ref-resolver.d.ts.map +1 -1
- package/dist/schema/ref-resolver.js +2 -2
- package/dist/schema/ref-resolver.js.map +1 -1
- package/dist/schema/strict.d.ts.map +1 -1
- package/dist/schema/strict.js +4 -1
- package/dist/schema/strict.js.map +1 -1
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +1 -1
- package/dist/schema/types.js.map +1 -1
- package/dist/schema/validator.d.ts.map +1 -1
- package/dist/schema/validator.js +11 -20
- package/dist/schema/validator.js.map +1 -1
- package/dist/streaming.d.ts +21 -0
- package/dist/streaming.d.ts.map +1 -0
- package/dist/streaming.js +32 -0
- package/dist/streaming.js.map +1 -0
- package/dist/sys-modules/control.d.ts +7 -0
- package/dist/sys-modules/control.d.ts.map +1 -1
- package/dist/sys-modules/control.js +32 -7
- package/dist/sys-modules/control.js.map +1 -1
- package/dist/sys-modules/manifest.js +7 -0
- package/dist/sys-modules/manifest.js.map +1 -1
- package/dist/sys-modules/registration.d.ts.map +1 -1
- package/dist/sys-modules/registration.js +18 -8
- package/dist/sys-modules/registration.js.map +1 -1
- package/dist/trace-context.d.ts.map +1 -1
- package/dist/trace-context.js +14 -3
- package/dist/trace-context.js.map +1 -1
- package/package.json +8 -4
- package/dist/registry/index.d.ts +0 -15
- package/dist/registry/index.d.ts.map +0 -1
- package/dist/registry/index.js +0 -11
- package/dist/registry/index.js.map +0 -1
- package/dist/schema/index.d.ts +0 -11
- package/dist/schema/index.d.ts.map +0 -1
- package/dist/schema/index.js +0 -9
- package/dist/schema/index.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../../src/middleware/circuit-breaker.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,eAAO,MAAM,iBAAiB,6BAA6B,CAAC;AAE5D,oBAAY,
|
|
1
|
+
{"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../../src/middleware/circuit-breaker.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,eAAO,MAAM,iBAAiB,6BAA6B,CAAC;AAE5D,oBAAY,mBAAmB;IAC7B,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,SAAS,cAAc;CACxB;AAwCD,MAAM,WAAW,qBAAqB;IACpC,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;KAAE,CAAC;IAC7C,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,wBAAyB,SAAQ,UAAU;IACtD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4C;IACrE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoC;gBAElD,OAAO,GAAE,qBAA0B;IAoC/C,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,KAAK;IAcJ,MAAM,CACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,EAAE,OAAO,GACf,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAqBxB,KAAK,CACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,EAAE,OAAO,GACf,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAcxB,OAAO,CACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,GACf,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IA0BjC,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,GAAG,IAAW,GAAG,mBAAmB;IAM/E,mFAAmF;IACnF,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,GAAG,IAAW,GAAG,IAAI;CAG9D"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* CircuitBreakerMiddleware — per-(module_id, caller_id) rolling-window circuit breaker (Issue #42).
|
|
3
3
|
*
|
|
4
4
|
* State machine:
|
|
5
|
-
* CLOSED → (error_rate >= open_threshold,
|
|
5
|
+
* CLOSED → (error_rate >= open_threshold, samples >= min_samples) → OPEN
|
|
6
6
|
* OPEN → (recovery_window_ms elapsed) → HALF_OPEN
|
|
7
7
|
* HALF_OPEN → (probe success) → CLOSED (emits apcore.circuit.closed)
|
|
8
8
|
* HALF_OPEN → (probe failure) → OPEN (emits apcore.circuit.opened)
|
|
@@ -11,12 +11,12 @@ import { CircuitBreakerOpenError } from '../errors.js';
|
|
|
11
11
|
import { createEvent } from '../events/emitter.js';
|
|
12
12
|
import { Middleware } from './base.js';
|
|
13
13
|
export const CTX_CIRCUIT_STATE = '_apcore.mw.circuit.state';
|
|
14
|
-
export var
|
|
15
|
-
(function (
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
})(
|
|
14
|
+
export var CircuitBreakerState;
|
|
15
|
+
(function (CircuitBreakerState) {
|
|
16
|
+
CircuitBreakerState["CLOSED"] = "CLOSED";
|
|
17
|
+
CircuitBreakerState["OPEN"] = "OPEN";
|
|
18
|
+
CircuitBreakerState["HALF_OPEN"] = "HALF_OPEN";
|
|
19
|
+
})(CircuitBreakerState || (CircuitBreakerState = {}));
|
|
20
20
|
class RollingWindow {
|
|
21
21
|
_cap;
|
|
22
22
|
_buf;
|
|
@@ -52,13 +52,38 @@ export class CircuitBreakerMiddleware extends Middleware {
|
|
|
52
52
|
_openThreshold;
|
|
53
53
|
_recoveryWindowMs;
|
|
54
54
|
_windowSize;
|
|
55
|
+
_minSamples;
|
|
55
56
|
_emitter;
|
|
56
57
|
_circuits = new Map();
|
|
57
58
|
constructor(options = {}) {
|
|
58
59
|
super(options.priority ?? 100);
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
const openThreshold = options.openThreshold ?? 0.5;
|
|
61
|
+
const recoveryWindowMs = options.recoveryWindowMs ?? 30000;
|
|
62
|
+
const windowSize = options.windowSize ?? 20;
|
|
63
|
+
let minSamples = options.minSamples ?? 5;
|
|
64
|
+
// Constructor validation + clamp — mirrors Python circuit_breaker.py:90-105.
|
|
65
|
+
if (!(openThreshold >= 0.0 && openThreshold <= 1.0)) {
|
|
66
|
+
throw new Error(`open_threshold must be in [0.0, 1.0], got ${openThreshold}`);
|
|
67
|
+
}
|
|
68
|
+
if (recoveryWindowMs < 0) {
|
|
69
|
+
throw new Error(`recovery_window_ms must be >= 0, got ${recoveryWindowMs}`);
|
|
70
|
+
}
|
|
71
|
+
if (windowSize < 1) {
|
|
72
|
+
throw new Error(`window_size must be >= 1, got ${windowSize}`);
|
|
73
|
+
}
|
|
74
|
+
if (minSamples < 1) {
|
|
75
|
+
throw new Error(`min_samples must be >= 1, got ${minSamples}`);
|
|
76
|
+
}
|
|
77
|
+
if (minSamples > windowSize) {
|
|
78
|
+
console.warn(`[apcore:middleware:circuit_breaker] min_samples (${minSamples}) exceeds ` +
|
|
79
|
+
`window_size (${windowSize}); clamping min_samples to window_size. ` +
|
|
80
|
+
'Otherwise the breaker could never open.');
|
|
81
|
+
minSamples = windowSize;
|
|
82
|
+
}
|
|
83
|
+
this._openThreshold = openThreshold;
|
|
84
|
+
this._recoveryWindowMs = recoveryWindowMs;
|
|
85
|
+
this._windowSize = windowSize;
|
|
86
|
+
this._minSamples = minSamples;
|
|
62
87
|
this._emitter = options.emitter ?? null;
|
|
63
88
|
}
|
|
64
89
|
_key(moduleId, callerId) {
|
|
@@ -68,7 +93,7 @@ export class CircuitBreakerMiddleware extends Middleware {
|
|
|
68
93
|
const key = this._key(moduleId, callerId);
|
|
69
94
|
if (!this._circuits.has(key)) {
|
|
70
95
|
this._circuits.set(key, {
|
|
71
|
-
state:
|
|
96
|
+
state: CircuitBreakerState.CLOSED,
|
|
72
97
|
window: new RollingWindow(this._windowSize),
|
|
73
98
|
openedAt: null,
|
|
74
99
|
probeInFlight: false,
|
|
@@ -77,22 +102,22 @@ export class CircuitBreakerMiddleware extends Middleware {
|
|
|
77
102
|
return this._circuits.get(key);
|
|
78
103
|
}
|
|
79
104
|
_maybeHalfOpen(record) {
|
|
80
|
-
if (record.state ===
|
|
105
|
+
if (record.state === CircuitBreakerState.OPEN && record.openedAt !== null) {
|
|
81
106
|
if (Date.now() - record.openedAt >= this._recoveryWindowMs) {
|
|
82
|
-
record.state =
|
|
107
|
+
record.state = CircuitBreakerState.HALF_OPEN;
|
|
83
108
|
record.probeInFlight = false;
|
|
84
109
|
}
|
|
85
110
|
}
|
|
86
111
|
}
|
|
87
112
|
_openCircuit(moduleId, callerId, record) {
|
|
88
|
-
record.state =
|
|
113
|
+
record.state = CircuitBreakerState.OPEN;
|
|
89
114
|
record.openedAt = Date.now();
|
|
90
115
|
record.probeInFlight = false;
|
|
91
116
|
console.warn(`[apcore:middleware] Circuit OPEN for module '${moduleId}' (caller: ${callerId ?? 'unknown'})`);
|
|
92
117
|
this._emit('apcore.circuit.opened', moduleId, callerId, 'warn');
|
|
93
118
|
}
|
|
94
119
|
_closeCircuit(moduleId, callerId, record) {
|
|
95
|
-
record.state =
|
|
120
|
+
record.state = CircuitBreakerState.CLOSED;
|
|
96
121
|
record.openedAt = null;
|
|
97
122
|
record.probeInFlight = false;
|
|
98
123
|
console.warn(`[apcore:middleware] Circuit CLOSED for module '${moduleId}' (caller: ${callerId ?? 'unknown'})`);
|
|
@@ -113,10 +138,10 @@ export class CircuitBreakerMiddleware extends Middleware {
|
|
|
113
138
|
const record = this._getRecord(moduleId, callerId);
|
|
114
139
|
this._maybeHalfOpen(record);
|
|
115
140
|
context.data[CTX_CIRCUIT_STATE] = record.state;
|
|
116
|
-
if (record.state ===
|
|
141
|
+
if (record.state === CircuitBreakerState.OPEN) {
|
|
117
142
|
throw new CircuitBreakerOpenError(moduleId, callerId);
|
|
118
143
|
}
|
|
119
|
-
if (record.state ===
|
|
144
|
+
if (record.state === CircuitBreakerState.HALF_OPEN) {
|
|
120
145
|
if (record.probeInFlight) {
|
|
121
146
|
throw new CircuitBreakerOpenError(moduleId, callerId);
|
|
122
147
|
}
|
|
@@ -128,9 +153,9 @@ export class CircuitBreakerMiddleware extends Middleware {
|
|
|
128
153
|
const callerId = context.callerId;
|
|
129
154
|
const record = this._getRecord(moduleId, callerId);
|
|
130
155
|
record.window.record(false);
|
|
131
|
-
if (record.state ===
|
|
156
|
+
if (record.state === CircuitBreakerState.HALF_OPEN) {
|
|
132
157
|
this._closeCircuit(moduleId, callerId, record);
|
|
133
|
-
context.data[CTX_CIRCUIT_STATE] =
|
|
158
|
+
context.data[CTX_CIRCUIT_STATE] = CircuitBreakerState.CLOSED;
|
|
134
159
|
}
|
|
135
160
|
return null;
|
|
136
161
|
}
|
|
@@ -141,15 +166,15 @@ export class CircuitBreakerMiddleware extends Middleware {
|
|
|
141
166
|
const callerId = context.callerId;
|
|
142
167
|
const record = this._getRecord(moduleId, callerId);
|
|
143
168
|
record.window.record(true);
|
|
144
|
-
if (record.state ===
|
|
169
|
+
if (record.state === CircuitBreakerState.HALF_OPEN) {
|
|
145
170
|
this._openCircuit(moduleId, callerId, record);
|
|
146
|
-
context.data[CTX_CIRCUIT_STATE] =
|
|
171
|
+
context.data[CTX_CIRCUIT_STATE] = CircuitBreakerState.OPEN;
|
|
147
172
|
}
|
|
148
|
-
else if (record.state ===
|
|
149
|
-
if (record.window.length >= this.
|
|
173
|
+
else if (record.state === CircuitBreakerState.CLOSED) {
|
|
174
|
+
if (record.window.length >= this._minSamples &&
|
|
150
175
|
record.window.errorRate >= this._openThreshold) {
|
|
151
176
|
this._openCircuit(moduleId, callerId, record);
|
|
152
|
-
context.data[CTX_CIRCUIT_STATE] =
|
|
177
|
+
context.data[CTX_CIRCUIT_STATE] = CircuitBreakerState.OPEN;
|
|
153
178
|
}
|
|
154
179
|
}
|
|
155
180
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../../src/middleware/circuit-breaker.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAEvD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,CAAC,MAAM,iBAAiB,GAAG,0BAA0B,CAAC;AAE5D,MAAM,CAAN,IAAY,
|
|
1
|
+
{"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../../src/middleware/circuit-breaker.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,11 +4,11 @@ export { BeforeMiddleware, AfterMiddleware } from './adapters.js';
|
|
|
4
4
|
export type { BeforeCallback, AfterCallback } from './adapters.js';
|
|
5
5
|
export { LoggingMiddleware } from './logging.js';
|
|
6
6
|
export type { Logger } from './logging.js';
|
|
7
|
-
export {
|
|
7
|
+
export { RetryMiddleware, RetryHintMiddleware, CTX_RETRY_COUNT_PREFIX, CTX_RETRY_DELAY_PREFIX } from './retry.js';
|
|
8
8
|
export type { RetryConfig } from './retry.js';
|
|
9
9
|
export { ErrorHistoryMiddleware } from './error-history.js';
|
|
10
10
|
export { PlatformNotifyMiddleware } from './platform-notify.js';
|
|
11
|
-
export { CircuitBreakerMiddleware,
|
|
11
|
+
export { CircuitBreakerMiddleware, CircuitBreakerState, CTX_CIRCUIT_STATE, } from './circuit-breaker.js';
|
|
12
12
|
export type { CircuitBreakerOptions } from './circuit-breaker.js';
|
|
13
13
|
export { TracingMiddleware, CTX_TRACING_SPAN_ID } from './tracing.js';
|
|
14
14
|
export type { OtelTracer, OtelSpan, TracingMiddlewareOptions } from './tracing.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAClE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAClE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAClH,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EACL,wBAAwB,EACxB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACtE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC5E,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC"}
|
package/dist/middleware/index.js
CHANGED
|
@@ -2,10 +2,10 @@ export { Middleware, RetrySignal } from './base.js';
|
|
|
2
2
|
export { MiddlewareManager, MiddlewareChainError } from './manager.js';
|
|
3
3
|
export { BeforeMiddleware, AfterMiddleware } from './adapters.js';
|
|
4
4
|
export { LoggingMiddleware } from './logging.js';
|
|
5
|
-
export {
|
|
5
|
+
export { RetryMiddleware, RetryHintMiddleware, CTX_RETRY_COUNT_PREFIX, CTX_RETRY_DELAY_PREFIX } from './retry.js';
|
|
6
6
|
export { ErrorHistoryMiddleware } from './error-history.js';
|
|
7
7
|
export { PlatformNotifyMiddleware } from './platform-notify.js';
|
|
8
|
-
export { CircuitBreakerMiddleware,
|
|
8
|
+
export { CircuitBreakerMiddleware, CircuitBreakerState, CTX_CIRCUIT_STATE, } from './circuit-breaker.js';
|
|
9
9
|
export { TracingMiddleware, CTX_TRACING_SPAN_ID } from './tracing.js';
|
|
10
10
|
export { validateContextKey, isAsyncHandler } from './context-namespace.js';
|
|
11
11
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAElE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAElE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAElH,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EACL,wBAAwB,EACxB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEtE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { Context } from '../context.js';
|
|
5
5
|
import { ModuleError } from '../errors.js';
|
|
6
|
-
import { Middleware, RetrySignal } from './base.js';
|
|
6
|
+
import { type Middleware, RetrySignal } from './base.js';
|
|
7
7
|
export declare class MiddlewareChainError extends ModuleError {
|
|
8
8
|
static readonly DEFAULT_RETRYABLE: boolean | null;
|
|
9
9
|
readonly original: Error;
|
|
@@ -12,7 +12,11 @@ export declare class MiddlewareChainError extends ModuleError {
|
|
|
12
12
|
}
|
|
13
13
|
export declare class MiddlewareManager {
|
|
14
14
|
private _middlewares;
|
|
15
|
-
|
|
15
|
+
private _registrations;
|
|
16
|
+
add(middleware: Middleware, opts?: {
|
|
17
|
+
allowDuplicate?: boolean;
|
|
18
|
+
identityKey?: string;
|
|
19
|
+
}): void;
|
|
16
20
|
remove(middleware: Middleware): boolean;
|
|
17
21
|
snapshot(): Middleware[];
|
|
18
22
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/middleware/manager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/middleware/manager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,KAAK,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAEzD,qBAAa,oBAAqB,SAAQ,WAAW;IACnD,gBAAyB,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAS;IAEnE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC;IACzB,QAAQ,CAAC,mBAAmB,EAAE,UAAU,EAAE,CAAC;gBAE/B,QAAQ,EAAE,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE;CAM/D;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,cAAc,CAAqE;IAE3F,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAiD5F,MAAM,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO;IAiBvC,QAAQ,IAAI,UAAU,EAAE;IAIxB;;;;;;OAMG;IACG,aAAa,CACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IAoB7C,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAe7B,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,EAChB,mBAAmB,EAAE,UAAU,EAAE,GAChC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW,GAAG,IAAI,CAAC;CAwBzD"}
|
|
@@ -16,7 +16,35 @@ export class MiddlewareChainError extends ModuleError {
|
|
|
16
16
|
}
|
|
17
17
|
export class MiddlewareManager {
|
|
18
18
|
_middlewares = [];
|
|
19
|
-
|
|
19
|
+
_registrations = new Map();
|
|
20
|
+
add(middleware, opts) {
|
|
21
|
+
// A-D-017: reject priority > 1000 at the manager level (Python/Rust parity).
|
|
22
|
+
// The Middleware base class also guards this at construction, but a plain
|
|
23
|
+
// object or a subclass bypassing super() could carry an out-of-range value.
|
|
24
|
+
if (middleware.priority > 1000) {
|
|
25
|
+
throw new RangeError(`Middleware '${middleware.constructor.name}' has priority ${middleware.priority} ` +
|
|
26
|
+
`which exceeds the maximum allowed value of 1000`);
|
|
27
|
+
}
|
|
28
|
+
// A-D-018(a) DEFERRED: default identity stays constructor.name. A robust
|
|
29
|
+
// module/package-qualified identity (Python uses module.qualname) is not
|
|
30
|
+
// reliably available for a JS class at runtime, so we keep the bare name.
|
|
31
|
+
const identity = opts?.identityKey ?? middleware.constructor.name;
|
|
32
|
+
const prior = this._registrations.get(identity);
|
|
33
|
+
if (!opts?.allowDuplicate && prior !== undefined) {
|
|
34
|
+
console.warn(`[apcore:middleware] Duplicate middleware registration detected for identity '${identity}' ` +
|
|
35
|
+
`(class: ${middleware.constructor.name}). ` +
|
|
36
|
+
`If intentional, pass allowDuplicate: true or use a unique identityKey. ` +
|
|
37
|
+
`Note: identity defaults to constructor.name, which may collide across packages. ` +
|
|
38
|
+
`Prior registration site:\n${prior.stack}\nCurrent registration site:\n${new Error().stack ?? '(unavailable)'}`);
|
|
39
|
+
}
|
|
40
|
+
// A-D-019(b) first-registration-wins: only record the identity when it is
|
|
41
|
+
// absent. A duplicate must NOT overwrite the original registration site.
|
|
42
|
+
// A-D-021/022(d): identity is recorded even when allowDuplicate is true —
|
|
43
|
+
// only the warning above is suppressed by allowDuplicate, not the recording.
|
|
44
|
+
if (prior === undefined) {
|
|
45
|
+
const stack = new Error().stack ?? '(unavailable)';
|
|
46
|
+
this._registrations.set(identity, { middleware, stack });
|
|
47
|
+
}
|
|
20
48
|
// Stable insertion: find the first middleware with a strictly lower priority
|
|
21
49
|
// and insert before it. This keeps higher-priority middlewares first and
|
|
22
50
|
// preserves registration order among equal priorities.
|
|
@@ -33,6 +61,13 @@ export class MiddlewareManager {
|
|
|
33
61
|
for (let i = 0; i < this._middlewares.length; i++) {
|
|
34
62
|
if (this._middlewares[i] === middleware) {
|
|
35
63
|
this._middlewares.splice(i, 1);
|
|
64
|
+
// Remove from identity registry so the same class can be re-added cleanly
|
|
65
|
+
for (const [key, reg] of this._registrations.entries()) {
|
|
66
|
+
if (reg.middleware === middleware) {
|
|
67
|
+
this._registrations.delete(key);
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
36
71
|
return true;
|
|
37
72
|
}
|
|
38
73
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/middleware/manager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/middleware/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,9 +7,8 @@
|
|
|
7
7
|
* when p99 latency exceeds the limit, and apcore.health.recovered when a
|
|
8
8
|
* previously alerted module recovers below threshold * 0.5.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
* `
|
|
12
|
-
* with `deprecated: true` in the payload (Issue #36).
|
|
10
|
+
* Issue #36 removed legacy aliases in v0.22.0 — only the canonical
|
|
11
|
+
* `apcore.health.*` event names are emitted.
|
|
13
12
|
*/
|
|
14
13
|
import type { Context } from '../context.js';
|
|
15
14
|
import type { EventEmitter } from '../events/emitter.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-notify.d.ts","sourceRoot":"","sources":["../../src/middleware/platform-notify.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"platform-notify.d.ts","sourceRoot":"","sources":["../../src/middleware/platform-notify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,qBAAa,wBAAyB,SAAQ,UAAU;IACtD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA0B;IAC5D,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAS;IAChD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuC;gBAG9D,YAAY,EAAE,YAAY,EAC1B,gBAAgB,GAAE,gBAAgB,GAAG,IAAW,EAChD,kBAAkB,GAAE,MAAY,EAChC,qBAAqB,GAAE,MAAa;IAS7B,KAAK,CACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,EAAE,OAAO,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAMxB,OAAO,CACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,MAAM,EAAE,KAAK,EACb,QAAQ,EAAE,OAAO,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IASjC,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,wBAAwB;IAchC,OAAO,CAAC,sBAAsB;IAiB9B,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,mBAAmB;CAe5B"}
|
|
@@ -7,11 +7,10 @@
|
|
|
7
7
|
* when p99 latency exceeds the limit, and apcore.health.recovered when a
|
|
8
8
|
* previously alerted module recovers below threshold * 0.5.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
* `
|
|
12
|
-
* with `deprecated: true` in the payload (Issue #36).
|
|
10
|
+
* Issue #36 removed legacy aliases in v0.22.0 — only the canonical
|
|
11
|
+
* `apcore.health.*` event names are emitted.
|
|
13
12
|
*/
|
|
14
|
-
import { createEvent
|
|
13
|
+
import { createEvent } from '../events/emitter.js';
|
|
15
14
|
import { computeModuleErrorRate, estimateP99FromHistogram } from '../observability/metrics-utils.js';
|
|
16
15
|
import { Middleware } from './base.js';
|
|
17
16
|
export class PlatformNotifyMiddleware extends Middleware {
|
|
@@ -57,7 +56,7 @@ export class PlatformNotifyMiddleware extends Middleware {
|
|
|
57
56
|
const errorRate = this._computeErrorRate(moduleId);
|
|
58
57
|
const alerted = this._getAlerted(moduleId);
|
|
59
58
|
if (errorRate >= this._errorRateThreshold && !alerted.has('error_rate')) {
|
|
60
|
-
|
|
59
|
+
this._emitter.emit(createEvent('apcore.health.error_threshold_exceeded', moduleId, 'error', { error_rate: errorRate, threshold: this._errorRateThreshold }));
|
|
61
60
|
alerted.add('error_rate');
|
|
62
61
|
}
|
|
63
62
|
}
|
|
@@ -69,7 +68,7 @@ export class PlatformNotifyMiddleware extends Middleware {
|
|
|
69
68
|
return;
|
|
70
69
|
const p99Ms = this._estimateP99Ms(moduleId);
|
|
71
70
|
if (p99Ms >= this._latencyP99ThresholdMs) {
|
|
72
|
-
|
|
71
|
+
this._emitter.emit(createEvent('apcore.health.latency_threshold_exceeded', moduleId, 'warn', { p99_latency_ms: p99Ms, threshold: this._latencyP99ThresholdMs }));
|
|
73
72
|
alerted.add('latency');
|
|
74
73
|
}
|
|
75
74
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-notify.js","sourceRoot":"","sources":["../../src/middleware/platform-notify.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"platform-notify.js","sourceRoot":"","sources":["../../src/middleware/platform-notify.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,8 +2,16 @@
|
|
|
2
2
|
* RetryMiddleware for automatic retry of retryable module errors.
|
|
3
3
|
*/
|
|
4
4
|
import type { Context } from '../context.js';
|
|
5
|
-
import { Middleware } from './base.js';
|
|
6
|
-
/**
|
|
5
|
+
import { Middleware, RetrySignal } from './base.js';
|
|
6
|
+
/**
|
|
7
|
+
* Well-known context.data key prefixes for retry state.
|
|
8
|
+
*
|
|
9
|
+
* `CTX_RETRY_COUNT_PREFIX + moduleId` is identical to
|
|
10
|
+
* `RETRY_COUNT_BASE.scoped(moduleId).name` and stores the per-module attempt
|
|
11
|
+
* counter used by {@link RetryMiddleware}. `CTX_RETRY_DELAY_PREFIX` is retained
|
|
12
|
+
* for backward compatibility with outer retry loops that inspected the legacy
|
|
13
|
+
* advisory delay hint; it is no longer written by the built-in middleware.
|
|
14
|
+
*/
|
|
7
15
|
export declare const CTX_RETRY_COUNT_PREFIX = "_apcore.mw.retry.count.";
|
|
8
16
|
export declare const CTX_RETRY_DELAY_PREFIX = "_apcore.mw.retry.delay_ms.";
|
|
9
17
|
export interface RetryConfig {
|
|
@@ -14,27 +22,37 @@ export interface RetryConfig {
|
|
|
14
22
|
jitter: boolean;
|
|
15
23
|
}
|
|
16
24
|
/**
|
|
17
|
-
*
|
|
25
|
+
* Middleware that retries failed module executions based on error retryability.
|
|
18
26
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
27
|
+
* When `onError` is called with a retryable error (`error.retryable === true`),
|
|
28
|
+
* this middleware sleeps for a calculated backoff delay and returns a
|
|
29
|
+
* {@link RetrySignal} carrying the original inputs. The executor recognises the
|
|
30
|
+
* signal and re-runs the module; remaining middlewares' `onError` handlers are
|
|
31
|
+
* not invoked for this attempt. After `maxRetries` attempts or for
|
|
32
|
+
* non-retryable errors, it returns `null` so the error propagates.
|
|
22
33
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
34
|
+
* Retry state is tracked per-module in `context.data` under
|
|
35
|
+
* `_apcore.mw.retry.count.{moduleId}` (via {@link RETRY_COUNT_BASE}). The
|
|
36
|
+
* counter is cleared by `after()` on successful completion so `context.data`
|
|
37
|
+
* does not grow unbounded across long call chains that recover before the
|
|
38
|
+
* limit is hit.
|
|
26
39
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
40
|
+
* Cross-language parity with apcore-python `RetryMiddleware`
|
|
41
|
+
* (returns `RetrySignal`) and apcore-rust `RetryMiddleware`
|
|
42
|
+
* (returns `Ok(Some(inputs))`).
|
|
29
43
|
*/
|
|
30
|
-
export declare class
|
|
44
|
+
export declare class RetryMiddleware extends Middleware {
|
|
31
45
|
private _config;
|
|
32
46
|
constructor(config?: Partial<RetryConfig>);
|
|
33
|
-
onError(moduleId: string, inputs: Record<string, unknown>, error: Error, context: Context):
|
|
47
|
+
onError(moduleId: string, inputs: Record<string, unknown>, error: Error, context: Context): Promise<RetrySignal | null>;
|
|
48
|
+
after(moduleId: string, _inputs: Record<string, unknown>, _output: Record<string, unknown>, context: Context): null;
|
|
34
49
|
private _calculateDelay;
|
|
35
50
|
}
|
|
36
51
|
/**
|
|
37
|
-
* @deprecated Use {@link
|
|
52
|
+
* @deprecated Use {@link RetryMiddleware} instead. This alias previously named
|
|
53
|
+
* an advisory no-op variant that only recorded hints in `context.data`; that
|
|
54
|
+
* behavior is gone — `RetryHintMiddleware` now performs real retries. Will be
|
|
55
|
+
* removed in 1.0.0.
|
|
38
56
|
*/
|
|
39
|
-
export declare const
|
|
57
|
+
export declare const RetryHintMiddleware: typeof RetryMiddleware;
|
|
40
58
|
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/middleware/retry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/middleware/retry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAG7C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAEpD;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,4BAA4B,CAAC;AAChE,eAAO,MAAM,sBAAsB,+BAA+B,CAAC;AAEnE,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;CACjB;AAcD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,OAAO,CAAC,OAAO,CAAc;gBAEjB,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC;IAK1B,OAAO,CACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IA0BrB,KAAK,CACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,EAAE,OAAO,GACf,IAAI;IAOP,OAAO,CAAC,eAAe;CAkBxB;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,wBAAkB,CAAC"}
|
package/dist/middleware/retry.js
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* RetryMiddleware for automatic retry of retryable module errors.
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
|
|
4
|
+
import { RETRY_COUNT_BASE } from '../context-keys.js';
|
|
5
|
+
import { Middleware, RetrySignal } from './base.js';
|
|
6
|
+
/**
|
|
7
|
+
* Well-known context.data key prefixes for retry state.
|
|
8
|
+
*
|
|
9
|
+
* `CTX_RETRY_COUNT_PREFIX + moduleId` is identical to
|
|
10
|
+
* `RETRY_COUNT_BASE.scoped(moduleId).name` and stores the per-module attempt
|
|
11
|
+
* counter used by {@link RetryMiddleware}. `CTX_RETRY_DELAY_PREFIX` is retained
|
|
12
|
+
* for backward compatibility with outer retry loops that inspected the legacy
|
|
13
|
+
* advisory delay hint; it is no longer written by the built-in middleware.
|
|
14
|
+
*/
|
|
6
15
|
export const CTX_RETRY_COUNT_PREFIX = '_apcore.mw.retry.count.';
|
|
7
16
|
export const CTX_RETRY_DELAY_PREFIX = '_apcore.mw.retry.delay_ms.';
|
|
8
17
|
const DEFAULT_RETRY_CONFIG = {
|
|
@@ -12,43 +21,56 @@ const DEFAULT_RETRY_CONFIG = {
|
|
|
12
21
|
maxDelayMs: 5000,
|
|
13
22
|
jitter: true,
|
|
14
23
|
};
|
|
24
|
+
function sleep(ms) {
|
|
25
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
26
|
+
}
|
|
15
27
|
/**
|
|
16
|
-
*
|
|
28
|
+
* Middleware that retries failed module executions based on error retryability.
|
|
17
29
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
30
|
+
* When `onError` is called with a retryable error (`error.retryable === true`),
|
|
31
|
+
* this middleware sleeps for a calculated backoff delay and returns a
|
|
32
|
+
* {@link RetrySignal} carrying the original inputs. The executor recognises the
|
|
33
|
+
* signal and re-runs the module; remaining middlewares' `onError` handlers are
|
|
34
|
+
* not invoked for this attempt. After `maxRetries` attempts or for
|
|
35
|
+
* non-retryable errors, it returns `null` so the error propagates.
|
|
21
36
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
37
|
+
* Retry state is tracked per-module in `context.data` under
|
|
38
|
+
* `_apcore.mw.retry.count.{moduleId}` (via {@link RETRY_COUNT_BASE}). The
|
|
39
|
+
* counter is cleared by `after()` on successful completion so `context.data`
|
|
40
|
+
* does not grow unbounded across long call chains that recover before the
|
|
41
|
+
* limit is hit.
|
|
25
42
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
43
|
+
* Cross-language parity with apcore-python `RetryMiddleware`
|
|
44
|
+
* (returns `RetrySignal`) and apcore-rust `RetryMiddleware`
|
|
45
|
+
* (returns `Ok(Some(inputs))`).
|
|
28
46
|
*/
|
|
29
|
-
export class
|
|
47
|
+
export class RetryMiddleware extends Middleware {
|
|
30
48
|
_config;
|
|
31
49
|
constructor(config) {
|
|
32
50
|
super();
|
|
33
51
|
this._config = { ...DEFAULT_RETRY_CONFIG, ...config };
|
|
34
52
|
}
|
|
35
|
-
onError(moduleId, inputs, error, context) {
|
|
53
|
+
async onError(moduleId, inputs, error, context) {
|
|
36
54
|
const retryable = error.retryable;
|
|
37
55
|
if (retryable !== true)
|
|
38
56
|
return null;
|
|
39
|
-
const retryKey =
|
|
40
|
-
const retryCount = context
|
|
57
|
+
const retryKey = RETRY_COUNT_BASE.scoped(moduleId);
|
|
58
|
+
const retryCount = retryKey.get(context, 0) ?? 0;
|
|
41
59
|
if (retryCount >= this._config.maxRetries) {
|
|
42
60
|
console.warn(`[apcore:retry] Max retries (${this._config.maxRetries}) exceeded for module '${moduleId}'`);
|
|
43
61
|
return null;
|
|
44
62
|
}
|
|
45
63
|
const delayMs = this._calculateDelay(retryCount);
|
|
46
|
-
context
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
64
|
+
retryKey.set(context, retryCount + 1);
|
|
65
|
+
console.warn(`[apcore:retry] Retrying module '${moduleId}' (attempt ${retryCount + 1}/${this._config.maxRetries}) ` +
|
|
66
|
+
`after ${Math.round(delayMs)}ms`);
|
|
67
|
+
await sleep(delayMs);
|
|
68
|
+
return new RetrySignal({ ...inputs });
|
|
69
|
+
}
|
|
70
|
+
after(moduleId, _inputs, _output, context) {
|
|
71
|
+
// Clear the per-module retry counter on successful completion so
|
|
72
|
+
// context.data does not accumulate stale `_apcore.mw.retry.count.*` keys.
|
|
73
|
+
RETRY_COUNT_BASE.scoped(moduleId).delete(context);
|
|
52
74
|
return null;
|
|
53
75
|
}
|
|
54
76
|
_calculateDelay(attempt) {
|
|
@@ -67,7 +89,10 @@ export class RetryHintMiddleware extends Middleware {
|
|
|
67
89
|
}
|
|
68
90
|
}
|
|
69
91
|
/**
|
|
70
|
-
* @deprecated Use {@link
|
|
92
|
+
* @deprecated Use {@link RetryMiddleware} instead. This alias previously named
|
|
93
|
+
* an advisory no-op variant that only recorded hints in `context.data`; that
|
|
94
|
+
* behavior is gone — `RetryHintMiddleware` now performs real retries. Will be
|
|
95
|
+
* removed in 1.0.0.
|
|
71
96
|
*/
|
|
72
|
-
export const
|
|
97
|
+
export const RetryHintMiddleware = RetryMiddleware;
|
|
73
98
|
//# sourceMappingURL=retry.js.map
|