@adonis-agora/durable 0.47.0 → 0.49.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/CHANGELOG.md +55 -0
- package/dist/assets/spa/assets/index-6nmSTfT7.css +1 -0
- package/dist/assets/spa/assets/index-DdB9zxuX.js +16 -0
- package/dist/assets/spa/assets/index-DdB9zxuX.js.map +1 -0
- package/dist/assets/spa/index.html +2 -2
- package/dist/configure.d.ts.map +1 -1
- package/dist/configure.js +1 -0
- package/dist/configure.js.map +1 -1
- package/dist/providers/dashboard_provider.d.ts +3 -1
- package/dist/providers/dashboard_provider.d.ts.map +1 -1
- package/dist/providers/dashboard_provider.js +7 -2
- package/dist/providers/dashboard_provider.js.map +1 -1
- package/dist/providers/durable_provider.d.ts +0 -25
- package/dist/providers/durable_provider.d.ts.map +1 -1
- package/dist/providers/durable_provider.js +30 -5
- package/dist/providers/durable_provider.js.map +1 -1
- package/dist/src/codec-state-store.d.ts +2 -0
- package/dist/src/codec-state-store.d.ts.map +1 -1
- package/dist/src/codec-state-store.js +6 -0
- package/dist/src/codec-state-store.js.map +1 -1
- package/dist/src/completion.d.ts +11 -0
- package/dist/src/completion.d.ts.map +1 -1
- package/dist/src/completion.js +18 -1
- package/dist/src/completion.js.map +1 -1
- package/dist/src/dashboard/gateway-adapter.d.ts.map +1 -1
- package/dist/src/dashboard/gateway-adapter.js +10 -0
- package/dist/src/dashboard/gateway-adapter.js.map +1 -1
- package/dist/src/dashboard/handlers.d.ts +22 -1
- package/dist/src/dashboard/handlers.d.ts.map +1 -1
- package/dist/src/dashboard/handlers.js +63 -10
- package/dist/src/dashboard/handlers.js.map +1 -1
- package/dist/src/dashboard/index.d.ts +1 -1
- package/dist/src/dashboard/index.js +1 -1
- package/dist/src/dashboard/openapi.d.ts.map +1 -1
- package/dist/src/dashboard/openapi.js +26 -2
- package/dist/src/dashboard/openapi.js.map +1 -1
- package/dist/src/define_config.d.ts +6 -0
- package/dist/src/define_config.d.ts.map +1 -1
- package/dist/src/define_config.js.map +1 -1
- package/dist/src/engine.d.ts +89 -3
- package/dist/src/engine.d.ts.map +1 -1
- package/dist/src/engine.js +448 -39
- package/dist/src/engine.js.map +1 -1
- package/dist/src/errors.d.ts +30 -12
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +17 -8
- package/dist/src/errors.js.map +1 -1
- package/dist/src/fan-join.d.ts +36 -6
- package/dist/src/fan-join.d.ts.map +1 -1
- package/dist/src/fan-join.js +63 -8
- package/dist/src/fan-join.js.map +1 -1
- package/dist/src/handshake/announced.d.ts +94 -0
- package/dist/src/handshake/announced.d.ts.map +1 -0
- package/dist/src/handshake/announced.js +113 -0
- package/dist/src/handshake/announced.js.map +1 -0
- package/dist/src/handshake/descriptor.d.ts +59 -0
- package/dist/src/handshake/descriptor.d.ts.map +1 -1
- package/dist/src/handshake/descriptor.js +38 -0
- package/dist/src/handshake/descriptor.js.map +1 -1
- package/dist/src/index.d.ts +6 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/interfaces.d.ts +85 -4
- package/dist/src/interfaces.d.ts.map +1 -1
- package/dist/src/interfaces.js.map +1 -1
- package/dist/src/metrics.d.ts +5 -0
- package/dist/src/metrics.d.ts.map +1 -1
- package/dist/src/metrics.js +14 -1
- package/dist/src/metrics.js.map +1 -1
- package/dist/src/on-error.d.ts +59 -0
- package/dist/src/on-error.d.ts.map +1 -0
- package/dist/src/on-error.js +71 -0
- package/dist/src/on-error.js.map +1 -0
- package/dist/src/otel/durable-metrics.d.ts +6 -0
- package/dist/src/otel/durable-metrics.d.ts.map +1 -1
- package/dist/src/otel/durable-metrics.js +22 -2
- package/dist/src/otel/durable-metrics.js.map +1 -1
- package/dist/src/otel/durable-otel.d.ts.map +1 -1
- package/dist/src/otel/durable-otel.js +15 -0
- package/dist/src/otel/durable-otel.js.map +1 -1
- package/dist/src/protocol.d.ts.map +1 -1
- package/dist/src/protocol.js +1 -0
- package/dist/src/protocol.js.map +1 -1
- package/dist/src/run-detail-summary.d.ts +98 -0
- package/dist/src/run-detail-summary.d.ts.map +1 -0
- package/dist/src/run-detail-summary.js +150 -0
- package/dist/src/run-detail-summary.js.map +1 -0
- package/dist/src/run-gateway/interface.d.ts +11 -0
- package/dist/src/run-gateway/interface.d.ts.map +1 -1
- package/dist/src/run-gateway/proxy-run-gateway.d.ts +3 -0
- package/dist/src/run-gateway/proxy-run-gateway.d.ts.map +1 -1
- package/dist/src/run-gateway/proxy-run-gateway.js +8 -0
- package/dist/src/run-gateway/proxy-run-gateway.js.map +1 -1
- package/dist/src/run-gateway/run-request-responder.d.ts +4 -3
- package/dist/src/run-gateway/run-request-responder.d.ts.map +1 -1
- package/dist/src/run-gateway/run-request-responder.js +23 -3
- package/dist/src/run-gateway/run-request-responder.js.map +1 -1
- package/dist/src/run-gateway/store-run-gateway.d.ts +3 -0
- package/dist/src/run-gateway/store-run-gateway.d.ts.map +1 -1
- package/dist/src/run-gateway/store-run-gateway.js +7 -0
- package/dist/src/run-gateway/store-run-gateway.js.map +1 -1
- package/dist/src/stores/lucid.d.ts +1 -0
- package/dist/src/stores/lucid.d.ts.map +1 -1
- package/dist/src/stores/lucid.js +17 -4
- package/dist/src/stores/lucid.js.map +1 -1
- package/dist/src/testing/in-memory-state-store.d.ts +1 -0
- package/dist/src/testing/in-memory-state-store.d.ts.map +1 -1
- package/dist/src/testing/in-memory-state-store.js +14 -6
- package/dist/src/testing/in-memory-state-store.js.map +1 -1
- package/dist/src/testing-kit/state-store-conformance.d.ts.map +1 -1
- package/dist/src/testing-kit/state-store-conformance.js +59 -0
- package/dist/src/testing-kit/state-store-conformance.js.map +1 -1
- package/dist/src/transports/bullmq/adaptive-concurrency.d.ts +144 -0
- package/dist/src/transports/bullmq/adaptive-concurrency.d.ts.map +1 -0
- package/dist/src/transports/bullmq/adaptive-concurrency.js +312 -0
- package/dist/src/transports/bullmq/adaptive-concurrency.js.map +1 -0
- package/dist/src/transports/bullmq/bullmq-transport.d.ts +18 -1
- package/dist/src/transports/bullmq/bullmq-transport.d.ts.map +1 -1
- package/dist/src/transports/bullmq/bullmq-transport.js +50 -49
- package/dist/src/transports/bullmq/bullmq-transport.js.map +1 -1
- package/dist/src/transports/bullmq/deps.d.ts +11 -1
- package/dist/src/transports/bullmq/deps.d.ts.map +1 -1
- package/dist/src/transports/bullmq/deps.js +12 -1
- package/dist/src/transports/bullmq/deps.js.map +1 -1
- package/dist/src/transports/bullmq/index.d.ts +1 -0
- package/dist/src/transports/bullmq/index.d.ts.map +1 -1
- package/dist/src/transports/bullmq/index.js +1 -0
- package/dist/src/transports/bullmq/index.js.map +1 -1
- package/dist/src/transports/db-schema.d.ts +12 -0
- package/dist/src/transports/db-schema.d.ts.map +1 -1
- package/dist/src/transports/db-schema.js +24 -0
- package/dist/src/transports/db-schema.js.map +1 -1
- package/dist/src/transports/db.d.ts +14 -0
- package/dist/src/transports/db.d.ts.map +1 -1
- package/dist/src/transports/db.js +34 -0
- package/dist/src/transports/db.js.map +1 -1
- package/dist/src/transports/event-emitter.d.ts +8 -0
- package/dist/src/transports/event-emitter.d.ts.map +1 -1
- package/dist/src/transports/event-emitter.js +27 -0
- package/dist/src/transports/event-emitter.js.map +1 -1
- package/dist/src/transports/factory.d.ts +33 -2
- package/dist/src/transports/factory.d.ts.map +1 -1
- package/dist/src/transports/factory.js +29 -1
- package/dist/src/transports/factory.js.map +1 -1
- package/dist/src/transports/queue.d.ts +19 -0
- package/dist/src/transports/queue.d.ts.map +1 -1
- package/dist/src/transports/queue.js +17 -0
- package/dist/src/transports/queue.js.map +1 -1
- package/dist/src/transports/worker-keys-db.d.ts +17 -0
- package/dist/src/transports/worker-keys-db.d.ts.map +1 -0
- package/dist/src/transports/worker-keys-db.js +43 -0
- package/dist/src/transports/worker-keys-db.js.map +1 -0
- package/dist/src/transports/worker-keys.d.ts +56 -0
- package/dist/src/transports/worker-keys.d.ts.map +1 -0
- package/dist/src/transports/worker-keys.js +92 -0
- package/dist/src/transports/worker-keys.js.map +1 -0
- package/dist/src/worker-runtime/index.d.ts +1 -1
- package/dist/src/worker-runtime/index.d.ts.map +1 -1
- package/dist/src/worker-runtime/index.js.map +1 -1
- package/dist/src/worker-runtime/worker-runtime.d.ts +7 -2
- package/dist/src/worker-runtime/worker-runtime.d.ts.map +1 -1
- package/dist/src/worker-runtime/worker-runtime.js +22 -20
- package/dist/src/worker-runtime/worker-runtime.js.map +1 -1
- package/dist/src/workflow-ctx.d.ts +13 -1
- package/dist/src/workflow-ctx.d.ts.map +1 -1
- package/dist/src/workflow-ctx.js +44 -6
- package/dist/src/workflow-ctx.js.map +1 -1
- package/dist/src/workflow-discovery.d.ts.map +1 -1
- package/dist/src/workflow-discovery.js +2 -1
- package/dist/src/workflow-discovery.js.map +1 -1
- package/dist/src/workflow-ref.d.ts +31 -0
- package/dist/src/workflow-ref.d.ts.map +1 -1
- package/dist/src/workflow-ref.js +22 -0
- package/dist/src/workflow-ref.js.map +1 -1
- package/dist/stubs/database/migrations/create_durable_transport_worker_keys.stub +24 -0
- package/package.json +5 -5
- package/skills/durable-cluster/SKILL.md +10 -0
- package/skills/durable-transports-stores/SKILL.md +37 -0
- package/skills/durable-workflows/SKILL.md +22 -1
- package/dist/assets/spa/assets/index-CL6q2kMB.js +0 -16
- package/dist/assets/spa/assets/index-CL6q2kMB.js.map +0 -1
- package/dist/assets/spa/assets/index-DU6cGcJz.css +0 -1
package/dist/src/errors.d.ts
CHANGED
|
@@ -6,7 +6,12 @@ import { CONTROL_FLOW_SIGNAL } from './control-flow-signal.js';
|
|
|
6
6
|
*/
|
|
7
7
|
export declare class FatalError extends Error {
|
|
8
8
|
readonly code?: string | undefined;
|
|
9
|
-
|
|
9
|
+
/** Structured, JSON-serializable detail (e.g. validation issues). It travels with the failure to
|
|
10
|
+
* the run's error, a parent's `allSettled` item and an onError handler's input. */
|
|
11
|
+
readonly details?: unknown;
|
|
12
|
+
/** Read by the step result builders, so a dispatched step's retry policy honours it too. */
|
|
13
|
+
readonly retryable = false;
|
|
14
|
+
constructor(message: string, code?: string, details?: unknown);
|
|
10
15
|
}
|
|
11
16
|
/**
|
|
12
17
|
* Thrown by `start` when a run would exceed its concurrency quota: `active` runs sharing the quota
|
|
@@ -61,6 +66,8 @@ export declare class RemoteStepTimeout extends Error {
|
|
|
61
66
|
* breaking changes (old runs finish on the version they started on).
|
|
62
67
|
*/
|
|
63
68
|
export declare class NonDeterminismError extends Error {
|
|
69
|
+
/** Marks the failure as a broken deploy, which an `onError` route never takes. */
|
|
70
|
+
readonly code = "non_determinism";
|
|
64
71
|
readonly runId: string;
|
|
65
72
|
readonly seq: number;
|
|
66
73
|
constructor(runId: string, seq: number, expected: string, recorded: string);
|
|
@@ -91,17 +98,17 @@ export declare class NestedWorkflowCallError extends FatalError {
|
|
|
91
98
|
* and the failing ids — the wait-all/fail-fast counterpart to a single child's FatalError. Mirrors
|
|
92
99
|
* the Python SDK's `GatherFailed`.
|
|
93
100
|
*/
|
|
101
|
+
/** One failed item of a fan: its input index, the child run id, and its failure. */
|
|
102
|
+
export interface GatherItemFailure {
|
|
103
|
+
index: number;
|
|
104
|
+
id: string;
|
|
105
|
+
error: string;
|
|
106
|
+
code?: string | undefined;
|
|
107
|
+
details?: unknown;
|
|
108
|
+
}
|
|
94
109
|
export declare class GatherError extends Error {
|
|
95
|
-
readonly failures:
|
|
96
|
-
|
|
97
|
-
id: string;
|
|
98
|
-
error: string;
|
|
99
|
-
}[];
|
|
100
|
-
constructor(failures: {
|
|
101
|
-
index: number;
|
|
102
|
-
id: string;
|
|
103
|
-
error: string;
|
|
104
|
-
}[], total?: number);
|
|
110
|
+
readonly failures: GatherItemFailure[];
|
|
111
|
+
constructor(failures: GatherItemFailure[], total?: number);
|
|
105
112
|
}
|
|
106
113
|
export declare class WorkflowSuspended extends Error {
|
|
107
114
|
/** Epoch ms to auto-resume (durable sleep), or undefined when waiting on an external signal. */
|
|
@@ -116,9 +123,20 @@ export declare class WorkflowSuspended extends Error {
|
|
|
116
123
|
readonly waitSeqs?: number[] | undefined;
|
|
117
124
|
/** Set when awaited children are what the run is waiting on — see {@link FanJoin}. */
|
|
118
125
|
readonly fan?: FanJoin | undefined;
|
|
126
|
+
/**
|
|
127
|
+
* The position blocks of the step fans (`ctx.all` over a `@Step`) this suspension waits on. Their
|
|
128
|
+
* steps are deliberately NOT in {@link waitSeqs}: one settled step must not re-drive the run, only
|
|
129
|
+
* a fan with no step left `pending` does.
|
|
130
|
+
*/
|
|
131
|
+
readonly stepFans?: StepFanRange[] | undefined;
|
|
119
132
|
/** Marks this as a control-flow signal — see {@link isWorkflowControlFlowSignal}. */
|
|
120
133
|
readonly [CONTROL_FLOW_SIGNAL] = true;
|
|
121
|
-
constructor(wakeAt?: number, waitSeqs?: number[], fan?: FanJoin);
|
|
134
|
+
constructor(wakeAt?: number, waitSeqs?: number[], fan?: FanJoin, stepFans?: StepFanRange[]);
|
|
135
|
+
}
|
|
136
|
+
/** The seqs `from..to` (inclusive) of one step fan's position block. */
|
|
137
|
+
export interface StepFanRange {
|
|
138
|
+
from: number;
|
|
139
|
+
to: number;
|
|
122
140
|
}
|
|
123
141
|
/**
|
|
124
142
|
* What a run suspended on when it awaits children (`ctx.all`, `ctx.child`). For each group of
|
package/dist/src/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAoC,MAAM,0BAA0B,CAAC;AAEjG;;;;GAIG;AACH,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,YAAY,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/src/errors.js
CHANGED
|
@@ -6,10 +6,16 @@ import { CONTROL_FLOW_SIGNAL } from './control-flow-signal.js';
|
|
|
6
6
|
*/
|
|
7
7
|
export class FatalError extends Error {
|
|
8
8
|
code;
|
|
9
|
-
|
|
9
|
+
/** Structured, JSON-serializable detail (e.g. validation issues). It travels with the failure to
|
|
10
|
+
* the run's error, a parent's `allSettled` item and an onError handler's input. */
|
|
11
|
+
details;
|
|
12
|
+
/** Read by the step result builders, so a dispatched step's retry policy honours it too. */
|
|
13
|
+
retryable = false;
|
|
14
|
+
constructor(message, code, details) {
|
|
10
15
|
super(message);
|
|
11
16
|
this.name = 'FatalError';
|
|
12
17
|
this.code = code;
|
|
18
|
+
this.details = details;
|
|
13
19
|
}
|
|
14
20
|
}
|
|
15
21
|
/**
|
|
@@ -88,6 +94,8 @@ export class RemoteStepTimeout extends Error {
|
|
|
88
94
|
* breaking changes (old runs finish on the version they started on).
|
|
89
95
|
*/
|
|
90
96
|
export class NonDeterminismError extends Error {
|
|
97
|
+
/** Marks the failure as a broken deploy, which an `onError` route never takes. */
|
|
98
|
+
code = 'non_determinism';
|
|
91
99
|
runId;
|
|
92
100
|
seq;
|
|
93
101
|
constructor(runId, seq, expected, recorded) {
|
|
@@ -124,12 +132,6 @@ export class NestedWorkflowCallError extends FatalError {
|
|
|
124
132
|
this.step = step;
|
|
125
133
|
}
|
|
126
134
|
}
|
|
127
|
-
/**
|
|
128
|
-
* Thrown by `ctx.all` when one or more parallel child workflows fail. Carries the per-item failures
|
|
129
|
-
* (input index, child run id, error message) and presents an aggregate message summarizing the count
|
|
130
|
-
* and the failing ids — the wait-all/fail-fast counterpart to a single child's FatalError. Mirrors
|
|
131
|
-
* the Python SDK's `GatherFailed`.
|
|
132
|
-
*/
|
|
133
135
|
export class GatherError extends Error {
|
|
134
136
|
failures;
|
|
135
137
|
constructor(failures, total) {
|
|
@@ -153,14 +155,21 @@ export class WorkflowSuspended extends Error {
|
|
|
153
155
|
waitSeqs;
|
|
154
156
|
/** Set when awaited children are what the run is waiting on — see {@link FanJoin}. */
|
|
155
157
|
fan;
|
|
158
|
+
/**
|
|
159
|
+
* The position blocks of the step fans (`ctx.all` over a `@Step`) this suspension waits on. Their
|
|
160
|
+
* steps are deliberately NOT in {@link waitSeqs}: one settled step must not re-drive the run, only
|
|
161
|
+
* a fan with no step left `pending` does.
|
|
162
|
+
*/
|
|
163
|
+
stepFans;
|
|
156
164
|
/** Marks this as a control-flow signal — see {@link isWorkflowControlFlowSignal}. */
|
|
157
165
|
[CONTROL_FLOW_SIGNAL] = true;
|
|
158
|
-
constructor(wakeAt, waitSeqs, fan) {
|
|
166
|
+
constructor(wakeAt, waitSeqs, fan, stepFans) {
|
|
159
167
|
super('workflow suspended');
|
|
160
168
|
this.name = 'WorkflowSuspended';
|
|
161
169
|
this.wakeAt = wakeAt;
|
|
162
170
|
this.waitSeqs = waitSeqs;
|
|
163
171
|
this.fan = fan;
|
|
172
|
+
this.stepFans = stepFans;
|
|
164
173
|
}
|
|
165
174
|
}
|
|
166
175
|
/**
|
package/dist/src/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAoC,MAAM,0BAA0B,CAAC;AAEjG;;;;GAIG;AACH,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,IAAI,CAAsB;IACnC,YAAY,OAAe,EAAE,IAAa;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/src/fan-join.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FanJoin, FanWait } from './errors.js';
|
|
2
|
-
import type { SignalWaiter } from './interfaces.js';
|
|
2
|
+
import type { SignalWaiter, StepCheckpoint } from './interfaces.js';
|
|
3
3
|
/**
|
|
4
4
|
* Naming shared by `ctx.all` (which mints the ids) and the engine's join barrier (which reads them
|
|
5
5
|
* back off a settling child's waiter). The child id and group are replay anchors: changing either
|
|
@@ -10,8 +10,32 @@ import type { SignalWaiter } from './interfaces.js';
|
|
|
10
10
|
* can wait on one wave at a time.
|
|
11
11
|
*/
|
|
12
12
|
export declare function allChildId(runId: string, firstSeq: number, index: number, wave?: number): string;
|
|
13
|
-
/**
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* The fan's `parallelGroup`: its first seq, its size (so a view can count the children not started
|
|
15
|
+
* yet), and a failFast mark so the barrier wakes it on the first failure.
|
|
16
|
+
*/
|
|
17
|
+
export declare function allGroup(firstSeq: number, size: number, mode: 'waitAll' | 'failFast'): string;
|
|
18
|
+
/**
|
|
19
|
+
* The `parallelGroup` of a step fan (`ctx.all` over a `@Step`). It carries the fan's position block,
|
|
20
|
+
* so the engine's join barrier can tell from any one step's checkpoint which steps it waits on.
|
|
21
|
+
*/
|
|
22
|
+
export declare function stepFanGroup(firstSeq: number, size: number, mode: 'waitAll' | 'failFast'): string;
|
|
23
|
+
/** The position block a {@link stepFanGroup} names, or undefined for any other group. */
|
|
24
|
+
export declare function parseStepFanGroup(group: string | undefined): {
|
|
25
|
+
firstSeq: number;
|
|
26
|
+
size: number;
|
|
27
|
+
} | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* What a fan's `parallelGroup` says about it: a child fan (`all:<seq>[:n<size>][:failFast]`) or a
|
|
30
|
+
* step fan (`steps:<seq>:<size>[:failFast]`). `size` is absent on a child fan dispatched before the
|
|
31
|
+
* group carried it.
|
|
32
|
+
*/
|
|
33
|
+
export declare function parseFanGroup(group: string | undefined): {
|
|
34
|
+
kind: 'all' | 'steps';
|
|
35
|
+
firstSeq: number;
|
|
36
|
+
size?: number | undefined;
|
|
37
|
+
failFast: boolean;
|
|
38
|
+
} | undefined;
|
|
15
39
|
/** The waiter and checkpoint name prefixes shared by a fan's children, or one wave's. */
|
|
16
40
|
export declare function allWait(runId: string, firstSeq: number, wave?: number): FanWait;
|
|
17
41
|
export declare function fanJoin(waits: FanWait[]): FanJoin;
|
|
@@ -43,9 +67,10 @@ export declare function allWaves(size: number, concurrency: number | undefined):
|
|
|
43
67
|
} | undefined;
|
|
44
68
|
/**
|
|
45
69
|
* The parent of a child run whose id the engine minted: a `ctx.all` child
|
|
46
|
-
* (`<parent>.all.<seq>.<i>`, or `.w<k>.<i>` under a `concurrency` limit)
|
|
47
|
-
* `ctx.startChild` child without an explicit id (`<parent>.child.<seq>`)
|
|
48
|
-
* run, including a child started with a
|
|
70
|
+
* (`<parent>.all.<seq>.<i>`, or `.w<k>.<i>` under a `concurrency` limit), a `ctx.child` /
|
|
71
|
+
* `ctx.startChild` child without an explicit id (`<parent>.child.<seq>`), or the onError handler of
|
|
72
|
+
* a failed run (`<parent>.onError.<attempt>`). Undefined for any other run, including a child started with a
|
|
73
|
+
* caller-chosen id.
|
|
49
74
|
*/
|
|
50
75
|
export declare function parentRunIdOf(runId: string): string | undefined;
|
|
51
76
|
/**
|
|
@@ -58,4 +83,9 @@ export declare function fanOfWaiter(waiter: SignalWaiter): {
|
|
|
58
83
|
waiterPrefix: string;
|
|
59
84
|
failFast: boolean;
|
|
60
85
|
} | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* The child run ids a parent's child-edge checkpoints point at: an awaited child
|
|
88
|
+
* (`signal:child:<id>`), a folded group of them, a spawn (`spawn:`). Other checkpoints are skipped.
|
|
89
|
+
*/
|
|
90
|
+
export declare function childIdsOf(checkpoints: StepCheckpoint[]): string[];
|
|
61
91
|
//# sourceMappingURL=fan-join.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fan-join.d.ts","sourceRoot":"","sources":["../../src/fan-join.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"fan-join.d.ts","sourceRoot":"","sources":["../../src/fan-join.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEpE;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhG;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAG7F;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAGjG;AAED,yFAAyF;AACzF,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAIhD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,GAAG,SAAS,GAEvB;IAAE,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GACzF,SAAS,CAUZ;AAED,yFAAyF;AACzF,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAG/E;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAEjD;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,SAAS,CAAC;AAEpC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,EAAE,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAEpF;AAED,wDAAwD;AACxD,wBAAgB,cAAc,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,EAAE,CAMvF;AAMD;;;;;GAKG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAUpD;AAID;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE/D;AAMD;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,YAAY,GACnB;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CASzD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CAQlE"}
|
package/dist/src/fan-join.js
CHANGED
|
@@ -10,9 +10,46 @@
|
|
|
10
10
|
export function allChildId(runId, firstSeq, index, wave) {
|
|
11
11
|
return `${allBase(runId, firstSeq, wave)}${index}`;
|
|
12
12
|
}
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
/**
|
|
14
|
+
* The fan's `parallelGroup`: its first seq, its size (so a view can count the children not started
|
|
15
|
+
* yet), and a failFast mark so the barrier wakes it on the first failure.
|
|
16
|
+
*/
|
|
17
|
+
export function allGroup(firstSeq, size, mode) {
|
|
18
|
+
const group = `all:${firstSeq}:n${size}`;
|
|
19
|
+
return mode === 'failFast' ? `${group}:failFast` : group;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The `parallelGroup` of a step fan (`ctx.all` over a `@Step`). It carries the fan's position block,
|
|
23
|
+
* so the engine's join barrier can tell from any one step's checkpoint which steps it waits on.
|
|
24
|
+
*/
|
|
25
|
+
export function stepFanGroup(firstSeq, size, mode) {
|
|
26
|
+
const group = `steps:${firstSeq}:${size}`;
|
|
27
|
+
return mode === 'failFast' ? `${group}:failFast` : group;
|
|
28
|
+
}
|
|
29
|
+
/** The position block a {@link stepFanGroup} names, or undefined for any other group. */
|
|
30
|
+
export function parseStepFanGroup(group) {
|
|
31
|
+
const fan = parseFanGroup(group);
|
|
32
|
+
if (fan?.kind !== 'steps' || fan.size === undefined)
|
|
33
|
+
return undefined;
|
|
34
|
+
return { firstSeq: fan.firstSeq, size: fan.size };
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* What a fan's `parallelGroup` says about it: a child fan (`all:<seq>[:n<size>][:failFast]`) or a
|
|
38
|
+
* step fan (`steps:<seq>:<size>[:failFast]`). `size` is absent on a child fan dispatched before the
|
|
39
|
+
* group carried it.
|
|
40
|
+
*/
|
|
41
|
+
export function parseFanGroup(group) {
|
|
42
|
+
const m = group ? /^(all|steps):(\d+)(?::n?(\d+))?(:failFast)?$/.exec(group) : null;
|
|
43
|
+
if (!m)
|
|
44
|
+
return undefined;
|
|
45
|
+
if (m[1] === 'steps' && m[3] === undefined)
|
|
46
|
+
return undefined;
|
|
47
|
+
return {
|
|
48
|
+
kind: m[1],
|
|
49
|
+
firstSeq: Number(m[2]),
|
|
50
|
+
size: m[3] === undefined ? undefined : Number(m[3]),
|
|
51
|
+
failFast: m[4] !== undefined,
|
|
52
|
+
};
|
|
16
53
|
}
|
|
17
54
|
/** The waiter and checkpoint name prefixes shared by a fan's children, or one wave's. */
|
|
18
55
|
export function allWait(runId, firstSeq, wave) {
|
|
@@ -63,17 +100,19 @@ export function allWaves(size, concurrency) {
|
|
|
63
100
|
return { waveSize: 1, maxWaves: 1 };
|
|
64
101
|
return { waveSize: Math.floor(concurrency / 2), maxWaves: 2 };
|
|
65
102
|
}
|
|
66
|
-
const ENGINE_CHILD_ID = /^(.+)\.(?:all\.\d+\.(?:w\d+\.)?\d+|child\.\d+)$/;
|
|
103
|
+
const ENGINE_CHILD_ID = /^(.+)\.(?:all\.\d+\.(?:w\d+\.)?\d+|child\.\d+|onError\.\d+)$/;
|
|
67
104
|
/**
|
|
68
105
|
* The parent of a child run whose id the engine minted: a `ctx.all` child
|
|
69
|
-
* (`<parent>.all.<seq>.<i>`, or `.w<k>.<i>` under a `concurrency` limit)
|
|
70
|
-
* `ctx.startChild` child without an explicit id (`<parent>.child.<seq>`)
|
|
71
|
-
* run, including a child started with a
|
|
106
|
+
* (`<parent>.all.<seq>.<i>`, or `.w<k>.<i>` under a `concurrency` limit), a `ctx.child` /
|
|
107
|
+
* `ctx.startChild` child without an explicit id (`<parent>.child.<seq>`), or the onError handler of
|
|
108
|
+
* a failed run (`<parent>.onError.<attempt>`). Undefined for any other run, including a child started with a
|
|
109
|
+
* caller-chosen id.
|
|
72
110
|
*/
|
|
73
111
|
export function parentRunIdOf(runId) {
|
|
74
112
|
return ENGINE_CHILD_ID.exec(runId)?.[1];
|
|
75
113
|
}
|
|
76
|
-
|
|
114
|
+
// A waiter stored before the group carried the fan's size has no `:n<size>` segment.
|
|
115
|
+
const GROUP = /^all:(\d+)(?::n\d+)?(:failFast)?$/;
|
|
77
116
|
const REST = /^(?:w(\d+)\.)?\d+$/;
|
|
78
117
|
/**
|
|
79
118
|
* The `ctx.all` fan (or, for a fan with a `concurrency` limit, the wave) a waiter belongs to, or
|
|
@@ -94,4 +133,20 @@ export function fanOfWaiter(waiter) {
|
|
|
94
133
|
const waiterPrefix = rest[1] === undefined ? base : `${base}w${rest[1]}.`;
|
|
95
134
|
return { waiterPrefix, failFast: group[2] !== undefined };
|
|
96
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* The child run ids a parent's child-edge checkpoints point at: an awaited child
|
|
138
|
+
* (`signal:child:<id>`), a folded group of them, a spawn (`spawn:`). Other checkpoints are skipped.
|
|
139
|
+
*/
|
|
140
|
+
export function childIdsOf(checkpoints) {
|
|
141
|
+
const ids = [];
|
|
142
|
+
for (const cp of checkpoints) {
|
|
143
|
+
if (cp.name.startsWith('signal:child:'))
|
|
144
|
+
ids.push(cp.name.slice('signal:child:'.length));
|
|
145
|
+
if (cp.name.startsWith(FOLDED_PREFIX))
|
|
146
|
+
ids.push(...foldedChildIds(cp));
|
|
147
|
+
if (cp.name.startsWith('spawn:') && typeof cp.output === 'string')
|
|
148
|
+
ids.push(cp.output);
|
|
149
|
+
}
|
|
150
|
+
return ids;
|
|
151
|
+
}
|
|
97
152
|
//# sourceMappingURL=fan-join.js.map
|
package/dist/src/fan-join.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fan-join.js","sourceRoot":"","sources":["../../src/fan-join.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,QAAgB,EAAE,KAAa,EAAE,IAAa;IACtF,OAAO,GAAG,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC;AACrD,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"fan-join.js","sourceRoot":"","sources":["../../src/fan-join.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The announced workflow registry (design §7.9) — the aggregate answer to "what workflows exist in
|
|
3
|
+
* this deployment?", built ONLY from what live workers say about themselves: each worker publishes
|
|
4
|
+
* what it can execute ({@link WorkerDescriptor.registrations}, or bare `workflows` names), and this
|
|
5
|
+
* module folds those statements together. Every entry is a fact somebody asserted, and the aggregate
|
|
6
|
+
* is the same on every pod because every pod reads the same published statements. Pure data, no I/O.
|
|
7
|
+
*/
|
|
8
|
+
import type { RawWorkerDescriptor, WorkerDescriptor, WorkflowRegistration } from './descriptor.js';
|
|
9
|
+
/** One live worker's claim about one workflow: the registration plus who announced it. */
|
|
10
|
+
export interface WorkflowAnnouncement extends WorkflowRegistration {
|
|
11
|
+
/** The announcing worker's instance id. */
|
|
12
|
+
instanceId: string;
|
|
13
|
+
/** The announcing worker's runtime — how a Python-served workflow is told from a Node-served one. */
|
|
14
|
+
runtime: 'node' | 'python';
|
|
15
|
+
}
|
|
16
|
+
/** An axis on which the live announcers of one workflow do not agree. `values` holds every distinct
|
|
17
|
+
* DECLARED value (sorted); an announcer that stated nothing on the axis contributes nothing. */
|
|
18
|
+
export interface Disagreement {
|
|
19
|
+
axis: 'group' | 'origin' | 'requires' | 'onError';
|
|
20
|
+
values: string[];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* How strong the fleet's claim about a workflow is. The two tiers are NOT interchangeable and a
|
|
24
|
+
* caller must not read them as the same fact:
|
|
25
|
+
*
|
|
26
|
+
* - `'declared'` — at least one live worker published a descriptor naming this workflow. Everything
|
|
27
|
+
* populated on the entry was STATED by that worker; everything absent it declined to state.
|
|
28
|
+
* - `'observed'` — nobody described it. What exists is a live routing token of this name, which is
|
|
29
|
+
* precisely the condition `resolveRemoteByConvention` uses to route a call, so the name IS
|
|
30
|
+
* reachable. Nothing else is known: no version, no origin, no runtime, and no assurance that the
|
|
31
|
+
* worker consuming that token serves a WORKFLOW there rather than a step handler of the same name.
|
|
32
|
+
* An entry like this is a live queue, not a promise.
|
|
33
|
+
*/
|
|
34
|
+
export type AnnouncementEvidence = 'declared' | 'observed';
|
|
35
|
+
/** One workflow the live fleet announces, folded across every worker that announced it. */
|
|
36
|
+
export interface AnnouncedWorkflow {
|
|
37
|
+
/** What kind of claim this entry rests on — see {@link AnnouncementEvidence}. A caller that shows
|
|
38
|
+
* a version, an origin or a runtime must check this first: an `'observed'` entry has none of
|
|
39
|
+
* them, and the emptiness is a fact about the fleet, not a rendering gap. */
|
|
40
|
+
evidence: AnnouncementEvidence;
|
|
41
|
+
/** `name@version`, or the bare `name` when no announcer stated a version. Stable sort key. */
|
|
42
|
+
key: string;
|
|
43
|
+
name: string;
|
|
44
|
+
/** Absent when no announcer stated one — never inferred from another announcer's version. */
|
|
45
|
+
version?: string;
|
|
46
|
+
/** Every distinct routing group announced (sorted). Empty = nobody stated one. On an `'observed'`
|
|
47
|
+
* entry this is the token the heartbeat was published UNDER — not a claim by anybody, but the
|
|
48
|
+
* queue a call would actually land on, which is the one thing an observation does establish. */
|
|
49
|
+
groups: string[];
|
|
50
|
+
/** Every distinct declaring package announced (sorted). Empty = nobody stated one. */
|
|
51
|
+
origins: string[];
|
|
52
|
+
/** Every distinct capability demand announced, each de-duplicated + sorted. Empty = nobody stated
|
|
53
|
+
* one. Two entries here means two workers demand different capabilities for the same version. */
|
|
54
|
+
requires: string[][];
|
|
55
|
+
/** Every distinct set of `onError` routes announced, each in canonical order. Empty = nobody stated
|
|
56
|
+
* one. Two entries here means the live workers route this workflow's failures differently. */
|
|
57
|
+
onError: {
|
|
58
|
+
code?: string;
|
|
59
|
+
workflow: string;
|
|
60
|
+
}[][];
|
|
61
|
+
/** Runtimes of the live announcers (sorted, de-duplicated). EMPTY on an `'observed'` entry: a
|
|
62
|
+
* heartbeat does not say what runtime wrote it, and the instance id's shape is a convention, not
|
|
63
|
+
* a statement, so it is not read as one. */
|
|
64
|
+
runtimes: ('node' | 'python')[];
|
|
65
|
+
/** Instance ids of the live workers announcing it (sorted, de-duplicated). Its length is how many
|
|
66
|
+
* workers can currently run this workflow — `1` is a single point of failure, and it is never 0
|
|
67
|
+
* (an entry exists only because somebody announced it, or because somebody is beating on it). */
|
|
68
|
+
instances: string[];
|
|
69
|
+
/** The axes the announcers differ on, empty when they speak with one voice. A caller that must
|
|
70
|
+
* pick a single target has to resolve these itself — the registry refuses to guess. */
|
|
71
|
+
disagreements: Disagreement[];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* What one descriptor announces. `registrations` is authoritative when present; any `workflows` name
|
|
75
|
+
* it does not cover is still announced as a bare, unversioned claim, so a worker that describes some
|
|
76
|
+
* of its workflows richly and others by name alone is reported in full rather than in part.
|
|
77
|
+
*
|
|
78
|
+
* A descriptor with neither field announces nothing — including the control plane's own descriptor,
|
|
79
|
+
* which is a router, not an executor.
|
|
80
|
+
*/
|
|
81
|
+
export declare function announcementsOf(raw: RawWorkerDescriptor | WorkerDescriptor): WorkflowAnnouncement[];
|
|
82
|
+
/**
|
|
83
|
+
* Fold every live descriptor's announcements into one entry per `name@version`, sorted by key.
|
|
84
|
+
*
|
|
85
|
+
* Pure: it holds nothing and caches nothing, so no pod ever carries a growing table of the fleet's
|
|
86
|
+
* registrations — the caller reads the live descriptors it already knows how to read, folds them
|
|
87
|
+
* here, and drops the result. The work is O(descriptors × announcements) per call, on demand.
|
|
88
|
+
*
|
|
89
|
+
* The same instance announcing the same workflow twice (a worker publishes its descriptor under
|
|
90
|
+
* every routing token it consumes, so the same bytes arrive several times) folds to ONE announcer:
|
|
91
|
+
* `instances` is a set, so it counts workers, not keys.
|
|
92
|
+
*/
|
|
93
|
+
export declare function aggregateAnnouncements(descriptors: readonly (RawWorkerDescriptor | WorkerDescriptor)[]): AnnouncedWorkflow[];
|
|
94
|
+
//# sourceMappingURL=announced.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"announced.d.ts","sourceRoot":"","sources":["../../../src/handshake/announced.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAGnG,0FAA0F;AAC1F,MAAM,WAAW,oBAAqB,SAAQ,oBAAoB;IAChE,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,qGAAqG;IACrG,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC5B;AAED;iGACiG;AACjG,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;IAClD,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG,UAAU,CAAC;AAE3D,2FAA2F;AAC3F,MAAM,WAAW,iBAAiB;IAChC;;kFAE8E;IAC9E,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,8FAA8F;IAC9F,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,6FAA6F;IAC7F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;qGAEiG;IACjG,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,sFAAsF;IACtF,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;sGACkG;IAClG,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC;IACrB;mGAC+F;IAC/F,OAAO,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,EAAE,CAAC;IACjD;;iDAE6C;IAC7C,QAAQ,EAAE,CAAC,MAAM,GAAG,QAAQ,CAAC,EAAE,CAAC;IAChC;;sGAEkG;IAClG,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB;4FACwF;IACxF,aAAa,EAAE,YAAY,EAAE,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,mBAAmB,GAAG,gBAAgB,GAC1C,oBAAoB,EAAE,CASxB;AAYD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,SAAS,CAAC,mBAAmB,GAAG,gBAAgB,CAAC,EAAE,GAC/D,iBAAiB,EAAE,CAkErB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The announced workflow registry (design §7.9) — the aggregate answer to "what workflows exist in
|
|
3
|
+
* this deployment?", built ONLY from what live workers say about themselves: each worker publishes
|
|
4
|
+
* what it can execute ({@link WorkerDescriptor.registrations}, or bare `workflows` names), and this
|
|
5
|
+
* module folds those statements together. Every entry is a fact somebody asserted, and the aggregate
|
|
6
|
+
* is the same on every pod because every pod reads the same published statements. Pure data, no I/O.
|
|
7
|
+
*/
|
|
8
|
+
import { canonicalRoutes, normalizeDescriptor } from './descriptor.js';
|
|
9
|
+
/**
|
|
10
|
+
* What one descriptor announces. `registrations` is authoritative when present; any `workflows` name
|
|
11
|
+
* it does not cover is still announced as a bare, unversioned claim, so a worker that describes some
|
|
12
|
+
* of its workflows richly and others by name alone is reported in full rather than in part.
|
|
13
|
+
*
|
|
14
|
+
* A descriptor with neither field announces nothing — including the control plane's own descriptor,
|
|
15
|
+
* which is a router, not an executor.
|
|
16
|
+
*/
|
|
17
|
+
export function announcementsOf(raw) {
|
|
18
|
+
const d = normalizeDescriptor(raw);
|
|
19
|
+
const identity = { instanceId: d.instanceId, runtime: d.runtime };
|
|
20
|
+
const announcements = (d.registrations ?? []).map((reg) => ({ ...reg, ...identity }));
|
|
21
|
+
const covered = new Set(announcements.map((a) => a.name));
|
|
22
|
+
for (const name of d.workflows) {
|
|
23
|
+
if (!covered.has(name))
|
|
24
|
+
announcements.push({ name, ...identity });
|
|
25
|
+
}
|
|
26
|
+
return announcements;
|
|
27
|
+
}
|
|
28
|
+
/** `name@version`, or the bare name when unversioned — the identity two announcements are folded on. */
|
|
29
|
+
function announcementKey(a) {
|
|
30
|
+
return a.version === undefined ? a.name : `${a.name}@${a.version}`;
|
|
31
|
+
}
|
|
32
|
+
/** Sorted, de-duplicated members of `values`, dropping the un-stated ones. */
|
|
33
|
+
function stated(values) {
|
|
34
|
+
return [...new Set(values.filter((v) => v !== undefined))].sort();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Fold every live descriptor's announcements into one entry per `name@version`, sorted by key.
|
|
38
|
+
*
|
|
39
|
+
* Pure: it holds nothing and caches nothing, so no pod ever carries a growing table of the fleet's
|
|
40
|
+
* registrations — the caller reads the live descriptors it already knows how to read, folds them
|
|
41
|
+
* here, and drops the result. The work is O(descriptors × announcements) per call, on demand.
|
|
42
|
+
*
|
|
43
|
+
* The same instance announcing the same workflow twice (a worker publishes its descriptor under
|
|
44
|
+
* every routing token it consumes, so the same bytes arrive several times) folds to ONE announcer:
|
|
45
|
+
* `instances` is a set, so it counts workers, not keys.
|
|
46
|
+
*/
|
|
47
|
+
export function aggregateAnnouncements(descriptors) {
|
|
48
|
+
const byKey = new Map();
|
|
49
|
+
for (const descriptor of descriptors) {
|
|
50
|
+
for (const announcement of announcementsOf(descriptor)) {
|
|
51
|
+
const key = announcementKey(announcement);
|
|
52
|
+
const bucket = byKey.get(key);
|
|
53
|
+
if (bucket)
|
|
54
|
+
bucket.push(announcement);
|
|
55
|
+
else
|
|
56
|
+
byKey.set(key, [announcement]);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const out = [];
|
|
60
|
+
for (const [key, announcements] of byKey) {
|
|
61
|
+
const groups = stated(announcements.map((a) => a.group));
|
|
62
|
+
const origins = stated(announcements.map((a) => a.origin));
|
|
63
|
+
// A capability demand is a SET, so it is compared as its canonical (sorted, de-duplicated) form:
|
|
64
|
+
// two workers demanding ['saga','signals'] and ['signals','saga'] agree, and must not be reported
|
|
65
|
+
// as a disagreement over the same demand written two ways.
|
|
66
|
+
const requiresByJson = new Map();
|
|
67
|
+
for (const a of announcements) {
|
|
68
|
+
if (a.requires === undefined)
|
|
69
|
+
continue;
|
|
70
|
+
const canonical = [...new Set(a.requires)].sort();
|
|
71
|
+
requiresByJson.set(JSON.stringify(canonical), canonical);
|
|
72
|
+
}
|
|
73
|
+
// Ordered by the same rendering `disagreements` uses, so the two lists read in step.
|
|
74
|
+
const requires = [...requiresByJson.values()].sort((x, y) => x.join(',').localeCompare(y.join(',')));
|
|
75
|
+
const routesByJson = new Map();
|
|
76
|
+
for (const a of announcements) {
|
|
77
|
+
if (a.onError === undefined)
|
|
78
|
+
continue;
|
|
79
|
+
const canonical = canonicalRoutes(a.onError).map((r) => r.code === null ? { workflow: r.workflow } : { code: r.code, workflow: r.workflow });
|
|
80
|
+
routesByJson.set(JSON.stringify(canonical), canonical);
|
|
81
|
+
}
|
|
82
|
+
const onError = [...routesByJson.keys()].sort().map((k) => routesByJson.get(k) ?? []);
|
|
83
|
+
const disagreements = [];
|
|
84
|
+
if (groups.length > 1)
|
|
85
|
+
disagreements.push({ axis: 'group', values: groups });
|
|
86
|
+
if (origins.length > 1)
|
|
87
|
+
disagreements.push({ axis: 'origin', values: origins });
|
|
88
|
+
if (requires.length > 1) {
|
|
89
|
+
disagreements.push({ axis: 'requires', values: requires.map((r) => r.join(',')) });
|
|
90
|
+
}
|
|
91
|
+
if (onError.length > 1) {
|
|
92
|
+
disagreements.push({ axis: 'onError', values: [...routesByJson.keys()].sort() });
|
|
93
|
+
}
|
|
94
|
+
const first = announcements[0];
|
|
95
|
+
if (!first)
|
|
96
|
+
continue;
|
|
97
|
+
out.push({
|
|
98
|
+
evidence: 'declared',
|
|
99
|
+
key,
|
|
100
|
+
name: first.name,
|
|
101
|
+
...(first.version !== undefined ? { version: first.version } : {}),
|
|
102
|
+
groups,
|
|
103
|
+
origins,
|
|
104
|
+
requires,
|
|
105
|
+
onError,
|
|
106
|
+
runtimes: [...new Set(announcements.map((a) => a.runtime))].sort(),
|
|
107
|
+
instances: [...new Set(announcements.map((a) => a.instanceId))].sort(),
|
|
108
|
+
disagreements,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
return out.sort((a, b) => a.key.localeCompare(b.key));
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=announced.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"announced.js","sourceRoot":"","sources":["../../../src/handshake/announced.ts"],"names":[],"mappings":"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"}
|