@voltro/workflow 0.69.1 → 0.71.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 +1369 -111
- package/dist/cluster-BRSoL1tb.js +489 -0
- package/dist/cluster.d.ts +598 -7
- package/dist/cluster.js +2 -2
- package/dist/clusterDiagnostics-jpkNVay6.js +379 -0
- package/dist/clusterTestSuite.js +4 -4
- package/dist/index.d.ts +1063 -95
- package/dist/index.js +4 -4
- package/dist/{primitives-CqHxfASq.js → primitives-DsMsMr5S.js} +141 -122
- package/dist/primitives.js +2 -2
- package/dist/src-OEBqLBJl.js +4842 -0
- package/package.json +4 -4
- package/dist/cluster-DoLWW-cp.js +0 -309
- package/dist/clusterDiagnostics-CNtl5LX9.js +0 -20
- package/dist/src-TRpoU54e.js +0 -2666
package/dist/cluster.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ConfigError } from 'effect';
|
|
2
2
|
import { Context } from 'effect';
|
|
3
3
|
import { Cron } from 'effect';
|
|
4
|
+
import { DataStore } from '@voltro/database';
|
|
4
5
|
import { Duration } from 'effect';
|
|
5
6
|
import { Effect } from 'effect';
|
|
6
7
|
import { Layer } from 'effect';
|
|
@@ -8,6 +9,7 @@ import { MessageStorage } from '@effect/cluster';
|
|
|
8
9
|
import { Sharding } from '@effect/cluster';
|
|
9
10
|
import { SqlClient } from '@effect/sql';
|
|
10
11
|
import { SqlError } from '@effect/sql';
|
|
12
|
+
import { SqlError as SqlError_2 } from '@effect/sql/SqlError';
|
|
11
13
|
import { Workflow } from '@effect/workflow';
|
|
12
14
|
import { WorkflowEngine } from '@effect/workflow';
|
|
13
15
|
|
|
@@ -20,6 +22,251 @@ import { WorkflowEngine } from '@effect/workflow';
|
|
|
20
22
|
*/
|
|
21
23
|
export declare const activityPrimaryKey: (activityName: string, attempt: number) => string;
|
|
22
24
|
|
|
25
|
+
/** Database-only capture while holding the resident admission/entry lock.
|
|
26
|
+
* observe reads the journal; it must never wake/reset the engine. Missing
|
|
27
|
+
* journal evidence waits without inventing a binding. After commit, every
|
|
28
|
+
* dispatch uses this immutable observation, including after a lost ACK. */
|
|
29
|
+
declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: string, observe: (target: {
|
|
30
|
+
readonly workflowName: string;
|
|
31
|
+
readonly executionId: string;
|
|
32
|
+
readonly requestId: string;
|
|
33
|
+
readonly restartToken: string | null;
|
|
34
|
+
}) => Promise<unknown>) => Promise<{
|
|
35
|
+
kind: "settled";
|
|
36
|
+
request: {
|
|
37
|
+
readonly id: string;
|
|
38
|
+
readonly cause?: {
|
|
39
|
+
readonly detail?: {
|
|
40
|
+
readonly [x: string]: unknown;
|
|
41
|
+
} | undefined;
|
|
42
|
+
readonly reason: string;
|
|
43
|
+
} | null | undefined;
|
|
44
|
+
readonly result: {
|
|
45
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
46
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
47
|
+
readonly errorMessage: string | null;
|
|
48
|
+
readonly output: unknown;
|
|
49
|
+
readonly errorTag: string | null;
|
|
50
|
+
readonly completedAt: number;
|
|
51
|
+
} | {
|
|
52
|
+
readonly status: "running";
|
|
53
|
+
readonly kind: "confirmed";
|
|
54
|
+
readonly generation: string;
|
|
55
|
+
readonly enteredAt: number;
|
|
56
|
+
} | null;
|
|
57
|
+
readonly requestedAt: number;
|
|
58
|
+
readonly executionId: string;
|
|
59
|
+
readonly runId: string;
|
|
60
|
+
readonly workflowName: string;
|
|
61
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
62
|
+
readonly generation: string;
|
|
63
|
+
readonly owner: {
|
|
64
|
+
readonly tenantId: string | null;
|
|
65
|
+
} | null;
|
|
66
|
+
readonly resumeJournal: {
|
|
67
|
+
readonly requestId: string;
|
|
68
|
+
readonly replyId: string;
|
|
69
|
+
readonly restartToken: string | null;
|
|
70
|
+
} | null;
|
|
71
|
+
readonly dispatchAttempts: number;
|
|
72
|
+
};
|
|
73
|
+
} | {
|
|
74
|
+
kind: "unknown";
|
|
75
|
+
request: {
|
|
76
|
+
readonly id: string;
|
|
77
|
+
readonly cause?: {
|
|
78
|
+
readonly detail?: {
|
|
79
|
+
readonly [x: string]: unknown;
|
|
80
|
+
} | undefined;
|
|
81
|
+
readonly reason: string;
|
|
82
|
+
} | null | undefined;
|
|
83
|
+
readonly result: {
|
|
84
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
85
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
86
|
+
readonly errorMessage: string | null;
|
|
87
|
+
readonly output: unknown;
|
|
88
|
+
readonly errorTag: string | null;
|
|
89
|
+
readonly completedAt: number;
|
|
90
|
+
} | {
|
|
91
|
+
readonly status: "running";
|
|
92
|
+
readonly kind: "confirmed";
|
|
93
|
+
readonly generation: string;
|
|
94
|
+
readonly enteredAt: number;
|
|
95
|
+
} | null;
|
|
96
|
+
readonly requestedAt: number;
|
|
97
|
+
readonly executionId: string;
|
|
98
|
+
readonly runId: string;
|
|
99
|
+
readonly workflowName: string;
|
|
100
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
101
|
+
readonly generation: string;
|
|
102
|
+
readonly owner: {
|
|
103
|
+
readonly tenantId: string | null;
|
|
104
|
+
} | null;
|
|
105
|
+
readonly resumeJournal: {
|
|
106
|
+
readonly requestId: string;
|
|
107
|
+
readonly replyId: string;
|
|
108
|
+
readonly restartToken: string | null;
|
|
109
|
+
} | null;
|
|
110
|
+
readonly dispatchAttempts: number;
|
|
111
|
+
};
|
|
112
|
+
} | {
|
|
113
|
+
kind: "superseded";
|
|
114
|
+
request: {
|
|
115
|
+
readonly id: string;
|
|
116
|
+
readonly cause?: {
|
|
117
|
+
readonly detail?: {
|
|
118
|
+
readonly [x: string]: unknown;
|
|
119
|
+
} | undefined;
|
|
120
|
+
readonly reason: string;
|
|
121
|
+
} | null | undefined;
|
|
122
|
+
readonly result: {
|
|
123
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
124
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
125
|
+
readonly errorMessage: string | null;
|
|
126
|
+
readonly output: unknown;
|
|
127
|
+
readonly errorTag: string | null;
|
|
128
|
+
readonly completedAt: number;
|
|
129
|
+
} | {
|
|
130
|
+
readonly status: "running";
|
|
131
|
+
readonly kind: "confirmed";
|
|
132
|
+
readonly generation: string;
|
|
133
|
+
readonly enteredAt: number;
|
|
134
|
+
} | null;
|
|
135
|
+
readonly requestedAt: number;
|
|
136
|
+
readonly executionId: string;
|
|
137
|
+
readonly runId: string;
|
|
138
|
+
readonly workflowName: string;
|
|
139
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
140
|
+
readonly generation: string;
|
|
141
|
+
readonly owner: {
|
|
142
|
+
readonly tenantId: string | null;
|
|
143
|
+
} | null;
|
|
144
|
+
readonly resumeJournal: {
|
|
145
|
+
readonly requestId: string;
|
|
146
|
+
readonly replyId: string;
|
|
147
|
+
readonly restartToken: string | null;
|
|
148
|
+
} | null;
|
|
149
|
+
readonly dispatchAttempts: number;
|
|
150
|
+
};
|
|
151
|
+
} | {
|
|
152
|
+
kind: "not-suspended";
|
|
153
|
+
request: {
|
|
154
|
+
readonly id: string;
|
|
155
|
+
readonly cause?: {
|
|
156
|
+
readonly detail?: {
|
|
157
|
+
readonly [x: string]: unknown;
|
|
158
|
+
} | undefined;
|
|
159
|
+
readonly reason: string;
|
|
160
|
+
} | null | undefined;
|
|
161
|
+
readonly result: {
|
|
162
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
163
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
164
|
+
readonly errorMessage: string | null;
|
|
165
|
+
readonly output: unknown;
|
|
166
|
+
readonly errorTag: string | null;
|
|
167
|
+
readonly completedAt: number;
|
|
168
|
+
} | {
|
|
169
|
+
readonly status: "running";
|
|
170
|
+
readonly kind: "confirmed";
|
|
171
|
+
readonly generation: string;
|
|
172
|
+
readonly enteredAt: number;
|
|
173
|
+
} | null;
|
|
174
|
+
readonly requestedAt: number;
|
|
175
|
+
readonly executionId: string;
|
|
176
|
+
readonly runId: string;
|
|
177
|
+
readonly workflowName: string;
|
|
178
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
179
|
+
readonly generation: string;
|
|
180
|
+
readonly owner: {
|
|
181
|
+
readonly tenantId: string | null;
|
|
182
|
+
} | null;
|
|
183
|
+
readonly resumeJournal: {
|
|
184
|
+
readonly requestId: string;
|
|
185
|
+
readonly replyId: string;
|
|
186
|
+
readonly restartToken: string | null;
|
|
187
|
+
} | null;
|
|
188
|
+
readonly dispatchAttempts: number;
|
|
189
|
+
};
|
|
190
|
+
} | {
|
|
191
|
+
kind: "bound";
|
|
192
|
+
request: {
|
|
193
|
+
readonly id: string;
|
|
194
|
+
readonly cause?: {
|
|
195
|
+
readonly detail?: {
|
|
196
|
+
readonly [x: string]: unknown;
|
|
197
|
+
} | undefined;
|
|
198
|
+
readonly reason: string;
|
|
199
|
+
} | null | undefined;
|
|
200
|
+
readonly result: {
|
|
201
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
202
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
203
|
+
readonly errorMessage: string | null;
|
|
204
|
+
readonly output: unknown;
|
|
205
|
+
readonly errorTag: string | null;
|
|
206
|
+
readonly completedAt: number;
|
|
207
|
+
} | {
|
|
208
|
+
readonly status: "running";
|
|
209
|
+
readonly kind: "confirmed";
|
|
210
|
+
readonly generation: string;
|
|
211
|
+
readonly enteredAt: number;
|
|
212
|
+
} | null;
|
|
213
|
+
readonly requestedAt: number;
|
|
214
|
+
readonly executionId: string;
|
|
215
|
+
readonly runId: string;
|
|
216
|
+
readonly workflowName: string;
|
|
217
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
218
|
+
readonly generation: string;
|
|
219
|
+
readonly owner: {
|
|
220
|
+
readonly tenantId: string | null;
|
|
221
|
+
} | null;
|
|
222
|
+
readonly resumeJournal: {
|
|
223
|
+
readonly requestId: string;
|
|
224
|
+
readonly replyId: string;
|
|
225
|
+
readonly restartToken: string | null;
|
|
226
|
+
} | null;
|
|
227
|
+
readonly dispatchAttempts: number;
|
|
228
|
+
};
|
|
229
|
+
} | {
|
|
230
|
+
kind: "waiting-journal";
|
|
231
|
+
request: {
|
|
232
|
+
readonly id: string;
|
|
233
|
+
readonly cause?: {
|
|
234
|
+
readonly detail?: {
|
|
235
|
+
readonly [x: string]: unknown;
|
|
236
|
+
} | undefined;
|
|
237
|
+
readonly reason: string;
|
|
238
|
+
} | null | undefined;
|
|
239
|
+
readonly result: {
|
|
240
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
241
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
242
|
+
readonly errorMessage: string | null;
|
|
243
|
+
readonly output: unknown;
|
|
244
|
+
readonly errorTag: string | null;
|
|
245
|
+
readonly completedAt: number;
|
|
246
|
+
} | {
|
|
247
|
+
readonly status: "running";
|
|
248
|
+
readonly kind: "confirmed";
|
|
249
|
+
readonly generation: string;
|
|
250
|
+
readonly enteredAt: number;
|
|
251
|
+
} | null;
|
|
252
|
+
readonly requestedAt: number;
|
|
253
|
+
readonly executionId: string;
|
|
254
|
+
readonly runId: string;
|
|
255
|
+
readonly workflowName: string;
|
|
256
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
257
|
+
readonly generation: string;
|
|
258
|
+
readonly owner: {
|
|
259
|
+
readonly tenantId: string | null;
|
|
260
|
+
} | null;
|
|
261
|
+
readonly resumeJournal: {
|
|
262
|
+
readonly requestId: string;
|
|
263
|
+
readonly replyId: string;
|
|
264
|
+
readonly restartToken: string | null;
|
|
265
|
+
} | null;
|
|
266
|
+
readonly dispatchAttempts: number;
|
|
267
|
+
};
|
|
268
|
+
}>;
|
|
269
|
+
|
|
23
270
|
export declare interface ClusterCronSpec {
|
|
24
271
|
/** Stable schedule name — used as the cluster cron's identity. */
|
|
25
272
|
readonly name: string;
|
|
@@ -54,6 +301,25 @@ declare interface ClusterDiagnosticsOps {
|
|
|
54
301
|
readonly shardLockHolders: (shardIds: ReadonlyArray<string>) => Effect.Effect<ReadonlyArray<ShardLockHolder>>;
|
|
55
302
|
/** The runner table — every address that registered, with its heartbeat. */
|
|
56
303
|
readonly runners: () => Effect.Effect<ReadonlyArray<ClusterRunner>>;
|
|
304
|
+
/**
|
|
305
|
+
* Delete the unprocessed messages addressed to one entity — the ONE write on
|
|
306
|
+
* this service. A run that ended outside the engine (cancelled by a sweep or
|
|
307
|
+
* an operator, parked as failed) leaves its unanswered requests behind: the
|
|
308
|
+
* `activity` a killed executor never replied to, the `run` itself if it was
|
|
309
|
+
* never processed. Every runner that acquires the shard re-reads them for the
|
|
310
|
+
* re-read window, forever, and an `activity` request for a run that does not
|
|
311
|
+
* execute waits on a latch that never opens. Nothing consumes them; deleting
|
|
312
|
+
* is what the engine's own reset does for one request. Returns how many.
|
|
313
|
+
*
|
|
314
|
+
* `unreadForMs`: only messages a runner last read at least this long ago —
|
|
315
|
+
* the guard for the sweep, which must not take a request an operator's
|
|
316
|
+
* redrive cleared a moment ago and a runner has just re-read.
|
|
317
|
+
*/
|
|
318
|
+
readonly discardMessages: (input: {
|
|
319
|
+
readonly entityType: string;
|
|
320
|
+
readonly entityId: string;
|
|
321
|
+
readonly unreadForMs?: number;
|
|
322
|
+
}) => Effect.Effect<number>;
|
|
57
323
|
}
|
|
58
324
|
|
|
59
325
|
export declare interface ClusterDiagnosticsOptions {
|
|
@@ -63,6 +329,14 @@ export declare interface ClusterDiagnosticsOptions {
|
|
|
63
329
|
readonly dialectId?: string | undefined;
|
|
64
330
|
/** Shard groups in configured order — the advisory lock base per group. */
|
|
65
331
|
readonly shardGroups?: ReadonlyArray<string>;
|
|
332
|
+
/**
|
|
333
|
+
* Does THIS runner hold the shard — `Sharding.hasShardId`, the engine's own
|
|
334
|
+
* account. This is what `own` on a holder means; without it every holder is
|
|
335
|
+
* a stranger. Not read from the database on purpose: the lock session's pid
|
|
336
|
+
* is not the pid of any query this service can make, and behind a pooler
|
|
337
|
+
* every session shares one client address and one application name.
|
|
338
|
+
*/
|
|
339
|
+
readonly hasShard?: (shardId: string) => boolean;
|
|
66
340
|
}
|
|
67
341
|
|
|
68
342
|
declare interface ClusterMessageState {
|
|
@@ -81,6 +355,8 @@ declare interface ClusterRunner {
|
|
|
81
355
|
readonly healthy: boolean;
|
|
82
356
|
}
|
|
83
357
|
|
|
358
|
+
declare type ControlStore = Parameters<typeof bindWorkflowResumeJournalInTransaction>[0];
|
|
359
|
+
|
|
84
360
|
/** Default port for the cluster's single-runner listener. Override per deploy. */
|
|
85
361
|
export declare const DEFAULT_RUNNER_LISTEN_PORT: 34000;
|
|
86
362
|
|
|
@@ -92,6 +368,301 @@ export declare const DEFAULT_RUNNER_LISTEN_PORT: 34000;
|
|
|
92
368
|
* somehow can't be probed can still force `VOLTRO_WORKFLOW_SHARD_LOCK=row`. */
|
|
93
369
|
export declare const detectWsrepCluster: Effect.Effect<boolean, never, SqlClient.SqlClient>;
|
|
94
370
|
|
|
371
|
+
/** Internal cluster dispatch, not an acceptance or completion API. The host
|
|
372
|
+
* supplies the resident admission transaction and the matching journal layer.
|
|
373
|
+
* Only the recorder's next entry can confirm the persisted resume receipt. */
|
|
374
|
+
declare const dispatchWorkflowResume: (options: {
|
|
375
|
+
readonly requestId: string;
|
|
376
|
+
readonly transaction: <A>(work: (tx: ControlStore) => Promise<A>) => Promise<A>;
|
|
377
|
+
}) => Effect.Effect<{
|
|
378
|
+
kind: "settled";
|
|
379
|
+
request: {
|
|
380
|
+
readonly id: string;
|
|
381
|
+
readonly cause?: {
|
|
382
|
+
readonly detail?: {
|
|
383
|
+
readonly [x: string]: unknown;
|
|
384
|
+
} | undefined;
|
|
385
|
+
readonly reason: string;
|
|
386
|
+
} | null | undefined;
|
|
387
|
+
readonly result: {
|
|
388
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
389
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
390
|
+
readonly errorMessage: string | null;
|
|
391
|
+
readonly output: unknown;
|
|
392
|
+
readonly errorTag: string | null;
|
|
393
|
+
readonly completedAt: number;
|
|
394
|
+
} | {
|
|
395
|
+
readonly status: "running";
|
|
396
|
+
readonly kind: "confirmed";
|
|
397
|
+
readonly generation: string;
|
|
398
|
+
readonly enteredAt: number;
|
|
399
|
+
} | null;
|
|
400
|
+
readonly requestedAt: number;
|
|
401
|
+
readonly executionId: string;
|
|
402
|
+
readonly runId: string;
|
|
403
|
+
readonly workflowName: string;
|
|
404
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
405
|
+
readonly generation: string;
|
|
406
|
+
readonly owner: {
|
|
407
|
+
readonly tenantId: string | null;
|
|
408
|
+
} | null;
|
|
409
|
+
readonly resumeJournal: {
|
|
410
|
+
readonly requestId: string;
|
|
411
|
+
readonly replyId: string;
|
|
412
|
+
readonly restartToken: string | null;
|
|
413
|
+
} | null;
|
|
414
|
+
readonly dispatchAttempts: number;
|
|
415
|
+
};
|
|
416
|
+
} | {
|
|
417
|
+
kind: "unknown";
|
|
418
|
+
request: {
|
|
419
|
+
readonly id: string;
|
|
420
|
+
readonly cause?: {
|
|
421
|
+
readonly detail?: {
|
|
422
|
+
readonly [x: string]: unknown;
|
|
423
|
+
} | undefined;
|
|
424
|
+
readonly reason: string;
|
|
425
|
+
} | null | undefined;
|
|
426
|
+
readonly result: {
|
|
427
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
428
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
429
|
+
readonly errorMessage: string | null;
|
|
430
|
+
readonly output: unknown;
|
|
431
|
+
readonly errorTag: string | null;
|
|
432
|
+
readonly completedAt: number;
|
|
433
|
+
} | {
|
|
434
|
+
readonly status: "running";
|
|
435
|
+
readonly kind: "confirmed";
|
|
436
|
+
readonly generation: string;
|
|
437
|
+
readonly enteredAt: number;
|
|
438
|
+
} | null;
|
|
439
|
+
readonly requestedAt: number;
|
|
440
|
+
readonly executionId: string;
|
|
441
|
+
readonly runId: string;
|
|
442
|
+
readonly workflowName: string;
|
|
443
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
444
|
+
readonly generation: string;
|
|
445
|
+
readonly owner: {
|
|
446
|
+
readonly tenantId: string | null;
|
|
447
|
+
} | null;
|
|
448
|
+
readonly resumeJournal: {
|
|
449
|
+
readonly requestId: string;
|
|
450
|
+
readonly replyId: string;
|
|
451
|
+
readonly restartToken: string | null;
|
|
452
|
+
} | null;
|
|
453
|
+
readonly dispatchAttempts: number;
|
|
454
|
+
};
|
|
455
|
+
} | {
|
|
456
|
+
kind: "superseded";
|
|
457
|
+
request: {
|
|
458
|
+
readonly id: string;
|
|
459
|
+
readonly cause?: {
|
|
460
|
+
readonly detail?: {
|
|
461
|
+
readonly [x: string]: unknown;
|
|
462
|
+
} | undefined;
|
|
463
|
+
readonly reason: string;
|
|
464
|
+
} | null | undefined;
|
|
465
|
+
readonly result: {
|
|
466
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
467
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
468
|
+
readonly errorMessage: string | null;
|
|
469
|
+
readonly output: unknown;
|
|
470
|
+
readonly errorTag: string | null;
|
|
471
|
+
readonly completedAt: number;
|
|
472
|
+
} | {
|
|
473
|
+
readonly status: "running";
|
|
474
|
+
readonly kind: "confirmed";
|
|
475
|
+
readonly generation: string;
|
|
476
|
+
readonly enteredAt: number;
|
|
477
|
+
} | null;
|
|
478
|
+
readonly requestedAt: number;
|
|
479
|
+
readonly executionId: string;
|
|
480
|
+
readonly runId: string;
|
|
481
|
+
readonly workflowName: string;
|
|
482
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
483
|
+
readonly generation: string;
|
|
484
|
+
readonly owner: {
|
|
485
|
+
readonly tenantId: string | null;
|
|
486
|
+
} | null;
|
|
487
|
+
readonly resumeJournal: {
|
|
488
|
+
readonly requestId: string;
|
|
489
|
+
readonly replyId: string;
|
|
490
|
+
readonly restartToken: string | null;
|
|
491
|
+
} | null;
|
|
492
|
+
readonly dispatchAttempts: number;
|
|
493
|
+
};
|
|
494
|
+
} | {
|
|
495
|
+
kind: "not-suspended";
|
|
496
|
+
request: {
|
|
497
|
+
readonly id: string;
|
|
498
|
+
readonly cause?: {
|
|
499
|
+
readonly detail?: {
|
|
500
|
+
readonly [x: string]: unknown;
|
|
501
|
+
} | undefined;
|
|
502
|
+
readonly reason: string;
|
|
503
|
+
} | null | undefined;
|
|
504
|
+
readonly result: {
|
|
505
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
506
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
507
|
+
readonly errorMessage: string | null;
|
|
508
|
+
readonly output: unknown;
|
|
509
|
+
readonly errorTag: string | null;
|
|
510
|
+
readonly completedAt: number;
|
|
511
|
+
} | {
|
|
512
|
+
readonly status: "running";
|
|
513
|
+
readonly kind: "confirmed";
|
|
514
|
+
readonly generation: string;
|
|
515
|
+
readonly enteredAt: number;
|
|
516
|
+
} | null;
|
|
517
|
+
readonly requestedAt: number;
|
|
518
|
+
readonly executionId: string;
|
|
519
|
+
readonly runId: string;
|
|
520
|
+
readonly workflowName: string;
|
|
521
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
522
|
+
readonly generation: string;
|
|
523
|
+
readonly owner: {
|
|
524
|
+
readonly tenantId: string | null;
|
|
525
|
+
} | null;
|
|
526
|
+
readonly resumeJournal: {
|
|
527
|
+
readonly requestId: string;
|
|
528
|
+
readonly replyId: string;
|
|
529
|
+
readonly restartToken: string | null;
|
|
530
|
+
} | null;
|
|
531
|
+
readonly dispatchAttempts: number;
|
|
532
|
+
};
|
|
533
|
+
} | {
|
|
534
|
+
kind: "waiting-journal";
|
|
535
|
+
request: {
|
|
536
|
+
readonly id: string;
|
|
537
|
+
readonly cause?: {
|
|
538
|
+
readonly detail?: {
|
|
539
|
+
readonly [x: string]: unknown;
|
|
540
|
+
} | undefined;
|
|
541
|
+
readonly reason: string;
|
|
542
|
+
} | null | undefined;
|
|
543
|
+
readonly result: {
|
|
544
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
545
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
546
|
+
readonly errorMessage: string | null;
|
|
547
|
+
readonly output: unknown;
|
|
548
|
+
readonly errorTag: string | null;
|
|
549
|
+
readonly completedAt: number;
|
|
550
|
+
} | {
|
|
551
|
+
readonly status: "running";
|
|
552
|
+
readonly kind: "confirmed";
|
|
553
|
+
readonly generation: string;
|
|
554
|
+
readonly enteredAt: number;
|
|
555
|
+
} | null;
|
|
556
|
+
readonly requestedAt: number;
|
|
557
|
+
readonly executionId: string;
|
|
558
|
+
readonly runId: string;
|
|
559
|
+
readonly workflowName: string;
|
|
560
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
561
|
+
readonly generation: string;
|
|
562
|
+
readonly owner: {
|
|
563
|
+
readonly tenantId: string | null;
|
|
564
|
+
} | null;
|
|
565
|
+
readonly resumeJournal: {
|
|
566
|
+
readonly requestId: string;
|
|
567
|
+
readonly replyId: string;
|
|
568
|
+
readonly restartToken: string | null;
|
|
569
|
+
} | null;
|
|
570
|
+
readonly dispatchAttempts: number;
|
|
571
|
+
};
|
|
572
|
+
} | {
|
|
573
|
+
kind: "already-terminal";
|
|
574
|
+
request: {
|
|
575
|
+
readonly id: string;
|
|
576
|
+
readonly cause?: {
|
|
577
|
+
readonly detail?: {
|
|
578
|
+
readonly [x: string]: unknown;
|
|
579
|
+
} | undefined;
|
|
580
|
+
readonly reason: string;
|
|
581
|
+
} | null | undefined;
|
|
582
|
+
readonly result: {
|
|
583
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
584
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
585
|
+
readonly errorMessage: string | null;
|
|
586
|
+
readonly output: unknown;
|
|
587
|
+
readonly errorTag: string | null;
|
|
588
|
+
readonly completedAt: number;
|
|
589
|
+
} | {
|
|
590
|
+
readonly status: "running";
|
|
591
|
+
readonly kind: "confirmed";
|
|
592
|
+
readonly generation: string;
|
|
593
|
+
readonly enteredAt: number;
|
|
594
|
+
} | null;
|
|
595
|
+
readonly requestedAt: number;
|
|
596
|
+
readonly executionId: string;
|
|
597
|
+
readonly runId: string;
|
|
598
|
+
readonly workflowName: string;
|
|
599
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
600
|
+
readonly generation: string;
|
|
601
|
+
readonly owner: {
|
|
602
|
+
readonly tenantId: string | null;
|
|
603
|
+
} | null;
|
|
604
|
+
readonly resumeJournal: {
|
|
605
|
+
readonly requestId: string;
|
|
606
|
+
readonly replyId: string;
|
|
607
|
+
readonly restartToken: string | null;
|
|
608
|
+
} | null;
|
|
609
|
+
readonly dispatchAttempts: number;
|
|
610
|
+
};
|
|
611
|
+
run: Readonly<Record<string, unknown>>;
|
|
612
|
+
} | {
|
|
613
|
+
kind: "attempted";
|
|
614
|
+
request: {
|
|
615
|
+
dispatchAttempts: number;
|
|
616
|
+
id: string;
|
|
617
|
+
cause?: {
|
|
618
|
+
readonly detail?: {
|
|
619
|
+
readonly [x: string]: unknown;
|
|
620
|
+
} | undefined;
|
|
621
|
+
readonly reason: string;
|
|
622
|
+
} | null | undefined;
|
|
623
|
+
result: {
|
|
624
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
625
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
626
|
+
readonly errorMessage: string | null;
|
|
627
|
+
readonly output: unknown;
|
|
628
|
+
readonly errorTag: string | null;
|
|
629
|
+
readonly completedAt: number;
|
|
630
|
+
} | {
|
|
631
|
+
readonly status: "running";
|
|
632
|
+
readonly kind: "confirmed";
|
|
633
|
+
readonly generation: string;
|
|
634
|
+
readonly enteredAt: number;
|
|
635
|
+
} | null;
|
|
636
|
+
requestedAt: number;
|
|
637
|
+
executionId: string;
|
|
638
|
+
runId: string;
|
|
639
|
+
workflowName: string;
|
|
640
|
+
operation: "resume" | "cancel" | "terminate";
|
|
641
|
+
generation: string;
|
|
642
|
+
owner: {
|
|
643
|
+
readonly tenantId: string | null;
|
|
644
|
+
} | null;
|
|
645
|
+
resumeJournal: {
|
|
646
|
+
readonly requestId: string;
|
|
647
|
+
readonly replyId: string;
|
|
648
|
+
readonly restartToken: string | null;
|
|
649
|
+
} | null;
|
|
650
|
+
};
|
|
651
|
+
journal: {
|
|
652
|
+
kind: "changed";
|
|
653
|
+
requestId: string;
|
|
654
|
+
count?: never;
|
|
655
|
+
} | {
|
|
656
|
+
kind: "already-reset";
|
|
657
|
+
count: number;
|
|
658
|
+
requestId?: never;
|
|
659
|
+
} | {
|
|
660
|
+
kind: "reset";
|
|
661
|
+
count: number;
|
|
662
|
+
requestId?: never;
|
|
663
|
+
};
|
|
664
|
+
}, SqlError_2, SqlClient.SqlClient | Sharding.Sharding>;
|
|
665
|
+
|
|
95
666
|
/** A step attempt to reset so it re-executes on the next drive. */
|
|
96
667
|
export declare interface FailedActivityRef {
|
|
97
668
|
readonly name: string;
|
|
@@ -144,16 +715,18 @@ export declare const redriveFailedRun: (target: RedriveTarget) => Effect.Effect<
|
|
|
144
715
|
export declare interface RedriveOutcome {
|
|
145
716
|
/** True iff the `run` reply was cleared and storage re-polled. */
|
|
146
717
|
readonly redriven: boolean;
|
|
147
|
-
/** True
|
|
718
|
+
/** True when clearing the terminal run reply was confirmed. False does not
|
|
719
|
+
* prove no write occurred when reason is run-reset-unconfirmed. */
|
|
148
720
|
readonly runReplyCleared: boolean;
|
|
149
721
|
/** How many failed activity replies were cleared (so they re-execute). */
|
|
150
722
|
readonly activitiesReset: number;
|
|
151
723
|
/** Set when `redriven` is false. */
|
|
152
|
-
readonly reason:
|
|
724
|
+
readonly reason: RedriveReason | null;
|
|
153
725
|
}
|
|
154
726
|
|
|
155
|
-
/** Why a
|
|
156
|
-
|
|
727
|
+
/** Why a replay was not confirmed. Reset failures can follow partial changes;
|
|
728
|
+
* they are not proof that the journal was left untouched. */
|
|
729
|
+
export declare type RedriveReason =
|
|
157
730
|
/** No `run` request found in the cluster journal — a memory engine, or
|
|
158
731
|
* a run that was never durably journaled. Nothing to re-drive. */
|
|
159
732
|
'no-journal'
|
|
@@ -162,7 +735,7 @@ export declare type RedriveSkipReason =
|
|
|
162
735
|
| 'no-reply'
|
|
163
736
|
/** The stored reply is a SUCCESS — the run completed cleanly. Nothing
|
|
164
737
|
* to re-drive; refuse rather than resurrect a finished run. */
|
|
165
|
-
| 'succeeded';
|
|
738
|
+
| 'succeeded' | 'suspended' | 'unrecognized-reply' | 'activity-not-found' | 'activity-reset-unconfirmed' | 'run-reset-unconfirmed';
|
|
166
739
|
|
|
167
740
|
export declare interface RedriveTarget {
|
|
168
741
|
/** The workflow definition — for its `name` (entity type) + `annotations` (shard group). */
|
|
@@ -327,7 +900,14 @@ declare interface ShardLockHolder {
|
|
|
327
900
|
/** Who holds it: `pid <n> from <client>` for a postgres advisory lock, the
|
|
328
901
|
* runner address for a row lease. */
|
|
329
902
|
readonly holder: string;
|
|
330
|
-
/**
|
|
903
|
+
/**
|
|
904
|
+
* `true` when THIS runner holds the shard — the engine's own answer
|
|
905
|
+
* (`Sharding.hasShardId`), never a guess from a connection. The first
|
|
906
|
+
* version compared the holder's pid with `pg_backend_pid()` of the query
|
|
907
|
+
* that asked, and the pool hands every query a different backend than the
|
|
908
|
+
* lock session, so a runner's own 300 locks read as a stranger's — and the
|
|
909
|
+
* report's lever, ending the holder's session, would have ended the runner.
|
|
910
|
+
*/
|
|
331
911
|
readonly own: boolean;
|
|
332
912
|
readonly since: Date | null;
|
|
333
913
|
readonly detail?: Record<string, unknown>;
|
|
@@ -362,12 +942,14 @@ declare interface ShardLockHolder {
|
|
|
362
942
|
*/
|
|
363
943
|
export declare type ShardLockMode = 'auto' | 'row' | 'advisory';
|
|
364
944
|
|
|
945
|
+
declare type Store = Pick<DataStore, 'query' | 'insert' | 'update'>;
|
|
946
|
+
|
|
365
947
|
declare interface UnreadMessage extends ClusterMessageState {
|
|
366
948
|
/** How long ago the last runner read it. */
|
|
367
949
|
readonly unreadForMs: number;
|
|
368
950
|
}
|
|
369
951
|
|
|
370
|
-
export declare const workflowEngineLayer: (options: WorkflowEngineLayerOptions) => Layer.Layer<WorkflowEngine.WorkflowEngine | Sharding.Sharding | MessageStorage.MessageStorage | ClusterDiagnostics>;
|
|
952
|
+
export declare const workflowEngineLayer: (options: WorkflowEngineLayerOptions) => Layer.Layer<WorkflowEngine.WorkflowEngine | Sharding.Sharding | MessageStorage.MessageStorage | ClusterDiagnostics | WorkflowResumeDispatcher>;
|
|
371
953
|
|
|
372
954
|
export declare interface WorkflowEngineLayerOptions {
|
|
373
955
|
/**
|
|
@@ -445,4 +1027,13 @@ export declare interface WorkflowEngineLayerOptions {
|
|
|
445
1027
|
readonly extraShardingLayers?: ReadonlyArray<Layer.Layer<never, never, Sharding.Sharding>>;
|
|
446
1028
|
}
|
|
447
1029
|
|
|
1030
|
+
/** Engine-bound dispatch capability. Accepts resident transactions, not a
|
|
1031
|
+
* caller-selected SQL connection. Results acknowledge attempts, never entry. */
|
|
1032
|
+
export declare class WorkflowResumeDispatcher extends WorkflowResumeDispatcher_base {
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
declare const WorkflowResumeDispatcher_base: Context.TagClass<WorkflowResumeDispatcher, "@voltro/workflow/WorkflowResumeDispatcher", {
|
|
1036
|
+
readonly dispatch: (options: Parameters<typeof dispatchWorkflowResume>[0]) => Effect.Effect<Effect.Effect.Success<ReturnType<typeof dispatchWorkflowResume>>, Effect.Effect.Error<ReturnType<typeof dispatchWorkflowResume>>>;
|
|
1037
|
+
}>;
|
|
1038
|
+
|
|
448
1039
|
export { }
|