@voltro/workflow 0.69.0 → 0.70.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 +168 -0
- package/dist/cluster-CSycI4sz.js +329 -0
- package/dist/cluster.d.ts +101 -1
- package/dist/cluster.js +2 -2
- package/dist/clusterDiagnostics-CNtl5LX9.js +20 -0
- package/dist/clusterTestSuite.js +2 -2
- package/dist/index.d.ts +141 -5
- package/dist/index.js +3 -2
- package/dist/{src-Dj8r1Kcn.js → src-TRpoU54e.js} +337 -312
- package/package.json +4 -4
- package/dist/cluster-OUXsLZ2x.js +0 -177
package/dist/cluster.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ConfigError } from 'effect';
|
|
2
|
+
import { Context } from 'effect';
|
|
2
3
|
import { Cron } from 'effect';
|
|
3
4
|
import { Duration } from 'effect';
|
|
4
5
|
import { Effect } from 'effect';
|
|
@@ -34,6 +35,79 @@ export declare interface ClusterCronSpec {
|
|
|
34
35
|
readonly skipIfOlderThan?: Duration.DurationInput;
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
declare class ClusterDiagnostics extends ClusterDiagnostics_base {
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
declare const ClusterDiagnostics_base: Context.TagClass<ClusterDiagnostics, "@voltro/workflow/ClusterDiagnostics", ClusterDiagnosticsOps>;
|
|
42
|
+
|
|
43
|
+
declare interface ClusterDiagnosticsOps {
|
|
44
|
+
/** This runner's advertised address — what keys its locks and its runner row. */
|
|
45
|
+
readonly ownAddress: string;
|
|
46
|
+
readonly shardLockMode: 'advisory' | 'row' | 'none';
|
|
47
|
+
/** Every message addressed to an entity — a workflow's `run` and its activities. */
|
|
48
|
+
readonly messagesFor: (entityId: string) => Effect.Effect<ReadonlyArray<ClusterMessageState>>;
|
|
49
|
+
/** Unprocessed, deliverable messages no runner has read for longer than
|
|
50
|
+
* `olderThanMs` (default: the engine's re-read window). */
|
|
51
|
+
readonly unreadMessages: (olderThanMs?: number) => Effect.Effect<ReadonlyArray<UnreadMessage>>;
|
|
52
|
+
/** Who holds the locks on these shards. Empty where the dialect cannot say
|
|
53
|
+
* (an advisory lock on MySQL has no holder view the framework reads). */
|
|
54
|
+
readonly shardLockHolders: (shardIds: ReadonlyArray<string>) => Effect.Effect<ReadonlyArray<ShardLockHolder>>;
|
|
55
|
+
/** The runner table — every address that registered, with its heartbeat. */
|
|
56
|
+
readonly runners: () => Effect.Effect<ReadonlyArray<ClusterRunner>>;
|
|
57
|
+
/**
|
|
58
|
+
* Delete the unprocessed messages addressed to one entity — the ONE write on
|
|
59
|
+
* this service. A run that ended outside the engine (cancelled by a sweep or
|
|
60
|
+
* an operator, parked as failed) leaves its unanswered requests behind: the
|
|
61
|
+
* `activity` a killed executor never replied to, the `run` itself if it was
|
|
62
|
+
* never processed. Every runner that acquires the shard re-reads them for the
|
|
63
|
+
* re-read window, forever, and an `activity` request for a run that does not
|
|
64
|
+
* execute waits on a latch that never opens. Nothing consumes them; deleting
|
|
65
|
+
* is what the engine's own reset does for one request. Returns how many.
|
|
66
|
+
*
|
|
67
|
+
* `unreadForMs`: only messages a runner last read at least this long ago —
|
|
68
|
+
* the guard for the sweep, which must not take a request an operator's
|
|
69
|
+
* redrive cleared a moment ago and a runner has just re-read.
|
|
70
|
+
*/
|
|
71
|
+
readonly discardMessages: (input: {
|
|
72
|
+
readonly entityType: string;
|
|
73
|
+
readonly entityId: string;
|
|
74
|
+
readonly unreadForMs?: number;
|
|
75
|
+
}) => Effect.Effect<number>;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export declare interface ClusterDiagnosticsOptions {
|
|
79
|
+
readonly ownAddress: string;
|
|
80
|
+
readonly shardLockMode: 'advisory' | 'row' | 'none';
|
|
81
|
+
readonly runnerStorage: 'sql' | 'memory';
|
|
82
|
+
readonly dialectId?: string | undefined;
|
|
83
|
+
/** Shard groups in configured order — the advisory lock base per group. */
|
|
84
|
+
readonly shardGroups?: ReadonlyArray<string>;
|
|
85
|
+
/**
|
|
86
|
+
* Does THIS runner hold the shard — `Sharding.hasShardId`, the engine's own
|
|
87
|
+
* account. This is what `own` on a holder means; without it every holder is
|
|
88
|
+
* a stranger. Not read from the database on purpose: the lock session's pid
|
|
89
|
+
* is not the pid of any query this service can make, and behind a pooler
|
|
90
|
+
* every session shares one client address and one application name.
|
|
91
|
+
*/
|
|
92
|
+
readonly hasShard?: (shardId: string) => boolean;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
declare interface ClusterMessageState {
|
|
96
|
+
/** The rpc tag — `run` for the workflow itself, `activity/<name>/<attempt>` for a step. */
|
|
97
|
+
readonly tag: string | null;
|
|
98
|
+
readonly entityType: string;
|
|
99
|
+
readonly entityId: string;
|
|
100
|
+
readonly shardId: string;
|
|
101
|
+
readonly processed: boolean;
|
|
102
|
+
readonly lastRead: Date | null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
declare interface ClusterRunner {
|
|
106
|
+
readonly address: string;
|
|
107
|
+
readonly lastHeartbeat: Date | null;
|
|
108
|
+
readonly healthy: boolean;
|
|
109
|
+
}
|
|
110
|
+
|
|
37
111
|
/** Default port for the cluster's single-runner listener. Override per deploy. */
|
|
38
112
|
export declare const DEFAULT_RUNNER_LISTEN_PORT: 34000;
|
|
39
113
|
|
|
@@ -59,6 +133,8 @@ export declare interface FailedActivityRef {
|
|
|
59
133
|
*/
|
|
60
134
|
export declare const makeClusterCronLayer: (spec: ClusterCronSpec) => Layer.Layer<never, never, Sharding.Sharding>;
|
|
61
135
|
|
|
136
|
+
export declare const makeClusterDiagnostics: (options: ClusterDiagnosticsOptions) => Effect.Effect<ClusterDiagnosticsOps, never, SqlClient.SqlClient>;
|
|
137
|
+
|
|
62
138
|
/** Parse `VOLTRO_WORKFLOW_SHARD_LOCK` (default `'auto'`). Throws on an
|
|
63
139
|
* unrecognized value so a typo fails boot loudly instead of silently keeping
|
|
64
140
|
* the advisory path that breaks cross-pod handoff on Galera. */
|
|
@@ -272,6 +348,25 @@ export declare interface RunnerIdentity {
|
|
|
272
348
|
*/
|
|
273
349
|
export declare type RunnerStorage = 'sql' | 'memory';
|
|
274
350
|
|
|
351
|
+
declare interface ShardLockHolder {
|
|
352
|
+
readonly shardId: string;
|
|
353
|
+
readonly mode: 'advisory' | 'row';
|
|
354
|
+
/** Who holds it: `pid <n> from <client>` for a postgres advisory lock, the
|
|
355
|
+
* runner address for a row lease. */
|
|
356
|
+
readonly holder: string;
|
|
357
|
+
/**
|
|
358
|
+
* `true` when THIS runner holds the shard — the engine's own answer
|
|
359
|
+
* (`Sharding.hasShardId`), never a guess from a connection. The first
|
|
360
|
+
* version compared the holder's pid with `pg_backend_pid()` of the query
|
|
361
|
+
* that asked, and the pool hands every query a different backend than the
|
|
362
|
+
* lock session, so a runner's own 300 locks read as a stranger's — and the
|
|
363
|
+
* report's lever, ending the holder's session, would have ended the runner.
|
|
364
|
+
*/
|
|
365
|
+
readonly own: boolean;
|
|
366
|
+
readonly since: Date | null;
|
|
367
|
+
readonly detail?: Record<string, unknown>;
|
|
368
|
+
}
|
|
369
|
+
|
|
275
370
|
/**
|
|
276
371
|
* How `@effect/cluster`'s `SqlRunnerStorage` coordinates shard ownership across
|
|
277
372
|
* a fleet of runners:
|
|
@@ -301,7 +396,12 @@ export declare type RunnerStorage = 'sql' | 'memory';
|
|
|
301
396
|
*/
|
|
302
397
|
export declare type ShardLockMode = 'auto' | 'row' | 'advisory';
|
|
303
398
|
|
|
304
|
-
|
|
399
|
+
declare interface UnreadMessage extends ClusterMessageState {
|
|
400
|
+
/** How long ago the last runner read it. */
|
|
401
|
+
readonly unreadForMs: number;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
export declare const workflowEngineLayer: (options: WorkflowEngineLayerOptions) => Layer.Layer<WorkflowEngine.WorkflowEngine | Sharding.Sharding | MessageStorage.MessageStorage | ClusterDiagnostics>;
|
|
305
405
|
|
|
306
406
|
export declare interface WorkflowEngineLayerOptions {
|
|
307
407
|
/**
|
package/dist/cluster.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as e, c as t, d as n, f as r, i, l as a,
|
|
2
|
-
export { e as DEFAULT_RUNNER_LISTEN_PORT,
|
|
1
|
+
import { a as e, c as t, d as n, f as r, i, l as a, m as o, n as s, o as c, p as l, r as u, s as d, t as f, u as p } from "./cluster-CSycI4sz.js";
|
|
2
|
+
export { e as DEFAULT_RUNNER_LISTEN_PORT, f as activityPrimaryKey, c as detectWsrepCluster, i as makeClusterCronLayer, o as makeClusterDiagnostics, d as parseShardLockMode, t as pollWorkflowStorage, s as redriveFailedRun, a as resolveFailoverTuning, p as resolveRunnerIdentity, n as resolveRunnerStorage, r as resolveShardLockDisableAdvisory, u as resumeRunFromStep, l as workflowEngineLayer };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Context as e, Effect as t } from "effect";
|
|
2
|
+
//#region src/clusterDiagnostics.ts
|
|
3
|
+
var n = 6e5, r = class extends e.Tag("@voltro/workflow/ClusterDiagnostics")() {}, i = (e, n, r = Date.now()) => t.flatMap(e.messagesFor(n), (n) => {
|
|
4
|
+
if (n.length === 0) return t.succeed(void 0);
|
|
5
|
+
let i = [...new Set(n.filter((e) => !e.processed).map((e) => e.shardId))], a = i.length === 0 ? t.succeed([]) : e.shardLockHolders(i);
|
|
6
|
+
return t.map(a, (t) => ({
|
|
7
|
+
runner: e.ownAddress,
|
|
8
|
+
shardLockMode: e.shardLockMode,
|
|
9
|
+
messages: n.map((e) => ({
|
|
10
|
+
tag: e.tag,
|
|
11
|
+
shardId: e.shardId,
|
|
12
|
+
processed: e.processed,
|
|
13
|
+
lastRead: e.lastRead === null ? null : e.lastRead.toISOString(),
|
|
14
|
+
unreadForMs: !e.processed && e.lastRead !== null ? Math.max(0, r - e.lastRead.getTime()) : null
|
|
15
|
+
})),
|
|
16
|
+
shardLocks: t
|
|
17
|
+
}));
|
|
18
|
+
});
|
|
19
|
+
//#endregion
|
|
20
|
+
export { r as n, i as r, n as t };
|
package/dist/clusterTestSuite.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { I as e, P as t, S as n, g as r, v as i } from "./primitives-CqHxfASq.js";
|
|
2
|
-
import { o as a } from "./src-
|
|
3
|
-
import { i as o, p as s } from "./cluster-
|
|
2
|
+
import { o as a } from "./src-TRpoU54e.js";
|
|
3
|
+
import { i as o, p as s } from "./cluster-CSycI4sz.js";
|
|
4
4
|
import { Cron as c, Deferred as l, Effect as u, Fiber as d, Layer as f, Schema as p } from "effect";
|
|
5
5
|
import { SqlClient as m } from "@effect/sql";
|
|
6
6
|
import { beforeAll as h, describe as g, expect as _, test as v } from "vitest";
|
package/dist/index.d.ts
CHANGED
|
@@ -687,6 +687,67 @@ export declare interface CloseWorkflowChildrenForParentOptions {
|
|
|
687
687
|
readonly interruptChild: (workflowName: string, executionId: string, policy: Exclude<WorkflowParentClosePolicy, 'abandon'>) => Promise<void>;
|
|
688
688
|
}
|
|
689
689
|
|
|
690
|
+
/** The engine's own re-read rule: an unprocessed message whose `last_read` is
|
|
691
|
+
* older than this is re-delivered by the shard's owner on its next poll. A
|
|
692
|
+
* message older than this that is STILL unread has no owner reading it. */
|
|
693
|
+
export declare const CLUSTER_REREAD_WINDOW_MS: number;
|
|
694
|
+
|
|
695
|
+
export declare class ClusterDiagnostics extends ClusterDiagnostics_base {
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
declare const ClusterDiagnostics_base: Context.TagClass<ClusterDiagnostics, "@voltro/workflow/ClusterDiagnostics", ClusterDiagnosticsOps>;
|
|
699
|
+
|
|
700
|
+
export declare interface ClusterDiagnosticsOps {
|
|
701
|
+
/** This runner's advertised address — what keys its locks and its runner row. */
|
|
702
|
+
readonly ownAddress: string;
|
|
703
|
+
readonly shardLockMode: 'advisory' | 'row' | 'none';
|
|
704
|
+
/** Every message addressed to an entity — a workflow's `run` and its activities. */
|
|
705
|
+
readonly messagesFor: (entityId: string) => Effect.Effect<ReadonlyArray<ClusterMessageState>>;
|
|
706
|
+
/** Unprocessed, deliverable messages no runner has read for longer than
|
|
707
|
+
* `olderThanMs` (default: the engine's re-read window). */
|
|
708
|
+
readonly unreadMessages: (olderThanMs?: number) => Effect.Effect<ReadonlyArray<UnreadMessage>>;
|
|
709
|
+
/** Who holds the locks on these shards. Empty where the dialect cannot say
|
|
710
|
+
* (an advisory lock on MySQL has no holder view the framework reads). */
|
|
711
|
+
readonly shardLockHolders: (shardIds: ReadonlyArray<string>) => Effect.Effect<ReadonlyArray<ShardLockHolder>>;
|
|
712
|
+
/** The runner table — every address that registered, with its heartbeat. */
|
|
713
|
+
readonly runners: () => Effect.Effect<ReadonlyArray<ClusterRunner>>;
|
|
714
|
+
/**
|
|
715
|
+
* Delete the unprocessed messages addressed to one entity — the ONE write on
|
|
716
|
+
* this service. A run that ended outside the engine (cancelled by a sweep or
|
|
717
|
+
* an operator, parked as failed) leaves its unanswered requests behind: the
|
|
718
|
+
* `activity` a killed executor never replied to, the `run` itself if it was
|
|
719
|
+
* never processed. Every runner that acquires the shard re-reads them for the
|
|
720
|
+
* re-read window, forever, and an `activity` request for a run that does not
|
|
721
|
+
* execute waits on a latch that never opens. Nothing consumes them; deleting
|
|
722
|
+
* is what the engine's own reset does for one request. Returns how many.
|
|
723
|
+
*
|
|
724
|
+
* `unreadForMs`: only messages a runner last read at least this long ago —
|
|
725
|
+
* the guard for the sweep, which must not take a request an operator's
|
|
726
|
+
* redrive cleared a moment ago and a runner has just re-read.
|
|
727
|
+
*/
|
|
728
|
+
readonly discardMessages: (input: {
|
|
729
|
+
readonly entityType: string;
|
|
730
|
+
readonly entityId: string;
|
|
731
|
+
readonly unreadForMs?: number;
|
|
732
|
+
}) => Effect.Effect<number>;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
export declare interface ClusterMessageState {
|
|
736
|
+
/** The rpc tag — `run` for the workflow itself, `activity/<name>/<attempt>` for a step. */
|
|
737
|
+
readonly tag: string | null;
|
|
738
|
+
readonly entityType: string;
|
|
739
|
+
readonly entityId: string;
|
|
740
|
+
readonly shardId: string;
|
|
741
|
+
readonly processed: boolean;
|
|
742
|
+
readonly lastRead: Date | null;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
export declare interface ClusterRunner {
|
|
746
|
+
readonly address: string;
|
|
747
|
+
readonly lastHeartbeat: Date | null;
|
|
748
|
+
readonly healthy: boolean;
|
|
749
|
+
}
|
|
750
|
+
|
|
690
751
|
/**
|
|
691
752
|
* Order pending rows for admission.
|
|
692
753
|
*
|
|
@@ -918,6 +979,15 @@ export declare const deferringControlsOf: (control: ResolvedFlowControl | undefi
|
|
|
918
979
|
* own. Use {@link discardIntent} for a start that is being dropped. */
|
|
919
980
|
export declare const deleteIntent: (store: AdmissionDataStore, id: string) => Promise<boolean>;
|
|
920
981
|
|
|
982
|
+
/**
|
|
983
|
+
* The cluster half of a stalled run's report, built from the diagnostics: the
|
|
984
|
+
* run's messages and, for the unprocessed ones, who holds their shards. Pure
|
|
985
|
+
* over the two reads, so the sweep's caller and a test agree on its shape.
|
|
986
|
+
* `undefined` when the engine has no message for the run at all — an
|
|
987
|
+
* in-memory engine, or a run whose journal was cleared.
|
|
988
|
+
*/
|
|
989
|
+
export declare const describeStalledRun: (ops: ClusterDiagnosticsOps, executionId: string, now?: number) => Effect.Effect<StalledRunClusterState | undefined>;
|
|
990
|
+
|
|
921
991
|
export declare interface DiscardDecision {
|
|
922
992
|
readonly intentId: string;
|
|
923
993
|
readonly reason: string;
|
|
@@ -977,14 +1047,23 @@ export declare interface DrainOutcome {
|
|
|
977
1047
|
*/
|
|
978
1048
|
readonly examined: boolean;
|
|
979
1049
|
/**
|
|
980
|
-
* When the earliest not-yet-due pending row comes due
|
|
1050
|
+
* When the earliest not-yet-due pending row comes due — OR the earliest
|
|
1051
|
+
* `timeouts.finish` deadline of a run still running — as an epoch ms: the
|
|
981
1052
|
* number that lets the drainer arm for that instant instead of polling until
|
|
982
1053
|
* it arrives.
|
|
983
1054
|
*
|
|
984
|
-
*
|
|
985
|
-
*
|
|
986
|
-
*
|
|
987
|
-
*
|
|
1055
|
+
* The finish deadline is part of it because the drain tick is what ENFORCES
|
|
1056
|
+
* `timeouts.finish`, and a running run writes nothing to the queue: a drainer
|
|
1057
|
+
* that disarmed on an empty queue while a run approached its bound would
|
|
1058
|
+
* not cancel it at the bound but at the next arrival that happened to wake
|
|
1059
|
+
* it — measured as a cancellation landing tens of minutes after the declared
|
|
1060
|
+
* limit, by an amount that depended on unrelated traffic.
|
|
1061
|
+
*
|
|
1062
|
+
* `undefined` means "nothing in the read window is waiting and no controlled
|
|
1063
|
+
* run is under a finish bound". It is a LOWER bound on the true next deadline
|
|
1064
|
+
* (the window is capped by `batchSize`), which is the safe direction: an
|
|
1065
|
+
* understated deadline costs one early tick, an overstated one misses a
|
|
1066
|
+
* start or a cancellation.
|
|
988
1067
|
*/
|
|
989
1068
|
readonly nextDueAt?: number;
|
|
990
1069
|
}
|
|
@@ -1836,6 +1915,25 @@ export declare const serialiseWorkflowRowForWire: (row: Record<string, unknown>)
|
|
|
1836
1915
|
*/
|
|
1837
1916
|
export declare const setSuspendSignalHintMs: (ms: number | undefined) => void;
|
|
1838
1917
|
|
|
1918
|
+
export declare interface ShardLockHolder {
|
|
1919
|
+
readonly shardId: string;
|
|
1920
|
+
readonly mode: 'advisory' | 'row';
|
|
1921
|
+
/** Who holds it: `pid <n> from <client>` for a postgres advisory lock, the
|
|
1922
|
+
* runner address for a row lease. */
|
|
1923
|
+
readonly holder: string;
|
|
1924
|
+
/**
|
|
1925
|
+
* `true` when THIS runner holds the shard — the engine's own answer
|
|
1926
|
+
* (`Sharding.hasShardId`), never a guess from a connection. The first
|
|
1927
|
+
* version compared the holder's pid with `pg_backend_pid()` of the query
|
|
1928
|
+
* that asked, and the pool hands every query a different backend than the
|
|
1929
|
+
* lock session, so a runner's own 300 locks read as a stranger's — and the
|
|
1930
|
+
* report's lever, ending the holder's session, would have ended the runner.
|
|
1931
|
+
*/
|
|
1932
|
+
readonly own: boolean;
|
|
1933
|
+
readonly since: Date | null;
|
|
1934
|
+
readonly detail?: Record<string, unknown>;
|
|
1935
|
+
}
|
|
1936
|
+
|
|
1839
1937
|
/**
|
|
1840
1938
|
* Durable sleep — wake time journaled in the cluster. Wrapper around
|
|
1841
1939
|
* `DurableClock.sleep` that emits `timer-set` / `timer-fired` events
|
|
@@ -1896,6 +1994,15 @@ export declare interface StalenessSweepDeps {
|
|
|
1896
1994
|
/** App-supplied reaction — page someone, open a ticket. Must not throw;
|
|
1897
1995
|
* a rejection is collected as a failure and the sweep continues. */
|
|
1898
1996
|
readonly onStalled?: (run: StalledRun) => Promise<void>;
|
|
1997
|
+
/**
|
|
1998
|
+
* What else the report should carry about THIS run — the cluster engine's
|
|
1999
|
+
* view of it (its messages, who holds their shards), attached by the CLI
|
|
2000
|
+
* from `ClusterDiagnostics`. Best-effort: a rejection is collected as a
|
|
2001
|
+
* failure and the report goes out without it. The fields land on the
|
|
2002
|
+
* `run-stalled` event payload and on the warning line, so the report says
|
|
2003
|
+
* where the run is stuck and not only that it is.
|
|
2004
|
+
*/
|
|
2005
|
+
readonly describeRun?: (run: StalledRun) => Promise<Record<string, unknown> | undefined>;
|
|
1899
2006
|
readonly now?: () => number;
|
|
1900
2007
|
readonly log?: {
|
|
1901
2008
|
readonly info: (message: string, fields?: Record<string, unknown>) => void;
|
|
@@ -1940,6 +2047,20 @@ export declare interface StalledRun {
|
|
|
1940
2047
|
readonly reason: StallReason;
|
|
1941
2048
|
}
|
|
1942
2049
|
|
|
2050
|
+
/** A `run-stalled` report's cluster half, as the sweep attaches it. */
|
|
2051
|
+
export declare interface StalledRunClusterState {
|
|
2052
|
+
readonly runner: string;
|
|
2053
|
+
readonly shardLockMode: ClusterDiagnosticsOps['shardLockMode'];
|
|
2054
|
+
readonly messages: ReadonlyArray<{
|
|
2055
|
+
readonly tag: string | null;
|
|
2056
|
+
readonly shardId: string;
|
|
2057
|
+
readonly processed: boolean;
|
|
2058
|
+
readonly lastRead: string | null;
|
|
2059
|
+
readonly unreadForMs: number | null;
|
|
2060
|
+
}>;
|
|
2061
|
+
readonly shardLocks: ReadonlyArray<ShardLockHolder>;
|
|
2062
|
+
}
|
|
2063
|
+
|
|
1943
2064
|
/** Why the sweep believes this run is not moving. Diagnostic, not a taxonomy
|
|
1944
2065
|
* the caller should branch on for correctness. */
|
|
1945
2066
|
export declare type StallReason =
|
|
@@ -2150,6 +2271,11 @@ export declare const sweepStalledRuns: (deps: StalenessSweepDeps, options?: Stal
|
|
|
2150
2271
|
|
|
2151
2272
|
export declare const truncateWorkflowValue: (value: unknown, bytes?: number) => unknown;
|
|
2152
2273
|
|
|
2274
|
+
export declare interface UnreadMessage extends ClusterMessageState {
|
|
2275
|
+
/** How long ago the last runner read it. */
|
|
2276
|
+
readonly unreadForMs: number;
|
|
2277
|
+
}
|
|
2278
|
+
|
|
2153
2279
|
/**
|
|
2154
2280
|
* Validate + resolve a declaration. Throws at DEFINITION time (module load,
|
|
2155
2281
|
* i.e. boot) with a message naming the workflow and the field.
|
|
@@ -2499,12 +2625,22 @@ export declare interface WorkflowExecuteRecordingOptions extends WorkflowRunReco
|
|
|
2499
2625
|
*
|
|
2500
2626
|
* Called on success AND on failure, and DELIBERATELY not on suspend: a
|
|
2501
2627
|
* suspended run is still holding the resource it was admitted for.
|
|
2628
|
+
*
|
|
2629
|
+
* On a failure it also carries the payload and the error, so the caller
|
|
2630
|
+
* can raise the workflow's `onFailure` — the one route into that signal
|
|
2631
|
+
* that produces a `failed` row, and the one that was not wired: the
|
|
2632
|
+
* flow-control paths (an expired start, a finish timeout, a dead-lettered
|
|
2633
|
+
* intent) notified, and a body that failed did not.
|
|
2502
2634
|
*/
|
|
2503
2635
|
readonly onTerminal?: (input: {
|
|
2504
2636
|
readonly workflowName: string;
|
|
2505
2637
|
readonly executionId: string;
|
|
2506
2638
|
readonly runId?: string;
|
|
2507
2639
|
readonly status: 'succeeded' | 'failed';
|
|
2640
|
+
/** The run's payload — present on `failed`, for the failure report. */
|
|
2641
|
+
readonly payload?: unknown;
|
|
2642
|
+
readonly errorTag?: string | null;
|
|
2643
|
+
readonly errorMessage?: string | null;
|
|
2508
2644
|
}) => Promise<void>;
|
|
2509
2645
|
/**
|
|
2510
2646
|
* CRASH-LOOP BREAKER — how many CONSECUTIVE runner deaths this run may cost
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { A as e, B as t, C as n, D as r, E as i, G as a, H as o, I as s, L as c, M as l, N as u, O as d, P as f, R as p, S as m, T as h, U as g, V as _, W as v, _ as y, a as b, b as x, c as S, d as C, f as w, g as T, h as E, i as D, j as O, k, l as A, m as j, n as M, o as N, p as P, r as F, s as I, t as L, u as R, v as z, w as B, x as V, y as H, z as U } from "./primitives-CqHxfASq.js";
|
|
2
|
-
import { $ as W, A as G, At as K, B as q, Bt as J, C as Y, Ct as X, D as Z, Dt as Q, E as $, Et as ee, F as te, Ft as ne, G as re, H as ie, I as ae, It as oe, J as se, K as ce, L as le, Lt as ue, M as de, Mt as fe, N as pe, Nt as me, O as he, Ot as ge, P as _e, Pt as ve, Q as ye, R as be, Rt as xe, S as Se, St as Ce, T as we, Tt as Te, U as Ee, V as De, Vt as Oe, W as ke, X as Ae, Y as je, Z as Me, _ as Ne, _t as Pe, a as Fe, at as Ie, b as Le, bt as Re, c as ze, ct as Be, d as Ve, dt as He, et as Ue, f as We, ft as Ge, g as Ke, gt as qe, h as Je, ht as Ye, i as Xe, it as Ze, j as Qe, jt as $e, k as et, kt as tt, l as nt, lt as rt, m as it, mt as at, n as ot, nt as st, o as ct, ot as lt, p as ut, pt as dt, q as ft, r as pt, rt as mt, s as ht, st as gt, t as _t, tt as vt, u as yt, ut as bt, v as xt, vt as St, w as Ct, wt, x as Tt, xt as Et, y as Dt, yt as Ot, z as kt, zt as At } from "./src-
|
|
3
|
-
|
|
2
|
+
import { $ as W, A as G, At as K, B as q, Bt as J, C as Y, Ct as X, D as Z, Dt as Q, E as $, Et as ee, F as te, Ft as ne, G as re, H as ie, I as ae, It as oe, J as se, K as ce, L as le, Lt as ue, M as de, Mt as fe, N as pe, Nt as me, O as he, Ot as ge, P as _e, Pt as ve, Q as ye, R as be, Rt as xe, S as Se, St as Ce, T as we, Tt as Te, U as Ee, V as De, Vt as Oe, W as ke, X as Ae, Y as je, Z as Me, _ as Ne, _t as Pe, a as Fe, at as Ie, b as Le, bt as Re, c as ze, ct as Be, d as Ve, dt as He, et as Ue, f as We, ft as Ge, g as Ke, gt as qe, h as Je, ht as Ye, i as Xe, it as Ze, j as Qe, jt as $e, k as et, kt as tt, l as nt, lt as rt, m as it, mt as at, n as ot, nt as st, o as ct, ot as lt, p as ut, pt as dt, q as ft, r as pt, rt as mt, s as ht, st as gt, t as _t, tt as vt, u as yt, ut as bt, v as xt, vt as St, w as Ct, wt, x as Tt, xt as Et, y as Dt, yt as Ot, z as kt, zt as At } from "./src-TRpoU54e.js";
|
|
3
|
+
import { n as jt, r as Mt, t as Nt } from "./clusterDiagnostics-CNtl5LX9.js";
|
|
4
|
+
export { mt as ADMISSIONS_TABLE, ut as BUDGET_HOLDS_TABLE, it as BudgetHoldExpired, ke as CANCEL_ON_WATERMARK, Nt as CLUSTER_REREAD_WINDOW_MS, jt as ClusterDiagnostics, l as CurrentWorkflowExecutionId, u as CurrentWorkflowPatches, B as CurrentWorkflowReplayShape, f as CurrentWorkflowRunId, Je as DEFAULT_BUDGET_HOLD_TIMEOUT_MS, re as DEFAULT_COLD_LOOKBACK_MS, be as DEFAULT_DRAIN_BATCH, ce as DEFAULT_EVENT_BATCH, Ze as DEFAULT_LEASE_MS, Xe as DEFAULT_MAX_RUN_RECLAIMS, Fe as DEFAULT_REPLAY_SHAPE_LIMIT, q as DEFAULT_STALL_AFTER_MS, De as DEFAULT_STALL_EVENT_LOOKBACK, ie as DEFAULT_STALL_RUN_PAGE, pe as DEFAULT_SUSPEND_HINT_MS, d as DEFAULT_WORKFLOW_SCHEDULE_MAX_RUNTIME_MS, t as DEFERRING_CONTROLS, ft as EVENTS_TABLE, ee as FlowControlKeyError, Ie as PAUSES_TABLE, lt as PENDING_TABLE, se as WATERMARKS_TABLE, L as WorkflowFlowControlProperty, M as WorkflowMessagesProperty, s as WorkflowRunRecorder, k as WorkflowScheduleProperty, c as WorkflowStepInterceptorTag, F as WorkflowVersionTypeId, D as WorkflowWorkerLayerTypeId, Ke as _voltroBudgetHoldsTable, ve as _voltroWorkflowAdmissionsTable, ne as _voltroWorkflowPausesTable, oe as _voltroWorkflowPendingTable, xe as _voltroWorkflowRunEventsTable, At as _voltroWorkflowRunStepsTable, J as _voltroWorkflowRunsTable, ue as _voltroWorkflowStartContextsTable, Ue as _voltroWorkflowWatermarksTable, vt as admitStart, gt as allIntents, _ as assertConsistentPools, Qe as awaitEvent, de as awaitSignal, Ct as awaitSignalSuspending, We as awaitUpdate, Ne as budgetHoldGeneration, xt as budgetHoldKey, Dt as budgetHoldSignalName, pt as closeWorkflowChildrenForParent, Q as comparePendingOrder, we as completeSuspendingSignal, Be as deadLetterIntent, ge as decideAdmission, o as deferringControlsOf, rt as deleteIntent, Mt as describeStalledRun, bt as discardIntent, kt as drainTick, He as dueIntents, b as durableClock, N as durableQueue, I as durableQueueModule, S as durableRateLimiterModule, Ge as evaluateAdmission, p as getCurrentWorkflowExecutionId, U as getCurrentWorkflowRunId, A as getWorkflowFlowControl, e as getWorkflowSchedule, R as getWorkflowVersionMetadata, g as hasCancelOn, v as hasFlowControl, Le as heldBudgets, Oe as inMemoryWorkflowEngineLayer, ot as inspectWorkflow, tt as isFinishExpired, K as isStartExpired, C as isWorkflowWorkerLayer, st as linkExecution, _t as makeInMemoryRecorder, h as makeReplayShapeTracker, ct as makeWorkflowRunRecorder, Z as makeWorkflowUpdateId, _e as maybeHintSuspendingSignal, ye as newestEventAt, $e as nextSlotAt, i as nondeterminismEventPayload, ht as normaliseWorkflowPatches, dt as noteIntentAttempt, at as parkDelayedStart, w as patch, Ye as pauseWorkflow, Tt as pendingBudgetHolds, qe as pendingSlotId, Pe as pendingWindow, St as persistDefer, W as planCancellations, fe as pooledConcurrencyKey, P as processQueue, Ot as pruneAdmissions, j as queueWorker, E as rateLimit, Re as readAdmissionState, Et as readPausedWorkflows, je as readWatermark, Ce as recordAdmission, Se as releaseBudgetHolds, X as releaseLease, r as reportNondeterminism, te as resetSuspendHintsForTest, me as resolveAdmissionKeys, ze as resolveRunGuardTuning, ae as resolveSuspendHintMs, he as resolveWorkflowMessageRun, wt as resumeWorkflow, Te as retryDeadLetterIntent, et as sendWorkflowSignal, G as sendWorkflowUpdate, nt as serialiseWorkflowRowForWire, le as setSuspendSignalHintMs, T as sleep, y as sleepUntil, z as step, H as stepIdempotencyKey, x as stepModule, Y as suspendForBudget, $ as suspendingSignalDeferredName, Ae as sweepCancelOn, Ee as sweepStalledRuns, yt as truncateWorkflowValue, a as validateFlowControl, O as validateWorkflowSchedule, V as withCompensation, m as workflow, n as workflowModule, Ve as wrapWorkflowExecuteWithRunRecording, Me as writeWatermark };
|