@lostgradient/weft 0.2.1 → 0.4.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 +123 -43
- package/dist/cli/conformance.js +7 -1
- package/dist/cli/generated/operation-client.generated.d.ts +55 -13
- package/dist/cli/generated/operation-client.generated.js +3 -0
- package/dist/cli/help-text.d.ts +1 -1
- package/dist/cli/help-text.js +1 -0
- package/dist/cli/operation-catalog-snapshot.d.ts +8 -0
- package/dist/cli/operation-catalog-snapshot.js +11 -0
- package/dist/cli/parse-schedule-arguments.js +3 -1
- package/dist/cli/schedule.js +2 -1
- package/dist/cli/types.d.ts +1 -0
- package/dist/cli-main.js +80 -79
- package/dist/client/handle-delegation.d.ts +7 -2
- package/dist/client/handle-delegation.js +9 -1
- package/dist/client/http-client-requests.d.ts +4 -1
- package/dist/client/http-client-requests.js +10 -0
- package/dist/client/http-client.d.ts +10 -4
- package/dist/client/http-client.js +18 -1
- package/dist/client/http-request.d.ts +11 -1
- package/dist/client/http-request.js +17 -7
- package/dist/client/index.d.ts +1 -1
- package/dist/client/interface.d.ts +100 -4
- package/dist/client/local.d.ts +7 -1
- package/dist/client/local.js +17 -2
- package/dist/client/start-body.d.ts +9 -2
- package/dist/client/start-body.js +13 -4
- package/dist/core/byte-arrays.d.ts +5 -0
- package/dist/core/byte-arrays.js +5 -0
- package/dist/core/checkpoint/lifecycle.d.ts +3 -0
- package/dist/core/checkpoint/lifecycle.js +9 -4
- package/dist/core/checkpoint/serialization.js +12 -5
- package/dist/core/codec/extension-codec.d.ts +16 -0
- package/dist/core/codec/extension-codec.js +104 -8
- package/dist/core/codec/index.d.ts +1 -0
- package/dist/core/codec/index.js +1 -0
- package/dist/core/codec/serializer-registry.d.ts +122 -0
- package/dist/core/codec/serializer-registry.js +51 -0
- package/dist/core/context/activity-retry-state.d.ts +38 -0
- package/dist/core/context/activity-retry-state.js +89 -0
- package/dist/core/context/activity-schedule-to-close.d.ts +159 -0
- package/dist/core/context/activity-schedule-to-close.js +69 -0
- package/dist/core/context/child-workflow-pipe.d.ts +5 -5
- package/dist/core/context/child-workflow-pipe.js +15 -2
- package/dist/core/context/context-presence.d.ts +19 -0
- package/dist/core/context/context-presence.js +13 -0
- package/dist/core/context/durable-operations.d.ts +25 -0
- package/dist/core/context/durable-operations.js +64 -0
- package/dist/core/context/index.d.ts +18 -5
- package/dist/core/context/index.js +17 -12
- package/dist/core/context/internals.d.ts +29 -0
- package/dist/core/context/internals.js +6 -1
- package/dist/core/context/operation-request.d.ts +35 -0
- package/dist/core/context/parallel-cache-entry.d.ts +14 -5
- package/dist/core/context/run-operation.d.ts +21 -3
- package/dist/core/context/run-operation.js +56 -93
- package/dist/core/context/session-state.js +7 -8
- package/dist/core/context/speculative-child.js +2 -0
- package/dist/core/context/types.d.ts +15 -0
- package/dist/core/context/version-patching.d.ts +8 -0
- package/dist/core/context/version-patching.js +40 -0
- package/dist/core/context/workflow-logger.d.ts +98 -0
- package/dist/core/context/workflow-logger.js +68 -0
- package/dist/core/engine/activity-heartbeat-tracking.d.ts +64 -0
- package/dist/core/engine/activity-heartbeat-tracking.js +42 -0
- package/dist/core/engine/activity-per-attempt-timeout.d.ts +41 -0
- package/dist/core/engine/activity-per-attempt-timeout.js +36 -0
- package/dist/core/engine/activity-reconciliation.d.ts +1 -0
- package/dist/core/engine/activity-reconciliation.js +12 -1
- package/dist/core/engine/activity-resolution.d.ts +23 -0
- package/dist/core/engine/activity-resolution.js +37 -0
- package/dist/core/engine/aggregate.js +66 -30
- package/dist/core/engine/async-activity-completion.d.ts +23 -6
- package/dist/core/engine/async-activity-completion.js +53 -12
- package/dist/core/engine/attributes-tags.js +9 -4
- package/dist/core/engine/bulk-operations-purge.d.ts +26 -0
- package/dist/core/engine/bulk-operations-purge.js +38 -3
- package/dist/core/engine/bulk-operations-shared.d.ts +2 -0
- package/dist/core/engine/bulk-operations-shared.js +8 -2
- package/dist/core/engine/bulk-operations.d.ts +4 -1
- package/dist/core/engine/bulk-operations.js +235 -24
- package/dist/core/engine/callback-creators-bundles.d.ts +9 -0
- package/dist/core/engine/callback-creators-bundles.js +30 -2
- package/dist/core/engine/callback-creators-core.js +6 -4
- package/dist/core/engine/callback-creators-router.js +10 -0
- package/dist/core/engine/callback-creators-schedule.d.ts +2 -2
- package/dist/core/engine/callback-creators-schedule.js +12 -8
- package/dist/core/engine/candidate-read-batching.d.ts +6 -0
- package/dist/core/engine/candidate-read-batching.js +1 -0
- package/dist/core/engine/checkpoint-io.js +61 -25
- package/dist/core/engine/checkpoint-reads.js +3 -2
- package/dist/core/engine/checkpoint-replay.d.ts +20 -0
- package/dist/core/engine/checkpoint-replay.js +242 -0
- package/dist/core/engine/checkpoint-side-effects.d.ts +23 -0
- package/dist/core/engine/checkpoint-side-effects.js +35 -0
- package/dist/core/engine/child-workflow-cancellation.d.ts +10 -0
- package/dist/core/engine/child-workflow-cancellation.js +40 -0
- package/dist/core/engine/child-workflow.js +27 -4
- package/dist/core/engine/condition-waiters.d.ts +14 -0
- package/dist/core/engine/condition-waiters.js +5 -0
- package/dist/core/engine/construction.d.ts +3 -1
- package/dist/core/engine/construction.js +30 -8
- package/dist/core/engine/coordination-branch-executors.d.ts +70 -0
- package/dist/core/engine/coordination-branch-executors.js +107 -0
- package/dist/core/engine/deferred-consume-envelope.d.ts +59 -0
- package/dist/core/engine/deferred-consume-envelope.js +14 -0
- package/dist/core/engine/disposal.js +25 -0
- package/dist/core/engine/engine-create-types.d.ts +14 -18
- package/dist/core/engine/engine-internal-types.d.ts +38 -3
- package/dist/core/engine/engine-leak-warnings.d.ts +6 -0
- package/dist/core/engine/engine-leak-warnings.js +4 -0
- package/dist/core/engine/engine-runtime-helpers.d.ts +17 -0
- package/dist/core/engine/engine-runtime-helpers.js +26 -5
- package/dist/core/engine/errors.d.ts +121 -0
- package/dist/core/engine/errors.js +45 -1
- package/dist/core/engine/event-log-compaction.d.ts +8 -0
- package/dist/core/engine/event-log-compaction.js +20 -2
- package/dist/core/engine/fenced-write.d.ts +65 -0
- package/dist/core/engine/fenced-write.js +71 -0
- package/dist/core/engine/finalizer-state.d.ts +28 -0
- package/dist/core/engine/finalizer-state.js +16 -0
- package/dist/core/engine/handle-result.js +1 -1
- package/dist/core/engine/handles.d.ts +97 -40
- package/dist/core/engine/handles.js +25 -27
- package/dist/core/engine/index.d.ts +125 -15
- package/dist/core/engine/index.js +207 -11
- package/dist/core/engine/inline-launch-queue.d.ts +14 -0
- package/dist/core/engine/inline-launch-queue.js +32 -7
- package/dist/core/engine/inline-parking.js +3 -2
- package/dist/core/engine/internals.d.ts +125 -13
- package/dist/core/engine/lease-codec.d.ts +35 -0
- package/dist/core/engine/lease-codec.js +32 -0
- package/dist/core/engine/lease-deposition.d.ts +66 -0
- package/dist/core/engine/lease-deposition.js +10 -0
- package/dist/core/engine/lease-errors.d.ts +99 -0
- package/dist/core/engine/lease-errors.js +30 -0
- package/dist/core/engine/lease-manager.d.ts +114 -0
- package/dist/core/engine/lease-manager.js +135 -0
- package/dist/core/engine/lifecycle/fork-helpers.js +1 -7
- package/dist/core/engine/lifecycle/persist.js +15 -52
- package/dist/core/engine/lifecycle/recovered-services.d.ts +8 -6
- package/dist/core/engine/lifecycle/recovered-services.js +18 -3
- package/dist/core/engine/lifecycle/resume.js +39 -11
- package/dist/core/engine/lifecycle/shared.d.ts +8 -1
- package/dist/core/engine/lifecycle/start-batch.d.ts +1 -1
- package/dist/core/engine/lifecycle/start-batch.js +2 -1
- package/dist/core/engine/lifecycle/start-commit.d.ts +56 -0
- package/dist/core/engine/lifecycle/start-commit.js +69 -0
- package/dist/core/engine/lifecycle/start-exec.d.ts +30 -2
- package/dist/core/engine/lifecycle/start-exec.js +38 -0
- package/dist/core/engine/lifecycle/start-or-signal-create.d.ts +58 -0
- package/dist/core/engine/lifecycle/start-or-signal-create.js +95 -0
- package/dist/core/engine/lifecycle/start-or-signal-resolution.d.ts +79 -0
- package/dist/core/engine/lifecycle/start-or-signal-resolution.js +60 -0
- package/dist/core/engine/lifecycle/start-or-signal.d.ts +46 -0
- package/dist/core/engine/lifecycle/start-or-signal.js +71 -0
- package/dist/core/engine/lifecycle/start-terminal-conflict-purge.d.ts +39 -0
- package/dist/core/engine/lifecycle/start-terminal-conflict-purge.js +28 -0
- package/dist/core/engine/lifecycle/start.d.ts +6 -6
- package/dist/core/engine/lifecycle/start.js +47 -45
- package/dist/core/engine/lifecycle/transition.js +17 -5
- package/dist/core/engine/lifecycle.d.ts +3 -2
- package/dist/core/engine/lifecycle.js +9 -2
- package/dist/core/engine/list-candidate-resolution.js +2 -2
- package/dist/core/engine/listing.js +10 -6
- package/dist/core/engine/operations-activity.d.ts +4 -11
- package/dist/core/engine/operations-activity.js +22 -49
- package/dist/core/engine/operations-coordination.d.ts +10 -0
- package/dist/core/engine/operations-coordination.js +43 -8
- package/dist/core/engine/operations-router.d.ts +6 -0
- package/dist/core/engine/operations-router.js +2 -0
- package/dist/core/engine/operations-speculate.js +6 -2
- package/dist/core/engine/operations-stream.js +12 -2
- package/dist/core/engine/operations-time.d.ts +4 -2
- package/dist/core/engine/operations-time.js +14 -2
- package/dist/core/engine/operations-wait-condition.d.ts +23 -0
- package/dist/core/engine/operations-wait-condition.js +62 -0
- package/dist/core/engine/ownership-options.d.ts +23 -0
- package/dist/core/engine/ownership-options.js +26 -0
- package/dist/core/engine/payload-size-policy.d.ts +3 -0
- package/dist/core/engine/payload-size-policy.js +4 -0
- package/dist/core/engine/pending-updates.d.ts +17 -0
- package/dist/core/engine/pending-updates.js +33 -11
- package/dist/core/engine/persisted-data-version.d.ts +5 -9
- package/dist/core/engine/persisted-data-version.js +4 -5
- package/dist/core/engine/queries.js +1 -1
- package/dist/core/engine/registration.d.ts +1 -0
- package/dist/core/engine/registration.js +18 -3
- package/dist/core/engine/schedule-handle.d.ts +45 -0
- package/dist/core/engine/schedule-handle.js +26 -0
- package/dist/core/engine/schedule-jitter.d.ts +5 -0
- package/dist/core/engine/schedule-jitter.js +10 -0
- package/dist/core/engine/schedule-run.d.ts +17 -0
- package/dist/core/engine/schedule-run.js +38 -0
- package/dist/core/engine/schedule-timer.js +81 -17
- package/dist/core/engine/schedules.d.ts +8 -5
- package/dist/core/engine/schedules.js +44 -19
- package/dist/core/engine/search-attribute-records.d.ts +4 -0
- package/dist/core/engine/search-attribute-records.js +17 -0
- package/dist/core/engine/second-instance-detector.d.ts +96 -0
- package/dist/core/engine/second-instance-detector.js +108 -0
- package/dist/core/engine/signals.d.ts +38 -0
- package/dist/core/engine/signals.js +55 -19
- package/dist/core/engine/state-utilities.d.ts +49 -2
- package/dist/core/engine/state-utilities.js +114 -3
- package/dist/core/engine/storage-io.d.ts +16 -2
- package/dist/core/engine/storage-io.js +26 -5
- package/dist/core/engine/stream-chunk-loading.d.ts +2 -0
- package/dist/core/engine/stream-chunk-loading.js +24 -1
- package/dist/core/engine/sub-operation.js +22 -3
- package/dist/core/engine/termination/cleanup.d.ts +28 -1
- package/dist/core/engine/termination/cleanup.js +44 -2
- package/dist/core/engine/termination/complete.js +48 -9
- package/dist/core/engine/termination/finalizer-activity.d.ts +53 -0
- package/dist/core/engine/termination/finalizer-activity.js +30 -0
- package/dist/core/engine/termination/finalizer-claim.d.ts +110 -0
- package/dist/core/engine/termination/finalizer-claim.js +80 -0
- package/dist/core/engine/termination/finalizer.d.ts +48 -0
- package/dist/core/engine/termination/finalizer.js +159 -0
- package/dist/core/engine/termination/suspend.d.ts +70 -0
- package/dist/core/engine/termination/suspend.js +41 -0
- package/dist/core/engine/termination.d.ts +5 -2
- package/dist/core/engine/termination.js +6 -0
- package/dist/core/engine/updates.js +5 -25
- package/dist/core/engine/validation/schedule.d.ts +2 -1
- package/dist/core/engine/validation/schedule.js +51 -2
- package/dist/core/engine/validation.js +54 -3
- package/dist/core/engine/waiting-update-response.d.ts +8 -0
- package/dist/core/engine/waiting-update-response.js +22 -0
- package/dist/core/engine/workflow-concurrency.d.ts +10 -0
- package/dist/core/engine/workflow-concurrency.js +136 -0
- package/dist/core/engine/workflow-feed.d.ts +9 -8
- package/dist/core/engine/workflow-feed.js +4 -1
- package/dist/core/engine/workflow-indexes.d.ts +9 -0
- package/dist/core/engine/workflow-indexes.js +10 -0
- package/dist/core/engine/workflow-state-stream.js +33 -13
- package/dist/core/engine/workflow-visibility-queries.d.ts +2 -2
- package/dist/core/engine-helpers.js +1 -0
- package/dist/core/events/activity-events.d.ts +43 -12
- package/dist/core/events/activity-events.js +28 -0
- package/dist/core/events/attribute-events.d.ts +2 -3
- package/dist/core/events/event-map.d.ts +19 -12
- package/dist/core/events/index.d.ts +1 -0
- package/dist/core/events/index.js +1 -0
- package/dist/core/events/schedule-events.d.ts +71 -0
- package/dist/core/events/schedule-events.js +29 -0
- package/dist/core/events/signal-events.d.ts +4 -6
- package/dist/core/events/system-events.d.ts +29 -19
- package/dist/core/events/system-events.js +26 -0
- package/dist/core/events/update-events.d.ts +6 -8
- package/dist/core/events/workflow-events.d.ts +108 -20
- package/dist/core/events/workflow-events.js +35 -0
- package/dist/core/failure-categories.js +5 -17
- package/dist/core/fault-code.d.ts +9 -3
- package/dist/core/fault-code.js +1 -0
- package/dist/core/inline-execution-strategy.context-options.d.ts +69 -0
- package/dist/core/inline-execution-strategy.context-options.js +56 -0
- package/dist/core/inline-execution-strategy.d.ts +31 -36
- package/dist/core/inline-execution-strategy.js +16 -27
- package/dist/core/list-filter-validation.d.ts +1 -1
- package/dist/core/list-filter-validation.js +2 -1
- package/dist/core/payload-size.d.ts +1 -1
- package/dist/core/persisted-data-incompatible-error.d.ts +9 -7
- package/dist/core/review/events.d.ts +6 -8
- package/dist/core/scheduler/scheduler-class.d.ts +10 -1
- package/dist/core/scheduler/scheduler-class.js +38 -11
- package/dist/core/scheduler/timer-batch.js +9 -1
- package/dist/core/scheduler/timer-sources.d.ts +1 -0
- package/dist/core/scheduler/timer-sources.js +11 -5
- package/dist/core/session-state.d.ts +0 -1
- package/dist/core/session-state.js +2 -2
- package/dist/core/start-workflow-validation.d.ts +56 -0
- package/dist/core/start-workflow-validation.js +30 -1
- package/dist/core/step-context.d.ts +10 -6
- package/dist/core/step-context.js +7 -15
- package/dist/core/types/activity-verification.d.ts +67 -0
- package/dist/core/types/activity-verification.js +0 -0
- package/dist/core/types/activity.d.ts +86 -64
- package/dist/core/types/bulk.d.ts +50 -9
- package/dist/core/types/checkpoint.d.ts +44 -8
- package/dist/core/types/identity.d.ts +8 -1
- package/dist/core/types/launch-metadata.d.ts +33 -0
- package/dist/core/types/launch-metadata.js +0 -0
- package/dist/core/types/list-options.d.ts +146 -0
- package/dist/core/types/list-options.js +0 -0
- package/dist/core/types/message-handles.d.ts +25 -0
- package/dist/core/types/options.d.ts +165 -215
- package/dist/core/types/reviews.d.ts +2 -1
- package/dist/core/types/schedules.d.ts +39 -3
- package/dist/core/types/services-resolution.d.ts +47 -0
- package/dist/core/types/services-resolution.js +0 -0
- package/dist/core/types/state.d.ts +11 -11
- package/dist/core/types/workflow-builder-runtime.d.ts +12 -3
- package/dist/core/types/workflow-builder-runtime.js +11 -2
- package/dist/core/types/workflow-builder.d.ts +47 -15
- package/dist/core/types/workflow-concurrency.d.ts +39 -0
- package/dist/core/types/workflow-concurrency.js +0 -0
- package/dist/core/types/workflow-context.d.ts +157 -14
- package/dist/core/types/workflow-definition.d.ts +53 -10
- package/dist/core/types/workflow-function.d.ts +101 -9
- package/dist/core/types/workflow-log.d.ts +98 -0
- package/dist/core/types/workflow-log.js +0 -0
- package/dist/core/types/workflow-registries.d.ts +14 -3
- package/dist/core/types/workflow-registry.d.ts +3 -0
- package/dist/core/types/workflow-snapshot.d.ts +29 -0
- package/dist/core/types/workflow-snapshot.js +0 -0
- package/dist/core/types.d.ts +7 -0
- package/dist/core/types.js +7 -0
- package/dist/core/versioning.d.ts +9 -39
- package/dist/core/versioning.js +2 -12
- package/dist/core/weft-error.d.ts +44 -1
- package/dist/core/weft-error.js +19 -1
- package/dist/core/worker-execution-strategy-options.d.ts +26 -0
- package/dist/core/worker-execution-strategy.js +40 -36
- package/dist/core/worker-inbound-message.d.ts +38 -0
- package/dist/core/worker-inbound-message.js +37 -0
- package/dist/core/worker-log-abuse-counter.d.ts +175 -0
- package/dist/core/worker-log-abuse-counter.js +107 -0
- package/dist/core/worker-message-helpers.d.ts +47 -0
- package/dist/core/worker-message-helpers.js +26 -0
- package/dist/core/worker-protocol-guard.js +1 -1
- package/dist/core/worker-protocol-log.d.ts +56 -0
- package/dist/core/worker-protocol-log.js +18 -0
- package/dist/core/worker-protocol.d.ts +23 -0
- package/dist/core/worker-protocol.js +12 -2
- package/dist/core/workflow-version-tuple.d.ts +3 -9
- package/dist/core/workflow-version-tuple.js +2 -3
- package/dist/diagnostics/doctor.js +6 -3
- package/dist/diagnostics/format.js +3 -8
- package/dist/diagnostics/types.d.ts +5 -5
- package/dist/diagnostics/validate.d.ts +0 -1
- package/dist/diagnostics/version-check.d.ts +1 -1
- package/dist/diagnostics/version-check.js +10 -13
- package/dist/index.d.ts +13 -11
- package/dist/index.js +39 -4
- package/dist/json-schema.js +3 -3
- package/dist/mcp/cli.js +35 -35
- package/dist/mcp/dispatcher.js +1 -1
- package/dist/mcp/http.js +16 -6
- package/dist/mcp/list-filter.js +2 -1
- package/dist/mcp/protocol.d.ts +2 -0
- package/dist/mcp/protocol.js +1 -1
- package/dist/mcp/session.d.ts +16 -0
- package/dist/mcp/session.js +60 -6
- package/dist/mcp/tools.js +73 -6
- package/dist/observability/index.js +2 -2
- package/dist/server/asyncapi-channels.js +5 -2
- package/dist/server/attribute-filters.d.ts +8 -3
- package/dist/server/attribute-filters.js +6 -1
- package/dist/server/authentication/api-key.d.ts +2 -1
- package/dist/server/authentication/api-key.js +5 -2
- package/dist/server/authentication/constant-time-api-key.d.ts +15 -0
- package/dist/server/authentication/constant-time-api-key.js +24 -0
- package/dist/server/authentication/index.d.ts +1 -1
- package/dist/server/authentication/index.js +7 -4
- package/dist/server/authentication/rotating-api-key-store.d.ts +5 -3
- package/dist/server/authentication/rotating-api-key-store.js +19 -11
- package/dist/server/engine-event-feed-backend.d.ts +4 -5
- package/dist/server/fault-to-http.js +8 -1
- package/dist/server/fault-to-json-rpc.js +1 -0
- package/dist/server/fleet-event-feed.d.ts +31 -0
- package/dist/server/fleet-event-feed.js +157 -0
- package/dist/server/handler/index.js +1 -1
- package/dist/server/handler/response-helpers.js +2 -1
- package/dist/server/handler/route-dispatch.d.ts +6 -3
- package/dist/server/handler/route-dispatch.js +2 -2
- package/dist/server/handler.js +31 -31
- package/dist/server/index.d.ts +32 -2
- package/dist/server/index.js +35 -35
- package/dist/server/interactive-operations.js +1 -0
- package/dist/server/json-rpc-transport-helpers.d.ts +1 -0
- package/dist/server/json-rpc-transport-helpers.js +2 -1
- package/dist/server/json-rpc-websocket-runtime.d.ts +11 -2
- package/dist/server/json-rpc-websocket-runtime.js +1 -0
- package/dist/server/json-rpc-websocket-subscriptions.d.ts +10 -0
- package/dist/server/json-rpc-websocket-subscriptions.js +29 -0
- package/dist/server/json-rpc-websocket-types.d.ts +22 -0
- package/dist/server/json-rpc-websocket-types.js +0 -0
- package/dist/server/json-rpc-websocket-validation.js +20 -4
- package/dist/server/json-rpc-websocket.d.ts +2 -43
- package/dist/server/json-rpc-websocket.js +57 -74
- package/dist/server/openapi.d.ts +2 -1
- package/dist/server/openapi.js +1 -3
- package/dist/server/openrpc-document-schema.d.ts +78 -0
- package/dist/server/openrpc-document-schema.js +27 -1
- package/dist/server/openrpc-errors.d.ts +3 -0
- package/dist/server/openrpc-errors.js +2 -1
- package/dist/server/openrpc.js +32 -0
- package/dist/server/operation-catalog/index.d.ts +1 -1
- package/dist/server/operation-catalog/pipeline-helpers.js +1 -0
- package/dist/server/operation-catalog/pipeline-stages.js +26 -12
- package/dist/server/operation-catalog/pipeline.js +8 -1
- package/dist/server/operation-catalog/registry.js +13 -0
- package/dist/server/operation-catalog/types.d.ts +20 -9
- package/dist/server/operation-fault.d.ts +10 -0
- package/dist/server/operation-fault.js +2 -0
- package/dist/server/operation-registry.d.ts +12 -11
- package/dist/server/operation-registry.js +12 -3
- package/dist/server/operations/aggregate-workflows.d.ts +15 -15
- package/dist/server/operations/async-activity.d.ts +2 -2
- package/dist/server/operations/async-activity.js +12 -7
- package/dist/server/operations/bulk-cancel-workflows.d.ts +1 -1
- package/dist/server/operations/bulk-cancel-workflows.js +2 -2
- package/dist/server/operations/bulk-delete-workflows.d.ts +1 -1
- package/dist/server/operations/bulk-delete-workflows.js +2 -2
- package/dist/server/operations/bulk-filter-helpers.d.ts +8 -6
- package/dist/server/operations/bulk-filter-helpers.js +54 -24
- package/dist/server/operations/bulk-mutate-workflow-tags.d.ts +11 -9
- package/dist/server/operations/bulk-mutate-workflow-tags.js +2 -2
- package/dist/server/operations/bulk-operation-helpers.d.ts +2 -2
- package/dist/server/operations/bulk-retry-failed-workflows.d.ts +7 -0
- package/dist/server/operations/bulk-retry-failed-workflows.js +64 -0
- package/dist/server/operations/bulk-signal-workflows.d.ts +11 -9
- package/dist/server/operations/bulk-signal-workflows.js +2 -2
- package/dist/server/operations/cancel-schedule.d.ts +1 -1
- package/dist/server/operations/create-schedule.d.ts +3 -1
- package/dist/server/operations/create-schedule.js +29 -11
- package/dist/server/operations/fleet-events-subscription.d.ts +54 -0
- package/dist/server/operations/fleet-events-subscription.js +99 -0
- package/dist/server/operations/fork-workflow.d.ts +1 -1
- package/dist/server/operations/fork-workflow.js +3 -2
- package/dist/server/operations/get-checkpoint-at.d.ts +1 -1
- package/dist/server/operations/get-registry.d.ts +1 -1
- package/dist/server/operations/get-retention-overview.d.ts +1 -1
- package/dist/server/operations/get-review.d.ts +1 -1
- package/dist/server/operations/get-schedule.d.ts +1 -1
- package/dist/server/operations/get-stream-chunks.d.ts +1 -1
- package/dist/server/operations/get-system-metrics.d.ts +2 -2
- package/dist/server/operations/get-task-diagnostics.d.ts +45 -6
- package/dist/server/operations/get-task-diagnostics.js +101 -7
- package/dist/server/operations/get-update-result.d.ts +1 -1
- package/dist/server/operations/get-workflow-attributes.d.ts +1 -1
- package/dist/server/operations/get-workflow-events.d.ts +1 -1
- package/dist/server/operations/get-workflow-result.d.ts +1 -1
- package/dist/server/operations/get-workflow-timeline.d.ts +1 -1
- package/dist/server/operations/get-workflow.d.ts +1 -1
- package/dist/server/operations/list-checkpoints.d.ts +1 -1
- package/dist/server/operations/list-reviews.d.ts +1 -1
- package/dist/server/operations/list-schedules.d.ts +1 -1
- package/dist/server/operations/list-task-queues.d.ts +2 -2
- package/dist/server/operations/list-workers.d.ts +2 -2
- package/dist/server/operations/list-workflows.d.ts +1 -1
- package/dist/server/operations/operation-helpers.d.ts +16 -1
- package/dist/server/operations/operation-helpers.js +15 -3
- package/dist/server/operations/pause-schedule.d.ts +1 -1
- package/dist/server/operations/purge-workflows.d.ts +5 -5
- package/dist/server/operations/purge-workflows.js +2 -2
- package/dist/server/operations/query-workflow.d.ts +1 -1
- package/dist/server/operations/query-workflow.js +3 -2
- package/dist/server/operations/recover-all.d.ts +1 -1
- package/dist/server/operations/replay-workflow.d.ts +1 -1
- package/dist/server/operations/resume-schedule.d.ts +1 -1
- package/dist/server/operations/resume-workflow.js +2 -2
- package/dist/server/operations/set-workflow-attributes.d.ts +1 -1
- package/dist/server/operations/set-workflow-attributes.js +6 -3
- package/dist/server/operations/signal-workflow.js +8 -3
- package/dist/server/operations/single-workflow-tag-mutation.js +13 -3
- package/dist/server/operations/start-or-signal-workflow.d.ts +44 -0
- package/dist/server/operations/start-or-signal-workflow.js +130 -0
- package/dist/server/operations/start-workflow-options.d.ts +38 -0
- package/dist/server/operations/start-workflow-options.js +63 -0
- package/dist/server/operations/start-workflow-rest-input.d.ts +14 -0
- package/dist/server/operations/start-workflow-rest-input.js +31 -0
- package/dist/server/operations/start-workflow.d.ts +1 -1
- package/dist/server/operations/start-workflow.js +15 -92
- package/dist/server/operations/storage.d.ts +6 -6
- package/dist/server/operations/storage.js +24 -14
- package/dist/server/operations/stream-workflow-sse.d.ts +1 -1
- package/dist/server/operations/submit-review-decision.d.ts +1 -1
- package/dist/server/operations/submit-review-decision.js +6 -3
- package/dist/server/operations/suspend-workflow.d.ts +13 -0
- package/dist/server/operations/suspend-workflow.js +36 -0
- package/dist/server/operations/update-schedule.d.ts +1 -1
- package/dist/server/operations/update-schedule.js +7 -4
- package/dist/server/operations/update-workflow.d.ts +1 -1
- package/dist/server/operations/update-workflow.js +7 -3
- package/dist/server/operations/worker-drain.d.ts +8 -8
- package/dist/server/operations/worker-drain.js +11 -8
- package/dist/server/operations/workflow-events-subscription.d.ts +7 -8
- package/dist/server/operations/workflow-events-subscription.js +43 -8
- package/dist/server/rest-binding.d.ts +21 -8
- package/dist/server/rest-bindings.js +24 -0
- package/dist/server/rest-body.d.ts +10 -0
- package/dist/server/rest-body.js +80 -0
- package/dist/server/runtime/authentication-bridge.d.ts +1 -0
- package/dist/server/runtime/authentication-bridge.js +33 -6
- package/dist/server/runtime/client-visible-events.d.ts +3 -0
- package/dist/server/runtime/client-visible-events.js +65 -0
- package/dist/server/runtime/context.d.ts +7 -0
- package/dist/server/runtime/event-broadcasting.d.ts +6 -0
- package/dist/server/runtime/event-broadcasting.js +72 -38
- package/dist/server/runtime/retry.d.ts +1 -0
- package/dist/server/runtime/retry.js +14 -0
- package/dist/server/runtime/shutdown.d.ts +7 -6
- package/dist/server/runtime/shutdown.js +6 -1
- package/dist/server/runtime/task-dispatch.js +5 -3
- package/dist/server/runtime/task-polling.d.ts +16 -2
- package/dist/server/runtime/task-polling.js +80 -24
- package/dist/server/runtime/task-reconciliation.js +9 -1
- package/dist/server/runtime/task-result-resolution.d.ts +15 -0
- package/dist/server/runtime/task-result-resolution.js +81 -0
- package/dist/server/runtime/websocket-stream.d.ts +20 -1
- package/dist/server/runtime/websocket-stream.js +173 -7
- package/dist/server/runtime/websocket-upgrade.js +22 -3
- package/dist/server/runtime/websocket-worker.d.ts +1 -1
- package/dist/server/runtime/websocket-worker.js +46 -30
- package/dist/server/serve-internals.d.ts +11 -1
- package/dist/server/serve-internals.js +20 -2
- package/dist/server/task-state.d.ts +38 -0
- package/dist/server/task-state.js +28 -0
- package/dist/server/workflow-event-feed.d.ts +36 -115
- package/dist/server/workflow-event-feed.js +92 -27
- package/dist/service-worker/index.js +31 -31
- package/dist/storage/auto.js +1 -1
- package/dist/storage/bun-sql.js +24 -0
- package/dist/storage/capabilities.d.ts +10 -2
- package/dist/storage/capabilities.js +2 -2
- package/dist/storage/compressed-storage.js +1 -1
- package/dist/storage/default-scope.d.ts +7 -4
- package/dist/storage/http.js +2 -2
- package/dist/storage/index.d.ts +81 -4
- package/dist/storage/indexeddb.js +1 -1
- package/dist/storage/interface.d.ts +189 -0
- package/dist/storage/interface.js +1 -1
- package/dist/storage/key-prefixes.d.ts +1 -1
- package/dist/storage/key-prefixes.js +12 -0
- package/dist/storage/lmdb.d.ts +4 -3
- package/dist/storage/lmdb.js +1 -1
- package/dist/storage/memory.js +1 -1
- package/dist/storage/neon-batch.d.ts +30 -0
- package/dist/storage/neon-batch.js +30 -0
- package/dist/storage/neon-value-mapping.d.ts +74 -0
- package/dist/storage/neon-value-mapping.js +23 -0
- package/dist/storage/neon.d.ts +124 -0
- package/dist/storage/neon.js +15 -0
- package/dist/storage/node-sqlite-loader.d.ts +71 -0
- package/dist/storage/node-sqlite-loader.js +41 -0
- package/dist/storage/node-sqlite.d.ts +1 -19
- package/dist/storage/node-sqlite.js +61 -32
- package/dist/storage/postgres-key-value-queries.d.ts +104 -0
- package/dist/storage/postgres-key-value-queries.js +101 -0
- package/dist/storage/resolve.d.ts +2 -165
- package/dist/storage/resolve.js +1 -1
- package/dist/storage/scoped-storage.js +1 -1
- package/dist/storage/storage-configuration.d.ts +209 -0
- package/dist/storage/storage-configuration.js +0 -0
- package/dist/storage/testing.d.ts +168 -0
- package/dist/storage/testing.js +2 -0
- package/dist/storage/text-value-store.d.ts +9 -9
- package/dist/storage/turso.d.ts +8 -0
- package/dist/storage/turso.js +2 -2
- package/dist/storage/typed-storage.js +1 -1
- package/dist/storage/web-extension.js +1 -1
- package/dist/testing/index.js +35 -35
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worker/index.js +9 -5
- package/dist/worker/long-poll.js +4 -0
- package/dist/worker/protocol-messages.d.ts +20 -0
- package/dist/worker/protocol-schemas.d.ts +32 -0
- package/dist/worker/protocol-schemas.js +8 -4
- package/dist/worker/protocol-task-result.d.ts +28 -0
- package/dist/worker/protocol-task-result.js +76 -0
- package/dist/worker/protocol.d.ts +4 -15
- package/dist/worker/protocol.js +1 -1
- package/dist/worker/registry/fair-share.d.ts +29 -0
- package/dist/worker/registry/fair-share.js +30 -0
- package/dist/worker/registry/routing.d.ts +18 -0
- package/dist/worker/registry/routing.js +14 -0
- package/dist/worker/registry/types.d.ts +7 -0
- package/dist/worker/registry.d.ts +16 -1
- package/dist/worker/registry.js +24 -36
- package/dist/workers/worker-replay-state.d.ts +32 -0
- package/dist/workers/worker-replay-state.js +35 -0
- package/dist/workers/worker-state-namespace.d.ts +21 -0
- package/dist/workers/worker-state-namespace.js +13 -0
- package/dist/workers/workflow-runner.d.ts +19 -15
- package/dist/workers/workflow-runner.js +72 -60
- package/dist/workers/workflow-worker-entry.js +5 -2
- package/package.json +21 -4
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { BatchOperation } from '../../storage/interface.ts';
|
|
1
2
|
import type { ListFilter, PurgeResult, WorkflowState } from '../types.ts';
|
|
2
3
|
import type { EngineInternals } from './internals.ts';
|
|
3
4
|
export declare const TERMINAL_CLEANUP_DELAY_MS = 60000;
|
|
@@ -9,3 +10,28 @@ export type PurgeParameters = {
|
|
|
9
10
|
export type CleanupWaiters = (workflowId: string) => void;
|
|
10
11
|
export declare function purgeInternal(internals: EngineInternals, filter: ListFilter | undefined, parameters: PurgeParameters, cleanupWaiters: CleanupWaiters): Promise<PurgeResult>;
|
|
11
12
|
export declare function purgeWorkflow(internals: EngineInternals, state: WorkflowState, cleanupWaiters: CleanupWaiters): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Collect every storage delete operation that removing a workflow id entails —
|
|
15
|
+
* index deletes (search attributes + tags), the explicit key set (state,
|
|
16
|
+
* checkpoint, headers, services marker, update requests/responses, and the
|
|
17
|
+
* `wf:`/`ev:`/`sig:`/... prefix sweeps), and the visibility-index transition to
|
|
18
|
+
* `null`. Pure: it reads storage to discover keys but writes nothing, so a caller
|
|
19
|
+
* can fold the returned ops into a larger atomic batch instead of committing them
|
|
20
|
+
* standalone. {@link purgeWorkflow} commits them on their own; the
|
|
21
|
+
* `onTerminalConflict: 'start-new'` restart path prepends them to the create batch
|
|
22
|
+
* so purge-and-recreate land as one atomic unit (no window where the prior run is
|
|
23
|
+
* gone but the new one has not committed). Keep this the single source of truth
|
|
24
|
+
* for "what a purge deletes" — do not fork the delete-set.
|
|
25
|
+
*/
|
|
26
|
+
export declare function collectWorkflowPurgeDeleteOperations(internals: EngineInternals, state: WorkflowState): Promise<BatchOperation[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Drop every in-memory cache entry a purged workflow id owns (checkpoints,
|
|
29
|
+
* heartbeat details, event-log heads, version tuples, handle cache, result
|
|
30
|
+
* resolvers, headers, nesting depths, type map, pending async activities) and run
|
|
31
|
+
* `cleanupWaiters` to settle any pending signal/update/sleep waiters. Split from
|
|
32
|
+
* the storage batch in {@link collectWorkflowPurgeDeleteOperations} so the restart
|
|
33
|
+
* path can clear the OLD run's in-memory state up front — before the new run's
|
|
34
|
+
* caches are written under the reused id — while the durable delete still commits
|
|
35
|
+
* atomically with the create.
|
|
36
|
+
*/
|
|
37
|
+
export declare function clearPurgedWorkflowInMemoryState(internals: EngineInternals, workflowId: string, cleanupWaiters: CleanupWaiters): void;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
KEYS,
|
|
3
3
|
encodeStorageKeyComponent,
|
|
4
|
+
storageHas,
|
|
4
5
|
storageKeys,
|
|
5
6
|
tryDecodeStorageKeyComponent
|
|
6
7
|
} from "../../storage/interface.js";
|
|
@@ -25,7 +26,7 @@ export async function purgeInternal(internals, filter, parameters, cleanupWaiter
|
|
|
25
26
|
let remainingOffset = manualOffset, deleted = 0;
|
|
26
27
|
const workflowStateStream = parameters.expiredOnly && filter === void 0 ? streamExpiredRetentionWorkflowStates(internals, parameters.now) : streamWorkflowStates(internals, filter);
|
|
27
28
|
for await (const state of workflowStateStream) {
|
|
28
|
-
if (!shouldPurgeWorkflowState(internals, state, parameters.expiredOnly, parameters.now))
|
|
29
|
+
if (!await shouldPurgeWorkflowState(internals, state, parameters.expiredOnly, parameters.now))
|
|
29
30
|
continue;
|
|
30
31
|
if (remainingOffset > 0) {
|
|
31
32
|
remainingOffset -= 1;
|
|
@@ -110,9 +111,11 @@ function resolvePurgeLimit(manualLimit, fallbackLimit) {
|
|
|
110
111
|
return manualLimit;
|
|
111
112
|
return Math.min(manualLimit, fallbackLimit);
|
|
112
113
|
}
|
|
113
|
-
function shouldPurgeWorkflowState(internals, state, expiredOnly, now) {
|
|
114
|
+
async function shouldPurgeWorkflowState(internals, state, expiredOnly, now) {
|
|
114
115
|
if (!isTerminalWorkflowStatus(state.status))
|
|
115
116
|
return !1;
|
|
117
|
+
if (await storageHas(internals.storage, KEYS.teardownOwed(state.id)))
|
|
118
|
+
return !1;
|
|
116
119
|
if (!expiredOnly)
|
|
117
120
|
return !0;
|
|
118
121
|
const deadline = getWorkflowRetentionDeadline(internals, state);
|
|
@@ -127,16 +130,25 @@ function getWorkflowRetentionDeadline(internals, state) {
|
|
|
127
130
|
return state.updatedAt + retentionMs;
|
|
128
131
|
}
|
|
129
132
|
export async function purgeWorkflow(internals, state, cleanupWaiters) {
|
|
133
|
+
const deleteOperations = await collectWorkflowPurgeDeleteOperations(internals, state);
|
|
134
|
+
await internals.storage.batch(deleteOperations);
|
|
135
|
+
clearPurgedWorkflowInMemoryState(internals, state.id, cleanupWaiters);
|
|
136
|
+
}
|
|
137
|
+
export async function collectWorkflowPurgeDeleteOperations(internals, state) {
|
|
130
138
|
const workflowId = state.id, attributeBytes = await internals.storage.get(KEYS.attribute(workflowId)), deleteOperations = buildWorkflowIndexDeleteOperations(state, attributeBytes), deleteKeys = await collectWorkflowPurgeDeleteKeys(internals, state);
|
|
131
139
|
appendKeyDeleteOperations(deleteOperations, deleteKeys);
|
|
132
140
|
deleteOperations.push(...buildWorkflowVisibilityIndexTransition(workflowId, state, null).batchOps);
|
|
133
|
-
|
|
141
|
+
return deleteOperations;
|
|
142
|
+
}
|
|
143
|
+
export function clearPurgedWorkflowInMemoryState(internals, workflowId, cleanupWaiters) {
|
|
134
144
|
forgetCommittedCheckpointBytes(internals, workflowId);
|
|
135
145
|
internals.checkpoints.delete(workflowId);
|
|
136
146
|
internals.heartbeatDetails.delete(workflowId);
|
|
147
|
+
internals.lastHeartbeatDetailsByStep.delete(workflowId);
|
|
137
148
|
for (const [token, pending] of internals.pendingAsyncActivities)
|
|
138
149
|
if (pending.workflowId === workflowId)
|
|
139
150
|
internals.pendingAsyncActivities.delete(token);
|
|
151
|
+
internals.pendingAsyncActivityResolutions.delete(workflowId);
|
|
140
152
|
internals.eventLogHeads.delete(workflowId);
|
|
141
153
|
internals.workflowVersionTuples.delete(workflowId);
|
|
142
154
|
internals.handleCache.delete(workflowId);
|
|
@@ -178,7 +190,10 @@ function buildBaseWorkflowDeleteKeys(state) {
|
|
|
178
190
|
KEYS.checkpoint(state.id),
|
|
179
191
|
KEYS.workflowHeaders(state.id),
|
|
180
192
|
KEYS.terminalCleanupNeeded(state.id),
|
|
193
|
+
KEYS.workflowConcurrencyHolder(state.id),
|
|
181
194
|
KEYS.workflowHasServices(state.id),
|
|
195
|
+
KEYS.finalizerState(state.id),
|
|
196
|
+
KEYS.teardownOwed(state.id),
|
|
182
197
|
KEYS.attribute(state.id),
|
|
183
198
|
KEYS.terminalWorkflow(state.updatedAt, state.id)
|
|
184
199
|
]);
|
|
@@ -216,11 +231,31 @@ async function addWorkflowPrefixDeleteKeys(storage, deleteKeys, workflowId) {
|
|
|
216
231
|
for (const key of keys)
|
|
217
232
|
deleteKeys.add(key);
|
|
218
233
|
}
|
|
234
|
+
await addWorkflowLinkedFleetEventDeleteKeys(storage, deleteKeys, workflowId);
|
|
235
|
+
}
|
|
236
|
+
async function addWorkflowLinkedFleetEventDeleteKeys(storage, deleteKeys, workflowId) {
|
|
237
|
+
const prefix = KEYS.fleetEventByWorkflowPrefix(workflowId);
|
|
238
|
+
for await (const [key] of storage.scan(prefix)) {
|
|
239
|
+
deleteKeys.add(key);
|
|
240
|
+
const sequence = parseFleetEventSequenceFromWorkflowIndexKey(prefix, key);
|
|
241
|
+
if (sequence !== null)
|
|
242
|
+
deleteKeys.add(KEYS.fleetEvent(sequence));
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
function parseFleetEventSequenceFromWorkflowIndexKey(prefix, key) {
|
|
246
|
+
if (!key.startsWith(prefix))
|
|
247
|
+
return null;
|
|
248
|
+
const rawSequence = key.slice(prefix.length);
|
|
249
|
+
if (!/^\d+$/.test(rawSequence))
|
|
250
|
+
return null;
|
|
251
|
+
const sequence = Number(rawSequence);
|
|
252
|
+
return Number.isSafeInteger(sequence) ? sequence : null;
|
|
219
253
|
}
|
|
220
254
|
function workflowPurgePrefixes(workflowId) {
|
|
221
255
|
const encodedWorkflowId = encodeStorageKeyComponent(workflowId);
|
|
222
256
|
return [
|
|
223
257
|
`wf:${encodedWorkflowId}:ckpt:`,
|
|
258
|
+
`wf:${encodedWorkflowId}:timeline:`,
|
|
224
259
|
`ev:${encodedWorkflowId}:`,
|
|
225
260
|
`sig:${encodedWorkflowId}:`,
|
|
226
261
|
`review:${encodedWorkflowId}:`,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { BulkOperationAction, BulkOperationAuditEvent, BulkOperationCommitOptions, BulkOperationDryRunResult, BulkOperationError, BulkOperationOptions, BulkOperationScopeSummary, ListFilter, WorkflowState, WorkflowStatus } from '../types.ts';
|
|
2
2
|
import type { EngineInternals } from './internals.ts';
|
|
3
3
|
export declare const BULK_OPERATION_SAMPLE_LIMIT = 20;
|
|
4
|
+
export declare const DEFAULT_BULK_OPERATION_CONCURRENCY = 1;
|
|
4
5
|
export type BulkWorkflowSnapshot = {
|
|
5
6
|
id: string;
|
|
6
7
|
type: string;
|
|
@@ -22,6 +23,7 @@ export declare function withBulkAuditEvent<TResult extends object>(internals: En
|
|
|
22
23
|
auditEvent: BulkOperationAuditEvent;
|
|
23
24
|
}>;
|
|
24
25
|
export declare function normalizeBulkOperationOptions<TOptions extends BulkOperationOptions>(options: TOptions): TOptions;
|
|
26
|
+
export declare function resolveBulkOperationConcurrency(options: BulkOperationOptions): number;
|
|
25
27
|
export declare function toBulkOperationError(_internals: EngineInternals, workflowId: string, error: unknown): BulkOperationError;
|
|
26
28
|
export declare function snapshotMatchingWorkflowSnapshots(internals: EngineInternals, filter?: ListFilter): Promise<BulkWorkflowSnapshot[]>;
|
|
27
29
|
export declare function workflowStateToBulkSnapshot(state: WorkflowState): BulkWorkflowSnapshot;
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from "./errors.js";
|
|
14
14
|
import { streamWorkflowStateBatches } from "./listing.js";
|
|
15
15
|
import { isTerminalWorkflowStatus } from "./validation.js";
|
|
16
|
-
export const BULK_OPERATION_SAMPLE_LIMIT = 20;
|
|
16
|
+
export const BULK_OPERATION_SAMPLE_LIMIT = 20, DEFAULT_BULK_OPERATION_CONCURRENCY = 1;
|
|
17
17
|
const DEFAULT_BULK_OPERATION_PRINCIPAL = { method: "in-process" };
|
|
18
18
|
export function buildActionableBulkWorkflowFilter(_internals, filter, actionableStatuses) {
|
|
19
19
|
const effectiveStatuses = (filter.status === void 0 ? actionableStatuses : Array.isArray(filter.status) ? filter.status : [filter.status]).filter((status) => actionableStatuses.includes(status));
|
|
@@ -69,7 +69,7 @@ function summarizeBulkFilter(filter) {
|
|
|
69
69
|
if (filter.attributes !== void 0)
|
|
70
70
|
summary.attributes = filter.attributes.map((attribute) => ({
|
|
71
71
|
key: searchAttributeName(attribute.key),
|
|
72
|
-
...attribute.value === void 0 ? {} : { value: attribute.value },
|
|
72
|
+
...attribute.value === void 0 ? {} : { value: Array.isArray(attribute.value) ? [...attribute.value] : attribute.value },
|
|
73
73
|
...attribute.gt === void 0 ? {} : { gt: attribute.gt },
|
|
74
74
|
...attribute.lt === void 0 ? {} : { lt: attribute.lt },
|
|
75
75
|
...attribute.gte === void 0 ? {} : { gte: attribute.gte },
|
|
@@ -136,6 +136,9 @@ async function persistBulkOperationAuditEvent(internals, preparation, options, a
|
|
|
136
136
|
return auditEvent;
|
|
137
137
|
}
|
|
138
138
|
export function normalizeBulkOperationOptions(options) {
|
|
139
|
+
const bulkConcurrency = options.bulkConcurrency;
|
|
140
|
+
if (bulkConcurrency !== void 0 && (!Number.isSafeInteger(bulkConcurrency) || bulkConcurrency < 1))
|
|
141
|
+
throw Error('Field "bulkConcurrency" must be a positive integer');
|
|
139
142
|
const confirmationToken = "confirmationToken" in options ? options.confirmationToken : void 0;
|
|
140
143
|
if (confirmationToken !== void 0 && confirmationToken.length > MAX_BULK_CONFIRMATION_TOKEN_LENGTH)
|
|
141
144
|
throw Error(`Field "confirmationToken" must be at most ${String(MAX_BULK_CONFIRMATION_TOKEN_LENGTH)} characters`);
|
|
@@ -143,6 +146,9 @@ export function normalizeBulkOperationOptions(options) {
|
|
|
143
146
|
throw Error(`Field "requestId" must be at most ${String(MAX_BULK_OPERATION_REQUEST_ID_LENGTH)} characters`);
|
|
144
147
|
return options;
|
|
145
148
|
}
|
|
149
|
+
export function resolveBulkOperationConcurrency(options) {
|
|
150
|
+
return options.bulkConcurrency ?? DEFAULT_BULK_OPERATION_CONCURRENCY;
|
|
151
|
+
}
|
|
146
152
|
export function toBulkOperationError(_internals, workflowId, error) {
|
|
147
153
|
return {
|
|
148
154
|
id: workflowId,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BulkCancelResult, BulkDeleteResult, BulkOperationCommitOptions, BulkOperationDryRunOptions, BulkOperationDryRunResult, BulkOperationOptions, BulkSignalAllCommitOptions, BulkSignalAllDryRunOptions, BulkSignalResult, BulkTagResult, ListFilter, PurgeResult } from '../types.ts';
|
|
1
|
+
import type { BulkCancelResult, BulkDeleteResult, BulkOperationCommitOptions, BulkOperationDryRunOptions, BulkOperationDryRunResult, BulkOperationOptions, BulkRetryFailedResult, BulkSignalAllCommitOptions, BulkSignalAllDryRunOptions, BulkSignalResult, BulkTagResult, ListFilter, PurgeResult } from '../types.ts';
|
|
2
2
|
import { type CleanupWaiters } from './bulk-operations-purge.ts';
|
|
3
3
|
import type { EngineInternals } from './internals.ts';
|
|
4
4
|
export { purgeInternal, TERMINAL_CLEANUP_DELAY_MS } from './bulk-operations-purge.ts';
|
|
@@ -6,6 +6,9 @@ export declare function purge(internals: EngineInternals, filter: ListFilter | u
|
|
|
6
6
|
export declare function cancelAll(internals: EngineInternals, filter: ListFilter, options: BulkOperationDryRunOptions): Promise<BulkOperationDryRunResult>;
|
|
7
7
|
export declare function cancelAll(internals: EngineInternals, filter: ListFilter, options?: BulkOperationCommitOptions): Promise<BulkCancelResult>;
|
|
8
8
|
export declare function cancelAll(internals: EngineInternals, filter: ListFilter, options?: BulkOperationDryRunOptions | BulkOperationCommitOptions): Promise<BulkCancelResult | BulkOperationDryRunResult>;
|
|
9
|
+
export declare function retryFailedAll(internals: EngineInternals, filter: ListFilter, options: BulkOperationDryRunOptions): Promise<BulkOperationDryRunResult>;
|
|
10
|
+
export declare function retryFailedAll(internals: EngineInternals, filter: ListFilter, options?: BulkOperationCommitOptions): Promise<BulkRetryFailedResult>;
|
|
11
|
+
export declare function retryFailedAll(internals: EngineInternals, filter: ListFilter, options?: BulkOperationDryRunOptions | BulkOperationCommitOptions): Promise<BulkRetryFailedResult | BulkOperationDryRunResult>;
|
|
9
12
|
export declare function signalAll(internals: EngineInternals, filter: ListFilter, name: string, payload: unknown, options: BulkSignalAllDryRunOptions): Promise<BulkOperationDryRunResult>;
|
|
10
13
|
export declare function signalAll(internals: EngineInternals, filter: ListFilter, name: string, payload: unknown, options: BulkSignalAllCommitOptions): Promise<BulkSignalResult>;
|
|
11
14
|
export declare function signalAll(internals: EngineInternals, filter: ListFilter, name: string, payload?: unknown, options?: BulkOperationCommitOptions): Promise<BulkSignalResult>;
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
KEYS,
|
|
3
|
+
requireStorageCapability,
|
|
4
|
+
storageConditionalBatch,
|
|
5
|
+
storageHas
|
|
6
|
+
} from "../../storage/interface.js";
|
|
1
7
|
import { assertScopedBulkWorkflowFilter } from "../bulk-workflow-filter.js";
|
|
2
|
-
import {
|
|
8
|
+
import { deserializeCheckpoint } from "../checkpoint.js";
|
|
9
|
+
import { decode, encode } from "../codec.js";
|
|
10
|
+
import { buildTimerBatchOperations } from "../scheduler.js";
|
|
11
|
+
import { buildIndexOperations } from "../search-attributes.js";
|
|
12
|
+
import { buildTerminalWorkflowIndexOperations, bulkMutateWorkflowTags } from "./attributes-tags.js";
|
|
3
13
|
import { purgeInternal, purgeWorkflow } from "./bulk-operations-purge.js";
|
|
4
14
|
import {
|
|
5
15
|
buildActionableBulkWorkflowFilter,
|
|
@@ -7,6 +17,7 @@ import {
|
|
|
7
17
|
collectTerminalWorkflowSnapshots,
|
|
8
18
|
normalizeBulkOperationOptions,
|
|
9
19
|
prepareBulkOperation,
|
|
20
|
+
resolveBulkOperationConcurrency,
|
|
10
21
|
shouldPersistBulkAudit,
|
|
11
22
|
toBulkOperationError,
|
|
12
23
|
validateBulkConfirmation,
|
|
@@ -14,10 +25,27 @@ import {
|
|
|
14
25
|
} from "./bulk-operations-shared.js";
|
|
15
26
|
import { BulkDeleteRequiresTerminalWorkflowsError } from "./errors.js";
|
|
16
27
|
import { BULK_OPERATION_BATCH_SIZE } from "./listing.js";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
28
|
+
import { createTerminalCleanupTimerId } from "./state-utilities.js";
|
|
29
|
+
import { loadWorkflowState, runSerializedWorkflowStateWrite } from "./storage-io.js";
|
|
30
|
+
import { decodeWorkflowState, isTerminalWorkflowStatus } from "./validation.js";
|
|
31
|
+
import { buildWorkflowConcurrencyStartOperations } from "./workflow-concurrency.js";
|
|
32
|
+
import { buildWorkflowVisibilityIndexTransition } from "./workflow-indexes.js";
|
|
19
33
|
export { purgeInternal, TERMINAL_CLEANUP_DELAY_MS } from "./bulk-operations-purge.js";
|
|
20
|
-
const ACTIVE_WORKFLOW_STATUSES = ["pending", "running"];
|
|
34
|
+
const ACTIVE_WORKFLOW_STATUSES = ["pending", "running", "suspended"], FAILED_WORKFLOW_STATUSES = ["failed"], CHECKPOINT_RETRY_CONCURRENCY_ADMISSION_MAX_ATTEMPTS = 5;
|
|
35
|
+
async function runBulkWorkflowPool(items, concurrencyLimit, operation) {
|
|
36
|
+
const results = [];
|
|
37
|
+
for (let batchStart = 0;batchStart < items.length; batchStart += concurrencyLimit) {
|
|
38
|
+
const batchItems = items.slice(batchStart, batchStart + concurrencyLimit);
|
|
39
|
+
results.push(...await Promise.all(batchItems.map(async (item) => {
|
|
40
|
+
try {
|
|
41
|
+
return { item, status: "fulfilled", value: await operation(item) };
|
|
42
|
+
} catch (reason) {
|
|
43
|
+
return { item, status: "rejected", reason };
|
|
44
|
+
}
|
|
45
|
+
})));
|
|
46
|
+
}
|
|
47
|
+
return results;
|
|
48
|
+
}
|
|
21
49
|
export async function purge(internals, filter, cleanupWaiters) {
|
|
22
50
|
return purgeInternal(internals, filter, { expiredOnly: !1, now: internals.options.getNow() }, cleanupWaiters);
|
|
23
51
|
}
|
|
@@ -28,20 +56,36 @@ async function runBulkCancellation(internals, filter, options = {}) {
|
|
|
28
56
|
if (options.dryRun === !0)
|
|
29
57
|
return preparation.preview;
|
|
30
58
|
validateBulkConfirmation(options, preparation);
|
|
31
|
-
const workflowIdsToCancel = preparation.workflowIds;
|
|
59
|
+
const workflowIdsToCancel = preparation.workflowIds, bulkConcurrency = resolveBulkOperationConcurrency(options);
|
|
32
60
|
let cancelled = 0;
|
|
33
|
-
const errors = []
|
|
34
|
-
for (const workflowId of workflowIdsToCancel)
|
|
61
|
+
const errors = [], cancellationResults = await runBulkWorkflowPool(workflowIdsToCancel, bulkConcurrency, async (workflowId) => {
|
|
35
62
|
try {
|
|
36
63
|
await internals.engine.cancel(workflowId);
|
|
37
|
-
if ((await loadWorkflowState(internals, workflowId))?.status === "cancelled")
|
|
38
|
-
cancelled
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
64
|
+
if ((await loadWorkflowState(internals, workflowId))?.status === "cancelled")
|
|
65
|
+
return { status: "cancelled" };
|
|
66
|
+
return {
|
|
67
|
+
status: "failed",
|
|
68
|
+
error: { id: workflowId, error: "Workflow no longer cancellable" }
|
|
69
|
+
};
|
|
42
70
|
} catch (error) {
|
|
43
|
-
|
|
71
|
+
return {
|
|
72
|
+
status: "failed",
|
|
73
|
+
error: toBulkOperationError(internals, workflowId, error)
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
for (const cancellationResult of cancellationResults) {
|
|
78
|
+
if (cancellationResult.status === "rejected") {
|
|
79
|
+
errors.push(toBulkOperationError(internals, cancellationResult.item, cancellationResult.reason));
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const { value } = cancellationResult;
|
|
83
|
+
if (value.status === "cancelled") {
|
|
84
|
+
cancelled += 1;
|
|
85
|
+
continue;
|
|
44
86
|
}
|
|
87
|
+
errors.push(value.error);
|
|
88
|
+
}
|
|
45
89
|
const result = { cancelled, failed: errors.length, errors };
|
|
46
90
|
if (!shouldPersistBulkAudit(options))
|
|
47
91
|
return result;
|
|
@@ -50,6 +94,145 @@ async function runBulkCancellation(internals, filter, options = {}) {
|
|
|
50
94
|
export async function cancelAll(internals, filter, options = {}) {
|
|
51
95
|
return runBulkCancellation(internals, filter, options);
|
|
52
96
|
}
|
|
97
|
+
async function runBulkFailedWorkflowRetry(internals, filter, options = {}) {
|
|
98
|
+
options = normalizeBulkOperationOptions(options);
|
|
99
|
+
assertScopedBulkWorkflowFilter(filter);
|
|
100
|
+
const actionableFilter = buildActionableBulkWorkflowFilter(internals, filter, FAILED_WORKFLOW_STATUSES), preparation = await prepareBulkOperation(internals, "retry-failed", actionableFilter, filter, {}, options);
|
|
101
|
+
if (options.dryRun === !0)
|
|
102
|
+
return preparation.preview;
|
|
103
|
+
validateBulkConfirmation(options, preparation);
|
|
104
|
+
const bulkConcurrency = resolveBulkOperationConcurrency(options);
|
|
105
|
+
let retried = 0;
|
|
106
|
+
const errors = [], retryResults = await runBulkWorkflowPool(preparation.workflowIds, bulkConcurrency, async (workflowId) => {
|
|
107
|
+
try {
|
|
108
|
+
await retryFailedWorkflow(internals, workflowId);
|
|
109
|
+
return { status: "retried" };
|
|
110
|
+
} catch (error) {
|
|
111
|
+
return {
|
|
112
|
+
status: "failed",
|
|
113
|
+
error: toBulkOperationError(internals, workflowId, error)
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
for (const retryResult of retryResults) {
|
|
118
|
+
if (retryResult.status === "rejected") {
|
|
119
|
+
errors.push(toBulkOperationError(internals, retryResult.item, retryResult.reason));
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
const { value } = retryResult;
|
|
123
|
+
if (value.status === "retried") {
|
|
124
|
+
retried += 1;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
errors.push(value.error);
|
|
128
|
+
}
|
|
129
|
+
const result = { retried, failed: errors.length, errors };
|
|
130
|
+
if (!shouldPersistBulkAudit(options))
|
|
131
|
+
return result;
|
|
132
|
+
return withBulkAuditEvent(internals, preparation, options, result, retried);
|
|
133
|
+
}
|
|
134
|
+
export async function retryFailedAll(internals, filter, options = {}) {
|
|
135
|
+
return runBulkFailedWorkflowRetry(internals, filter, options);
|
|
136
|
+
}
|
|
137
|
+
async function retryFailedWorkflow(internals, workflowId) {
|
|
138
|
+
const state = await loadWorkflowState(internals, workflowId);
|
|
139
|
+
if (state === null)
|
|
140
|
+
throw Error("Workflow no longer exists");
|
|
141
|
+
if (state.status !== "failed")
|
|
142
|
+
throw Error(`Workflow is ${state.status}, not failed`);
|
|
143
|
+
if (await internals.storage.get(KEYS.checkpoint(workflowId)) !== null) {
|
|
144
|
+
await reactivateFailedWorkflowFromCheckpoint(internals, state);
|
|
145
|
+
await internals.engine.resume(workflowId);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
await internals.engine.start(state.type, state.input, {
|
|
149
|
+
id: workflowId,
|
|
150
|
+
onTerminalConflict: "start-new",
|
|
151
|
+
...state.tags !== void 0 ? { tags: state.tags } : {}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
async function reactivateFailedWorkflowFromCheckpoint(internals, state) {
|
|
155
|
+
const reactivated = await runSerializedWorkflowStateWrite(internals, state.id, async () => reactivateFailedWorkflowFromCheckpointSerialized(internals, state.id));
|
|
156
|
+
if (reactivated.terminalCleanupTimerId !== void 0)
|
|
157
|
+
await internals.scheduler.cancel(reactivated.terminalCleanupTimerId, state.id);
|
|
158
|
+
}
|
|
159
|
+
async function reactivateFailedWorkflowFromCheckpointSerialized(internals, workflowId) {
|
|
160
|
+
let lastConcurrencyStateKey;
|
|
161
|
+
for (let attempt = 0;attempt < CHECKPOINT_RETRY_CONCURRENCY_ADMISSION_MAX_ATTEMPTS; attempt += 1) {
|
|
162
|
+
const currentStateBytes = await internals.storage.get(KEYS.workflow(workflowId));
|
|
163
|
+
if (currentStateBytes === null)
|
|
164
|
+
throw Error("Workflow no longer exists");
|
|
165
|
+
const currentState = decodeWorkflowState(currentStateBytes);
|
|
166
|
+
if (currentState.status !== "failed")
|
|
167
|
+
throw Error(`Workflow is ${currentState.status}, not failed`);
|
|
168
|
+
const currentCheckpointBytes = await internals.storage.get(KEYS.checkpoint(workflowId));
|
|
169
|
+
if (currentCheckpointBytes === null)
|
|
170
|
+
throw Error("Checkpoint no longer exists");
|
|
171
|
+
const checkpoint = deserializeCheckpoint(currentCheckpointBytes), registration = internals.registrations.get(currentState.type);
|
|
172
|
+
if (registration === void 0)
|
|
173
|
+
throw Error(`No workflow registered with name "${currentState.type}" (needed to retry "${workflowId}")`);
|
|
174
|
+
const concurrencyStartOperations = registration.concurrency === void 0 ? void 0 : await buildWorkflowConcurrencyStartOperations(internals, currentState.type, workflowId, currentState.input, registration.concurrency);
|
|
175
|
+
lastConcurrencyStateKey = concurrencyStartOperations?.stateKey ?? lastConcurrencyStateKey;
|
|
176
|
+
const reactivatedState = buildReactivatedWorkflowState(internals, currentState), currentAttributes = await loadSearchAttributes(internals, workflowId), operations = [
|
|
177
|
+
...buildTerminalWorkflowIndexOperations(currentState, reactivatedState),
|
|
178
|
+
{ type: "put", key: KEYS.workflow(workflowId), value: encode(reactivatedState) },
|
|
179
|
+
...buildWorkflowVisibilityIndexTransition(workflowId, currentState, reactivatedState).batchOps,
|
|
180
|
+
...buildRetrySearchAttributeOperations(workflowId, currentAttributes, checkpoint.searchAttributes),
|
|
181
|
+
...reactivatedState.executionDeadline === void 0 ? [] : buildTimerBatchOperations({
|
|
182
|
+
id: `deadline:${workflowId}`,
|
|
183
|
+
workflowId,
|
|
184
|
+
fireAt: reactivatedState.executionDeadline,
|
|
185
|
+
kind: "execution-deadline"
|
|
186
|
+
}),
|
|
187
|
+
...concurrencyStartOperations?.operations ?? []
|
|
188
|
+
], conditions = concurrencyStartOperations?.conditions ?? [];
|
|
189
|
+
if (await commitFailedWorkflowReactivation(internals, operations, conditions))
|
|
190
|
+
return {
|
|
191
|
+
terminalCleanupTimerId: currentState.terminalCleanupToken === void 0 ? void 0 : createTerminalCleanupTimerId(!1, currentState.terminalCleanupToken)
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
throw Error(`Workflow concurrency admission for "${lastConcurrencyStateKey ?? workflowId}" changed too many times while retrying failed workflow "${workflowId}"`);
|
|
195
|
+
}
|
|
196
|
+
async function commitFailedWorkflowReactivation(internals, operations, conditions) {
|
|
197
|
+
if (conditions.length === 0) {
|
|
198
|
+
await internals.storage.batch(operations);
|
|
199
|
+
return !0;
|
|
200
|
+
}
|
|
201
|
+
requireStorageCapability(internals.storage, "conditionalBatch", "retry failed workflow");
|
|
202
|
+
return storageConditionalBatch(internals.storage, conditions, operations);
|
|
203
|
+
}
|
|
204
|
+
function buildReactivatedWorkflowState(internals, state) {
|
|
205
|
+
const reactivatedState = {
|
|
206
|
+
...state,
|
|
207
|
+
status: "running",
|
|
208
|
+
updatedAt: internals.options.getNow()
|
|
209
|
+
};
|
|
210
|
+
delete reactivatedState.error;
|
|
211
|
+
delete reactivatedState.errorStack;
|
|
212
|
+
delete reactivatedState.failureCategory;
|
|
213
|
+
delete reactivatedState.result;
|
|
214
|
+
delete reactivatedState.terminationReason;
|
|
215
|
+
delete reactivatedState.terminalCleanupToken;
|
|
216
|
+
return reactivatedState;
|
|
217
|
+
}
|
|
218
|
+
async function loadSearchAttributes(internals, workflowId) {
|
|
219
|
+
const attributeBytes = await internals.storage.get(KEYS.attribute(workflowId));
|
|
220
|
+
if (attributeBytes === null)
|
|
221
|
+
return {};
|
|
222
|
+
return decode(attributeBytes);
|
|
223
|
+
}
|
|
224
|
+
function buildRetrySearchAttributeOperations(workflowId, currentAttributes, checkpointAttributes) {
|
|
225
|
+
const operations = buildIndexOperations(workflowId, currentAttributes, checkpointAttributes);
|
|
226
|
+
if (Object.keys(checkpointAttributes).length === 0)
|
|
227
|
+
operations.push({ type: "delete", key: KEYS.attribute(workflowId) });
|
|
228
|
+
else
|
|
229
|
+
operations.push({
|
|
230
|
+
type: "put",
|
|
231
|
+
key: KEYS.attribute(workflowId),
|
|
232
|
+
value: encode(checkpointAttributes)
|
|
233
|
+
});
|
|
234
|
+
return operations;
|
|
235
|
+
}
|
|
53
236
|
export async function signalAll(internals, filter, name, payload, maybeOptions) {
|
|
54
237
|
const options = normalizeBulkOperationOptions(maybeOptions ?? {});
|
|
55
238
|
assertScopedBulkWorkflowFilter(filter);
|
|
@@ -59,15 +242,21 @@ export async function signalAll(internals, filter, name, payload, maybeOptions)
|
|
|
59
242
|
if (options.dryRun === !0)
|
|
60
243
|
return preparation.preview;
|
|
61
244
|
validateBulkConfirmation(options, preparation);
|
|
62
|
-
const workflowIdsToSignal = preparation.workflowIds;
|
|
245
|
+
const workflowIdsToSignal = preparation.workflowIds, bulkConcurrency = resolveBulkOperationConcurrency(options);
|
|
63
246
|
let signalled = 0, failed = 0;
|
|
64
|
-
|
|
247
|
+
const signalResults = await runBulkWorkflowPool(workflowIdsToSignal, bulkConcurrency, async (workflowId) => {
|
|
65
248
|
try {
|
|
66
249
|
await internals.engine.signal(workflowId, name, payload);
|
|
67
|
-
signalled
|
|
250
|
+
return { status: "signalled" };
|
|
68
251
|
} catch {
|
|
69
|
-
failed
|
|
252
|
+
return { status: "failed" };
|
|
70
253
|
}
|
|
254
|
+
});
|
|
255
|
+
for (const signalResult of signalResults)
|
|
256
|
+
if (signalResult.status === "fulfilled" && signalResult.value.status === "signalled")
|
|
257
|
+
signalled += 1;
|
|
258
|
+
else
|
|
259
|
+
failed += 1;
|
|
71
260
|
const result = { signalled, failed };
|
|
72
261
|
if (!shouldPersistBulkAudit(options))
|
|
73
262
|
return result;
|
|
@@ -77,18 +266,40 @@ async function runBulkDeletion(internals, filter, cleanupWaiters, options = {})
|
|
|
77
266
|
options = normalizeBulkOperationOptions(options);
|
|
78
267
|
assertScopedBulkWorkflowFilter(filter);
|
|
79
268
|
const candidateWorkflowSnapshots = await collectTerminalWorkflowSnapshots(internals, filter), preparation = buildBulkOperationPreparation("delete", filter, {}, candidateWorkflowSnapshots, options);
|
|
80
|
-
if (options.dryRun === !0)
|
|
81
|
-
|
|
269
|
+
if (options.dryRun === !0) {
|
|
270
|
+
const skippedTeardownPending = [];
|
|
271
|
+
for (const workflowId of preparation.workflowIds)
|
|
272
|
+
if (await storageHas(internals.storage, KEYS.teardownOwed(workflowId)))
|
|
273
|
+
skippedTeardownPending.push(workflowId);
|
|
274
|
+
return skippedTeardownPending.length > 0 ? { ...preparation.preview, skippedTeardownPending } : preparation.preview;
|
|
275
|
+
}
|
|
82
276
|
validateBulkConfirmation(options, preparation);
|
|
277
|
+
const bulkConcurrency = resolveBulkOperationConcurrency(options);
|
|
83
278
|
let deleted = 0;
|
|
279
|
+
const skippedTeardownPending = [];
|
|
84
280
|
for (let batchStart = 0;batchStart < preparation.workflowIds.length; batchStart += BULK_OPERATION_BATCH_SIZE) {
|
|
85
|
-
const batchWorkflowIds = preparation.workflowIds.slice(batchStart, batchStart + BULK_OPERATION_BATCH_SIZE), workflowStatesToDelete = await loadTerminalWorkflowStatesForBatch(internals, batchWorkflowIds);
|
|
86
|
-
for (const workflowState of workflowStatesToDelete)
|
|
281
|
+
const batchWorkflowIds = preparation.workflowIds.slice(batchStart, batchStart + BULK_OPERATION_BATCH_SIZE), workflowStatesToDelete = await loadTerminalWorkflowStatesForBatch(internals, batchWorkflowIds), deletableStates = [];
|
|
282
|
+
for (const workflowState of workflowStatesToDelete)
|
|
283
|
+
if (await storageHas(internals.storage, KEYS.teardownOwed(workflowState.id)))
|
|
284
|
+
skippedTeardownPending.push(workflowState.id);
|
|
285
|
+
else
|
|
286
|
+
deletableStates.push(workflowState);
|
|
287
|
+
const deletionResults = await runBulkWorkflowPool(deletableStates, bulkConcurrency, async (workflowState) => {
|
|
87
288
|
await purgeWorkflow(internals, workflowState, cleanupWaiters);
|
|
88
|
-
|
|
89
|
-
}
|
|
289
|
+
return workflowState.id;
|
|
290
|
+
}), deletionErrors = [];
|
|
291
|
+
for (const deletionResult of deletionResults)
|
|
292
|
+
if (deletionResult.status === "fulfilled")
|
|
293
|
+
deleted += 1;
|
|
294
|
+
else
|
|
295
|
+
deletionErrors.push(deletionResult.reason);
|
|
296
|
+
if (deletionErrors.length > 0)
|
|
297
|
+
throw AggregateError(deletionErrors, `Bulk delete failed for ${deletionErrors.length} workflow(s) after deleting ${deleted} workflow(s)`);
|
|
90
298
|
}
|
|
91
|
-
const result = {
|
|
299
|
+
const result = {
|
|
300
|
+
deleted,
|
|
301
|
+
...skippedTeardownPending.length > 0 ? { skippedTeardownPending } : {}
|
|
302
|
+
};
|
|
92
303
|
if (!shouldPersistBulkAudit(options))
|
|
93
304
|
return result;
|
|
94
305
|
return withBulkAuditEvent(internals, preparation, options, result, deleted);
|
|
@@ -9,16 +9,25 @@ import { type OperationWithCallerStack } from './operations-router.ts';
|
|
|
9
9
|
import type { StateOperationCallbacks } from './operations-state.ts';
|
|
10
10
|
import type { StreamOperationCallbacks } from './operations-stream.ts';
|
|
11
11
|
import type { TimeOperationCallbacks } from './operations-time.ts';
|
|
12
|
+
import type { ConditionOperationCallbacks } from './operations-wait-condition.ts';
|
|
12
13
|
import { type UpdateCallbacks } from './updates.ts';
|
|
13
14
|
export declare function createChildWorkflowOperationCallbacks<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>): ChildWorkflowOperationCallbacks;
|
|
14
15
|
export declare function createActivityOperationCallbacks<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>): ActivityOperationCallbacks;
|
|
15
16
|
export declare function createCoordinationOperationCallbacks<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>): CoordinationOperationCallbacks;
|
|
17
|
+
export declare function createConditionOperationCallbacks<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>): ConditionOperationCallbacks;
|
|
16
18
|
export declare function createDataOperationCallbacks<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>): DataOperationCallbacks;
|
|
17
19
|
export declare function createStateOperationCallbacks<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>): StateOperationCallbacks;
|
|
18
20
|
export declare function createStreamOperationCallbacks<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>): StreamOperationCallbacks;
|
|
19
21
|
export declare function createTimeOperationCallbacks<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>): TimeOperationCallbacks;
|
|
20
22
|
export declare function createUpdateCallbacks<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>): UpdateCallbacks;
|
|
21
23
|
export declare function completeOperationForEngine<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>, workflowId: string, value: unknown): void;
|
|
24
|
+
/**
|
|
25
|
+
* Fail the pending operation for a workflow, feeding the error to the generator
|
|
26
|
+
* so it re-throws at the `yield*` site (catchable by the workflow body). Used by
|
|
27
|
+
* the wait-condition processor when the user predicate throws, so a throwing
|
|
28
|
+
* predicate surfaces as a workflow failure instead of parking the run forever.
|
|
29
|
+
*/
|
|
30
|
+
export declare function failOperationForEngine<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>, workflowId: string, operation: OperationWithCallerStack, error: unknown): void;
|
|
22
31
|
export declare function runOperationWithResultForEngine<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>, workflowId: string, operation: OperationWithCallerStack, execute: () => Promise<unknown>): Promise<void>;
|
|
23
32
|
export declare function runOperationWithoutResultForEngine<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>, workflowId: string, operation: OperationWithCallerStack, execute: () => Promise<void>): Promise<void>;
|
|
24
33
|
export declare function executeSubOperationForEngine<TWorkflows extends object, TActivities extends object>(engine: Engine<TWorkflows, TActivities>, workflowId: string, operation: ContextOperationRequest, signal?: AbortSignal, speculativeState?: import('./speculative-execution-state.ts').SpeculativeExecutionState): Promise<unknown>;
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
createReviewOperationCallbacks,
|
|
16
16
|
handleScheduleTimerForEngine
|
|
17
17
|
} from "./callback-creators-schedule.js";
|
|
18
|
+
import { commitFencedEngineWrite } from "./fenced-write.js";
|
|
18
19
|
import { guardTerminalWorkflow, guardTerminalWorkflowAfterCoordinatedRequest } from "./guards.js";
|
|
19
20
|
import { getInternals } from "./internals.js";
|
|
20
21
|
import {
|
|
@@ -27,6 +28,7 @@ import {
|
|
|
27
28
|
} from "./lifecycle.js";
|
|
28
29
|
import {
|
|
29
30
|
completeOperation,
|
|
31
|
+
failOperation,
|
|
30
32
|
runOperationWithResult,
|
|
31
33
|
runOperationWithoutResult
|
|
32
34
|
} from "./operations-router.js";
|
|
@@ -34,6 +36,7 @@ import { schedulePendingInlineUpdateDrain } from "./pending-updates.js";
|
|
|
34
36
|
import { processReviewOperation } from "./reviews.js";
|
|
35
37
|
import { loadWorkflowState, runSerializedWorkflowStateWrite } from "./storage-io.js";
|
|
36
38
|
import {
|
|
39
|
+
feedOperationResult,
|
|
37
40
|
getComposedActivityInterceptor,
|
|
38
41
|
getComposedWorkflowInterceptor
|
|
39
42
|
} from "./strategy-helpers.js";
|
|
@@ -41,7 +44,9 @@ import { executeSubOperation } from "./sub-operation.js";
|
|
|
41
44
|
import {
|
|
42
45
|
ensureTerminalCleanupTracked,
|
|
43
46
|
failWorkflow,
|
|
44
|
-
|
|
47
|
+
finalizePendingTimelineEntry,
|
|
48
|
+
runDeferredTerminalCleanup,
|
|
49
|
+
runWorkflowFinalizer
|
|
45
50
|
} from "./termination.js";
|
|
46
51
|
import {
|
|
47
52
|
createCoordinatedUpdateResponder,
|
|
@@ -60,6 +65,8 @@ export function createChildWorkflowOperationCallbacks(engine) {
|
|
|
60
65
|
export function createActivityOperationCallbacks(engine) {
|
|
61
66
|
return {
|
|
62
67
|
runOperationWithResult: (workflowId, operation, execute) => runOperationWithResultForEngine(engine, workflowId, operation, execute),
|
|
68
|
+
finalizePendingTimelineEntry: (workflowId, status, value) => finalizePendingTimelineEntry(getInternals(engine), workflowId, status, value),
|
|
69
|
+
feedOperationResult: (workflowId, result, error) => feedOperationResult(getInternals(engine), workflowId, result, error),
|
|
63
70
|
getComposedActivityInterceptor: () => getComposedActivityInterceptor(getInternals(engine)),
|
|
64
71
|
getComposedWorkflowInterceptor: () => getComposedWorkflowInterceptor(getInternals(engine))
|
|
65
72
|
};
|
|
@@ -72,6 +79,22 @@ export function createCoordinationOperationCallbacks(engine) {
|
|
|
72
79
|
getActivityOperationCallbacks: () => createActivityOperationCallbacks(engine)
|
|
73
80
|
};
|
|
74
81
|
}
|
|
82
|
+
export function createConditionOperationCallbacks(engine) {
|
|
83
|
+
return {
|
|
84
|
+
completeOperation: (workflowId, value) => completeOperationForEngine(engine, workflowId, value),
|
|
85
|
+
failOperation: (workflowId, operation, error) => failOperationForEngine(engine, workflowId, operation, error),
|
|
86
|
+
isWorkflowRunning: async (workflowId) => {
|
|
87
|
+
return (await loadWorkflowState(getInternals(engine), workflowId))?.status === "running";
|
|
88
|
+
},
|
|
89
|
+
scheduleConditionDeadline: (workflowId, step, fireAt) => getInternals(engine).scheduler.schedule({
|
|
90
|
+
id: `cond:${workflowId}:${step}`,
|
|
91
|
+
workflowId,
|
|
92
|
+
fireAt,
|
|
93
|
+
kind: "wait-condition"
|
|
94
|
+
}),
|
|
95
|
+
cancelConditionDeadline: (workflowId, step) => getInternals(engine).scheduler.cancel(`cond:${workflowId}:${step}`, workflowId)
|
|
96
|
+
};
|
|
97
|
+
}
|
|
75
98
|
export function createDataOperationCallbacks(engine) {
|
|
76
99
|
return {
|
|
77
100
|
runOperationWithResult: (workflowId, operation, execute) => runOperationWithResultForEngine(engine, workflowId, operation, execute)
|
|
@@ -92,6 +115,7 @@ export function createStreamOperationCallbacks(engine) {
|
|
|
92
115
|
export function createTimeOperationCallbacks(engine) {
|
|
93
116
|
return {
|
|
94
117
|
completeOperation: (workflowId, value) => completeOperationForEngine(engine, workflowId, value),
|
|
118
|
+
dispatchEvent: (event) => engine.dispatchEvent(event),
|
|
95
119
|
loadWorkflowState: (workflowId) => loadWorkflowState(getInternals(engine), workflowId),
|
|
96
120
|
failWorkflow: (workflowId, error) => failWorkflow(getInternals(engine), workflowId, error, createTerminationCallbacks(engine)),
|
|
97
121
|
runSerializedWorkflowStateWrite: (workflowId, writeOperation) => runSerializedWorkflowStateWrite(getInternals(engine), workflowId, writeOperation),
|
|
@@ -101,6 +125,7 @@ export function createTimeOperationCallbacks(engine) {
|
|
|
101
125
|
loadWorkflowStartHeaders: (workflowId) => loadWorkflowStartHeaders(getInternals(engine), workflowId, createLifecycleCallbacks(engine)),
|
|
102
126
|
parseStartOptionDuration: (value, fieldName) => parseStartOptionDuration(getInternals(engine), value, fieldName, createLifecycleCallbacks(engine)),
|
|
103
127
|
runDeferredTerminalCleanup: (workflowId, timerId) => runDeferredTerminalCleanup(getInternals(engine), workflowId, timerId, createTerminationCallbacks(engine)),
|
|
128
|
+
runWorkflowFinalizer: (workflowId, timerId) => runWorkflowFinalizer(getInternals(engine), workflowId, timerId, createTerminationCallbacks(engine)),
|
|
104
129
|
handleScheduleTimer: (entry) => handleScheduleTimerForEngine(engine, entry),
|
|
105
130
|
timeout: (workflowId) => engine.timeout(workflowId),
|
|
106
131
|
handleCleanupError: (source, error, workflowId) => createTerminationCallbacks(engine).handleCleanupError(source, error, workflowId)
|
|
@@ -126,7 +151,7 @@ export function createUpdateCallbacks(engine) {
|
|
|
126
151
|
async function persistCoordinatedUpdateResponse(engine, workflowId, updateName, updateId, idempotencyKey, value) {
|
|
127
152
|
const internals = getInternals(engine), responseOperations = internals.updateCoordinator.buildResponseOperations(updateId, workflowId, value, void 0, idempotencyKey);
|
|
128
153
|
try {
|
|
129
|
-
await internals
|
|
154
|
+
await commitFencedEngineWrite(internals, responseOperations, [], () => Error(`Coordinated update response for workflow "${workflowId}" lost its CAS race.`));
|
|
130
155
|
engine.dispatchEvent(new UpdateCompletedEvent(updateId, workflowId, updateName, value));
|
|
131
156
|
broadcastFromInternals(internals, { type: "update:completed", workflowId, updateId }, createBroadcastCallbacks(engine));
|
|
132
157
|
} catch (error) {
|
|
@@ -136,6 +161,9 @@ async function persistCoordinatedUpdateResponse(engine, workflowId, updateName,
|
|
|
136
161
|
export function completeOperationForEngine(engine, workflowId, value) {
|
|
137
162
|
return completeOperation(getInternals(engine), workflowId, value, callRouterCallbacks(engine));
|
|
138
163
|
}
|
|
164
|
+
export function failOperationForEngine(engine, workflowId, operation, error) {
|
|
165
|
+
return failOperation(getInternals(engine), workflowId, operation, error, callRouterCallbacks(engine));
|
|
166
|
+
}
|
|
139
167
|
export async function runOperationWithResultForEngine(engine, workflowId, operation, execute) {
|
|
140
168
|
return runOperationWithResult(getInternals(engine), workflowId, operation, execute, callRouterCallbacks(engine));
|
|
141
169
|
}
|