@dudousxd/nestjs-durable-core 0.38.0 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +165 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +94 -9
- package/dist/index.d.ts +94 -9
- package/dist/index.js +165 -25
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -246,6 +246,13 @@ interface WorkflowRun {
|
|
|
246
246
|
tags?: string[] | undefined;
|
|
247
247
|
/** Typed, queryable run data (e.g. `{ amount: 200, tier: 'pro' }`) — see {@link RunQuery.attributes}. */
|
|
248
248
|
searchAttributes?: SearchAttributes | undefined;
|
|
249
|
+
/**
|
|
250
|
+
* The worker-pool partition this run belongs to. Stamped at creation from the creating engine's
|
|
251
|
+
* `namespace` (default `'default'`). A worker only picks up / recovers / resumes-timers-for /
|
|
252
|
+
* times-out runs in its own namespace. `undefined` on a run created before this field existed; the
|
|
253
|
+
* store persists it as `'default'`. Read paths (dashboard, `getRun`) are NOT namespace-scoped.
|
|
254
|
+
*/
|
|
255
|
+
namespace?: string | undefined;
|
|
249
256
|
/**
|
|
250
257
|
* Dispatch priority for a REMOTE run (one advanced by a {@link WorkflowExecutor} over a broker):
|
|
251
258
|
* carried onto each {@link WorkflowTask} so an urgent child workflow can jump ahead of enqueued
|
|
@@ -433,11 +440,11 @@ interface StateStore {
|
|
|
433
440
|
*/
|
|
434
441
|
saveCheckpoint(checkpoint: StepCheckpoint): Promise<void>;
|
|
435
442
|
/** Used by recovery on boot to find runs to resume (crashed, left `running`). */
|
|
436
|
-
listIncompleteRuns(): Promise<WorkflowRun[]>;
|
|
443
|
+
listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]>;
|
|
437
444
|
/** The oldest `pending` runs awaiting dispatch (FIFO, by `createdAt`), capped at `limit`. */
|
|
438
|
-
listPendingRuns(limit: number): Promise<WorkflowRun[]>;
|
|
445
|
+
listPendingRuns(limit: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
439
446
|
/** Suspended runs whose durable timer is due (`wakeAt <= nowMs`), ready to resume. */
|
|
440
|
-
listDueTimers(nowMs: number): Promise<WorkflowRun[]>;
|
|
447
|
+
listDueTimers(nowMs: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
441
448
|
/**
|
|
442
449
|
* Atomically acquire the recovery lease on a run for `owner` until `leaseUntilMs`, but only if
|
|
443
450
|
* it is currently unlocked or its lease has expired (`<= nowMs`). Returns whether it was
|
|
@@ -549,6 +556,8 @@ interface RunQuery {
|
|
|
549
556
|
* `workflow`/`status`/`tag` to bound the scan on large stores.
|
|
550
557
|
*/
|
|
551
558
|
attributes?: AttributeFilter[] | undefined;
|
|
559
|
+
/** Restrict to runs in this namespace (exact match), ANDed with the other predicates. */
|
|
560
|
+
namespace?: string | undefined;
|
|
552
561
|
limit?: number | undefined;
|
|
553
562
|
offset?: number | undefined;
|
|
554
563
|
}
|
|
@@ -1336,6 +1345,13 @@ interface WorkflowEngineDeps {
|
|
|
1336
1345
|
admission?: AdmissionBackend | undefined;
|
|
1337
1346
|
/** Unique id for this engine instance, used for recovery leases. Defaults to a random id. */
|
|
1338
1347
|
instanceId?: string | undefined;
|
|
1348
|
+
/**
|
|
1349
|
+
* Worker-pool partition for this engine. Stamped on every run it creates; the poll paths
|
|
1350
|
+
* (`runPending`/`recoverIncomplete`/`resumeDueTimers`/`sweepTimeouts`) only act on runs in this
|
|
1351
|
+
* namespace. Default `'default'` — byte-identical to a single-pool deployment. Set distinct values
|
|
1352
|
+
* to safely share ONE state store across non-interchangeable pools (e.g. local dev vs a cluster).
|
|
1353
|
+
*/
|
|
1354
|
+
namespace?: string | undefined;
|
|
1339
1355
|
/** Recovery lease duration in ms — how long this instance owns a run it picked up. Default 30s. */
|
|
1340
1356
|
leaseMs?: number | undefined;
|
|
1341
1357
|
/**
|
|
@@ -1427,6 +1443,7 @@ declare class WorkflowEngine {
|
|
|
1427
1443
|
private readonly controlPlane?;
|
|
1428
1444
|
private readonly clock;
|
|
1429
1445
|
private readonly instanceId;
|
|
1446
|
+
private readonly namespace;
|
|
1430
1447
|
private readonly leaseMs;
|
|
1431
1448
|
private readonly maxRecoveryAttempts?;
|
|
1432
1449
|
private readonly remoteAdvanceSilenceMs?;
|
|
@@ -1503,6 +1520,16 @@ declare class WorkflowEngine {
|
|
|
1503
1520
|
* Register a workflow version. Register multiple versions of the same name to keep in-flight
|
|
1504
1521
|
* runs working across a breaking change: old runs resume on the version they started on, new
|
|
1505
1522
|
* runs start on the newest registered version.
|
|
1523
|
+
*
|
|
1524
|
+
* GROUP-SERVED (uniform dispatch, opt-in): pass `{ group, executor }` to have the engine DISPATCH
|
|
1525
|
+
* this workflow's turns to a worker `group` (via `executor.advance`) instead of running `fn`
|
|
1526
|
+
* inline — exactly as {@link registerRemote} does for a cross-SDK (e.g. Python) body, EXCEPT the
|
|
1527
|
+
* body is a TS `fn` the engine retains so an IN-APP worker on `group` can fetch it by name
|
|
1528
|
+
* ({@link workflowBody}) and run it. This is "one app, both roles": the same process owns the
|
|
1529
|
+
* engine AND consumes its own group. Recovery, timers, singleton, cancel and dead-lettering stay
|
|
1530
|
+
* engine concerns, identical to a remote run. OMIT `group`/`executor` (the default) to keep the
|
|
1531
|
+
* inline fast path — `fn` runs in-process and the run pays zero dispatch round-trips. The first
|
|
1532
|
+
* step toward routing every run through a group with no local/remote flag (Phase 3).
|
|
1506
1533
|
*/
|
|
1507
1534
|
register(name: string, version: string, fn: WorkflowFn, opts?: {
|
|
1508
1535
|
tags?: string[] | undefined;
|
|
@@ -1511,7 +1538,22 @@ declare class WorkflowEngine {
|
|
|
1511
1538
|
validateInput?: ((input: unknown) => void | Promise<void>) | undefined;
|
|
1512
1539
|
onEvent?: string[] | undefined;
|
|
1513
1540
|
eventBatch?: EventBatchConfig | undefined;
|
|
1541
|
+
/** Worker group to DISPATCH this workflow's turns to (uniform dispatch). Requires `executor`.
|
|
1542
|
+
* Omit for the default inline fast path. See the method doc. */
|
|
1543
|
+
group?: string | undefined;
|
|
1544
|
+
/** Advances a turn by dispatching a {@link WorkflowTask} to `group`. Requires `group`. For an
|
|
1545
|
+
* in-app worker, pair a transport-backed {@link RemoteWorkflowExecutor} (group consumed by a
|
|
1546
|
+
* worker that calls {@link workflowBody}) so the retained `fn` runs through the transport hop. */
|
|
1547
|
+
executor?: WorkflowExecutor | undefined;
|
|
1514
1548
|
}): void;
|
|
1549
|
+
/**
|
|
1550
|
+
* The retained in-process body for `name@version`, for an IN-APP worker that consumes this engine's
|
|
1551
|
+
* own group to SERVE a group-served `register(..., { group, executor })` workflow (uniform dispatch):
|
|
1552
|
+
* the worker fetches the body by name when it picks up the dispatched {@link WorkflowTask}, replays
|
|
1553
|
+
* it, and returns the {@link WorkflowDecision}. `undefined` for an unregistered name or a body-less
|
|
1554
|
+
* remote (a `registerRemote` / synthesized child carries only a throwing stub, never handed out).
|
|
1555
|
+
*/
|
|
1556
|
+
workflowBody(name: string, version: string): WorkflowFn | undefined;
|
|
1515
1557
|
/**
|
|
1516
1558
|
* Register a workflow whose body runs in another SDK (e.g. Python). The engine owns the run exactly
|
|
1517
1559
|
* as for a TS workflow — it persists checkpoints, recovers, runs timers — but advances it by handing
|
|
@@ -1575,6 +1617,49 @@ declare class WorkflowEngine {
|
|
|
1575
1617
|
/** Read a run's current persisted state (or null if unknown). A thin pass-through to the store. */
|
|
1576
1618
|
getRun(runId: string): Promise<WorkflowRun | null>;
|
|
1577
1619
|
resume(runId: string): Promise<RunResult>;
|
|
1620
|
+
/**
|
|
1621
|
+
* The registration for an UNREGISTERED run, INHERITED from its nearest REMOTE ancestor — or
|
|
1622
|
+
* `undefined` if it has none (the skew-protection error case in {@link resume}). Callers check the
|
|
1623
|
+
* flat registry FIRST (so an explicit `registerRemote(name, …)` ALWAYS wins, and a registered run
|
|
1624
|
+
* never reaches here); this resolves only the new case: a child spawned by a remote workflow (e.g. a
|
|
1625
|
+
* Python `gather_children` / `start_child` fan-out) of a name the host never `registerRemote`-ed. It
|
|
1626
|
+
* is driven as a remote run on the ancestor's group + the SAME executor instance, so the host needs
|
|
1627
|
+
* no redundant registration per child name.
|
|
1628
|
+
*
|
|
1629
|
+
* RECOMPUTED per resume rather than memoized into `this.workflows`: a synthesized child is not a real
|
|
1630
|
+
* registration and must not leak into `latest`, `knownGroups`, or `sweepTimeouts` (which iterate the
|
|
1631
|
+
* registry); recomputing also stays correct if the ancestor's remote registration is re-pointed at a
|
|
1632
|
+
* new executor across a deploy. Only unregistered runs pay it, so registered workflows pay nothing.
|
|
1633
|
+
*/
|
|
1634
|
+
private findInheritedRegistration;
|
|
1635
|
+
/**
|
|
1636
|
+
* A throwaway {@link RegisteredWorkflow} that routes `name@version` as a remote run on the ancestor's
|
|
1637
|
+
* group via the ancestor's SAME executor instance. The executor is group-scoped (it dispatches a
|
|
1638
|
+
* {@link WorkflowTask} carrying `run.workflow`, and the worker picks the body by name), so reusing it
|
|
1639
|
+
* is correct AND required — a second executor on the same group would race the worker for results.
|
|
1640
|
+
* Only `remote` is inherited; the child gets none of the ancestor's singleton/timeout/validator, so
|
|
1641
|
+
* its identity stays its own.
|
|
1642
|
+
*/
|
|
1643
|
+
private synthesizeRemoteChild;
|
|
1644
|
+
/**
|
|
1645
|
+
* Walk the parent chain of `childRunId` to the nearest ancestor registered as REMOTE, returning its
|
|
1646
|
+
* registration (or `undefined` if there is none). The parent of an awaited child is found via its
|
|
1647
|
+
* live `child:<childId>` signal waiter — present for as long as the parent is suspended awaiting the
|
|
1648
|
+
* child, i.e. throughout the child's executable lifetime (start, every resume, crash recovery, cancel
|
|
1649
|
+
* cascade), which is exactly when we resolve. A registered-but-LOCAL parent stops the walk (an
|
|
1650
|
+
* unregistered child of a TS workflow is a genuine misconfiguration → skew error); only an
|
|
1651
|
+
* unregistered parent keeps walking, so a child of an inherited child still reaches the remote root.
|
|
1652
|
+
* `visited` guards against a pathological cyclic id graph.
|
|
1653
|
+
*/
|
|
1654
|
+
private findRemoteAncestor;
|
|
1655
|
+
/**
|
|
1656
|
+
* The run that spawned `childRunId`, via its live `child:<childRunId>` signal waiter — every awaited
|
|
1657
|
+
* child (`ctx.child`, `ctx.all`, a remote `start_child`) suspends its parent on exactly this waiter,
|
|
1658
|
+
* and the waiter is written BEFORE the child is started. Only reached for an UNREGISTERED child, so
|
|
1659
|
+
* registered runs never pay the scan; returns `undefined` once the parent has settled the child (the
|
|
1660
|
+
* waiter is consumed), but by then the child is terminal and no longer resolved.
|
|
1661
|
+
*/
|
|
1662
|
+
private findParentRunId;
|
|
1578
1663
|
/** Track an in-flight execution so {@link drain} can wait for it. */
|
|
1579
1664
|
private track;
|
|
1580
1665
|
/**
|
|
@@ -2078,9 +2163,9 @@ declare class CodecStateStore implements StateStore {
|
|
|
2078
2163
|
raw: unknown;
|
|
2079
2164
|
saveCheckpoint: (cp: StepCheckpoint) => Promise<void>;
|
|
2080
2165
|
}) => Promise<T>): Promise<T>;
|
|
2081
|
-
listIncompleteRuns(): Promise<WorkflowRun[]>;
|
|
2082
|
-
listPendingRuns(limit: number): Promise<WorkflowRun[]>;
|
|
2083
|
-
listDueTimers(nowMs: number): Promise<WorkflowRun[]>;
|
|
2166
|
+
listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]>;
|
|
2167
|
+
listPendingRuns(limit: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
2168
|
+
listDueTimers(nowMs: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
2084
2169
|
tryLockRun(runId: string, owner: string, leaseUntilMs: number, nowMs: number): Promise<boolean>;
|
|
2085
2170
|
releaseRunLock(runId: string): Promise<void>;
|
|
2086
2171
|
renewRunLock(runId: string, owner: string, leaseUntilMs: number): Promise<boolean>;
|
|
@@ -2342,9 +2427,9 @@ declare class InMemoryStateStore implements StateStore {
|
|
|
2342
2427
|
deleteRun(runId: string): Promise<void>;
|
|
2343
2428
|
getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null>;
|
|
2344
2429
|
saveCheckpoint(checkpoint: StepCheckpoint): Promise<void>;
|
|
2345
|
-
listIncompleteRuns(): Promise<WorkflowRun[]>;
|
|
2346
|
-
listPendingRuns(limit: number): Promise<WorkflowRun[]>;
|
|
2347
|
-
listDueTimers(nowMs: number): Promise<WorkflowRun[]>;
|
|
2430
|
+
listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]>;
|
|
2431
|
+
listPendingRuns(limit: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
2432
|
+
listDueTimers(nowMs: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
2348
2433
|
tryLockRun(runId: string, owner: string, leaseUntilMs: number, nowMs: number): Promise<boolean>;
|
|
2349
2434
|
releaseRunLock(runId: string): Promise<void>;
|
|
2350
2435
|
renewRunLock(runId: string, owner: string, leaseUntilMs: number): Promise<boolean>;
|
package/dist/index.d.ts
CHANGED
|
@@ -246,6 +246,13 @@ interface WorkflowRun {
|
|
|
246
246
|
tags?: string[] | undefined;
|
|
247
247
|
/** Typed, queryable run data (e.g. `{ amount: 200, tier: 'pro' }`) — see {@link RunQuery.attributes}. */
|
|
248
248
|
searchAttributes?: SearchAttributes | undefined;
|
|
249
|
+
/**
|
|
250
|
+
* The worker-pool partition this run belongs to. Stamped at creation from the creating engine's
|
|
251
|
+
* `namespace` (default `'default'`). A worker only picks up / recovers / resumes-timers-for /
|
|
252
|
+
* times-out runs in its own namespace. `undefined` on a run created before this field existed; the
|
|
253
|
+
* store persists it as `'default'`. Read paths (dashboard, `getRun`) are NOT namespace-scoped.
|
|
254
|
+
*/
|
|
255
|
+
namespace?: string | undefined;
|
|
249
256
|
/**
|
|
250
257
|
* Dispatch priority for a REMOTE run (one advanced by a {@link WorkflowExecutor} over a broker):
|
|
251
258
|
* carried onto each {@link WorkflowTask} so an urgent child workflow can jump ahead of enqueued
|
|
@@ -433,11 +440,11 @@ interface StateStore {
|
|
|
433
440
|
*/
|
|
434
441
|
saveCheckpoint(checkpoint: StepCheckpoint): Promise<void>;
|
|
435
442
|
/** Used by recovery on boot to find runs to resume (crashed, left `running`). */
|
|
436
|
-
listIncompleteRuns(): Promise<WorkflowRun[]>;
|
|
443
|
+
listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]>;
|
|
437
444
|
/** The oldest `pending` runs awaiting dispatch (FIFO, by `createdAt`), capped at `limit`. */
|
|
438
|
-
listPendingRuns(limit: number): Promise<WorkflowRun[]>;
|
|
445
|
+
listPendingRuns(limit: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
439
446
|
/** Suspended runs whose durable timer is due (`wakeAt <= nowMs`), ready to resume. */
|
|
440
|
-
listDueTimers(nowMs: number): Promise<WorkflowRun[]>;
|
|
447
|
+
listDueTimers(nowMs: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
441
448
|
/**
|
|
442
449
|
* Atomically acquire the recovery lease on a run for `owner` until `leaseUntilMs`, but only if
|
|
443
450
|
* it is currently unlocked or its lease has expired (`<= nowMs`). Returns whether it was
|
|
@@ -549,6 +556,8 @@ interface RunQuery {
|
|
|
549
556
|
* `workflow`/`status`/`tag` to bound the scan on large stores.
|
|
550
557
|
*/
|
|
551
558
|
attributes?: AttributeFilter[] | undefined;
|
|
559
|
+
/** Restrict to runs in this namespace (exact match), ANDed with the other predicates. */
|
|
560
|
+
namespace?: string | undefined;
|
|
552
561
|
limit?: number | undefined;
|
|
553
562
|
offset?: number | undefined;
|
|
554
563
|
}
|
|
@@ -1336,6 +1345,13 @@ interface WorkflowEngineDeps {
|
|
|
1336
1345
|
admission?: AdmissionBackend | undefined;
|
|
1337
1346
|
/** Unique id for this engine instance, used for recovery leases. Defaults to a random id. */
|
|
1338
1347
|
instanceId?: string | undefined;
|
|
1348
|
+
/**
|
|
1349
|
+
* Worker-pool partition for this engine. Stamped on every run it creates; the poll paths
|
|
1350
|
+
* (`runPending`/`recoverIncomplete`/`resumeDueTimers`/`sweepTimeouts`) only act on runs in this
|
|
1351
|
+
* namespace. Default `'default'` — byte-identical to a single-pool deployment. Set distinct values
|
|
1352
|
+
* to safely share ONE state store across non-interchangeable pools (e.g. local dev vs a cluster).
|
|
1353
|
+
*/
|
|
1354
|
+
namespace?: string | undefined;
|
|
1339
1355
|
/** Recovery lease duration in ms — how long this instance owns a run it picked up. Default 30s. */
|
|
1340
1356
|
leaseMs?: number | undefined;
|
|
1341
1357
|
/**
|
|
@@ -1427,6 +1443,7 @@ declare class WorkflowEngine {
|
|
|
1427
1443
|
private readonly controlPlane?;
|
|
1428
1444
|
private readonly clock;
|
|
1429
1445
|
private readonly instanceId;
|
|
1446
|
+
private readonly namespace;
|
|
1430
1447
|
private readonly leaseMs;
|
|
1431
1448
|
private readonly maxRecoveryAttempts?;
|
|
1432
1449
|
private readonly remoteAdvanceSilenceMs?;
|
|
@@ -1503,6 +1520,16 @@ declare class WorkflowEngine {
|
|
|
1503
1520
|
* Register a workflow version. Register multiple versions of the same name to keep in-flight
|
|
1504
1521
|
* runs working across a breaking change: old runs resume on the version they started on, new
|
|
1505
1522
|
* runs start on the newest registered version.
|
|
1523
|
+
*
|
|
1524
|
+
* GROUP-SERVED (uniform dispatch, opt-in): pass `{ group, executor }` to have the engine DISPATCH
|
|
1525
|
+
* this workflow's turns to a worker `group` (via `executor.advance`) instead of running `fn`
|
|
1526
|
+
* inline — exactly as {@link registerRemote} does for a cross-SDK (e.g. Python) body, EXCEPT the
|
|
1527
|
+
* body is a TS `fn` the engine retains so an IN-APP worker on `group` can fetch it by name
|
|
1528
|
+
* ({@link workflowBody}) and run it. This is "one app, both roles": the same process owns the
|
|
1529
|
+
* engine AND consumes its own group. Recovery, timers, singleton, cancel and dead-lettering stay
|
|
1530
|
+
* engine concerns, identical to a remote run. OMIT `group`/`executor` (the default) to keep the
|
|
1531
|
+
* inline fast path — `fn` runs in-process and the run pays zero dispatch round-trips. The first
|
|
1532
|
+
* step toward routing every run through a group with no local/remote flag (Phase 3).
|
|
1506
1533
|
*/
|
|
1507
1534
|
register(name: string, version: string, fn: WorkflowFn, opts?: {
|
|
1508
1535
|
tags?: string[] | undefined;
|
|
@@ -1511,7 +1538,22 @@ declare class WorkflowEngine {
|
|
|
1511
1538
|
validateInput?: ((input: unknown) => void | Promise<void>) | undefined;
|
|
1512
1539
|
onEvent?: string[] | undefined;
|
|
1513
1540
|
eventBatch?: EventBatchConfig | undefined;
|
|
1541
|
+
/** Worker group to DISPATCH this workflow's turns to (uniform dispatch). Requires `executor`.
|
|
1542
|
+
* Omit for the default inline fast path. See the method doc. */
|
|
1543
|
+
group?: string | undefined;
|
|
1544
|
+
/** Advances a turn by dispatching a {@link WorkflowTask} to `group`. Requires `group`. For an
|
|
1545
|
+
* in-app worker, pair a transport-backed {@link RemoteWorkflowExecutor} (group consumed by a
|
|
1546
|
+
* worker that calls {@link workflowBody}) so the retained `fn` runs through the transport hop. */
|
|
1547
|
+
executor?: WorkflowExecutor | undefined;
|
|
1514
1548
|
}): void;
|
|
1549
|
+
/**
|
|
1550
|
+
* The retained in-process body for `name@version`, for an IN-APP worker that consumes this engine's
|
|
1551
|
+
* own group to SERVE a group-served `register(..., { group, executor })` workflow (uniform dispatch):
|
|
1552
|
+
* the worker fetches the body by name when it picks up the dispatched {@link WorkflowTask}, replays
|
|
1553
|
+
* it, and returns the {@link WorkflowDecision}. `undefined` for an unregistered name or a body-less
|
|
1554
|
+
* remote (a `registerRemote` / synthesized child carries only a throwing stub, never handed out).
|
|
1555
|
+
*/
|
|
1556
|
+
workflowBody(name: string, version: string): WorkflowFn | undefined;
|
|
1515
1557
|
/**
|
|
1516
1558
|
* Register a workflow whose body runs in another SDK (e.g. Python). The engine owns the run exactly
|
|
1517
1559
|
* as for a TS workflow — it persists checkpoints, recovers, runs timers — but advances it by handing
|
|
@@ -1575,6 +1617,49 @@ declare class WorkflowEngine {
|
|
|
1575
1617
|
/** Read a run's current persisted state (or null if unknown). A thin pass-through to the store. */
|
|
1576
1618
|
getRun(runId: string): Promise<WorkflowRun | null>;
|
|
1577
1619
|
resume(runId: string): Promise<RunResult>;
|
|
1620
|
+
/**
|
|
1621
|
+
* The registration for an UNREGISTERED run, INHERITED from its nearest REMOTE ancestor — or
|
|
1622
|
+
* `undefined` if it has none (the skew-protection error case in {@link resume}). Callers check the
|
|
1623
|
+
* flat registry FIRST (so an explicit `registerRemote(name, …)` ALWAYS wins, and a registered run
|
|
1624
|
+
* never reaches here); this resolves only the new case: a child spawned by a remote workflow (e.g. a
|
|
1625
|
+
* Python `gather_children` / `start_child` fan-out) of a name the host never `registerRemote`-ed. It
|
|
1626
|
+
* is driven as a remote run on the ancestor's group + the SAME executor instance, so the host needs
|
|
1627
|
+
* no redundant registration per child name.
|
|
1628
|
+
*
|
|
1629
|
+
* RECOMPUTED per resume rather than memoized into `this.workflows`: a synthesized child is not a real
|
|
1630
|
+
* registration and must not leak into `latest`, `knownGroups`, or `sweepTimeouts` (which iterate the
|
|
1631
|
+
* registry); recomputing also stays correct if the ancestor's remote registration is re-pointed at a
|
|
1632
|
+
* new executor across a deploy. Only unregistered runs pay it, so registered workflows pay nothing.
|
|
1633
|
+
*/
|
|
1634
|
+
private findInheritedRegistration;
|
|
1635
|
+
/**
|
|
1636
|
+
* A throwaway {@link RegisteredWorkflow} that routes `name@version` as a remote run on the ancestor's
|
|
1637
|
+
* group via the ancestor's SAME executor instance. The executor is group-scoped (it dispatches a
|
|
1638
|
+
* {@link WorkflowTask} carrying `run.workflow`, and the worker picks the body by name), so reusing it
|
|
1639
|
+
* is correct AND required — a second executor on the same group would race the worker for results.
|
|
1640
|
+
* Only `remote` is inherited; the child gets none of the ancestor's singleton/timeout/validator, so
|
|
1641
|
+
* its identity stays its own.
|
|
1642
|
+
*/
|
|
1643
|
+
private synthesizeRemoteChild;
|
|
1644
|
+
/**
|
|
1645
|
+
* Walk the parent chain of `childRunId` to the nearest ancestor registered as REMOTE, returning its
|
|
1646
|
+
* registration (or `undefined` if there is none). The parent of an awaited child is found via its
|
|
1647
|
+
* live `child:<childId>` signal waiter — present for as long as the parent is suspended awaiting the
|
|
1648
|
+
* child, i.e. throughout the child's executable lifetime (start, every resume, crash recovery, cancel
|
|
1649
|
+
* cascade), which is exactly when we resolve. A registered-but-LOCAL parent stops the walk (an
|
|
1650
|
+
* unregistered child of a TS workflow is a genuine misconfiguration → skew error); only an
|
|
1651
|
+
* unregistered parent keeps walking, so a child of an inherited child still reaches the remote root.
|
|
1652
|
+
* `visited` guards against a pathological cyclic id graph.
|
|
1653
|
+
*/
|
|
1654
|
+
private findRemoteAncestor;
|
|
1655
|
+
/**
|
|
1656
|
+
* The run that spawned `childRunId`, via its live `child:<childRunId>` signal waiter — every awaited
|
|
1657
|
+
* child (`ctx.child`, `ctx.all`, a remote `start_child`) suspends its parent on exactly this waiter,
|
|
1658
|
+
* and the waiter is written BEFORE the child is started. Only reached for an UNREGISTERED child, so
|
|
1659
|
+
* registered runs never pay the scan; returns `undefined` once the parent has settled the child (the
|
|
1660
|
+
* waiter is consumed), but by then the child is terminal and no longer resolved.
|
|
1661
|
+
*/
|
|
1662
|
+
private findParentRunId;
|
|
1578
1663
|
/** Track an in-flight execution so {@link drain} can wait for it. */
|
|
1579
1664
|
private track;
|
|
1580
1665
|
/**
|
|
@@ -2078,9 +2163,9 @@ declare class CodecStateStore implements StateStore {
|
|
|
2078
2163
|
raw: unknown;
|
|
2079
2164
|
saveCheckpoint: (cp: StepCheckpoint) => Promise<void>;
|
|
2080
2165
|
}) => Promise<T>): Promise<T>;
|
|
2081
|
-
listIncompleteRuns(): Promise<WorkflowRun[]>;
|
|
2082
|
-
listPendingRuns(limit: number): Promise<WorkflowRun[]>;
|
|
2083
|
-
listDueTimers(nowMs: number): Promise<WorkflowRun[]>;
|
|
2166
|
+
listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]>;
|
|
2167
|
+
listPendingRuns(limit: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
2168
|
+
listDueTimers(nowMs: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
2084
2169
|
tryLockRun(runId: string, owner: string, leaseUntilMs: number, nowMs: number): Promise<boolean>;
|
|
2085
2170
|
releaseRunLock(runId: string): Promise<void>;
|
|
2086
2171
|
renewRunLock(runId: string, owner: string, leaseUntilMs: number): Promise<boolean>;
|
|
@@ -2342,9 +2427,9 @@ declare class InMemoryStateStore implements StateStore {
|
|
|
2342
2427
|
deleteRun(runId: string): Promise<void>;
|
|
2343
2428
|
getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null>;
|
|
2344
2429
|
saveCheckpoint(checkpoint: StepCheckpoint): Promise<void>;
|
|
2345
|
-
listIncompleteRuns(): Promise<WorkflowRun[]>;
|
|
2346
|
-
listPendingRuns(limit: number): Promise<WorkflowRun[]>;
|
|
2347
|
-
listDueTimers(nowMs: number): Promise<WorkflowRun[]>;
|
|
2430
|
+
listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]>;
|
|
2431
|
+
listPendingRuns(limit: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
2432
|
+
listDueTimers(nowMs: number, namespace?: string): Promise<WorkflowRun[]>;
|
|
2348
2433
|
tryLockRun(runId: string, owner: string, leaseUntilMs: number, nowMs: number): Promise<boolean>;
|
|
2349
2434
|
releaseRunLock(runId: string): Promise<void>;
|
|
2350
2435
|
renewRunLock(runId: string, owner: string, leaseUntilMs: number): Promise<boolean>;
|