@lostgradient/weft 0.16.0 → 0.18.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/README.md +1 -1
- package/dist/alerting/alert-manager.d.ts +5 -5
- package/dist/alerting/alert-manager.js +24 -6
- package/dist/alerting/index.d.ts +1 -1
- package/dist/alerting/types.d.ts +17 -13
- package/dist/alerting/types.js +5 -0
- package/dist/cli/generated/operation-catalog.snapshot.json +73 -0
- package/dist/cli/generated/operation-client.generated.d.ts +11 -2
- package/dist/cli/generated/operation-client.generated.js +2 -0
- package/dist/core/engine/disposal.js +7 -0
- package/dist/core/engine/engine-runtime-helpers.d.ts +3 -1
- package/dist/core/engine/engine-runtime-helpers.js +2 -2
- package/dist/core/engine/errors.d.ts +20 -0
- package/dist/core/engine/errors.js +8 -0
- package/dist/core/engine/index.d.ts +39 -17
- package/dist/core/engine/index.js +81 -9
- package/dist/core/engine/inline-launch-queue.d.ts +6 -2
- package/dist/core/engine/inline-launch-queue.js +41 -6
- package/dist/core/engine/internals.d.ts +2 -0
- package/dist/core/engine/lease-manager.d.ts +3 -2
- package/dist/core/engine/lease-manager.js +7 -3
- package/dist/core/engine/operations-time.js +6 -0
- package/dist/core/execution-strategy.d.ts +8 -0
- package/dist/core/inline-execution-strategy.d.ts +1 -0
- package/dist/core/inline-execution-strategy.js +33 -20
- package/dist/core/weft-error.d.ts +1 -1
- package/dist/core/weft-error.js +1 -0
- package/dist/core/worker-execution-strategy.d.ts +2 -0
- package/dist/core/worker-execution-strategy.js +7 -2
- package/dist/core/worker-turn-watchdog.d.ts +4 -1
- package/dist/core/worker-turn-watchdog.js +9 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -0
- package/dist/indexeddb.js +1 -1
- package/dist/json-schema.js +1 -1
- package/dist/mcp/tools.js +1 -3
- package/dist/server/authorization-scope.d.ts +32 -2
- package/dist/server/dashboard-assets.d.ts +12 -1
- package/dist/server/dashboard-assets.js +145 -31
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +4 -0
- package/dist/server/operations/aggregate-workflows.js +0 -7
- package/dist/server/operations/async-activity.js +5 -24
- package/dist/server/operations/bulk-cancel-workflows.js +3 -8
- package/dist/server/operations/bulk-delete-workflows.js +3 -8
- package/dist/server/operations/bulk-mutate-workflow-tags.js +3 -8
- package/dist/server/operations/bulk-operation-helpers.d.ts +2 -10
- package/dist/server/operations/bulk-operation-helpers.js +0 -6
- package/dist/server/operations/bulk-retry-failed-workflows.js +3 -8
- package/dist/server/operations/bulk-signal-workflows.js +3 -8
- package/dist/server/operations/cancel-schedule.js +1 -3
- package/dist/server/operations/cancel-workflow.js +1 -3
- package/dist/server/operations/create-schedule.js +2 -3
- package/dist/server/operations/fork-workflow.js +2 -3
- package/dist/server/operations/get-checkpoint-at.js +1 -6
- package/dist/server/operations/get-principal.d.ts +75 -0
- package/dist/server/operations/get-principal.js +41 -0
- package/dist/server/operations/get-registry.js +1 -7
- package/dist/server/operations/get-retention-overview.js +2 -15
- package/dist/server/operations/get-review.js +2 -15
- package/dist/server/operations/get-schedule.js +2 -8
- package/dist/server/operations/get-stream-chunks.js +2 -6
- package/dist/server/operations/get-system-lease.js +1 -7
- package/dist/server/operations/get-system-metrics.js +0 -4
- package/dist/server/operations/get-task-diagnostics.js +2 -13
- package/dist/server/operations/get-update-result.js +1 -6
- package/dist/server/operations/get-workflow-attributes.js +2 -15
- package/dist/server/operations/get-workflow-events.js +2 -15
- package/dist/server/operations/get-workflow-observability.js +2 -5
- package/dist/server/operations/get-workflow-result.js +0 -7
- package/dist/server/operations/get-workflow-timeline.js +1 -6
- package/dist/server/operations/get-workflow.d.ts +3 -6
- package/dist/server/operations/get-workflow.js +2 -12
- package/dist/server/operations/list-alerts.d.ts +5 -2
- package/dist/server/operations/list-alerts.js +2 -9
- package/dist/server/operations/list-checkpoints.js +1 -6
- package/dist/server/operations/list-reviews.js +0 -7
- package/dist/server/operations/list-schedules.js +3 -8
- package/dist/server/operations/list-task-queues.js +0 -4
- package/dist/server/operations/list-workers.js +0 -4
- package/dist/server/operations/list-workflows.js +0 -7
- package/dist/server/operations/pause-schedule.js +1 -3
- package/dist/server/operations/purge-workflows.js +2 -5
- package/dist/server/operations/query-workflow.js +4 -15
- package/dist/server/operations/replay-workflow.js +2 -6
- package/dist/server/operations/resume-schedule.js +1 -3
- package/dist/server/operations/resume-workflow.js +1 -3
- package/dist/server/operations/set-workflow-attributes.js +3 -15
- package/dist/server/operations/signal-workflow.js +3 -12
- package/dist/server/operations/single-workflow-tag-mutation.js +0 -7
- package/dist/server/operations/start-or-signal-workflow.js +2 -3
- package/dist/server/operations/start-workflow.js +2 -3
- package/dist/server/operations/static-registrations.d.ts +28 -0
- package/dist/server/operations/static-registrations.js +263 -0
- package/dist/server/operations/storage-capabilities.js +1 -3
- package/dist/server/operations/storage.js +7 -13
- package/dist/server/operations/submit-review-decision.js +3 -12
- package/dist/server/operations/suspend-workflow.js +1 -3
- package/dist/server/operations/timeout-workflow.js +1 -3
- package/dist/server/operations/update-schedule.js +1 -3
- package/dist/server/operations/update-workflow.js +2 -3
- package/dist/server/operations/worker-drain.js +0 -8
- package/dist/server/rest-binding.d.ts +3 -2
- package/dist/server/rest-bindings.d.ts +5 -0
- package/dist/server/rest-bindings.js +4 -312
- package/dist/server/route-model.d.ts +2 -0
- package/dist/server/route-model.js +1 -1
- package/dist/server/runtime/task-reconciliation.d.ts +10 -1
- package/dist/server/runtime/task-reconciliation.js +26 -2
- package/dist/server/serve-internals.js +12 -6
- package/dist/storage/indexeddb.js +28 -48
- package/dist/storage/testing.d.ts +6 -3
- package/dist/storage/testing.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker/protocol-schemas.d.ts +2 -2
- package/dist/worker/protocol-schemas.js +2 -2
- package/dist/worker/protocol.js +1 -1
- package/package.json +1 -1
|
@@ -79,6 +79,7 @@ import {
|
|
|
79
79
|
} from "./engine-runtime-helpers.js";
|
|
80
80
|
import {
|
|
81
81
|
EngineCreateNameMismatchError,
|
|
82
|
+
EngineDisposalError,
|
|
82
83
|
EngineDisposedError,
|
|
83
84
|
StartOrSignalConflictError
|
|
84
85
|
} from "./errors.js";
|
|
@@ -194,6 +195,7 @@ export {
|
|
|
194
195
|
BulkDeleteRequiresTerminalWorkflowsError,
|
|
195
196
|
BulkOperationConfirmationError,
|
|
196
197
|
EngineCreateNameMismatchError,
|
|
198
|
+
EngineDisposalError,
|
|
197
199
|
EngineDisposedError,
|
|
198
200
|
IdempotencyKeyPurgedError,
|
|
199
201
|
PersistedDataIncompatibleError,
|
|
@@ -222,7 +224,7 @@ export {
|
|
|
222
224
|
shouldEmitEngineLeakWarningForTesting
|
|
223
225
|
} from "./engine-leak-warnings.js";
|
|
224
226
|
export { assertCompatiblePersistedDataVersion };
|
|
225
|
-
export const ENGINE_PARKED_WORKFLOW_COUNT_FOR_TESTING = Symbol("engineParkedWorkflowCountForTesting"), ENGINE_SIGNAL_WAITER_COUNT_FOR_TESTING = Symbol("engineSignalWaiterCountForTesting"), ENGINE_SLEEP_RESOLVER_COUNT_FOR_TESTING = Symbol("engineSleepResolverCountForTesting"), ENGINE_LEASE_SYNCHRONOUS_DISPOSE_WARNING_NAME = "WeftEngineLeaseSynchronousDisposeWarning";
|
|
227
|
+
export const ENGINE_PARKED_WORKFLOW_COUNT_FOR_TESTING = Symbol("engineParkedWorkflowCountForTesting"), ENGINE_SIGNAL_WAITER_COUNT_FOR_TESTING = Symbol("engineSignalWaiterCountForTesting"), ENGINE_SLEEP_RESOLVER_COUNT_FOR_TESTING = Symbol("engineSleepResolverCountForTesting"), ENGINE_WAIT_FOR_SLEEP_RESOLVER_FOR_TESTING = Symbol("engineWaitForSleepResolverForTesting"), ENGINE_SET_WORKER_TURN_TIMEOUT_RESOLVER_FOR_TESTING = Symbol("engineSetWorkerTurnTimeoutResolverForTesting"), SLEEP_RESOLVER_READY_WAIT_TIMEOUT_MS_FOR_TESTING = 3000, ENGINE_LEASE_SYNCHRONOUS_DISPOSE_WARNING_NAME = "WeftEngineLeaseSynchronousDisposeWarning";
|
|
226
228
|
|
|
227
229
|
export { ENGINE_LEASE_LOST_WARNING_NAME };
|
|
228
230
|
function scheduleDefinitionFromInternals(internals, definition) {
|
|
@@ -237,6 +239,9 @@ function scheduleDefinitionFromInternals(internals, definition) {
|
|
|
237
239
|
}
|
|
238
240
|
|
|
239
241
|
export class Engine extends EventTarget {
|
|
242
|
+
#asyncDisposeResult = null;
|
|
243
|
+
#shutdownResult = null;
|
|
244
|
+
#synchronousDisposeResult = null;
|
|
240
245
|
static async create(options) {
|
|
241
246
|
validateEngineCreateBackgroundTaskOptions(options);
|
|
242
247
|
const engine = new Engine(options);
|
|
@@ -294,6 +299,7 @@ export class Engine extends EventTarget {
|
|
|
294
299
|
getInternals(this).updateWaitersByWorkflow = new Map;
|
|
295
300
|
getInternals(this).sleepResolvers = new Map;
|
|
296
301
|
getInternals(this).sleepResolversByWorkflow = new Map;
|
|
302
|
+
getInternals(this).sleepResolverReadyWaitersForTesting = new Map;
|
|
297
303
|
getInternals(this).sleepTimerAcknowledgementWaiters = new Map;
|
|
298
304
|
getInternals(this).durableInlineOperations = new Map;
|
|
299
305
|
getInternals(this).sleepTimersFiredWithoutResolver = new Map;
|
|
@@ -434,7 +440,9 @@ export class Engine extends EventTarget {
|
|
|
434
440
|
throw error;
|
|
435
441
|
}
|
|
436
442
|
if (internals.disposed) {
|
|
437
|
-
|
|
443
|
+
const releaseResult = manager.release();
|
|
444
|
+
this.#synchronousDisposeResult = releaseResult;
|
|
445
|
+
await releaseResult;
|
|
438
446
|
if (internals.leaseManager === manager)
|
|
439
447
|
internals.leaseManager = null;
|
|
440
448
|
throw new EngineDisposedError;
|
|
@@ -455,7 +463,9 @@ export class Engine extends EventTarget {
|
|
|
455
463
|
return;
|
|
456
464
|
const leaseManager = internals.leaseManager;
|
|
457
465
|
disposeEngine(internals);
|
|
458
|
-
|
|
466
|
+
if (this.#synchronousDisposeResult === null)
|
|
467
|
+
this.#synchronousDisposeResult = (leaseManager?.release() ?? Promise.resolve(!0)).catch(() => !1);
|
|
468
|
+
this.#synchronousDisposeResult;
|
|
459
469
|
}
|
|
460
470
|
#startSecondInstanceDetection() {
|
|
461
471
|
const internals = getInternals(this);
|
|
@@ -699,6 +709,34 @@ export class Engine extends EventTarget {
|
|
|
699
709
|
[ENGINE_SLEEP_RESOLVER_COUNT_FOR_TESTING]() {
|
|
700
710
|
return getInternals(this).sleepResolvers.size;
|
|
701
711
|
}
|
|
712
|
+
async[ENGINE_WAIT_FOR_SLEEP_RESOLVER_FOR_TESTING](workflowId) {
|
|
713
|
+
const internals = getInternals(this);
|
|
714
|
+
if (internals.sleepResolversByWorkflow.has(workflowId))
|
|
715
|
+
return;
|
|
716
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
717
|
+
let waiters = internals.sleepResolverReadyWaitersForTesting?.get(workflowId);
|
|
718
|
+
if (waiters === void 0) {
|
|
719
|
+
waiters = new Set;
|
|
720
|
+
internals.sleepResolverReadyWaitersForTesting?.set(workflowId, waiters);
|
|
721
|
+
}
|
|
722
|
+
waiters.add(resolve);
|
|
723
|
+
const expiry = setTimeout(() => {
|
|
724
|
+
const pendingWaiters = internals.sleepResolverReadyWaitersForTesting?.get(workflowId);
|
|
725
|
+
if (pendingWaiters !== void 0) {
|
|
726
|
+
pendingWaiters.delete(resolve);
|
|
727
|
+
if (pendingWaiters.size === 0)
|
|
728
|
+
internals.sleepResolverReadyWaitersForTesting?.delete(workflowId);
|
|
729
|
+
}
|
|
730
|
+
reject(Error(`Timed out after ${SLEEP_RESOLVER_READY_WAIT_TIMEOUT_MS_FOR_TESTING}ms waiting for workflow "${workflowId}" to register a sleep resolver`));
|
|
731
|
+
}, SLEEP_RESOLVER_READY_WAIT_TIMEOUT_MS_FOR_TESTING);
|
|
732
|
+
return await promise.finally(() => clearTimeout(expiry));
|
|
733
|
+
}
|
|
734
|
+
[ENGINE_SET_WORKER_TURN_TIMEOUT_RESOLVER_FOR_TESTING](resolver) {
|
|
735
|
+
const strategy = getInternals(this).strategy;
|
|
736
|
+
if (strategy.setWorkflowTurnTimeoutResolverForTesting === void 0)
|
|
737
|
+
throw Error("Worker turn timeout resolver is only available in Worker execution mode");
|
|
738
|
+
strategy.setWorkflowTurnTimeoutResolverForTesting(resolver);
|
|
739
|
+
}
|
|
702
740
|
async signal(workflowId, nameOrDefinition, payload, options) {
|
|
703
741
|
return signalWorkflow(getInternals(this), workflowId, messageName(nameOrDefinition), payload, {
|
|
704
742
|
loadWorkflowState: (id) => loadWorkflowState(getInternals(this), id),
|
|
@@ -871,28 +909,62 @@ export class Engine extends EventTarget {
|
|
|
871
909
|
return submitCoordinatedUpdateFromInternals(getInternals(this), workflowId, name, payload, options, this.#createUpdateCallbacks());
|
|
872
910
|
}
|
|
873
911
|
async shutdown() {
|
|
874
|
-
|
|
912
|
+
if (this.#shutdownResult === null)
|
|
913
|
+
this.#shutdownResult = (async () => {
|
|
914
|
+
await this[Symbol.asyncDispose]();
|
|
915
|
+
const baseResult = this.#asyncDisposeResult;
|
|
916
|
+
if (baseResult === null) {
|
|
917
|
+
await getInternals(this).inFlightLeaseAcquire?.catch(() => {});
|
|
918
|
+
return await this.#synchronousDisposeResult ?? !0;
|
|
919
|
+
}
|
|
920
|
+
try {
|
|
921
|
+
return await baseResult;
|
|
922
|
+
} catch (error) {
|
|
923
|
+
return error instanceof EngineDisposalError ? error.leaseReleased : !0;
|
|
924
|
+
}
|
|
925
|
+
})();
|
|
926
|
+
return this.#shutdownResult;
|
|
875
927
|
}
|
|
876
928
|
[Symbol.dispose]() {
|
|
929
|
+
if (this.#asyncDisposeResult !== null) {
|
|
930
|
+
this.#asyncDisposeResult;
|
|
931
|
+
return;
|
|
932
|
+
}
|
|
877
933
|
const leaseManager = getInternals(this).leaseManager;
|
|
878
934
|
if (leaseManager !== null && leaseManager.currentEpochBytes() !== null)
|
|
879
935
|
process.emitWarning("engine ownership lease disposed synchronously; lease release is fire-and-forget, so exiting before the release completes can make the next instance wait for leaseTtl. Use await engine.shutdown(), await using, or await engine[Symbol.asyncDispose]() for prompt rolling-deploy handoff.", ENGINE_LEASE_SYNCHRONOUS_DISPOSE_WARNING_NAME);
|
|
880
936
|
disposeEngine(getInternals(this));
|
|
881
|
-
|
|
937
|
+
if (this.#synchronousDisposeResult === null)
|
|
938
|
+
this.#synchronousDisposeResult = leaseManager?.release() ?? Promise.resolve(!0);
|
|
939
|
+
this.#synchronousDisposeResult;
|
|
882
940
|
}
|
|
883
|
-
async
|
|
941
|
+
async#disposeAsyncWithLeaseResult() {
|
|
884
942
|
if (!getInternals(this).disposed) {
|
|
885
943
|
const leaseManager = getInternals(this).leaseManager;
|
|
944
|
+
let leaseReleased = !0, drainFailure = null;
|
|
886
945
|
try {
|
|
887
|
-
await drainQueuedInlineWorkflowStartsForEngine(this
|
|
946
|
+
await drainQueuedInlineWorkflowStartsForEngine(this, {
|
|
947
|
+
abortStartedWorkflows: !0
|
|
948
|
+
});
|
|
949
|
+
} catch (error) {
|
|
950
|
+
drainFailure = { error };
|
|
888
951
|
} finally {
|
|
889
952
|
disposeEngine(getInternals(this));
|
|
890
953
|
await getInternals(this).inFlightLeaseAcquire?.catch(() => {});
|
|
891
|
-
await leaseManager?.release();
|
|
954
|
+
leaseReleased = await (this.#synchronousDisposeResult ?? leaseManager?.release() ?? Promise.resolve(!0));
|
|
892
955
|
}
|
|
893
|
-
|
|
956
|
+
if (drainFailure !== null)
|
|
957
|
+
throw new EngineDisposalError(drainFailure.error, leaseReleased);
|
|
958
|
+
return leaseReleased;
|
|
894
959
|
}
|
|
895
960
|
this[Symbol.dispose]();
|
|
961
|
+
await getInternals(this).inFlightLeaseAcquire?.catch(() => {});
|
|
962
|
+
return await this.#synchronousDisposeResult ?? !0;
|
|
963
|
+
}
|
|
964
|
+
async[Symbol.asyncDispose]() {
|
|
965
|
+
if (this.#asyncDisposeResult === null)
|
|
966
|
+
this.#asyncDisposeResult = this.#disposeAsyncWithLeaseResult();
|
|
967
|
+
await this.#asyncDisposeResult;
|
|
896
968
|
}
|
|
897
969
|
get storage() {
|
|
898
970
|
return getInternals(this).storage;
|
|
@@ -6,7 +6,9 @@ export type InlineLaunchQueueCallbacks = {
|
|
|
6
6
|
};
|
|
7
7
|
/** Queue a new inline workflow start and schedule a flush if one is not already scheduled. */
|
|
8
8
|
export declare function queueInlineWorkflowExecutionStart(internals: EngineInternals, start: QueuedInlineWorkflowExecutionStart, callbacks: InlineLaunchQueueCallbacks): void;
|
|
9
|
-
export declare function flushQueuedInlineWorkflowStarts(internals: EngineInternals, callbacks: InlineLaunchQueueCallbacks
|
|
9
|
+
export declare function flushQueuedInlineWorkflowStarts(internals: EngineInternals, callbacks: InlineLaunchQueueCallbacks, options?: {
|
|
10
|
+
abortStartedWorkflows?: boolean;
|
|
11
|
+
}): Promise<void>;
|
|
10
12
|
/** Used by scheduler-driven direct backfill flushes. Clears the scheduled flag first. */
|
|
11
13
|
export declare function flushQueuedInlineWorkflowStartsDirectly(internals: EngineInternals, callbacks: InlineLaunchQueueCallbacks): Promise<void>;
|
|
12
14
|
/**
|
|
@@ -22,7 +24,9 @@ export declare function flushQueuedInlineWorkflowStartsDirectly(internals: Engin
|
|
|
22
24
|
* is left for the synchronous `disposeQueuedInlineWorkflowStarts` path, which
|
|
23
25
|
* discards it and settles its `defer: false` awaiter.
|
|
24
26
|
*/
|
|
25
|
-
export declare function drainQueuedInlineWorkflowStarts(internals: EngineInternals, callbacks: InlineLaunchQueueCallbacks
|
|
27
|
+
export declare function drainQueuedInlineWorkflowStarts(internals: EngineInternals, callbacks: InlineLaunchQueueCallbacks, options?: {
|
|
28
|
+
abortStartedWorkflows?: boolean;
|
|
29
|
+
}): Promise<void>;
|
|
26
30
|
export declare function dropQueuedInlineWorkflowStart(internals: EngineInternals, workflowId: string): boolean;
|
|
27
31
|
export declare function disposeQueuedInlineWorkflowStarts(internals: EngineInternals): void;
|
|
28
32
|
export declare function hasQueuedInlineWorkflowStart(internals: EngineInternals, workflowId: string): boolean;
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import { WorkflowStartedEvent } from "../events.js";
|
|
2
2
|
import { startWorkflowExecution } from "./lifecycle.js";
|
|
3
3
|
import { loadWorkflowState } from "./storage-io.js";
|
|
4
|
+
async function yieldQueuedShutdownAdvanceOpportunity() {
|
|
5
|
+
await new Promise((resolve) => {
|
|
6
|
+
setTimeout(resolve, 0);
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
async function settleQueuedShutdownWork(pendingWork) {
|
|
10
|
+
if (pendingWork.length === 0)
|
|
11
|
+
return [];
|
|
12
|
+
const opportunityElapsed = yieldQueuedShutdownAdvanceOpportunity().then(() => !1);
|
|
13
|
+
return (await Promise.all(pendingWork.map(async ({ workflowId, promise }) => {
|
|
14
|
+
if (promise === void 0)
|
|
15
|
+
return workflowId;
|
|
16
|
+
return await Promise.race([promise.then(() => !0), opportunityElapsed]) ? workflowId : null;
|
|
17
|
+
}))).filter((workflowId) => workflowId !== null);
|
|
18
|
+
}
|
|
4
19
|
export function queueInlineWorkflowExecutionStart(internals, start, callbacks) {
|
|
5
20
|
internals.queuedInlineWorkflowStartIds.add(start.workflowId);
|
|
6
21
|
internals.queuedOrLaunchingInlineWorkflowStartIds.add(start.workflowId);
|
|
@@ -24,7 +39,7 @@ function settleDiscardedInlineStarts(internals, discarded) {
|
|
|
24
39
|
start.onStarted?.();
|
|
25
40
|
}
|
|
26
41
|
}
|
|
27
|
-
export async function flushQueuedInlineWorkflowStarts(internals, callbacks) {
|
|
42
|
+
export async function flushQueuedInlineWorkflowStarts(internals, callbacks, options) {
|
|
28
43
|
if (internals.abortController.signal.aborted) {
|
|
29
44
|
const discarded = internals.queuedInlineWorkflowStarts;
|
|
30
45
|
internals.queuedInlineWorkflowStarts = [];
|
|
@@ -36,22 +51,39 @@ export async function flushQueuedInlineWorkflowStarts(internals, callbacks) {
|
|
|
36
51
|
const pendingStarts = internals.queuedInlineWorkflowStarts;
|
|
37
52
|
internals.queuedInlineWorkflowStarts = [];
|
|
38
53
|
for (const start of pendingStarts)
|
|
39
|
-
await callbacks.swallowPromiseRejection(startQueuedInlineWorkflowExecution(internals, start, callbacks));
|
|
54
|
+
await callbacks.swallowPromiseRejection(startQueuedInlineWorkflowExecution(internals, start, callbacks, options));
|
|
40
55
|
}
|
|
41
56
|
export async function flushQueuedInlineWorkflowStartsDirectly(internals, callbacks) {
|
|
42
57
|
internals.queuedInlineWorkflowStartFlushScheduled = !1;
|
|
43
58
|
await flushQueuedInlineWorkflowStarts(internals, callbacks);
|
|
44
59
|
}
|
|
45
|
-
export async function drainQueuedInlineWorkflowStarts(internals, callbacks) {
|
|
60
|
+
export async function drainQueuedInlineWorkflowStarts(internals, callbacks, options) {
|
|
46
61
|
internals.queuedInlineWorkflowStartFlushScheduled = !1;
|
|
47
62
|
let passes = 0;
|
|
48
63
|
const maxPasses = 1000;
|
|
49
64
|
while (internals.queuedInlineWorkflowStarts.length > 0 && !internals.abortController.signal.aborted && passes < maxPasses) {
|
|
50
65
|
passes += 1;
|
|
51
|
-
|
|
66
|
+
const workflowIds = internals.queuedInlineWorkflowStarts.map((start) => start.workflowId);
|
|
67
|
+
await callbacks.swallowPromiseRejection(flushQueuedInlineWorkflowStarts(internals, callbacks, options));
|
|
68
|
+
const pendingAdvances = workflowIds.map((workflowId) => {
|
|
69
|
+
const pendingAdvance = internals.inlineStrategy?.waitForWorkflowAdvance(workflowId);
|
|
70
|
+
return {
|
|
71
|
+
workflowId,
|
|
72
|
+
promise: pendingAdvance === void 0 ? void 0 : callbacks.swallowPromiseRejection(pendingAdvance)
|
|
73
|
+
};
|
|
74
|
+
}), settledWorkflowIds = await settleQueuedShutdownWork(pendingAdvances);
|
|
75
|
+
if (settledWorkflowIds.length > 0) {
|
|
76
|
+
const terminalTurns = settledWorkflowIds.flatMap((workflowId) => {
|
|
77
|
+
if (internals.inlineStrategy?.hasGenerator(workflowId))
|
|
78
|
+
return [];
|
|
79
|
+
const pendingTurn = internals.inlineStrategy?.waitForWorkflowTurn(workflowId);
|
|
80
|
+
return pendingTurn === void 0 ? [] : [callbacks.swallowPromiseRejection(pendingTurn)];
|
|
81
|
+
});
|
|
82
|
+
await Promise.all(terminalTurns);
|
|
83
|
+
}
|
|
52
84
|
}
|
|
53
85
|
}
|
|
54
|
-
async function startQueuedInlineWorkflowExecution(internals, start, callbacks) {
|
|
86
|
+
async function startQueuedInlineWorkflowExecution(internals, start, callbacks, options) {
|
|
55
87
|
try {
|
|
56
88
|
const state = await loadWorkflowState(internals, start.workflowId);
|
|
57
89
|
if (!state || state.status !== "running")
|
|
@@ -59,7 +91,10 @@ async function startQueuedInlineWorkflowExecution(internals, start, callbacks) {
|
|
|
59
91
|
internals.queuedInlineWorkflowStartIds.delete(start.workflowId);
|
|
60
92
|
internals.engine.dispatchEvent(new WorkflowStartedEvent(start.workflowId, start.workflowType, start.input));
|
|
61
93
|
startWorkflowExecution(internals, start.workflowId, state.workflowExecutionToken, start.workflowType, start.input, start.checkpoint, start.nestingDepth, start.executionDeadline, start.executionStateOwnerId);
|
|
62
|
-
|
|
94
|
+
if (options?.abortStartedWorkflows === !0)
|
|
95
|
+
internals.inlineStrategy?.abortWorkflowAdvanceForShutdown(start.workflowId);
|
|
96
|
+
else
|
|
97
|
+
await callbacks.processPendingUpdatesAfterInlineAdvance(start.workflowId);
|
|
63
98
|
} finally {
|
|
64
99
|
internals.queuedInlineWorkflowStartIds.delete(start.workflowId);
|
|
65
100
|
internals.queuedOrLaunchingInlineWorkflowStartIds.delete(start.workflowId);
|
|
@@ -114,6 +114,8 @@ export interface EngineInternals {
|
|
|
114
114
|
fireAt: number;
|
|
115
115
|
}>;
|
|
116
116
|
sleepResolversByWorkflow: Map<string, Set<string>>;
|
|
117
|
+
/** Test-only event waiters notified when a workflow registers a sleep resolver. */
|
|
118
|
+
sleepResolverReadyWaitersForTesting?: Map<string, Set<() => void>>;
|
|
117
119
|
/**
|
|
118
120
|
* Fired sleep timers awaiting proof that the awakened inline workflow reached
|
|
119
121
|
* its next durable checkpoint or terminal state. External schedulers must not
|
|
@@ -95,7 +95,8 @@ export type LeaseManagerOptions = {
|
|
|
95
95
|
* - `currentEpochBytes()` returns the held epoch as bytes for Step-2 fencing
|
|
96
96
|
* conditions; `null` before a successful acquire. Synchronous and stable across
|
|
97
97
|
* renewals.
|
|
98
|
-
* - `release()` best-effort relinquishes the lease (holder key only) on dispose
|
|
98
|
+
* - `release()` best-effort relinquishes the lease (holder key only) on dispose
|
|
99
|
+
* and resolves to whether the holder delete committed.
|
|
99
100
|
*/
|
|
100
101
|
export type LeaseManager = {
|
|
101
102
|
acquire(): Promise<void>;
|
|
@@ -104,7 +105,7 @@ export type LeaseManager = {
|
|
|
104
105
|
currentEpochBytes(): Uint8Array | null;
|
|
105
106
|
/** Return a defensive, synchronous view of this process's last-known lease state. */
|
|
106
107
|
health(): LeaseManagerHealth;
|
|
107
|
-
release(): Promise<
|
|
108
|
+
release(): Promise<boolean>;
|
|
108
109
|
stop(): void;
|
|
109
110
|
};
|
|
110
111
|
/**
|
|
@@ -149,11 +149,15 @@ export function createLeaseManager(options) {
|
|
|
149
149
|
if (inFlightRenewal !== null)
|
|
150
150
|
await inFlightRenewal;
|
|
151
151
|
if (lastHolderBytes === null)
|
|
152
|
-
return;
|
|
152
|
+
return !0;
|
|
153
153
|
try {
|
|
154
|
-
|
|
154
|
+
const deleted = await storageConditionalBatch(storage, [{ key: KEYS.leaseHolder(), expectedValue: lastHolderBytes }], [{ type: "delete", key: KEYS.leaseHolder() }]);
|
|
155
|
+
if (deleted)
|
|
155
156
|
lastHolderBytes = null;
|
|
156
|
-
|
|
157
|
+
return deleted;
|
|
158
|
+
} catch {
|
|
159
|
+
return !1;
|
|
160
|
+
}
|
|
157
161
|
}
|
|
158
162
|
function stop() {
|
|
159
163
|
stopped = !0;
|
|
@@ -71,6 +71,12 @@ export function registerSleepResolver(internals, workflowId, operationId, resolv
|
|
|
71
71
|
internals.sleepResolversByWorkflow.set(workflowId, workflowOperations);
|
|
72
72
|
}
|
|
73
73
|
workflowOperations.add(operationId);
|
|
74
|
+
const readinessWaiters = internals.sleepResolverReadyWaitersForTesting?.get(workflowId);
|
|
75
|
+
if (readinessWaiters !== void 0) {
|
|
76
|
+
internals.sleepResolverReadyWaitersForTesting?.delete(workflowId);
|
|
77
|
+
for (const notifyReady of readinessWaiters)
|
|
78
|
+
notifyReady();
|
|
79
|
+
}
|
|
74
80
|
}
|
|
75
81
|
export async function startDelayedWorkflow(internals, entry, callbacks) {
|
|
76
82
|
const state = await callbacks.loadWorkflowState(entry.workflowId);
|
|
@@ -71,6 +71,14 @@
|
|
|
71
71
|
*/
|
|
72
72
|
import type { OperationOutcome, WorkerOutboundMessage } from './types.ts';
|
|
73
73
|
export interface ExecutionStrategy extends Disposable, AsyncDisposable {
|
|
74
|
+
/**
|
|
75
|
+
* Internal test seam for selecting a load-tolerant timeout around one
|
|
76
|
+
* intentionally wedged Worker turn. Production construction never sets it.
|
|
77
|
+
*/
|
|
78
|
+
setWorkflowTurnTimeoutResolverForTesting?: (resolver: (turn: {
|
|
79
|
+
workflowId: string;
|
|
80
|
+
kind: 'run' | 'resume';
|
|
81
|
+
}) => number) => void;
|
|
74
82
|
/**
|
|
75
83
|
* Start a new workflow execution from the beginning.
|
|
76
84
|
*/
|
|
@@ -53,6 +53,7 @@ export declare class InlineExecutionStrategy implements ExecutionStrategy {
|
|
|
53
53
|
clearParkedContext(workflowId: string): void;
|
|
54
54
|
getAbortController(workflowId: string): AbortController | undefined;
|
|
55
55
|
waitForWorkflowTurn(workflowId: string): Promise<void> | undefined;
|
|
56
|
+
abortWorkflowAdvanceForShutdown(workflowId: string): void;
|
|
56
57
|
waitForWorkflowAdvance(workflowId: string): Promise<void> | undefined;
|
|
57
58
|
hasGenerator(workflowId: string): boolean;
|
|
58
59
|
/**
|
|
@@ -13,6 +13,7 @@ export class InlineExecutionStrategy {
|
|
|
13
13
|
#parkedContexts;
|
|
14
14
|
#workflowAdvances;
|
|
15
15
|
#workflowTurns;
|
|
16
|
+
#shutdownAbortedWorkflowIds;
|
|
16
17
|
#messageHandler;
|
|
17
18
|
constructor(dependencies) {
|
|
18
19
|
this.#dependencies = dependencies;
|
|
@@ -22,6 +23,7 @@ export class InlineExecutionStrategy {
|
|
|
22
23
|
this.#parkedContexts = new Map;
|
|
23
24
|
this.#workflowAdvances = new Map;
|
|
24
25
|
this.#workflowTurns = new Map;
|
|
26
|
+
this.#shutdownAbortedWorkflowIds = new Set;
|
|
25
27
|
this.#messageHandler = null;
|
|
26
28
|
}
|
|
27
29
|
onMessage(handler) {
|
|
@@ -91,6 +93,10 @@ export class InlineExecutionStrategy {
|
|
|
91
93
|
waitForWorkflowTurn(workflowId) {
|
|
92
94
|
return this.#workflowTurns.get(workflowId);
|
|
93
95
|
}
|
|
96
|
+
abortWorkflowAdvanceForShutdown(workflowId) {
|
|
97
|
+
this.#shutdownAbortedWorkflowIds.add(workflowId);
|
|
98
|
+
this.#abortControllers.get(workflowId)?.abort();
|
|
99
|
+
}
|
|
94
100
|
waitForWorkflowAdvance(workflowId) {
|
|
95
101
|
return this.#workflowAdvances.get(workflowId);
|
|
96
102
|
}
|
|
@@ -122,6 +128,7 @@ export class InlineExecutionStrategy {
|
|
|
122
128
|
this.#parkedContexts.clear();
|
|
123
129
|
this.#workflowAdvances.clear();
|
|
124
130
|
this.#workflowTurns.clear();
|
|
131
|
+
this.#shutdownAbortedWorkflowIds.clear();
|
|
125
132
|
this.#messageHandler = null;
|
|
126
133
|
}
|
|
127
134
|
async[Symbol.asyncDispose]() {
|
|
@@ -138,26 +145,7 @@ export class InlineExecutionStrategy {
|
|
|
138
145
|
try {
|
|
139
146
|
if (this.#abortControllers.get(workflowId)?.signal.aborted)
|
|
140
147
|
return;
|
|
141
|
-
|
|
142
|
-
if (iterationResult.done) {
|
|
143
|
-
this.#cleanup(workflowId, {
|
|
144
|
-
preserveTrackedAdvance: !0,
|
|
145
|
-
preserveTrackedTurn: !0
|
|
146
|
-
});
|
|
147
|
-
this.#emit({
|
|
148
|
-
type: "completed",
|
|
149
|
-
workflowId,
|
|
150
|
-
result: iterationResult.value
|
|
151
|
-
});
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
const operation = iterationResult.value;
|
|
155
|
-
this.#emit({
|
|
156
|
-
type: "checkpoint",
|
|
157
|
-
workflowId,
|
|
158
|
-
checkpoint: new ArrayBuffer(0),
|
|
159
|
-
operationRequest: operation
|
|
160
|
-
});
|
|
148
|
+
this.#handleIterationResult(workflowId, await advance());
|
|
161
149
|
} catch (error) {
|
|
162
150
|
this.#cleanup(workflowId, {
|
|
163
151
|
preserveTrackedAdvance: !0,
|
|
@@ -177,6 +165,30 @@ export class InlineExecutionStrategy {
|
|
|
177
165
|
}
|
|
178
166
|
})());
|
|
179
167
|
}
|
|
168
|
+
#handleIterationResult(workflowId, iterationResult) {
|
|
169
|
+
const shutdownAborted = this.#shutdownAbortedWorkflowIds.delete(workflowId);
|
|
170
|
+
if (!iterationResult.done && shutdownAborted)
|
|
171
|
+
return;
|
|
172
|
+
if (iterationResult.done) {
|
|
173
|
+
this.#cleanup(workflowId, {
|
|
174
|
+
preserveTrackedAdvance: !0,
|
|
175
|
+
preserveTrackedTurn: !0
|
|
176
|
+
});
|
|
177
|
+
this.#emit({
|
|
178
|
+
type: "completed",
|
|
179
|
+
workflowId,
|
|
180
|
+
result: iterationResult.value
|
|
181
|
+
});
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const operation = iterationResult.value;
|
|
185
|
+
this.#emit({
|
|
186
|
+
type: "checkpoint",
|
|
187
|
+
workflowId,
|
|
188
|
+
checkpoint: new ArrayBuffer(0),
|
|
189
|
+
operationRequest: operation
|
|
190
|
+
});
|
|
191
|
+
}
|
|
180
192
|
#trackWorkflowAdvance(workflowId, pendingAdvance) {
|
|
181
193
|
const trackedAdvance = pendingAdvance.finally(() => {
|
|
182
194
|
if (this.#workflowAdvances.get(workflowId) === trackedAdvance)
|
|
@@ -212,5 +224,6 @@ export class InlineExecutionStrategy {
|
|
|
212
224
|
this.#workflowAdvances.delete(workflowId);
|
|
213
225
|
if (!options?.preserveTrackedTurn)
|
|
214
226
|
this.#workflowTurns.delete(workflowId);
|
|
227
|
+
this.#shutdownAbortedWorkflowIds.delete(workflowId);
|
|
215
228
|
}
|
|
216
229
|
}
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* }
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
|
-
export type WeftErrorCode = 'WorkflowAlreadyExistsError' | 'BulkDeleteRequiresTerminalWorkflowsError' | 'BulkOperationConfirmationError' | 'WorkflowTypeNotRegisteredForRecoveryError' | 'EngineCreateNameMismatchError' | 'EngineDisposedError' | 'WorkflowNotFoundError' | 'WorkflowNotRegisteredError' | 'WorkflowConcurrencyLimitExceededError' | 'WorkflowSuspendNotSupportedError' | 'ActivityResolutionError' | 'BranchTopologyChangedError' | 'PersistedDataIncompatibleError' | 'WorkflowTimeoutError' | 'HttpClientError' | 'WorkerProtocolIncompatibleError' | 'UpdateTimeoutError' | 'UpdateValidationError' | 'WorkflowTerminalError' | 'WorkflowBuilderError' | 'VersionMismatchError' | 'EffectReplayConflictError' | 'ReviewTimeoutError' | 'AtomicStateConflictError' | 'StandardSchemaValidationError' | 'ActivityReconciliationCapabilityError' | 'ActivityReconciliationConflictError' | 'ActivityReconciliationIndeterminateError' | 'DurableActivityScopeError' | 'DurableActivityUnsupportedError' | 'AsyncActivityTokenNotFoundError' | 'ActivityScheduleToCloseTimeoutError' | 'ActivityPerAttemptTimeoutError' | 'PayloadSizeExceededError' | 'StartOrSignalConflictError' | 'WorkflowTeardownPendingError' | 'IdempotencyKeyPurgedError';
|
|
28
|
+
export type WeftErrorCode = 'WorkflowAlreadyExistsError' | 'BulkDeleteRequiresTerminalWorkflowsError' | 'BulkOperationConfirmationError' | 'WorkflowTypeNotRegisteredForRecoveryError' | 'EngineCreateNameMismatchError' | 'EngineDisposedError' | 'EngineDisposalError' | 'WorkflowNotFoundError' | 'WorkflowNotRegisteredError' | 'WorkflowConcurrencyLimitExceededError' | 'WorkflowSuspendNotSupportedError' | 'ActivityResolutionError' | 'BranchTopologyChangedError' | 'PersistedDataIncompatibleError' | 'WorkflowTimeoutError' | 'HttpClientError' | 'WorkerProtocolIncompatibleError' | 'UpdateTimeoutError' | 'UpdateValidationError' | 'WorkflowTerminalError' | 'WorkflowBuilderError' | 'VersionMismatchError' | 'EffectReplayConflictError' | 'ReviewTimeoutError' | 'AtomicStateConflictError' | 'StandardSchemaValidationError' | 'ActivityReconciliationCapabilityError' | 'ActivityReconciliationConflictError' | 'ActivityReconciliationIndeterminateError' | 'DurableActivityScopeError' | 'DurableActivityUnsupportedError' | 'AsyncActivityTokenNotFoundError' | 'ActivityScheduleToCloseTimeoutError' | 'ActivityPerAttemptTimeoutError' | 'PayloadSizeExceededError' | 'StartOrSignalConflictError' | 'WorkflowTeardownPendingError' | 'IdempotencyKeyPurgedError';
|
|
29
29
|
/**
|
|
30
30
|
* Generic abstract base for all Weft library errors. The `TCode` parameter
|
|
31
31
|
* makes each subclass's `code` its own literal type; the exported base surface
|
package/dist/core/weft-error.js
CHANGED
|
@@ -13,6 +13,7 @@ const publicWeftErrorCodeMap = {
|
|
|
13
13
|
WorkflowTypeNotRegisteredForRecoveryError: !0,
|
|
14
14
|
EngineCreateNameMismatchError: !0,
|
|
15
15
|
EngineDisposedError: !0,
|
|
16
|
+
EngineDisposalError: !0,
|
|
16
17
|
WorkflowNotFoundError: !0,
|
|
17
18
|
WorkflowNotRegisteredError: !0,
|
|
18
19
|
WorkflowConcurrencyLimitExceededError: !0,
|
|
@@ -2,10 +2,12 @@ import type { WorkerPool } from '../workers/pool.ts';
|
|
|
2
2
|
import type { ExecutionStrategy } from './execution-strategy.ts';
|
|
3
3
|
import type { OperationOutcome, WorkerOutboundMessage } from './types.ts';
|
|
4
4
|
import type { WorkerExecutionStrategyOptions } from './worker-execution-strategy-options.ts';
|
|
5
|
+
import { type WorkerTurnTimeoutResolverForTesting } from './worker-turn-watchdog.ts';
|
|
5
6
|
export declare class WorkerExecutionStrategy implements ExecutionStrategy {
|
|
6
7
|
#private;
|
|
7
8
|
constructor(pool: WorkerPool, options?: WorkerExecutionStrategyOptions);
|
|
8
9
|
onMessage(handler: (message: WorkerOutboundMessage) => void | Promise<void>): void;
|
|
10
|
+
setWorkflowTurnTimeoutResolverForTesting(resolver: WorkerTurnTimeoutResolverForTesting): void;
|
|
9
11
|
startWorkflow(parameters: {
|
|
10
12
|
workflowId: string;
|
|
11
13
|
workflowExecutionToken?: string;
|
|
@@ -16,7 +16,9 @@ import {
|
|
|
16
16
|
import { WorkerProtocolGuard } from "./worker-protocol-guard.js";
|
|
17
17
|
import { isWorkerLogMessage } from "./worker-protocol-log.js";
|
|
18
18
|
import { WORKER_PROTOCOL_VERSION } from "./worker-protocol.js";
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
WorkerTurnWatchdog
|
|
21
|
+
} from "./worker-turn-watchdog.js";
|
|
20
22
|
|
|
21
23
|
export class WorkerExecutionStrategy {
|
|
22
24
|
#pool;
|
|
@@ -99,6 +101,9 @@ export class WorkerExecutionStrategy {
|
|
|
99
101
|
onMessage(handler) {
|
|
100
102
|
this.#messageHandler = handler;
|
|
101
103
|
}
|
|
104
|
+
setWorkflowTurnTimeoutResolverForTesting(resolver) {
|
|
105
|
+
this.#turnWatchdog.setTimeoutResolverForTesting(resolver);
|
|
106
|
+
}
|
|
102
107
|
startWorkflow(parameters) {
|
|
103
108
|
this.#ownership.resetWorkflow(parameters.workflowId);
|
|
104
109
|
this.#checkpointResumeState.resetWorkflow(parameters.workflowId);
|
|
@@ -315,7 +320,7 @@ export class WorkerExecutionStrategy {
|
|
|
315
320
|
this.#discardWorkerAndFailWorkflows(turn.worker, {
|
|
316
321
|
targetWorkflowId: turn.workflowId,
|
|
317
322
|
targetCategory: "timeout",
|
|
318
|
-
targetError: `Worker workflow turn timed out after ${
|
|
323
|
+
targetError: `Worker workflow turn timed out after ${turn.timeoutMs}ms`,
|
|
319
324
|
otherCategory: "timeout",
|
|
320
325
|
otherError: `Worker discarded after workflow turn timed out: ${turn.workflowId}`
|
|
321
326
|
});
|
|
@@ -3,11 +3,14 @@ export interface WorkerTurnState {
|
|
|
3
3
|
workflowId: string;
|
|
4
4
|
turnId: number;
|
|
5
5
|
kind: 'run' | 'resume';
|
|
6
|
+
timeoutMs: number | undefined;
|
|
6
7
|
}
|
|
8
|
+
export type WorkerTurnTimeoutResolverForTesting = (turn: Pick<WorkerTurnState, 'workflowId' | 'kind'>) => number;
|
|
7
9
|
export declare class WorkerTurnWatchdog {
|
|
8
10
|
#private;
|
|
9
11
|
constructor(timeoutMs: number | undefined, onTimeout: (turn: WorkerTurnState) => void);
|
|
10
|
-
begin(worker: Worker, workflowId: string, turnId: number, kind: WorkerTurnState['kind']): void;
|
|
12
|
+
begin(worker: Worker, workflowId: string, turnId: number, kind: WorkerTurnState['kind'], timeoutMs?: number | undefined): void;
|
|
13
|
+
setTimeoutResolverForTesting(resolver: WorkerTurnTimeoutResolverForTesting): void;
|
|
11
14
|
clear(worker: Worker): void;
|
|
12
15
|
clearAll(): void;
|
|
13
16
|
get(worker: Worker): WorkerTurnState | undefined;
|
|
@@ -2,26 +2,31 @@ export class WorkerTurnWatchdog {
|
|
|
2
2
|
#turnsByWorker = new Map;
|
|
3
3
|
#timeoutMs;
|
|
4
4
|
#onTimeout;
|
|
5
|
+
#timeoutResolverForTesting = null;
|
|
5
6
|
constructor(timeoutMs, onTimeout) {
|
|
6
7
|
this.#timeoutMs = timeoutMs;
|
|
7
8
|
this.#onTimeout = onTimeout;
|
|
8
9
|
}
|
|
9
|
-
begin(worker, workflowId, turnId, kind) {
|
|
10
|
+
begin(worker, workflowId, turnId, kind, timeoutMs = this.#timeoutMs) {
|
|
10
11
|
this.clear(worker);
|
|
11
|
-
const turn = {
|
|
12
|
+
const resolvedTimeoutMs = this.#timeoutResolverForTesting?.({ workflowId, kind }) ?? timeoutMs, turn = {
|
|
12
13
|
worker,
|
|
13
14
|
workflowId,
|
|
14
15
|
turnId,
|
|
15
16
|
kind,
|
|
17
|
+
timeoutMs: resolvedTimeoutMs,
|
|
16
18
|
timeout: null
|
|
17
19
|
};
|
|
18
|
-
if (
|
|
20
|
+
if (resolvedTimeoutMs !== void 0)
|
|
19
21
|
turn.timeout = setTimeout(() => {
|
|
20
22
|
if (this.#turnsByWorker.get(worker) === turn)
|
|
21
23
|
this.#onTimeout(turn);
|
|
22
|
-
},
|
|
24
|
+
}, resolvedTimeoutMs);
|
|
23
25
|
this.#turnsByWorker.set(worker, turn);
|
|
24
26
|
}
|
|
27
|
+
setTimeoutResolverForTesting(resolver) {
|
|
28
|
+
this.#timeoutResolverForTesting = resolver;
|
|
29
|
+
}
|
|
25
30
|
clear(worker) {
|
|
26
31
|
const turn = this.#turnsByWorker.get(worker);
|
|
27
32
|
if (!turn)
|
package/dist/index.d.ts
CHANGED
|
@@ -21,12 +21,12 @@ export type { WeftErrorCode } from './core/weft-error.ts';
|
|
|
21
21
|
export { FAULT_CODE_TO_FAILURE_CATEGORY, failureCategoryForFaultCode, isFaultCode, } from './core/fault-code.ts';
|
|
22
22
|
export type { FaultCode } from './core/fault-code.ts';
|
|
23
23
|
export { DurableActivityScopeError, DurableActivityUnsupportedError, durableActivity, } from './core/context/durable-activity.ts';
|
|
24
|
-
export { ActivityReconciliationCapabilityError, ActivityReconciliationConflictError, ActivityReconciliationIndeterminateError, ActivityResolutionError, AsyncActivityTokenNotFoundError, BulkDeleteRequiresTerminalWorkflowsError, BulkOperationConfirmationError, ENGINE_LEASE_LOST_WARNING_NAME, ENGINE_LEASE_SYNCHRONOUS_DISPOSE_WARNING_NAME, Engine, EngineCreateNameMismatchError, EngineDisposedError, EngineLeaseAcquisitionTimeoutError, EngineLeaseCorruptedError, EngineLeaseNotHeldError, IdempotencyKeyPurgedError, PersistedDataIncompatibleError, ScheduleHandle, StartOrSignalConflictError, WorkflowAlreadyExistsError, WorkflowConcurrencyLimitExceededError, WorkflowHandle, WorkflowNotFoundError, WorkflowNotRegisteredError, WorkflowSuspendNotSupportedError, WorkflowTeardownPendingError, WorkflowTypeNotRegisteredForRecoveryError, } from './core/engine';
|
|
24
|
+
export { ActivityReconciliationCapabilityError, ActivityReconciliationConflictError, ActivityReconciliationIndeterminateError, ActivityResolutionError, AsyncActivityTokenNotFoundError, BulkDeleteRequiresTerminalWorkflowsError, BulkOperationConfirmationError, ENGINE_LEASE_LOST_WARNING_NAME, ENGINE_LEASE_SYNCHRONOUS_DISPOSE_WARNING_NAME, Engine, EngineCreateNameMismatchError, EngineDisposalError, EngineDisposedError, EngineLeaseAcquisitionTimeoutError, EngineLeaseCorruptedError, EngineLeaseNotHeldError, IdempotencyKeyPurgedError, PersistedDataIncompatibleError, ScheduleHandle, StartOrSignalConflictError, WorkflowAlreadyExistsError, WorkflowConcurrencyLimitExceededError, WorkflowHandle, WorkflowNotFoundError, WorkflowNotRegisteredError, WorkflowSuspendNotSupportedError, WorkflowTeardownPendingError, WorkflowTypeNotRegisteredForRecoveryError, } from './core/engine';
|
|
25
25
|
export type { EngineCreateOptions, EngineLeaseHealth, EngineStateNamespace, LeaseLostReason, RecoverAllOptions, RecoveredWorkflowInfo, } from './core/engine';
|
|
26
26
|
export { DEFAULT_CHECKPOINT_SIZE_WARNING_THRESHOLD, DEFAULT_MAX_NESTING_DEPTH, DEFAULT_POLL_INTERVAL_MS, DEFAULT_RETRY_POLICY, DEFAULT_VISIBILITY_TIMEOUT_MS, HISTORY_CIRCUIT_BREAKER_REASON, WorkflowBuilderError, query, schedule, signal, update, workflow, } from './core/types';
|
|
27
27
|
export type { ActivityArgsFor, ActivityCallOptions, ActivityCallable, ActivityContext, ActivityDefinition, ActivityEntryInput, ActivityFunction, ActivityMap, ActivityMapInput, ActivityObjectInput, ActivityResultFor, ActivityVerificationContext, ActivityVerificationPhase, ActivityVerificationResult, AnyActivityDefinition, AnyWorkflowDefinition, ArchiveAdapter, BuilderState, BuiltWorkflowDefinition, BulkCancelResult, BulkDeleteResult, BulkOperationAction, BulkOperationAuditEvent, BulkOperationCommitOptions, BulkOperationDryRunOptions, BulkOperationDryRunResult, BulkOperationError, BulkOperationFilterSummary, BulkOperationOptions, BulkOperationPrincipal, BulkOperationScopeSummary, BulkRetryFailedResult, BulkSignalAllCommitOptions, BulkSignalAllDryRunOptions, BulkSignalAllOptions, BulkSignalResult, BulkTagResult, Checkpoint, CheckpointState, CheckpointSummary, CompletedReviewEntry, CoordinatedUpdateResult, DefinitionSchema, Duration, EngineOptions, FailureCategory, ForkLineage, ForkOptions, HistoryPolicy, InferActivityEntries, InferActivityEntry, InferWorkflowEntries, InferWorkflowEntry, InitialBuilderState, LaunchMetadata, ListFilter, ListOptions, MarkBuilderState, NormalizeActivities, NormalizedActivityEntry, NormalizedRetentionPolicy, PaginatedResult, PayloadSizePolicy, PendingAsyncActivityInfo, PendingAsyncActivityListOptions, PendingAsyncActivityPage, PendingReviewEntry, PurgeResult, QueryDefinition, QueryMap, QueryShape, RegisteredWorkflowDefinition, RestartLineage, RetentionOverview, RetentionPolicy, RetryPolicy, ReviewDecision, ReviewListEntry, ReviewListFilter, ReviewStatus, ScheduleDefinition, ScheduleFilter, ScheduleOptions, ScheduleOverlapPolicy, ScheduleQueuedRun, ScheduleSpec, ScheduleState, ScheduleStatus, ScheduleSummary, ScheduleUpdateOptions, SearchAttributeDefinition, SearchAttributeHandle, SearchAttributeSchema, SearchAttributeValue, Serializer, SignalDefinition, SignalDeliveryOptions, SignalMap, SignalPayload, StartOptions, StartOrSignalOptions, StartOrSignalSignal, SubmitReviewOptions, TerminationReason, UpdateDefinition, UpdateMap, UpdatePayload, WorkerReplayOperationFailure, WorkerReplayOperationSignature, WorkflowAlreadyRegistered, WorkflowAtomicState, WorkflowAtomicStateOptions, WorkflowBuilder, WorkflowBuilderOptions, WorkflowConcurrencyOptions, WorkflowContext, WorkflowDefinition, WorkflowEvent, WorkflowFinalizerStatus, WorkflowFunction, WorkflowGenerator, WorkflowId, WorkflowKeyedRaceResult, WorkflowLogLevel, WorkflowLogRecord, WorkflowLogger, WorkflowRegistry, WorkflowReplay, WorkflowScheduleProvenance, WorkflowServicesResolution, WorkflowServicesResolverInfo, WorkflowServicesResolverLaunchOptions, WorkflowServicesResolverScheduleInfo, WorkflowSessionState, WorkflowSnapshot, WorkflowState, WorkflowStateNamespace, WorkflowStatus, WorkflowSummary, WorkflowTimelineEntry, WorkflowTimelineOperationDetail, WorkflowTimelineStatus, WorkflowTypeRetentionPolicy, } from './core/types';
|
|
28
28
|
export { AlertManager } from './alerting/index';
|
|
29
|
-
export type { AlertAction, AlertMetric, AlertRule,
|
|
29
|
+
export type { AlertAction, AlertMetric, AlertRule, AlertStateSnapshot, AlertStatus, AlertingOptions, WebhookTarget, } from './alerting/types';
|
|
30
30
|
export { ActivityAsyncPendingEvent, ActivityCompletedEvent, ActivityFailedEvent, ActivityStartedEvent, AlertFiredEvent, AlertResolvedEvent, AttributesChangedEvent, CheckpointSizeWarningEvent, ConstraintViolatedEvent, DevelopmentWarningEvent, ScheduleFiredEvent, ScheduleMissedFireEvent, SignalDeliveredEvent, SignalReceivedEvent, StorageSizeReportedEvent, TaskResultDeadLetteredEvent, UpdateCompletedEvent, UpdateReceivedEvent, WorkflowCancelledEvent, WorkflowCompletedEvent, WorkflowDefinitionRegisteredEvent, WorkflowFailedEvent, WorkflowRecoverySkippedEvent, WorkflowResumedEvent, WorkflowStartedEvent, WorkflowSuspendedEvent, WorkflowTeardownEvent, WorkflowTimedOutEvent, } from './core/events';
|
|
31
31
|
export type { TypedEventTarget, WeftEventMap, WorkflowRecoverySkippedReason, WorkflowTeardownStatus, } from './core/events';
|
|
32
32
|
export { detectRuntime, hashBytes, hashString, sleep } from './runtime/portable';
|