@cotal-ai/core 0.11.6 → 0.13.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/acls.d.ts +31 -7
- package/dist/acls.d.ts.map +1 -1
- package/dist/acls.js +105 -17
- package/dist/acls.js.map +1 -1
- package/dist/agent-file.js +1 -1
- package/dist/agent-file.js.map +1 -1
- package/dist/auth-provider.d.ts +90 -10
- package/dist/auth-provider.d.ts.map +1 -1
- package/dist/auth-provider.js.map +1 -1
- package/dist/backup-config.d.ts +55 -0
- package/dist/backup-config.d.ts.map +1 -0
- package/dist/backup-config.js +243 -0
- package/dist/backup-config.js.map +1 -0
- package/dist/backup.d.ts +86 -0
- package/dist/backup.d.ts.map +1 -0
- package/dist/backup.js +497 -0
- package/dist/backup.js.map +1 -0
- package/dist/broker-floor.d.ts +34 -0
- package/dist/broker-floor.d.ts.map +1 -0
- package/dist/broker-floor.js +39 -0
- package/dist/broker-floor.js.map +1 -0
- package/dist/canonical.d.ts +24 -0
- package/dist/canonical.d.ts.map +1 -0
- package/dist/canonical.js +159 -0
- package/dist/canonical.js.map +1 -0
- package/dist/channels.d.ts.map +1 -1
- package/dist/channels.js +8 -1
- package/dist/channels.js.map +1 -1
- package/dist/connector.d.ts +4 -0
- package/dist/connector.d.ts.map +1 -1
- package/dist/endpoint-action.d.ts +424 -0
- package/dist/endpoint-action.d.ts.map +1 -0
- package/dist/endpoint-action.js +910 -0
- package/dist/endpoint-action.js.map +1 -0
- package/dist/endpoint-binding.d.ts +344 -0
- package/dist/endpoint-binding.d.ts.map +1 -0
- package/dist/endpoint-binding.js +753 -0
- package/dist/endpoint-binding.js.map +1 -0
- package/dist/endpoint-checkpoint.d.ts +292 -0
- package/dist/endpoint-checkpoint.d.ts.map +1 -0
- package/dist/endpoint-checkpoint.js +818 -0
- package/dist/endpoint-checkpoint.js.map +1 -0
- package/dist/endpoint-cluster.d.ts +95 -0
- package/dist/endpoint-cluster.d.ts.map +1 -0
- package/dist/endpoint-cluster.js +194 -0
- package/dist/endpoint-cluster.js.map +1 -0
- package/dist/endpoint-contract-store.d.ts +90 -0
- package/dist/endpoint-contract-store.d.ts.map +1 -0
- package/dist/endpoint-contract-store.js +348 -0
- package/dist/endpoint-contract-store.js.map +1 -0
- package/dist/endpoint-envelope.d.ts +165 -0
- package/dist/endpoint-envelope.d.ts.map +1 -0
- package/dist/endpoint-envelope.js +346 -0
- package/dist/endpoint-envelope.js.map +1 -0
- package/dist/endpoint-grants.d.ts +123 -0
- package/dist/endpoint-grants.d.ts.map +1 -0
- package/dist/endpoint-grants.js +215 -0
- package/dist/endpoint-grants.js.map +1 -0
- package/dist/endpoint-guard.d.ts +222 -0
- package/dist/endpoint-guard.d.ts.map +1 -0
- package/dist/endpoint-guard.js +468 -0
- package/dist/endpoint-guard.js.map +1 -0
- package/dist/endpoint-handle.d.ts +176 -0
- package/dist/endpoint-handle.d.ts.map +1 -0
- package/dist/endpoint-handle.js +608 -0
- package/dist/endpoint-handle.js.map +1 -0
- package/dist/endpoint-journal.d.ts +225 -0
- package/dist/endpoint-journal.d.ts.map +1 -0
- package/dist/endpoint-journal.js +431 -0
- package/dist/endpoint-journal.js.map +1 -0
- package/dist/endpoint-receipt.d.ts +225 -0
- package/dist/endpoint-receipt.d.ts.map +1 -0
- package/dist/endpoint-receipt.js +417 -0
- package/dist/endpoint-receipt.js.map +1 -0
- package/dist/endpoint-records.d.ts +243 -0
- package/dist/endpoint-records.d.ts.map +1 -0
- package/dist/endpoint-records.js +591 -0
- package/dist/endpoint-records.js.map +1 -0
- package/dist/endpoint-serve.d.ts +176 -0
- package/dist/endpoint-serve.d.ts.map +1 -0
- package/dist/endpoint-serve.js +446 -0
- package/dist/endpoint-serve.js.map +1 -0
- package/dist/endpoint-service.d.ts +518 -0
- package/dist/endpoint-service.d.ts.map +1 -0
- package/dist/endpoint-service.js +973 -0
- package/dist/endpoint-service.js.map +1 -0
- package/dist/endpoint-session.d.ts +398 -0
- package/dist/endpoint-session.d.ts.map +1 -0
- package/dist/endpoint-session.js +834 -0
- package/dist/endpoint-session.js.map +1 -0
- package/dist/endpoint-signing.d.ts +105 -0
- package/dist/endpoint-signing.d.ts.map +1 -0
- package/dist/endpoint-signing.js +190 -0
- package/dist/endpoint-signing.js.map +1 -0
- package/dist/endpoint-subjects.d.ts +222 -0
- package/dist/endpoint-subjects.d.ts.map +1 -0
- package/dist/endpoint-subjects.js +381 -0
- package/dist/endpoint-subjects.js.map +1 -0
- package/dist/endpoint-supervisor.d.ts +19 -0
- package/dist/endpoint-supervisor.d.ts.map +1 -0
- package/dist/endpoint-supervisor.js +12 -0
- package/dist/endpoint-supervisor.js.map +1 -0
- package/dist/endpoint-traits.d.ts +225 -0
- package/dist/endpoint-traits.d.ts.map +1 -0
- package/dist/endpoint-traits.js +469 -0
- package/dist/endpoint-traits.js.map +1 -0
- package/dist/endpoint-verbs.d.ts +277 -0
- package/dist/endpoint-verbs.d.ts.map +1 -0
- package/dist/endpoint-verbs.js +576 -0
- package/dist/endpoint-verbs.js.map +1 -0
- package/dist/endpoint-virtual.d.ts +308 -0
- package/dist/endpoint-virtual.d.ts.map +1 -0
- package/dist/endpoint-virtual.js +440 -0
- package/dist/endpoint-virtual.js.map +1 -0
- package/dist/endpoint-work.d.ts +304 -0
- package/dist/endpoint-work.d.ts.map +1 -0
- package/dist/endpoint-work.js +728 -0
- package/dist/endpoint-work.js.map +1 -0
- package/dist/endpoint.d.ts +66 -22
- package/dist/endpoint.d.ts.map +1 -1
- package/dist/endpoint.js +289 -89
- package/dist/endpoint.js.map +1 -1
- package/dist/evict.d.ts +95 -32
- package/dist/evict.d.ts.map +1 -1
- package/dist/evict.js +193 -3
- package/dist/evict.js.map +1 -1
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -1
- package/dist/lease.d.ts +4 -0
- package/dist/lease.d.ts.map +1 -1
- package/dist/lease.js.map +1 -1
- package/dist/members.d.ts +4 -4
- package/dist/members.d.ts.map +1 -1
- package/dist/members.js +12 -12
- package/dist/members.js.map +1 -1
- package/dist/provision.d.ts +78 -20
- package/dist/provision.d.ts.map +1 -1
- package/dist/provision.js +214 -37
- package/dist/provision.js.map +1 -1
- package/dist/runtime.d.ts +3 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/safe-pattern.d.ts +33 -0
- package/dist/safe-pattern.d.ts.map +1 -0
- package/dist/safe-pattern.js +486 -0
- package/dist/safe-pattern.js.map +1 -0
- package/dist/schema-profile.d.ts +93 -0
- package/dist/schema-profile.d.ts.map +1 -0
- package/dist/schema-profile.js +284 -0
- package/dist/schema-profile.js.map +1 -0
- package/dist/secret-store.d.ts +46 -0
- package/dist/secret-store.d.ts.map +1 -0
- package/dist/secret-store.js +2 -0
- package/dist/secret-store.js.map +1 -0
- package/dist/space-auth.d.ts +9 -0
- package/dist/space-auth.d.ts.map +1 -0
- package/dist/space-auth.js +126 -0
- package/dist/space-auth.js.map +1 -0
- package/dist/streams.d.ts +14 -10
- package/dist/streams.d.ts.map +1 -1
- package/dist/streams.js +47 -76
- package/dist/streams.js.map +1 -1
- package/dist/subjects.d.ts +100 -40
- package/dist/subjects.d.ts.map +1 -1
- package/dist/subjects.js +136 -60
- package/dist/subjects.js.map +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,576 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v0.4 caller-side verbs (SPEC §13.5 "Verbs", §13.2 rails, §13.3 envelope) — call, cast, watch,
|
|
3
|
+
* and scatter over the endpoint rails. The verb never changes the subject grammar (§13.2): a
|
|
4
|
+
* call and a cast publish the same request form; the verb rides `replyExpected`, and only the
|
|
5
|
+
* §13.5 gather semantics differ.
|
|
6
|
+
*
|
|
7
|
+
* Boundary discipline mirrors the serve side: args validate against the COMPILED input contract
|
|
8
|
+
* before publish (a caller never emits a request its own contract refuses), the pinned
|
|
9
|
+
* invocation digests are DERIVED from each contract's closure digest, and every consumed reply
|
|
10
|
+
* or event is runtime-validated at this, its consuming boundary (§13.3) — subject-attributed
|
|
11
|
+
* (instance + epoch from the SUBJECT, never the body), id-echoed, and schema-checked under the
|
|
12
|
+
* same fixed §13.8 budget the responder ran. Journal-class work never rides these rails: the
|
|
13
|
+
* verbs pin `class: "ephemeral"`; submissions go through the `epj` journal machinery (§13.4).
|
|
14
|
+
*/
|
|
15
|
+
import { randomBytes } from "node:crypto";
|
|
16
|
+
import { spacePrefix } from "./subjects.js";
|
|
17
|
+
import { epRequestSubject, parseEpSubject, callerTokens, assertLifecycleToken, assertBoundedOwner, } from "./endpoint-subjects.js";
|
|
18
|
+
import { EpEnvelopeError, parseEndpointReply, parseEndpointEvent, assertArgsValid, assertOutputValid, } from "./endpoint-envelope.js";
|
|
19
|
+
import { freezeExpectedSet, registrationReconciler, serviceEpochReader } from "./endpoint-service.js";
|
|
20
|
+
const nonce = () => randomBytes(24).toString("base64url"); // 32 tokens of [A-Za-z0-9_-], 192 bits
|
|
21
|
+
function subjectTarget(t) {
|
|
22
|
+
if (t.mode === "self")
|
|
23
|
+
return { mode: "self" };
|
|
24
|
+
if (t.mode === "handle")
|
|
25
|
+
return { mode: "handle", tOwner: t.owner, tActor: t.actor, tUid: t.lifecycleUid };
|
|
26
|
+
return { mode: t.mode, tOwner: t.owner };
|
|
27
|
+
}
|
|
28
|
+
function bodyTarget(t) {
|
|
29
|
+
if (t.mode === "self")
|
|
30
|
+
return undefined;
|
|
31
|
+
return {
|
|
32
|
+
owner: assertBoundedOwner(t.owner, "target owner"),
|
|
33
|
+
actor: t.actor,
|
|
34
|
+
lifecycleUid: assertLifecycleToken(t.lifecycleUid, "target lifecycleUid"),
|
|
35
|
+
...(t.mappingRevision !== undefined ? { mappingRevision: t.mappingRevision } : {}),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function buildRequest(space, route, op, verb) {
|
|
39
|
+
// §13.7: the caller's own contract gates the args BEFORE publish — the same validator and the
|
|
40
|
+
// same budget the responder runs, so a request this boundary admits pins digests the
|
|
41
|
+
// responder can honor or reject, never digests detached from the payload.
|
|
42
|
+
assertArgsValid(op.contract.input.validate, op.args);
|
|
43
|
+
const n = nonce();
|
|
44
|
+
const subject = epRequestSubject(space, {
|
|
45
|
+
route, endpoint: op.endpoint, command: op.command,
|
|
46
|
+
...(op.target ? { target: subjectTarget(op.target) } : {}),
|
|
47
|
+
caller: op.caller, nonce: n,
|
|
48
|
+
});
|
|
49
|
+
const requestId = nonce();
|
|
50
|
+
const env = {
|
|
51
|
+
v: 1,
|
|
52
|
+
id: requestId,
|
|
53
|
+
op: {
|
|
54
|
+
endpoint: op.endpoint,
|
|
55
|
+
command: op.command,
|
|
56
|
+
inputDigest: op.contract.input.closureDigest,
|
|
57
|
+
outputDigest: op.contract.output.closureDigest,
|
|
58
|
+
},
|
|
59
|
+
class: "ephemeral", // journal work rides epj submissions, never a rail verb (§13.4/§13.5)
|
|
60
|
+
replyExpected: verb.replyExpected,
|
|
61
|
+
...(op.goalId !== undefined ? { goalId: op.goalId } : {}),
|
|
62
|
+
...(op.target && op.target.mode !== "self" ? { target: bodyTarget(op.target) } : {}),
|
|
63
|
+
...(op.args !== undefined ? { args: op.args } : {}),
|
|
64
|
+
from: { id: `${op.caller.owner}.${op.caller.actor}`, name: op.name ?? op.caller.actor },
|
|
65
|
+
...(verb.deadlineMs !== undefined ? { deadlineMs: verb.deadlineMs } : {}),
|
|
66
|
+
...(op.correlation !== undefined ? { correlation: op.correlation } : {}),
|
|
67
|
+
...(op.auth !== undefined ? { auth: op.auth } : {}),
|
|
68
|
+
};
|
|
69
|
+
return { subject, requestId, n, body: new TextEncoder().encode(JSON.stringify(env)) };
|
|
70
|
+
}
|
|
71
|
+
// Node clamps a `setTimeout` delay beyond 2^31-1 ms (~24.8 days) to 1ms, so an over-large deadline
|
|
72
|
+
// would fire IMMEDIATELY (an unbounded budget masquerading as a huge one). Bound every budget to the
|
|
73
|
+
// timer range so the deadline the caller passes is the deadline the timer honors.
|
|
74
|
+
const MAX_TIMER_MS = 2_147_483_647;
|
|
75
|
+
function assertDeadline(deadlineMs, what = "deadlineMs") {
|
|
76
|
+
if (!Number.isSafeInteger(deadlineMs) || deadlineMs <= 0 || deadlineMs > MAX_TIMER_MS)
|
|
77
|
+
throw new EpEnvelopeError("bad-request", `${what} ${deadlineMs} must be a positive budget within the timer bound ${MAX_TIMER_MS}ms (SPEC 13.3: bounded, never unbounded; a larger setTimeout clamps to 1ms)`);
|
|
78
|
+
return deadlineMs;
|
|
79
|
+
}
|
|
80
|
+
/** A NATS "no responders" control message: the broker answered that the request subject had zero
|
|
81
|
+
* subscribers (SPEC 13.5: no responder → unavailable), delivered to the publish reply-to as an empty
|
|
82
|
+
* message with a 503 status header — distinct from a responder that exists but missed the deadline.
|
|
83
|
+
* A responder CAN attach a 503 header to its own reply, so this header alone is not proof of broker
|
|
84
|
+
* authorship: callers must trust it ONLY on the reserved no-responders sentinel subject (which carries
|
|
85
|
+
* no responder publish grant), never on a normal reply subject. */
|
|
86
|
+
function isNoRespondersMsg(msg) {
|
|
87
|
+
const h = msg.headers;
|
|
88
|
+
return h != null && (h.code === 503 || h.status === "503");
|
|
89
|
+
}
|
|
90
|
+
/** Race a caller-supplied read against a bounded budget so a never-settling hook cannot exceed the
|
|
91
|
+
* operation deadline (SPEC 13.5: deadline mandatory). Clears its timer on either outcome. */
|
|
92
|
+
async function raceBounded(read, ms, what) {
|
|
93
|
+
let t;
|
|
94
|
+
try {
|
|
95
|
+
return await Promise.race([
|
|
96
|
+
(async () => read())(),
|
|
97
|
+
new Promise((_, reject) => { t = setTimeout(() => reject(new EpEnvelopeError("deadline-exceeded", `${what} did not settle within the ${ms}ms budget (SPEC 13.5)`)), ms); }),
|
|
98
|
+
]);
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
if (t !== undefined)
|
|
102
|
+
clearTimeout(t);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** The caller's per-request reply subscription: its own rail narrowed to exactly this request's
|
|
106
|
+
* nonce (contained in the §13.9 reply-read grant), so concurrent calls never see each other. */
|
|
107
|
+
function replySubjectFor(space, caller, n) {
|
|
108
|
+
return `${spacePrefix(space)}.ep.reply.*.*.*.${callerTokens(caller).join(".")}.${n}`;
|
|
109
|
+
}
|
|
110
|
+
function parseAttributedReply(space, subject, data, requestId, op, expect) {
|
|
111
|
+
const parsed = parseEpSubject(subject);
|
|
112
|
+
if (!parsed || parsed.plane !== "reply")
|
|
113
|
+
throw new EpEnvelopeError("internal", `a message on the caller's reply rail does not parse as a reply subject: ${subject}`);
|
|
114
|
+
// §13.2 (:1173-1189): ACCEPTANCE binds the subject-borne attribution to the INVOKED identity.
|
|
115
|
+
// Reading the endpoint/instance/epoch off the subject is not the same as checking them against the
|
|
116
|
+
// invocation: a truthfully-attributed reply from a DIFFERENT endpoint (or a stale/other instance)
|
|
117
|
+
// is not the requested responder, and nonce possession is addressing, not authorization. A stale
|
|
118
|
+
// process "publishes attributably stale replies that callers reject" — so the caller rejects here.
|
|
119
|
+
if (parsed.endpoint !== op.endpoint)
|
|
120
|
+
throw new EpEnvelopeError("internal", `reply endpoint "${parsed.endpoint}" is not the invoked endpoint "${op.endpoint}" (SPEC 13.2: the caller binds a reply to the requested identity, never trusts the subject alone)`);
|
|
121
|
+
if (expect?.instanceId !== undefined && parsed.instanceId !== expect.instanceId)
|
|
122
|
+
throw new EpEnvelopeError("internal", `reply instance "${parsed.instanceId}" is not the addressed instance "${expect.instanceId}" (SPEC 13.2)`);
|
|
123
|
+
if (expect?.epoch !== undefined && parsed.epoch !== expect.epoch)
|
|
124
|
+
throw new EpEnvelopeError("expired", `reply epoch ${parsed.epoch} is not the addressed epoch ${expect.epoch}; a superseded incarnation's reply is rejected (SPEC 13.2:1187-1189)`);
|
|
125
|
+
// §13.3: an unparseable body is THIS boundary's own structured refusal — the documented catalog
|
|
126
|
+
// (`internal`) holds; a raw SyntaxError must never escape the verb (the watch path already wraps
|
|
127
|
+
// its decode the same way).
|
|
128
|
+
let rawBody;
|
|
129
|
+
try {
|
|
130
|
+
rawBody = JSON.parse(new TextDecoder().decode(data));
|
|
131
|
+
}
|
|
132
|
+
catch (e) {
|
|
133
|
+
throw new EpEnvelopeError("internal", `the reply body on the caller's rail is not JSON (${e instanceof Error ? e.message : String(e)}); an unparseable reply is a responder bug surfaced as the caller boundary's structured refusal (SPEC 13.3)`);
|
|
134
|
+
}
|
|
135
|
+
const reply = parseEndpointReply(rawBody);
|
|
136
|
+
if (reply.id !== requestId)
|
|
137
|
+
throw new EpEnvelopeError("internal", `reply id "${reply.id}" does not echo the request id "${requestId}" on its nonce-scoped rail (SPEC 13.3)`);
|
|
138
|
+
// §13.3: a success payload validates against the pinned output contract at ITS consuming
|
|
139
|
+
// boundary, under the same fixed budget; the responder's bug never parses as caller success.
|
|
140
|
+
if (reply.ok)
|
|
141
|
+
assertOutputValid(op.contract.output.validate, reply.data);
|
|
142
|
+
return { reply, responder: { endpoint: parsed.endpoint, instanceId: parsed.instanceId, epoch: parsed.epoch } };
|
|
143
|
+
}
|
|
144
|
+
// ---- call (§13.5: request/reply, deadline-bounded) ----------------------------------------------
|
|
145
|
+
/**
|
|
146
|
+
* Call one command and await its reply within `deadlineMs`: on the `one` (queue-group anycast) or
|
|
147
|
+
* `inst` (stable incarnation) rail with `replyExpected: true`, subscribe the caller's own
|
|
148
|
+
* nonce-scoped reply subject BEFORE publishing, and resolve the first attributed reply — BOUND to
|
|
149
|
+
* the invoked identity (§13.2:1187-1189: "callers reject" stale-process replies), on BOTH rails:
|
|
150
|
+
* - `inst` pins the addressed `(instanceId, epoch)` incarnation up front; a stale-epoch reply is
|
|
151
|
+
* `expired` and a wrong-instance reply `internal`.
|
|
152
|
+
* - `one` cannot pin an instance up front (the queue picks the responder), so the caller MUST supply
|
|
153
|
+
* `currentEpoch(instanceId)`: after the reply lands, the answering incarnation's epoch is checked
|
|
154
|
+
* against its current registry epoch, and a superseded-but-still-connected queue member's reply is
|
|
155
|
+
* `expired`. The queue winner is NOT implicitly current — that is a check, not an assumption.
|
|
156
|
+
*
|
|
157
|
+
* Application-level failure is NOT a throw: the resolved `reply` carries `ok: false` with the
|
|
158
|
+
* responder's structured error (§13.3). This boundary throws only for its own refusals: invalid args
|
|
159
|
+
* `bad-request`; an unparseable/mis-echoed/mis-attributed reply `internal` (a raw decode error never
|
|
160
|
+
* escapes); a throwing `currentEpoch` hook `internal` and a garbled (non-integer/negative) currency
|
|
161
|
+
* value `failed-precondition` (the read's own failure, never mislabeled staleness); a stale reply `expired`;
|
|
162
|
+
* NO responder `unavailable` (SPEC 13.5:1484 — the broker's no-responders 503 lands on a reply-to that
|
|
163
|
+
* sits on THIS caller's own rail, so a manual, fully-disposed probe distinguishes it from a slow
|
|
164
|
+
* responder without leaving a lingering request); a failed reply subscription `unavailable`; the
|
|
165
|
+
* elapsed budget `deadline-exceeded`. Every subscription and timer is released in the `finally`.
|
|
166
|
+
*/
|
|
167
|
+
export async function epCall(nc, space, route, op, opts) {
|
|
168
|
+
const deadlineMs = assertDeadline(opts.deadlineMs);
|
|
169
|
+
if (route.mode === "one" && opts.currentEpoch === undefined)
|
|
170
|
+
throw new EpEnvelopeError("bad-request", "epCall on the `one` rail requires opts.currentEpoch: the queue winner is not implicitly current, and a superseded-but-connected member's reply must be rejected (SPEC 13.2:1187-1189)");
|
|
171
|
+
const req = buildRequest(space, route, op, { replyExpected: true, deadlineMs });
|
|
172
|
+
const expect = route.mode === "inst" ? { instanceId: route.instanceId, epoch: route.epoch } : undefined;
|
|
173
|
+
// A no-responders reply-to that lands on THIS caller's OWN rail (within its §13.9 read grant, no
|
|
174
|
+
// inbox prefix needed): responders answer on the DERIVED rail, so this sentinel only ever carries
|
|
175
|
+
// the broker's no-responders 503, which our rail subscription observes and disposes with everything
|
|
176
|
+
// else in the finally — no ghost request/subscription/timer survives a successful call.
|
|
177
|
+
const noRespReplyTo = `${spacePrefix(space)}.ep.reply._nr._nr._nr.${callerTokens(op.caller).join(".")}.${req.n}`;
|
|
178
|
+
const started = Date.now();
|
|
179
|
+
let sub;
|
|
180
|
+
let timer;
|
|
181
|
+
try {
|
|
182
|
+
const outcome = new Promise((resolve, reject) => {
|
|
183
|
+
sub = nc.subscribe(replySubjectFor(space, op.caller, req.n), {
|
|
184
|
+
callback: (err, msg) => {
|
|
185
|
+
if (err) {
|
|
186
|
+
reject(new EpEnvelopeError("unavailable", `the caller's reply subscription failed: ${err.message}`));
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
// Broker no-responders is authoritative ONLY on the reserved sentinel reply-to: no responder
|
|
190
|
+
// holds a publish grant for the `_nr._nr._nr` subject (§13.9), so only the broker's control
|
|
191
|
+
// frame reaches it. A 503 status header on a NORMAL responder subject is just a responder
|
|
192
|
+
// frame carrying a status line — a recipient knows the nonce and could forge one to
|
|
193
|
+
// impersonate transport absence — so it takes the ordinary attributed-reply path below, never
|
|
194
|
+
// the broker-control path.
|
|
195
|
+
if (msg.subject === noRespReplyTo) {
|
|
196
|
+
if (isNoRespondersMsg(msg)) {
|
|
197
|
+
reject(new EpEnvelopeError("unavailable", `no responder for ${op.endpoint}.${op.command} (SPEC 13.5)`));
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
reject(new EpEnvelopeError("internal", `a non-503 message reached the reserved no-responders sentinel for ${op.endpoint}.${op.command}; nothing but the broker control frame is addressable there`));
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
resolve({ subject: msg.subject, data: msg.data });
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
nc.publish(req.subject, req.body, { reply: noRespReplyTo });
|
|
208
|
+
const timeout = new Promise((_, reject) => { timer = setTimeout(() => reject(new EpEnvelopeError("deadline-exceeded", `no reply to ${op.endpoint}.${op.command} within the ${deadlineMs}ms budget (SPEC 13.5)`)), deadlineMs); });
|
|
209
|
+
const msg = await Promise.race([outcome, timeout]);
|
|
210
|
+
const attributed = parseAttributedReply(space, msg.subject, msg.data, req.requestId, op, expect);
|
|
211
|
+
if (route.mode === "one") {
|
|
212
|
+
// §13.2:1187-1189 currency for the queue winner, bounded by the REMAINING budget so the whole
|
|
213
|
+
// call stays within ONE `deadlineMs` (deliberately NOT a second dedicated budget like scatter's
|
|
214
|
+
// `reconcileDeadlineMs`: a call's reply usually arrives well before T, leaving room to verify,
|
|
215
|
+
// whereas scatter's gather deterministically eats its whole deadline). The consequence is a
|
|
216
|
+
// deliberate disposition: a VALID reply that lands with no budget left to verify currency is
|
|
217
|
+
// `deadline-exceeded`, not the reply — the operation could not complete-and-verify within its
|
|
218
|
+
// budget. Recorded for the panel's §13.5 reconciliation (dedicated one-rail currency budget?).
|
|
219
|
+
const remaining = deadlineMs - (Date.now() - started);
|
|
220
|
+
if (remaining <= 0)
|
|
221
|
+
throw new EpEnvelopeError("deadline-exceeded", `no budget left to verify the \`one\` responder's currency within ${deadlineMs}ms (SPEC 13.5)`);
|
|
222
|
+
// The hook is an untrusted caller-supplied boundary (same class as scatter's reconcile): its
|
|
223
|
+
// own throw is normalized into the documented catalog, and its VALUE is runtime-fenced — a
|
|
224
|
+
// NaN/garbled epoch compares unequal to any real epoch and would masquerade as staleness
|
|
225
|
+
// (`expired`), mislabeling a valid reply; fail loud as the read's own failure instead.
|
|
226
|
+
let cur;
|
|
227
|
+
try {
|
|
228
|
+
cur = await raceBounded(() => opts.currentEpoch(attributed.responder.instanceId), remaining, `the \`one\` currency read for ${op.endpoint}.${op.command}`);
|
|
229
|
+
}
|
|
230
|
+
catch (e) {
|
|
231
|
+
if (e instanceof EpEnvelopeError)
|
|
232
|
+
throw e; // the bound's deadline-exceeded, or the hook's own structured refusal
|
|
233
|
+
throw new EpEnvelopeError("internal", `the \`one\` currency read threw (${e instanceof Error ? e.message : String(e)}); the documented error catalog holds at this boundary (SPEC 13.3)`);
|
|
234
|
+
}
|
|
235
|
+
if (!Number.isSafeInteger(cur) || cur < 0)
|
|
236
|
+
throw new EpEnvelopeError("failed-precondition", `the \`one\` currency read returned a non-integer/negative epoch ${String(cur)}; a garbled currency read is refused as the read's own failure, never reported as responder staleness (SPEC 13.2)`);
|
|
237
|
+
if (attributed.responder.epoch !== cur)
|
|
238
|
+
throw new EpEnvelopeError("expired", `the \`one\` responder ${attributed.responder.instanceId} answered at epoch ${attributed.responder.epoch}, not its current ${cur}; a superseded incarnation's reply is rejected (SPEC 13.2:1187-1189)`);
|
|
239
|
+
}
|
|
240
|
+
return attributed;
|
|
241
|
+
}
|
|
242
|
+
finally {
|
|
243
|
+
sub?.unsubscribe();
|
|
244
|
+
if (timer !== undefined)
|
|
245
|
+
clearTimeout(timer);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// ---- cast (§13.5: at-most-once, never replied) --------------------------------------------------
|
|
249
|
+
/**
|
|
250
|
+
* Cast one command: the same request form with `replyExpected: false` — the responder never
|
|
251
|
+
* replies, even on failure (§13.5 at-most-once), so this resolves once the request is flushed to
|
|
252
|
+
* the broker. `deadlineMs` is optional and advisory for `one`/`inst` (the envelope requires it only
|
|
253
|
+
* for calls and journal submissions, §13.3), but MANDATORY for `all`: §13.2's
|
|
254
|
+
* `checkRequestSubjectAgreement` refuses an all-rail request without a deadline regardless of
|
|
255
|
+
* `replyExpected`, and a cast has no reply on which that refusal could surface — so an all-cast
|
|
256
|
+
* without a deadline would be silently dropped by every responder. Fail loud at the caller instead.
|
|
257
|
+
*/
|
|
258
|
+
export async function epCast(nc, space, route, op, opts = {}) {
|
|
259
|
+
if (route.mode === "all" && opts.deadlineMs === undefined)
|
|
260
|
+
throw new EpEnvelopeError("bad-request", "an all-rail cast (scatter) requires deadlineMs (SPEC 13.2: checkRequestSubjectAgreement refuses an all request without a deadline; a cast has no reply to carry that refusal, so it would be silently dropped)");
|
|
261
|
+
const req = buildRequest(space, route, op, {
|
|
262
|
+
replyExpected: false,
|
|
263
|
+
...(opts.deadlineMs !== undefined ? { deadlineMs: assertDeadline(opts.deadlineMs) } : {}),
|
|
264
|
+
});
|
|
265
|
+
nc.publish(req.subject, req.body);
|
|
266
|
+
await nc.flush();
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Watch a granted `epe` subtree LIVE (the event half of §13.5 `watch`; §13.9: the read grant is the
|
|
270
|
+
* caller's own `sub.allow` row, e.g. the per-goal progress subtree — delivery lands only on this
|
|
271
|
+
* caller's own subscription). Every event is validated at this consuming boundary: an unparseable
|
|
272
|
+
* subject or body is reported through `onError` (§13.3: fail loud, never a silent drop) and never
|
|
273
|
+
* reaches `onEvent`. This is the LIVE tap ONLY — durable catch-up / filtered replay is the §13.9
|
|
274
|
+
* mediated read (see the module note above), and record watch is `watchRecord` (§13.4).
|
|
275
|
+
*/
|
|
276
|
+
export function epWatchEvents(nc, space, filter, handlers) {
|
|
277
|
+
if (!filter.startsWith(`${spacePrefix(space)}.epe.`))
|
|
278
|
+
throw new Error(`epWatchEvents filter "${filter}" is not an epe subtree of space "${space}" (SPEC 13.9: watch reads the event plane)`);
|
|
279
|
+
const sub = nc.subscribe(filter, {
|
|
280
|
+
callback: (err, msg) => {
|
|
281
|
+
if (err) {
|
|
282
|
+
handlers.onError(new EpEnvelopeError("unavailable", `the watch subscription failed: ${err.message}`));
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
const parsed = parseEpSubject(msg.subject);
|
|
286
|
+
if (!parsed || parsed.plane !== "event") {
|
|
287
|
+
handlers.onError(new EpEnvelopeError("internal", `a message on the watch filter does not parse as an event subject: ${msg.subject}`));
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
let event;
|
|
291
|
+
try {
|
|
292
|
+
event = parseEndpointEvent(JSON.parse(new TextDecoder().decode(msg.data)));
|
|
293
|
+
}
|
|
294
|
+
catch (e) {
|
|
295
|
+
handlers.onError(e instanceof EpEnvelopeError ? e : new EpEnvelopeError("internal", `event body does not decode: ${e.message}`));
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
handlers.onEvent({ endpoint: parsed.endpoint, instanceId: parsed.instanceId, epoch: parsed.epoch, topic: parsed.topic, event });
|
|
299
|
+
},
|
|
300
|
+
});
|
|
301
|
+
return { stop: () => sub.drain() };
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Scatter one command to a FROZEN expected set (§13.5): publish once on the `all` rail, gather
|
|
305
|
+
* attributed replies on the caller's nonce-scoped rail, and CLASSIFY against the freeze. An empty set
|
|
306
|
+
* refuses (`failed-precondition`, never an empty success), and the observation channel is fail-loud:
|
|
307
|
+
* a failed reply subscription is `unavailable`, never fabricated member silence.
|
|
308
|
+
*
|
|
309
|
+
* CLASSIFICATION LINEARIZES AT THE GATHER DEADLINE. The classification point T is `min(all frozen
|
|
310
|
+
* slots answered-valid, deadline)`; `missing` is fixed at T (from the `respondedAtDeadline` snapshot).
|
|
311
|
+
* The `lateDrainMs` window runs AFTER T on an ABSOLUTE clock — the rail is closed exactly `lateDrainMs`
|
|
312
|
+
* after T regardless of how long the reconcile takes, so late classification cannot leak past the
|
|
313
|
+
* requested horizon. It is OBSERVATIONAL only: it may add to `late`/`duplicate`, never move
|
|
314
|
+
* `missing`/`churn`/`complete`. With `lateDrainMs` omitted the rail closes at T (no `late`).
|
|
315
|
+
*
|
|
316
|
+
* WHOLE-OPERATION BUDGET. The op is bounded: the gather to T comes FIRST, then a post-T phase in which
|
|
317
|
+
* the reconcile and the drain run CONCURRENTLY (the drain is armed at T, before the reconcile await).
|
|
318
|
+
* So worst-case wall-clock ≈ `deadlineMs` (gather) + `max(reconcileDeadlineMs, lateDrainMs)` (post-T),
|
|
319
|
+
* NOT their sum. The reconcile is a bounded read taken SHORTLY AFTER T (not a zero-width at-T snapshot):
|
|
320
|
+
* a true instant-of-T revision would need a watch/frontier, so a re-registration strictly concurrent
|
|
321
|
+
* with the bounded read is an inherent, documented window (recorded for the §13.5 SPEC reconciliation).
|
|
322
|
+
*
|
|
323
|
+
* Two §13.5 signals are not on the reply rail, so the caller supplies them as HOOKS (keeping the verb
|
|
324
|
+
* free of storage coupling; the §13.9 read grant stays with the caller, and a caller-read revision is
|
|
325
|
+
* more trustworthy than a responder-stamped one):
|
|
326
|
+
* - `reconcileRegistration` (REQUIRED): reads EVERY frozen slot's CURRENT state after the classification
|
|
327
|
+
* point, returning a per-instance `EpRegistrationState` verdict. A slot still registered at a revision
|
|
328
|
+
* ADVANCED past its frozen one is `churn` ("registration") and uncounted (a re-registration advances
|
|
329
|
+
* registrationRevision WITHOUT advancing the epoch, so the reply rail cannot see it). A slot the read
|
|
330
|
+
* observed as GONE (`{ registered: false }`) is an explicit mid-scatter deregistration: NOT churn, and
|
|
331
|
+
* a valid reply it already gave still counts (a plain departure does not invalidate the reply the way
|
|
332
|
+
* a re-registration would). Its result is COMPLETENESS-validated: a frozen id ABSENT from the returned
|
|
333
|
+
* Map is an incomplete read (`failed-precondition`) — distinct from an explicit `{ registered: false }`
|
|
334
|
+
* verdict — a non-integer/non-positive revision is a garbled read (`failed-precondition`), and a
|
|
335
|
+
* revision BELOW the frozen one is a non-monotonic/buggy read (`failed-precondition`); otherwise a
|
|
336
|
+
* partial hook would silently preserve the old full-triple over-claim. It is BOUNDED by
|
|
337
|
+
* `reconcileDeadlineMs`: a never-settling read is `unavailable`, never a hung scatter (SPEC 13.5:
|
|
338
|
+
* deadline mandatory); an unreadable registry is `failed-precondition`. Authoritative `complete`
|
|
339
|
+
* requires it.
|
|
340
|
+
* - `reconcileDeadlineMs` (optional, default `deadlineMs`): the explicit bound on that post-T read,
|
|
341
|
+
* named so the single `deadlineMs` is not silently spent twice.
|
|
342
|
+
* - `lateDrainMs` (optional): the absolute post-T horizon for `late` classification. Omitted → none.
|
|
343
|
+
*/
|
|
344
|
+
export async function epScatter(nc, space, op, opts) {
|
|
345
|
+
const deadlineMs = assertDeadline(opts.deadlineMs);
|
|
346
|
+
const reconcileDeadlineMs = opts.reconcileDeadlineMs !== undefined ? assertDeadline(opts.reconcileDeadlineMs, "reconcileDeadlineMs") : deadlineMs;
|
|
347
|
+
const lateDrainMs = opts.lateDrainMs !== undefined ? assertDeadline(opts.lateDrainMs, "lateDrainMs") : 0;
|
|
348
|
+
if (opts.expected.length === 0)
|
|
349
|
+
throw new EpEnvelopeError("failed-precondition", "scatter requires a non-empty frozen expected set (SPEC 13.5: an empty registry is never an empty success)");
|
|
350
|
+
const frozen = new Map();
|
|
351
|
+
for (const slot of opts.expected) {
|
|
352
|
+
const iId = assertLifecycleToken(slot.instanceId, "instanceId");
|
|
353
|
+
// Validate the frozen (epoch, registrationRevision) coordinates at this public ingress: an untyped
|
|
354
|
+
// adapter that handed in a NaN/float/negative would otherwise slip past the currency and
|
|
355
|
+
// monotonicity fences downstream (a NaN compares false both ways). Epoch is a non-negative safe
|
|
356
|
+
// integer (the subject epoch), registrationRevision a positive safe integer (a KV revision, §13.7).
|
|
357
|
+
if (!Number.isSafeInteger(slot.epoch) || slot.epoch < 0)
|
|
358
|
+
throw new EpEnvelopeError("bad-request", `frozen instance ${iId} has a non-integer/negative epoch ${slot.epoch}; a frozen coordinate must be a safe integer so an untyped adapter cannot disable the currency fence (§13.2)`);
|
|
359
|
+
if (!Number.isSafeInteger(slot.registrationRevision) || slot.registrationRevision <= 0)
|
|
360
|
+
throw new EpEnvelopeError("bad-request", `frozen instance ${iId} has a non-integer/non-positive registrationRevision ${slot.registrationRevision}; a frozen coordinate must be a positive safe integer so an untyped adapter cannot disable the monotonicity fence (§13.7)`);
|
|
361
|
+
if (frozen.has(iId))
|
|
362
|
+
throw new EpEnvelopeError("failed-precondition", `the frozen expected set names instance ${iId} twice`);
|
|
363
|
+
frozen.set(iId, { epoch: slot.epoch, registrationRevision: slot.registrationRevision });
|
|
364
|
+
}
|
|
365
|
+
const req = buildRequest(space, { mode: "all" }, op, { replyExpected: true, deadlineMs });
|
|
366
|
+
const result = { complete: false, replies: new Map(), missing: [], unexpected: [], churn: [], duplicate: [], late: [], invalid: [] };
|
|
367
|
+
const terminal = new Set(); // frozen slots with a VALID frozen-epoch reply (drives early completion)
|
|
368
|
+
const seen = new Set(); // "(instanceId,epoch)" pairs already classified non-invalid (drives §13.5 duplicate)
|
|
369
|
+
const responded = new Set(); // frozen slots that produced ANY reply (live)
|
|
370
|
+
const regChurned = new Set();
|
|
371
|
+
const failMsg = (e) => (e instanceof Error ? e.message : String(e));
|
|
372
|
+
let respondedAtDeadline; // `responded` snapshotted at the classification point
|
|
373
|
+
let deadlinePassed = false;
|
|
374
|
+
let subError;
|
|
375
|
+
// Classify one reply; returns true when every frozen slot has a VALID reply (early completion).
|
|
376
|
+
const handle = (subject, data) => {
|
|
377
|
+
const parsed = parseEpSubject(subject);
|
|
378
|
+
if (!parsed || parsed.plane !== "reply")
|
|
379
|
+
return false; // not a reply subject: no sender, MUST NOT be handled (§13.2)
|
|
380
|
+
const { instanceId, epoch } = parsed;
|
|
381
|
+
// §13.2 endpoint binding BEFORE slot matching: instanceIds are unique only within (space,
|
|
382
|
+
// endpoint), so a truthfully-attributed reply from a DIFFERENT endpoint with a colliding
|
|
383
|
+
// (instanceId, epoch) must never satisfy a frozen slot.
|
|
384
|
+
if (parsed.endpoint !== op.endpoint) {
|
|
385
|
+
result.unexpected.push({ instanceId, epoch });
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
const slot = frozen.get(instanceId);
|
|
389
|
+
if (slot === undefined) {
|
|
390
|
+
result.unexpected.push({ instanceId, epoch });
|
|
391
|
+
return false;
|
|
392
|
+
}
|
|
393
|
+
responded.add(instanceId);
|
|
394
|
+
const key = `${instanceId}:${epoch}`;
|
|
395
|
+
// §13.5 duplicate: a second reply from the SAME (instanceId, epoch) after its first NON-INVALID
|
|
396
|
+
// classification (valid | churn-epoch | late) — reported, first wins. An invalid frame never marks
|
|
397
|
+
// the coordinate seen, so a later valid frame from it is NOT mislabeled duplicate.
|
|
398
|
+
if (seen.has(key)) {
|
|
399
|
+
result.duplicate.push({ instanceId, epoch });
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
if (epoch !== slot.epoch) {
|
|
403
|
+
result.churn.push({ instanceId, epoch, reason: "epoch" });
|
|
404
|
+
seen.add(key);
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
407
|
+
if (deadlinePassed) {
|
|
408
|
+
// Post-deadline, frozen epoch: a first VALID reply is LATE (observational, uncounted); a boundary
|
|
409
|
+
// failure is `invalid` (NON-terminal — the coordinate stays un-seen).
|
|
410
|
+
try {
|
|
411
|
+
parseAttributedReply(space, subject, data, req.requestId, op);
|
|
412
|
+
result.late.push({ instanceId, epoch });
|
|
413
|
+
seen.add(key);
|
|
414
|
+
}
|
|
415
|
+
catch (e) {
|
|
416
|
+
result.invalid.push({ instanceId, epoch, message: failMsg(e) });
|
|
417
|
+
}
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
// Pre-deadline, frozen epoch. An invalid frame is NON-TERMINAL: reported, the slot stays open to a
|
|
421
|
+
// later valid reply, the coordinate stays un-seen, and it never triggers early completion.
|
|
422
|
+
try {
|
|
423
|
+
result.replies.set(instanceId, parseAttributedReply(space, subject, data, req.requestId, op));
|
|
424
|
+
}
|
|
425
|
+
catch (e) {
|
|
426
|
+
result.invalid.push({ instanceId, epoch, message: failMsg(e) });
|
|
427
|
+
return false;
|
|
428
|
+
}
|
|
429
|
+
terminal.add(instanceId);
|
|
430
|
+
seen.add(key);
|
|
431
|
+
return terminal.size === frozen.size;
|
|
432
|
+
};
|
|
433
|
+
let sub;
|
|
434
|
+
// Phase 1 — gather to the classification point T = min(all-valid, deadline). NO drain here; the drain
|
|
435
|
+
// is a later observational phase so it can never move the classification.
|
|
436
|
+
await new Promise((resolve) => {
|
|
437
|
+
const finishAtT = () => { if (respondedAtDeadline === undefined)
|
|
438
|
+
respondedAtDeadline = new Set(responded); };
|
|
439
|
+
const timer = setTimeout(() => { deadlinePassed = true; finishAtT(); resolve(); }, deadlineMs);
|
|
440
|
+
sub = nc.subscribe(replySubjectFor(space, op.caller, req.n), {
|
|
441
|
+
callback: (err, msg) => {
|
|
442
|
+
if (err) {
|
|
443
|
+
subError ??= err;
|
|
444
|
+
finishAtT();
|
|
445
|
+
clearTimeout(timer);
|
|
446
|
+
resolve();
|
|
447
|
+
return;
|
|
448
|
+
} // fail loud, never fake `missing`
|
|
449
|
+
if (handle(msg.subject, msg.data)) {
|
|
450
|
+
finishAtT();
|
|
451
|
+
clearTimeout(timer);
|
|
452
|
+
resolve();
|
|
453
|
+
}
|
|
454
|
+
},
|
|
455
|
+
});
|
|
456
|
+
nc.publish(req.subject, req.body);
|
|
457
|
+
});
|
|
458
|
+
let drainTimer;
|
|
459
|
+
try {
|
|
460
|
+
if (subError !== undefined)
|
|
461
|
+
throw new EpEnvelopeError("unavailable", `the scatter reply subscription failed; without a working observation channel member silence cannot be classified, never fabricated (SPEC 13.5): ${failMsg(subError)}`);
|
|
462
|
+
// The late window is an ABSOLUTE horizon from T: close the rail exactly `lateDrainMs` after T
|
|
463
|
+
// (early completion has no window), independent of how long the reconcile below runs — so a reply
|
|
464
|
+
// during a slow reconcile is NOT misclassified `late`, and with no `lateDrainMs` the rail closes
|
|
465
|
+
// now. Runs concurrently with the reconcile.
|
|
466
|
+
const drainMs = deadlinePassed ? lateDrainMs : 0;
|
|
467
|
+
const drainDone = new Promise((resolve) => {
|
|
468
|
+
if (drainMs > 0)
|
|
469
|
+
drainTimer = setTimeout(() => { sub?.unsubscribe(); resolve(); }, drainMs);
|
|
470
|
+
else {
|
|
471
|
+
sub?.unsubscribe();
|
|
472
|
+
resolve();
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
// Reconcile shortly after T, bounded by its OWN explicit budget (not a second full `deadlineMs`):
|
|
476
|
+
// a never-settling read is `unavailable`, an unreadable registry `failed-precondition`.
|
|
477
|
+
let current;
|
|
478
|
+
let reconcileTimer;
|
|
479
|
+
try {
|
|
480
|
+
current = await Promise.race([
|
|
481
|
+
opts.reconcileRegistration(),
|
|
482
|
+
new Promise((_, reject) => { reconcileTimer = setTimeout(() => reject(new EpEnvelopeError("unavailable", `the scatter registration reconcile did not settle within its ${reconcileDeadlineMs}ms bound (SPEC 13.5: deadline mandatory, never a hung scatter)`)), reconcileDeadlineMs); }),
|
|
483
|
+
]);
|
|
484
|
+
}
|
|
485
|
+
catch (e) {
|
|
486
|
+
if (e instanceof EpEnvelopeError && e.code === "unavailable")
|
|
487
|
+
throw e; // the reconcile bound
|
|
488
|
+
throw new EpEnvelopeError("failed-precondition", `the scatter registration reconcile is unreadable; an unreadable registry is failed-precondition, never an empty success (SPEC 13.5): ${failMsg(e)}`);
|
|
489
|
+
}
|
|
490
|
+
finally {
|
|
491
|
+
if (reconcileTimer !== undefined)
|
|
492
|
+
clearTimeout(reconcileTimer);
|
|
493
|
+
}
|
|
494
|
+
// COMPLETENESS + MONOTONICITY: the mandatory reconcile must return an EXPLICIT verdict for every
|
|
495
|
+
// frozen slot, else a partial/buggy read would silently preserve the old full-triple over-claim.
|
|
496
|
+
// An ABSENT Map entry is an incomplete read (fail-loud) — distinct from an explicit deregistration
|
|
497
|
+
// verdict. A still-registered slot's revision below-frozen is non-monotonic (revisions only advance
|
|
498
|
+
// on mediated registration writes, §13.7), a NaN/non-integer one is garbled: both fail-loud. An
|
|
499
|
+
// advanced revision is registration-churn (drops the counted reply). An explicit deregistration is
|
|
500
|
+
// NOT churn: a valid reply the instance already gave still counts, and if it never replied its slot
|
|
501
|
+
// falls to `missing` below.
|
|
502
|
+
for (const [instanceId, slot] of frozen) {
|
|
503
|
+
const state = current.get(instanceId);
|
|
504
|
+
if (state === undefined)
|
|
505
|
+
throw new EpEnvelopeError("failed-precondition", `the reconcile returned no verdict for frozen instance ${instanceId}; an incomplete registration read cannot authorize completion, and an absent Map entry is NOT an implicit deregistration (SPEC 13.5)`);
|
|
506
|
+
// RUNTIME-validate the discriminant at this untrusted boundary (TS alone cannot fence a
|
|
507
|
+
// caller-supplied/legacy hook): the verdict MUST be an explicit `{ registered: boolean }`. A bare
|
|
508
|
+
// number, `{}`, or `{ registered: 0 }` must FAIL LOUD, never fall through the falsy check below as
|
|
509
|
+
// an implicit deregistration and bypass the completeness fence the typed result exists to enforce.
|
|
510
|
+
if (typeof state !== "object" || state === null || typeof state.registered !== "boolean")
|
|
511
|
+
throw new EpEnvelopeError("failed-precondition", `the reconcile verdict for instance ${instanceId} is not a typed { registered: boolean } state; an untyped/legacy value must never masquerade as a deregistration (SPEC 13.5)`);
|
|
512
|
+
if (state.registered === false)
|
|
513
|
+
continue; // explicit mid-scatter deregistration: not churn; a prior reply still counts
|
|
514
|
+
const now = state.registrationRevision;
|
|
515
|
+
if (!Number.isSafeInteger(now) || now <= 0)
|
|
516
|
+
throw new EpEnvelopeError("failed-precondition", `the reconcile reports instance ${instanceId} at a non-integer/non-positive registrationRevision ${now}; a NaN or garbled value is neither below nor above the frozen revision and would silently disable the monotonicity fence (§13.7), so it is refused, never a counted completion`);
|
|
517
|
+
if (now < slot.registrationRevision)
|
|
518
|
+
throw new EpEnvelopeError("failed-precondition", `the reconcile reports instance ${instanceId} at registrationRevision ${now}, below its frozen ${slot.registrationRevision}; registration revisions are monotonic (§13.7), so a lower value is a buggy/unreadable read`);
|
|
519
|
+
if (now > slot.registrationRevision) {
|
|
520
|
+
result.replies.delete(instanceId);
|
|
521
|
+
result.churn.push({ instanceId, epoch: slot.epoch, reason: "registration" });
|
|
522
|
+
regChurned.add(instanceId);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
await drainDone; // let the absolute late window fully elapse (observational) before finalizing
|
|
526
|
+
}
|
|
527
|
+
finally {
|
|
528
|
+
if (drainTimer !== undefined)
|
|
529
|
+
clearTimeout(drainTimer);
|
|
530
|
+
sub?.unsubscribe();
|
|
531
|
+
}
|
|
532
|
+
const respondedT = respondedAtDeadline ?? responded;
|
|
533
|
+
for (const instanceId of frozen.keys())
|
|
534
|
+
if (!respondedT.has(instanceId) && !regChurned.has(instanceId))
|
|
535
|
+
result.missing.push(instanceId);
|
|
536
|
+
// Coverage completion: every frozen slot has a counted valid reply, none reg-churned (drops
|
|
537
|
+
// replies.size), no missing, and NO observed invalid frame (fail-loud: an invalid is not clean).
|
|
538
|
+
result.complete = result.missing.length === 0 && result.invalid.length === 0 && result.replies.size === frozen.size;
|
|
539
|
+
return result;
|
|
540
|
+
}
|
|
541
|
+
// ---- the registry-wired caller entry points (§13.5) ---------------------------------------------
|
|
542
|
+
/**
|
|
543
|
+
* Scatter one command to the LIVE class (§13.5), registry-wired end to end: freeze the expected
|
|
544
|
+
* set from the service registry, publish once on the `all` rail, and reconcile registration
|
|
545
|
+
* currency post-T — the full §13.5 sequence behind one call. `jsm` drives the LEADER-served
|
|
546
|
+
* coordinate reads (the freeze's per-slot spec/status and the reconcile), `kv` the bounded-lag
|
|
547
|
+
* instance enumeration; every freeze/reconcile refusal (`failed-precondition` on an empty or
|
|
548
|
+
* unreadable registry, `internal` on malformed mediated-writer state) and every gather
|
|
549
|
+
* classification passes through unchanged. The hooks stay public: a caller composing its own
|
|
550
|
+
* freeze (a pinned set, a test harness) uses {@link epScatter} directly.
|
|
551
|
+
*/
|
|
552
|
+
export async function epScatterService(nc, jsm, kv, space, op, opts) {
|
|
553
|
+
// ONE ABSOLUTE deadline covers the whole op (distsys BLOCKING 2): the freeze (kv.keys enumeration
|
|
554
|
+
// + per-slot leader reads) is charged against `deadlineMs`, not run unbounded before it. A freeze
|
|
555
|
+
// that never settles is `deadline-exceeded`, never a scatter that silently overruns its budget,
|
|
556
|
+
// and the gather runs on the REMAINING budget.
|
|
557
|
+
const deadlineMs = assertDeadline(opts.deadlineMs);
|
|
558
|
+
const started = Date.now();
|
|
559
|
+
const expected = await raceBounded(() => freezeExpectedSet(jsm, kv, space, op.endpoint), deadlineMs, `the scatter freeze for ${op.endpoint}`);
|
|
560
|
+
const remaining = deadlineMs - (Date.now() - started);
|
|
561
|
+
if (remaining <= 0)
|
|
562
|
+
throw new EpEnvelopeError("deadline-exceeded", `the scatter freeze for ${op.endpoint} consumed the whole ${deadlineMs}ms budget; no time left to gather (SPEC 13.5)`);
|
|
563
|
+
return epScatter(nc, space, op, { ...opts, deadlineMs: remaining, expected, reconcileRegistration: registrationReconciler(jsm, space, op.endpoint, expected) });
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Call one command with the registry-wired currency check (§13.2): on the `one` rail the queue
|
|
567
|
+
* winner's epoch is verified against a LEADER-served read of its `svc….status` through
|
|
568
|
+
* {@link serviceEpochReader}; the `inst` rail pins its incarnation up front and needs no read, so
|
|
569
|
+
* the hook is not wired there. Every {@link epCall} refusal passes through unchanged (a superseded
|
|
570
|
+
* winner is `expired`; an unregistered or never-converged responder is the read's own
|
|
571
|
+
* `failed-precondition`, never mislabeled staleness).
|
|
572
|
+
*/
|
|
573
|
+
export async function epCallService(nc, jsm, space, route, op, opts) {
|
|
574
|
+
return epCall(nc, space, route, op, route.mode === "one" ? { ...opts, currentEpoch: serviceEpochReader(jsm, space, op.endpoint) } : opts);
|
|
575
|
+
}
|
|
576
|
+
//# sourceMappingURL=endpoint-verbs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoint-verbs.js","sourceRoot":"","sources":["../src/endpoint-verbs.ts"],"names":[],"mappings":"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"}
|