@nodii/grpc-interceptors 0.5.2 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cancellation-guard.d.ts","sourceRoot":"","sources":["../../src/interceptors/cancellation-guard.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,kBAAkB,EAGlB,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAKlB,wBAAgB,iBAAiB,CAC/B,MAAM,GAAE,kBAAuB,GAC9B,gBAAgB,
|
|
1
|
+
{"version":3,"file":"cancellation-guard.d.ts","sourceRoot":"","sources":["../../src/interceptors/cancellation-guard.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,kBAAkB,EAGlB,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAKlB,wBAAgB,iBAAiB,CAC/B,MAAM,GAAE,kBAAuB,GAC9B,gBAAgB,CA8ElB"}
|
|
@@ -13,7 +13,18 @@ export function cancellationGuard(config = {}) {
|
|
|
13
13
|
return (_methodName, handler) => {
|
|
14
14
|
return async (call) => {
|
|
15
15
|
let cancelled = false;
|
|
16
|
-
|
|
16
|
+
// `handlerDone` is the in-flight gate. grpc-js 1.14.x fires the server
|
|
17
|
+
// `call.on("cancelled")` event on NORMAL end-of-call teardown — i.e.
|
|
18
|
+
// AFTER the handler has already resolved on the success path. We must
|
|
19
|
+
// only treat the event as a real cancel when it arrives while the
|
|
20
|
+
// handler is still running; once the handler has completed it is a
|
|
21
|
+
// benign teardown signal and must NOT throw `RpcCancelledError`.
|
|
22
|
+
let handlerDone = false;
|
|
23
|
+
// Resolves (never rejects) once the onCancel handlers + grace window
|
|
24
|
+
// settle. Throwing is done explicitly at the await sites so the
|
|
25
|
+
// promise never floats as an unhandled rejection (which happens if a
|
|
26
|
+
// `.then(throw)` chain settles before anything awaits it).
|
|
27
|
+
let gracePromise = null;
|
|
17
28
|
const onCancelled = () => {
|
|
18
29
|
cancelled = true;
|
|
19
30
|
// Fire handlers but cap waits at graceMs.
|
|
@@ -26,27 +37,47 @@ export function cancellationGuard(config = {}) {
|
|
|
26
37
|
}
|
|
27
38
|
}));
|
|
28
39
|
const grace = new Promise((resolve) => setTimeout(resolve, graceMs));
|
|
29
|
-
return Promise.race([handlers, grace]).then(() =>
|
|
30
|
-
throw new RpcCancelledError();
|
|
31
|
-
});
|
|
40
|
+
return Promise.race([handlers, grace]).then(() => undefined);
|
|
32
41
|
};
|
|
33
42
|
if (typeof call.on === "function") {
|
|
34
43
|
call.on("cancelled", () => {
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
// Normal end-of-call teardown (grpc-js 1.14.x) fires this AFTER the
|
|
45
|
+
// handler resolved — ignore it so a successful RPC isn't reported
|
|
46
|
+
// as CANCELLED.
|
|
47
|
+
if (handlerDone)
|
|
48
|
+
return;
|
|
49
|
+
if (!gracePromise)
|
|
50
|
+
gracePromise = onCancelled();
|
|
37
51
|
});
|
|
38
52
|
}
|
|
39
53
|
// Fixture path: tests set `call.cancelled = true` before calling.
|
|
40
|
-
if (call.cancelled && !
|
|
41
|
-
|
|
54
|
+
if (call.cancelled && !gracePromise) {
|
|
55
|
+
gracePromise = onCancelled();
|
|
42
56
|
}
|
|
43
|
-
const handlerPromise = handler(call)
|
|
44
|
-
|
|
45
|
-
return
|
|
57
|
+
const handlerPromise = handler(call).then((value) => {
|
|
58
|
+
handlerDone = true;
|
|
59
|
+
return value;
|
|
60
|
+
});
|
|
61
|
+
// Pre-cancel path: cancel was already in-flight before the handler
|
|
62
|
+
// started — race the handler against the grace window, then throw.
|
|
63
|
+
if (gracePromise) {
|
|
64
|
+
const cancelThrow = gracePromise.then(() => {
|
|
65
|
+
throw new RpcCancelledError();
|
|
66
|
+
});
|
|
67
|
+
return Promise.race([handlerPromise, cancelThrow]);
|
|
46
68
|
}
|
|
47
69
|
const result = await handlerPromise;
|
|
48
|
-
|
|
70
|
+
// A cancel that arrived WHILE the handler was still running still throws.
|
|
71
|
+
// `gracePromise` was assigned by `onCancelled()` (runs the onCancel
|
|
72
|
+
// handlers + grace race); await it so those side-effects complete before
|
|
73
|
+
// we surface the error. A cancel arriving AFTER `handlerDone` is gated
|
|
74
|
+
// out in `onCancelled`, so reaching here with `cancelled === true`
|
|
75
|
+
// always means a genuine mid-handler cancel.
|
|
76
|
+
if (cancelled) {
|
|
77
|
+
if (gracePromise)
|
|
78
|
+
await gracePromise;
|
|
49
79
|
throw new RpcCancelledError();
|
|
80
|
+
}
|
|
50
81
|
return result;
|
|
51
82
|
};
|
|
52
83
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cancellation-guard.js","sourceRoot":"","sources":["../../src/interceptors/cancellation-guard.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,EAAE;AACF,wEAAwE;AACxE,iEAAiE;AACjE,uEAAuE;AACvE,uEAAuE;AACvE,0EAA0E;AAQ1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B,MAAM,UAAU,iBAAiB,CAC/B,SAA6B,EAAE;IAE/B,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,IAAI,gBAAgB,CAAC;IACzD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;IAEvC,OAAO,CAAC,WAAmB,EAAE,OAAqB,EAAgB,EAAE;QAClE,OAAO,KAAK,EAAE,IAAe,EAAoB,EAAE;YACjD,IAAI,SAAS,GAAG,KAAK,CAAC;YACtB,IAAI,
|
|
1
|
+
{"version":3,"file":"cancellation-guard.js","sourceRoot":"","sources":["../../src/interceptors/cancellation-guard.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nodii/grpc-interceptors",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "Substrate gRPC interceptor library for the Nodii microservice stack — 8 cross-cutting interceptors (logging, audit, enrichAuthContext, tenantContext, auditContext, deadlineGuard, cancellationGuard, errorMap) + re-export façade over @nodii/grpc-auth/saga/idempotency + locked-order createStandardServerStack factory. Spec: planning hub docKey=grpc-interceptors.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -24,14 +24,14 @@
|
|
|
24
24
|
"test": "bun test"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@nodii/audit-chain": "0.
|
|
27
|
+
"@nodii/audit-chain": "0.9.1",
|
|
28
28
|
"ioredis": "^5.4.0",
|
|
29
29
|
"postgres": "^3.4.0",
|
|
30
30
|
"typescript": "^5.9.3",
|
|
31
31
|
"@nodii/grpc-auth": "0.9.1",
|
|
32
32
|
"@nodii/idempotency": "0.6.1",
|
|
33
|
-
"@nodii/saga": "0.
|
|
34
|
-
"@nodii/telemetry": "0.9.
|
|
33
|
+
"@nodii/saga": "0.8.0",
|
|
34
|
+
"@nodii/telemetry": "0.9.1"
|
|
35
35
|
},
|
|
36
36
|
"repository": {
|
|
37
37
|
"type": "git",
|