@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,24 +1,19 @@
|
|
|
1
1
|
import { encode } from "../../core/codec.js";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
SignalDeliveredEvent,
|
|
8
|
-
SignalReceivedEvent,
|
|
9
|
-
UpdateCompletedEvent,
|
|
10
|
-
UpdateReceivedEvent,
|
|
3
|
+
encodeStoredStreamTailSequence,
|
|
4
|
+
loadStoredStreamTailSequence
|
|
5
|
+
} from "../../core/engine/stream-chunk-loading.js";
|
|
6
|
+
import {
|
|
11
7
|
WorkflowCancelledEvent,
|
|
12
8
|
WorkflowCompletedEvent,
|
|
13
9
|
WorkflowFailedEvent,
|
|
14
|
-
WorkflowStartedEvent,
|
|
15
10
|
WorkflowTimedOutEvent
|
|
16
11
|
} from "../../core/events.js";
|
|
17
12
|
import { KEYS } from "../../storage/interface.js";
|
|
18
13
|
import { claimNextSequence } from "../runtime-helpers.js";
|
|
14
|
+
import { CLIENT_VISIBLE_EVENT_TYPES, TOKEN_EVENT_TYPE } from "./client-visible-events.js";
|
|
19
15
|
import { cancelTask } from "./task-dispatch.js";
|
|
20
16
|
import { withRetry } from "./websocket-worker.js";
|
|
21
|
-
const TOKEN_EVENT_TYPE = "stream:token";
|
|
22
17
|
function workflowChannelPath(workflowId, connectionType) {
|
|
23
18
|
return `/v1/workflows/${encodeURIComponent(workflowId)}/${connectionType}`;
|
|
24
19
|
}
|
|
@@ -106,6 +101,11 @@ export function wireEventBroadcasting(engine, server, options) {
|
|
|
106
101
|
if (existing)
|
|
107
102
|
return existing;
|
|
108
103
|
const promise = (async () => {
|
|
104
|
+
const storedTailSequence = await loadStoredStreamTailSequence(engine.storage, workflowId, "tokens");
|
|
105
|
+
if (storedTailSequence !== null) {
|
|
106
|
+
tokenSequenceCounters.set(workflowId, storedTailSequence + 1);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
109
|
const prefix = KEYS.streamChunkPrefix(workflowId, "tokens");
|
|
110
110
|
let highestSequence = -1;
|
|
111
111
|
for await (const [key] of engine.storage.scan(prefix, { reverse: !0, limit: 1 })) {
|
|
@@ -122,11 +122,7 @@ export function wireEventBroadcasting(engine, server, options) {
|
|
|
122
122
|
return promise;
|
|
123
123
|
}
|
|
124
124
|
async function persistAndPublishEvent(workflowId, eventType, message) {
|
|
125
|
-
|
|
126
|
-
const parsed = JSON.parse(message), sequence = claimNextSequence(sequenceCounters, workflowId), storageKey = KEYS.event(workflowId, sequence), encoded = encode(parsed);
|
|
127
|
-
await withRetry(async () => engine.storage.put(storageKey, encoded), `persist event "${eventType}" for workflow "${workflowId}"`);
|
|
128
|
-
const watchChannel = workflowChannelPath(workflowId, "watch");
|
|
129
|
-
server.publish(watchChannel, message);
|
|
125
|
+
const parsed = JSON.parse(message);
|
|
130
126
|
if (eventType === TOKEN_EVENT_TYPE) {
|
|
131
127
|
const tokenPayload = {
|
|
132
128
|
workflowId: typeof parsed.data.workflowId === "string" ? parsed.data.workflowId : workflowId,
|
|
@@ -135,10 +131,23 @@ export function wireEventBroadcasting(engine, server, options) {
|
|
|
135
131
|
};
|
|
136
132
|
await ensureTokenSequenceInitialized(workflowId);
|
|
137
133
|
const tokenSequence = claimNextSequence(tokenSequenceCounters, workflowId);
|
|
138
|
-
await withRetry(async () => engine.storage.
|
|
134
|
+
await withRetry(async () => engine.storage.batch([
|
|
135
|
+
{
|
|
136
|
+
type: "put",
|
|
137
|
+
key: KEYS.streamChunk(workflowId, "tokens", tokenSequence),
|
|
138
|
+
value: encode(tokenPayload)
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
type: "put",
|
|
142
|
+
key: KEYS.streamTail(workflowId, "tokens"),
|
|
143
|
+
value: encodeStoredStreamTailSequence(tokenSequence)
|
|
144
|
+
}
|
|
145
|
+
]), `persist token stream chunk for workflow "${workflowId}"`);
|
|
139
146
|
const streamMessage = JSON.stringify({
|
|
140
|
-
|
|
147
|
+
type: parsed.type,
|
|
148
|
+
timestamp: parsed.timestamp,
|
|
141
149
|
sequence: tokenSequence,
|
|
150
|
+
cursor: String(tokenSequence),
|
|
142
151
|
data: tokenPayload
|
|
143
152
|
});
|
|
144
153
|
if (options?.publishTokenMessage)
|
|
@@ -147,32 +156,34 @@ export function wireEventBroadcasting(engine, server, options) {
|
|
|
147
156
|
const streamChannel = workflowChannelPath(workflowId, "stream");
|
|
148
157
|
server.publish(streamChannel, streamMessage);
|
|
149
158
|
}
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
await ensureSequenceInitialized(workflowId);
|
|
162
|
+
const sequence = claimNextSequence(sequenceCounters, workflowId), watchMessage = JSON.stringify({
|
|
163
|
+
type: parsed.type,
|
|
164
|
+
timestamp: parsed.timestamp,
|
|
165
|
+
data: parsed.data,
|
|
166
|
+
sequence,
|
|
167
|
+
cursor: String(sequence)
|
|
168
|
+
}), storageKey = KEYS.event(workflowId, sequence), encoded = encode(JSON.parse(watchMessage));
|
|
169
|
+
await withRetry(async () => engine.storage.put(storageKey, encoded), `persist event "${eventType}" for workflow "${workflowId}"`);
|
|
170
|
+
await appendFleetEvent(options?.fleetEventFeed, eventType, workflowId, message);
|
|
171
|
+
if (options?.publishWatchMessage)
|
|
172
|
+
options.publishWatchMessage(workflowId, sequence, watchMessage);
|
|
173
|
+
else {
|
|
174
|
+
const watchChannel = workflowChannelPath(workflowId, "watch");
|
|
175
|
+
server.publish(watchChannel, watchMessage);
|
|
150
176
|
}
|
|
151
177
|
}
|
|
152
|
-
const
|
|
153
|
-
WorkflowStartedEvent.type,
|
|
154
|
-
WorkflowCompletedEvent.type,
|
|
155
|
-
WorkflowFailedEvent.type,
|
|
156
|
-
WorkflowCancelledEvent.type,
|
|
157
|
-
WorkflowTimedOutEvent.type,
|
|
158
|
-
ActivityStartedEvent.type,
|
|
159
|
-
ActivityCompletedEvent.type,
|
|
160
|
-
ActivityFailedEvent.type,
|
|
161
|
-
TOKEN_EVENT_TYPE,
|
|
162
|
-
SignalReceivedEvent.type,
|
|
163
|
-
SignalDeliveredEvent.type,
|
|
164
|
-
AttributesChangedEvent.type,
|
|
165
|
-
UpdateReceivedEvent.type,
|
|
166
|
-
UpdateCompletedEvent.type
|
|
167
|
-
];
|
|
168
|
-
for (const eventType of eventTypes)
|
|
178
|
+
for (const eventType of CLIENT_VISIBLE_EVENT_TYPES)
|
|
169
179
|
engine.addEventListener(eventType, (event) => {
|
|
170
|
-
const workflowId = getWorkflowIdFromEvent(event);
|
|
171
|
-
if (workflowId === void 0)
|
|
172
|
-
return;
|
|
173
|
-
const message = serializeEvent(event);
|
|
180
|
+
const workflowId = getWorkflowIdFromEvent(event), message = serializeEvent(event);
|
|
174
181
|
if (message === null)
|
|
175
182
|
return;
|
|
183
|
+
if (workflowId === void 0) {
|
|
184
|
+
appendFleetEvent(options?.fleetEventFeed, eventType, void 0, message);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
176
187
|
const nextChain = (sequenceChains.get(workflowId) ?? Promise.resolve()).then(() => persistAndPublishEvent(workflowId, eventType, message)).catch((error) => {
|
|
177
188
|
console.error(`[weft] Failed to persist event "${eventType}" for workflow "${workflowId}":`, error);
|
|
178
189
|
});
|
|
@@ -203,3 +214,26 @@ export function wireEventBroadcasting(engine, server, options) {
|
|
|
203
214
|
cleanupWorkflow
|
|
204
215
|
};
|
|
205
216
|
}
|
|
217
|
+
async function appendFleetEvent(fleetEventFeed, eventType, workflowId, message) {
|
|
218
|
+
if (eventType === TOKEN_EVENT_TYPE)
|
|
219
|
+
return;
|
|
220
|
+
if (fleetEventFeed === void 0)
|
|
221
|
+
return;
|
|
222
|
+
try {
|
|
223
|
+
const parsed = JSON.parse(message), event = {
|
|
224
|
+
kind: eventType,
|
|
225
|
+
emittedAtMs: parsed.timestamp,
|
|
226
|
+
payload: parsed.data
|
|
227
|
+
};
|
|
228
|
+
if (workflowId === void 0) {
|
|
229
|
+
await fleetEventFeed.append(event);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
await fleetEventFeed.appendWorkflowEventIfPresent({
|
|
233
|
+
...event,
|
|
234
|
+
workflowId
|
|
235
|
+
});
|
|
236
|
+
} catch (error) {
|
|
237
|
+
console.error(`[weft] Failed to append fleet event "${eventType}":`, error);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function withRetry<T>(operation: () => Promise<T>, label: string, maxAttempts?: number): Promise<T>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export async function withRetry(operation, label, maxAttempts = 2) {
|
|
2
|
+
let lastError;
|
|
3
|
+
for (let attempt = 1;attempt <= maxAttempts; attempt++)
|
|
4
|
+
try {
|
|
5
|
+
return await operation();
|
|
6
|
+
} catch (error) {
|
|
7
|
+
lastError = error;
|
|
8
|
+
if (attempt < maxAttempts) {
|
|
9
|
+
console.warn(`[weft] Retrying "${label}" (attempt ${attempt + 1}/${maxAttempts})`);
|
|
10
|
+
await Bun.sleep(100 * attempt);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
throw lastError;
|
|
14
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { ServerContext } from './context.ts';
|
|
2
2
|
export declare const DEFAULT_SHUTDOWN_TIMEOUT_MS = 30000;
|
|
3
|
+
type WorkerShutdownOptions = {
|
|
4
|
+
timeoutMs?: number | undefined;
|
|
5
|
+
stopWaitingWhenIdle?: boolean | undefined;
|
|
6
|
+
};
|
|
3
7
|
/** Send a shutdown message to a specific worker and wait for it to disconnect. */
|
|
4
|
-
export declare function shutdownWorker(context: ServerContext, workerId: string, shutdownOptions?:
|
|
5
|
-
timeoutMs?: number;
|
|
6
|
-
}): Promise<boolean>;
|
|
8
|
+
export declare function shutdownWorker(context: ServerContext, workerId: string, shutdownOptions?: WorkerShutdownOptions): Promise<boolean>;
|
|
7
9
|
/** Send a shutdown message to all connected workers and wait for them to disconnect. */
|
|
8
|
-
export declare function shutdownAllWorkers(context: ServerContext, shutdownOptions?:
|
|
9
|
-
|
|
10
|
-
}): Promise<void>;
|
|
10
|
+
export declare function shutdownAllWorkers(context: ServerContext, shutdownOptions?: WorkerShutdownOptions): Promise<void>;
|
|
11
|
+
export {};
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
export const DEFAULT_SHUTDOWN_TIMEOUT_MS = 30000;
|
|
2
|
+
function workerShutdownFinished(context, workerId, options) {
|
|
3
|
+
if (!context.workerSockets.has(workerId))
|
|
4
|
+
return !0;
|
|
5
|
+
return options?.stopWaitingWhenIdle === !0 && context.registry.getWorkerTasks(workerId).length === 0;
|
|
6
|
+
}
|
|
2
7
|
export async function shutdownWorker(context, workerId, shutdownOptions) {
|
|
3
8
|
const ws = context.workerSockets.get(workerId);
|
|
4
9
|
if (!ws)
|
|
5
10
|
return !1;
|
|
6
11
|
ws.send(JSON.stringify({ type: "shutdown" }));
|
|
7
12
|
const timeout = shutdownOptions?.timeoutMs ?? DEFAULT_SHUTDOWN_TIMEOUT_MS, deadline = Date.now() + timeout;
|
|
8
|
-
while (context
|
|
13
|
+
while (!workerShutdownFinished(context, workerId, shutdownOptions)) {
|
|
9
14
|
if (Date.now() >= deadline)
|
|
10
15
|
return !0;
|
|
11
16
|
await Bun.sleep(50);
|
|
@@ -59,8 +59,8 @@ async function selectAndReserveWorker(context, options, task, queue, visibilityT
|
|
|
59
59
|
const ws = context.workerSockets.get(worker.id);
|
|
60
60
|
if (!ws)
|
|
61
61
|
return !1;
|
|
62
|
-
const now = Date.now(), existingQueuedRecord = await readQueuedRecord(options.engine.storage, task.operationId);
|
|
63
|
-
context.registry.assignTask(worker.id, task.operationId, visibilityTimeout, task.fairShareKey);
|
|
62
|
+
const now = Date.now(), existingQueuedRecord = await readQueuedRecord(options.engine.storage, task.operationId), attemptToken = crypto.randomUUID();
|
|
63
|
+
context.registry.assignTask(worker.id, task.operationId, visibilityTimeout, task.fairShareKey, attemptToken);
|
|
64
64
|
const deadline = now + visibilityTimeout;
|
|
65
65
|
context.deadlineTracker.add({ operationId: task.operationId, deadline });
|
|
66
66
|
const inflightRecord = {
|
|
@@ -73,7 +73,8 @@ async function selectAndReserveWorker(context, options, task, queue, visibilityT
|
|
|
73
73
|
attempt: task.attempt ?? 1,
|
|
74
74
|
visibilityTimeout,
|
|
75
75
|
retryPolicy: task.retryPolicy,
|
|
76
|
-
workflowId: task.workflowId
|
|
76
|
+
workflowId: task.workflowId,
|
|
77
|
+
attemptToken
|
|
77
78
|
}, normalizedInflightRecord = await transitionQueuedToInflight(options.engine.storage, task.operationId, inflightRecord, {
|
|
78
79
|
queuedRecord: existingQueuedRecord,
|
|
79
80
|
now
|
|
@@ -84,6 +85,7 @@ async function selectAndReserveWorker(context, options, task, queue, visibilityT
|
|
|
84
85
|
activityName: task.activityName,
|
|
85
86
|
input: task.input === void 0 ? null : task.input,
|
|
86
87
|
attempt: task.attempt ?? 1,
|
|
88
|
+
attemptToken,
|
|
87
89
|
...task.headers ? { headers: task.headers } : {}
|
|
88
90
|
}));
|
|
89
91
|
recordTaskQueueLatencyMetric(context.metricsCollector, normalizedInflightRecord);
|
|
@@ -3,7 +3,21 @@ import { type Principal } from '../principal.ts';
|
|
|
3
3
|
import type { PendingTask } from '../task-queue-types.ts';
|
|
4
4
|
import type { InflightRecord } from '../task-state.ts';
|
|
5
5
|
import type { ServerContext } from './context.ts';
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* A freshly created long-poll inflight record always carries an `attemptToken`.
|
|
8
|
+
* The intersection makes that invariant a compile-time fact so the claim can read
|
|
9
|
+
* the token directly without an unreachable empty-string fallback.
|
|
10
|
+
*/
|
|
11
|
+
type TokenedInflightRecord = InflightRecord & {
|
|
12
|
+
attemptToken: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function createLongPollInflightRecord(queue: string, task: PendingTask): TokenedInflightRecord;
|
|
15
|
+
/** The worker-facing identity of a long-poll claim: the synthetic worker id and its per-claim token. */
|
|
16
|
+
export interface LongPollClaim {
|
|
17
|
+
workerId: string;
|
|
18
|
+
attemptToken: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function markTaskClaimedByLongPollWorker(context: ServerContext, options: ServeOptions, queue: string, task: PendingTask): Promise<LongPollClaim>;
|
|
8
21
|
export declare function handleTaskPollRequest(context: ServerContext, options: ServeOptions, request: Request, url: URL, principal?: Principal): Promise<Response | null>;
|
|
9
22
|
export declare function handleTaskResultRequest(context: ServerContext, options: ServeOptions, request: Request, url: URL, principal?: Principal): Promise<Response | null>;
|
|
23
|
+
export {};
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import { isAuthenticated } from "../principal.js";
|
|
2
|
+
import { readRestJsonBody } from "../rest-body.js";
|
|
3
|
+
import { readInflightRecord, transitionQueuedToInflight } from "../task-state.js";
|
|
4
|
+
import { recordTaskBacklogMetric, recordTaskQueueLatencyMetric } from "./task-metrics.js";
|
|
2
5
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} from "../task-state.js";
|
|
7
|
-
import {
|
|
8
|
-
recordTaskBacklogMetric,
|
|
9
|
-
recordTaskExecutionLatencyMetric,
|
|
10
|
-
recordTaskQueueLatencyMetric
|
|
11
|
-
} from "./task-metrics.js";
|
|
6
|
+
taskResultPayloadSizeError,
|
|
7
|
+
transitionTaskResultToResolvedWithRetry
|
|
8
|
+
} from "./task-result-resolution.js";
|
|
12
9
|
const TASK_POLL_RE = /^\/v1\/tasks\/([\w-]+)$/, TASK_RESULT_RE = /^\/v1\/tasks\/([\w-]+)\/result$/, TASK_DIAGNOSTICS_PATH = "/v1/tasks/diagnostics", MAX_POLL_TIMEOUT = 60000, DEFAULT_POLL_TIMEOUT = 30000, DEFAULT_VISIBILITY_TIMEOUT = 30000;
|
|
13
|
-
async function parseTaskResultBody(request) {
|
|
10
|
+
async function parseTaskResultBody(request, options) {
|
|
14
11
|
try {
|
|
15
|
-
return await request
|
|
16
|
-
} catch {
|
|
12
|
+
return await readRestJsonBody(request, options);
|
|
13
|
+
} catch (error) {
|
|
14
|
+
if (isPayloadTooLargeFault(error))
|
|
15
|
+
return Response.json({ error: error.message }, { status: 413 });
|
|
17
16
|
return null;
|
|
18
17
|
}
|
|
19
18
|
}
|
|
19
|
+
function isPayloadTooLargeFault(value) {
|
|
20
|
+
return typeof value === "object" && value !== null && value.code === "PayloadTooLarge" && typeof value.message === "string";
|
|
21
|
+
}
|
|
20
22
|
function authorizeWorkerPrincipal(principal) {
|
|
21
23
|
if (principal === void 0)
|
|
22
24
|
return null;
|
|
@@ -30,12 +32,16 @@ function validateTaskResultBody(body) {
|
|
|
30
32
|
return Response.json({ error: "Missing required fields: operationId, status" }, { status: 400 });
|
|
31
33
|
if (status !== "completed" && status !== "failed")
|
|
32
34
|
return Response.json({ error: 'status must be "completed" or "failed"' }, { status: 400 });
|
|
35
|
+
const rawAttemptToken = body.attemptToken;
|
|
36
|
+
if (rawAttemptToken !== void 0 && (typeof rawAttemptToken !== "string" || rawAttemptToken === ""))
|
|
37
|
+
return Response.json({ error: "attemptToken must be a non-empty string when present" }, { status: 400 });
|
|
33
38
|
return {
|
|
34
39
|
operationId,
|
|
35
40
|
status,
|
|
36
41
|
workerId: typeof body.workerId === "string" ? body.workerId : void 0,
|
|
37
42
|
value: body.value,
|
|
38
|
-
error: typeof body.error === "string" ? body.error : void 0
|
|
43
|
+
error: typeof body.error === "string" ? body.error : void 0,
|
|
44
|
+
attemptToken: rawAttemptToken
|
|
39
45
|
};
|
|
40
46
|
}
|
|
41
47
|
async function applyTaskResult(context, options, result, inflightRecord) {
|
|
@@ -43,19 +49,42 @@ async function applyTaskResult(context, options, result, inflightRecord) {
|
|
|
43
49
|
try {
|
|
44
50
|
context.taskQueue.complete({ operationId, status, value, error });
|
|
45
51
|
context.deadlineTracker.remove(operationId);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
resolvedAt,
|
|
52
|
+
await transitionTaskResultToResolvedWithRetry(context, options, {
|
|
53
|
+
operationId,
|
|
54
|
+
status: resolvedStatus,
|
|
50
55
|
resolutionReason: resolvedStatus,
|
|
56
|
+
inflightRecord,
|
|
51
57
|
...status === "completed" ? { value } : { error }
|
|
52
58
|
});
|
|
53
|
-
if (inflightRecord !== null)
|
|
54
|
-
recordTaskExecutionLatencyMetric(context.metricsCollector, inflightRecord, resolvedAt);
|
|
55
59
|
} catch (storageError) {
|
|
56
60
|
console.error(`[weft] Failed to transition task "${operationId}" to resolved \u2014 inflight record may leak:`, storageError);
|
|
57
61
|
}
|
|
58
62
|
}
|
|
63
|
+
async function applyPayloadRejectedTaskResult(context, options, result, inflightRecord, error) {
|
|
64
|
+
context.taskQueue.complete({
|
|
65
|
+
operationId: result.operationId,
|
|
66
|
+
status: "failed",
|
|
67
|
+
error: error.message
|
|
68
|
+
});
|
|
69
|
+
context.deadlineTracker.remove(result.operationId);
|
|
70
|
+
await transitionTaskResultToResolvedWithRetry(context, options, {
|
|
71
|
+
operationId: result.operationId,
|
|
72
|
+
status: "failed",
|
|
73
|
+
resolutionReason: "failed",
|
|
74
|
+
inflightRecord,
|
|
75
|
+
error: error.message,
|
|
76
|
+
skipPayloadSizeCheck: !0
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
function payloadSizeExceededResponse(error) {
|
|
80
|
+
return Response.json({
|
|
81
|
+
error: error.message,
|
|
82
|
+
code: error.code,
|
|
83
|
+
maxBytes: error.maxBytes,
|
|
84
|
+
serializedBytes: error.serializedBytes,
|
|
85
|
+
payloadKind: error.payloadKind
|
|
86
|
+
}, { status: 413 });
|
|
87
|
+
}
|
|
59
88
|
export function createLongPollInflightRecord(queue, task) {
|
|
60
89
|
const now = Date.now(), visibilityTimeout = task.visibilityTimeout ?? DEFAULT_VISIBILITY_TIMEOUT, deadline = now + visibilityTimeout;
|
|
61
90
|
return {
|
|
@@ -69,6 +98,7 @@ export function createLongPollInflightRecord(queue, task) {
|
|
|
69
98
|
visibilityTimeout,
|
|
70
99
|
retryPolicy: task.retryPolicy,
|
|
71
100
|
workflowId: task.workflowId,
|
|
101
|
+
attemptToken: crypto.randomUUID(),
|
|
72
102
|
firstQueuedAt: task.firstQueuedAt ?? task.enqueuedAt ?? now,
|
|
73
103
|
lastQueuedAt: task.lastQueuedAt ?? task.enqueuedAt ?? now,
|
|
74
104
|
lastDispatchedAt: now,
|
|
@@ -87,7 +117,10 @@ export async function markTaskClaimedByLongPollWorker(context, options, queue, t
|
|
|
87
117
|
const normalizedInflightRecord = await transitionQueuedToInflight(options.engine.storage, task.operationId, inflightRecord);
|
|
88
118
|
recordTaskQueueLatencyMetric(context.metricsCollector, normalizedInflightRecord);
|
|
89
119
|
recordTaskBacklogMetric(context.metricsCollector, context.taskQueue);
|
|
90
|
-
return
|
|
120
|
+
return {
|
|
121
|
+
workerId: normalizedInflightRecord.workerId,
|
|
122
|
+
attemptToken: inflightRecord.attemptToken
|
|
123
|
+
};
|
|
91
124
|
}
|
|
92
125
|
export async function handleTaskPollRequest(context, options, request, url, principal) {
|
|
93
126
|
if (request.method !== "GET")
|
|
@@ -105,8 +138,8 @@ export async function handleTaskPollRequest(context, options, request, url, prin
|
|
|
105
138
|
return Response.json({ error: 'At least one "activity" query parameter is required' }, { status: 400 });
|
|
106
139
|
const rawTimeout = url.searchParams.get("timeout"), timeout = rawTimeout !== null ? Math.min(Math.max(0, Number(rawTimeout)), MAX_POLL_TIMEOUT) : DEFAULT_POLL_TIMEOUT, task = await context.taskQueue.poll(queue, activities, timeout, request.signal);
|
|
107
140
|
if (task !== null) {
|
|
108
|
-
const
|
|
109
|
-
return Response.json({ ...task, workerId });
|
|
141
|
+
const claim = await markTaskClaimedByLongPollWorker(context, options, queue, task);
|
|
142
|
+
return Response.json({ ...task, workerId: claim.workerId, attemptToken: claim.attemptToken });
|
|
110
143
|
}
|
|
111
144
|
return new Response(null, { status: 204 });
|
|
112
145
|
}
|
|
@@ -118,15 +151,38 @@ export async function handleTaskResultRequest(context, options, request, url, pr
|
|
|
118
151
|
const authorizationResponse = authorizeWorkerPrincipal(principal);
|
|
119
152
|
if (authorizationResponse !== null)
|
|
120
153
|
return authorizationResponse;
|
|
121
|
-
const body = await parseTaskResultBody(request);
|
|
154
|
+
const body = await parseTaskResultBody(request, options.maxRequestBodyBytes !== void 0 ? { maxBodyBytes: options.maxRequestBodyBytes } : {});
|
|
155
|
+
if (body instanceof Response)
|
|
156
|
+
return body;
|
|
122
157
|
if (body === null)
|
|
123
158
|
return Response.json({ error: "Invalid JSON body" }, { status: 400 });
|
|
124
159
|
const validated = validateTaskResultBody(body);
|
|
125
160
|
if (validated instanceof Response)
|
|
126
161
|
return validated;
|
|
127
162
|
const inflightRecord = await readInflightRecord(options.engine.storage, validated.operationId);
|
|
128
|
-
if (inflightRecord !== null && (
|
|
163
|
+
if (inflightRecord !== null && !isLongPollCompletionAuthorized(inflightRecord, validated))
|
|
129
164
|
return Response.json({ error: "Forbidden" }, { status: 403 });
|
|
165
|
+
const payloadError = taskResultPayloadSizeError({
|
|
166
|
+
operationId: validated.operationId,
|
|
167
|
+
status: validated.status,
|
|
168
|
+
resolutionReason: validated.status,
|
|
169
|
+
...validated.status === "completed" ? { value: validated.value } : { error: validated.error }
|
|
170
|
+
}, context.payloadSizeMaxBytes);
|
|
171
|
+
if (payloadError !== null) {
|
|
172
|
+
try {
|
|
173
|
+
await applyPayloadRejectedTaskResult(context, options, validated, inflightRecord, payloadError);
|
|
174
|
+
} catch (error) {
|
|
175
|
+
console.error(`[weft] Failed to persist oversized task result rejection for task "${validated.operationId}":`, error);
|
|
176
|
+
}
|
|
177
|
+
return payloadSizeExceededResponse(payloadError);
|
|
178
|
+
}
|
|
130
179
|
await applyTaskResult(context, options, validated, inflightRecord);
|
|
131
180
|
return Response.json({ ok: !0 });
|
|
132
181
|
}
|
|
182
|
+
function isLongPollCompletionAuthorized(inflightRecord, validated) {
|
|
183
|
+
if (validated.workerId === void 0 || inflightRecord.workerId !== validated.workerId)
|
|
184
|
+
return !1;
|
|
185
|
+
if (inflightRecord.attemptToken !== void 0 && validated.attemptToken !== inflightRecord.attemptToken)
|
|
186
|
+
return !1;
|
|
187
|
+
return !0;
|
|
188
|
+
}
|
|
@@ -3,7 +3,11 @@ import { ActivityFailedEvent } from "../../core/events.js";
|
|
|
3
3
|
import { calculateBackoff } from "../../core/scheduler.js";
|
|
4
4
|
import { KEYS } from "../../storage/interface.js";
|
|
5
5
|
import { restoreExtendedDeadlineIfStillActive } from "../runtime-helpers.js";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
isTaskDeadLettered,
|
|
8
|
+
transitionInflightToQueued,
|
|
9
|
+
transitionInflightToResolved
|
|
10
|
+
} from "../task-state.js";
|
|
7
11
|
import { dispatchTaskImpl, scheduleDelayedDispatch } from "./task-dispatch.js";
|
|
8
12
|
import {
|
|
9
13
|
isTaskHeartbeatStaleForMetrics,
|
|
@@ -98,6 +102,8 @@ export async function scanExpiredTasks(context, options, cleanupWorkflowIndex) {
|
|
|
98
102
|
console.error(`[weft] Corrupt inflight record for task "${operationId}" \u2014 skipping`);
|
|
99
103
|
continue;
|
|
100
104
|
}
|
|
105
|
+
if (await isTaskDeadLettered(options.engine.storage, operationId))
|
|
106
|
+
continue;
|
|
101
107
|
if (restoreExtendedDeadlineIfStillActive(context.deadlineTracker, operationId, decoded.deadline, now))
|
|
102
108
|
continue;
|
|
103
109
|
context.registry.completeTask(decoded.operationId);
|
|
@@ -130,6 +136,8 @@ export async function reconcileOrphanedRecords(context, options, cleanupWorkflow
|
|
|
130
136
|
continue;
|
|
131
137
|
if (isTaskHeartbeatStaleForMetrics(decoded, now))
|
|
132
138
|
staleHeartbeatCount += 1;
|
|
139
|
+
if (await isTaskDeadLettered(options.engine.storage, decoded.operationId))
|
|
140
|
+
continue;
|
|
133
141
|
if (decoded.deadline > now) {
|
|
134
142
|
if (context.processingOperations.has(decoded.operationId))
|
|
135
143
|
continue;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { PayloadSizeExceededError } from '../../core/payload-size.ts';
|
|
2
|
+
import type { ServeOptions } from '../index.ts';
|
|
3
|
+
import { type InflightRecord, type TaskResolutionReason } from '../task-state.ts';
|
|
4
|
+
import type { ServerContext } from './context.ts';
|
|
5
|
+
export type TaskResultResolutionInput = {
|
|
6
|
+
readonly operationId: string;
|
|
7
|
+
readonly status: 'completed' | 'failed';
|
|
8
|
+
readonly resolutionReason: TaskResolutionReason;
|
|
9
|
+
readonly value?: unknown;
|
|
10
|
+
readonly error?: string | undefined;
|
|
11
|
+
readonly inflightRecord?: InflightRecord | null | undefined;
|
|
12
|
+
readonly skipPayloadSizeCheck?: boolean | undefined;
|
|
13
|
+
};
|
|
14
|
+
export declare function taskResultPayloadSizeError(input: TaskResultResolutionInput, maxBytes: number | null): PayloadSizeExceededError | null;
|
|
15
|
+
export declare function transitionTaskResultToResolvedWithRetry(context: ServerContext, options: ServeOptions, input: TaskResultResolutionInput): Promise<void>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { TaskResultDeadLetteredEvent } from "../../core/events.js";
|
|
2
|
+
import { PayloadSizeExceededError, assertPayloadWithinLimit } from "../../core/payload-size.js";
|
|
3
|
+
import {
|
|
4
|
+
readInflightRecord,
|
|
5
|
+
transitionInflightToResolved,
|
|
6
|
+
writeDeadLetteredTaskRecord
|
|
7
|
+
} from "../task-state.js";
|
|
8
|
+
import { withRetry } from "./retry.js";
|
|
9
|
+
import { recordTaskExecutionLatencyMetric } from "./task-metrics.js";
|
|
10
|
+
const TASK_RESULT_RESOLUTION_RETRY_ATTEMPTS = 2;
|
|
11
|
+
function taskResultPayloadForSizeCheck(input) {
|
|
12
|
+
return input.status === "completed" ? input.value : input.error ?? "";
|
|
13
|
+
}
|
|
14
|
+
export function taskResultPayloadSizeError(input, maxBytes) {
|
|
15
|
+
try {
|
|
16
|
+
assertPayloadWithinLimit(taskResultPayloadForSizeCheck(input), maxBytes, "activity result");
|
|
17
|
+
return null;
|
|
18
|
+
} catch (error) {
|
|
19
|
+
if (error instanceof PayloadSizeExceededError)
|
|
20
|
+
return error;
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export async function transitionTaskResultToResolvedWithRetry(context, options, input) {
|
|
25
|
+
if (input.skipPayloadSizeCheck !== !0) {
|
|
26
|
+
const payloadError = taskResultPayloadSizeError(input, context.payloadSizeMaxBytes);
|
|
27
|
+
if (payloadError !== null)
|
|
28
|
+
throw payloadError;
|
|
29
|
+
}
|
|
30
|
+
const storage = options.engine.storage, resolvedAt = Date.now();
|
|
31
|
+
let latestInflightRecord = input.inflightRecord;
|
|
32
|
+
try {
|
|
33
|
+
await withRetry(async () => {
|
|
34
|
+
if (latestInflightRecord === void 0)
|
|
35
|
+
latestInflightRecord = await readInflightRecord(storage, input.operationId);
|
|
36
|
+
await transitionInflightToResolved(storage, input.operationId, input.status, {
|
|
37
|
+
...latestInflightRecord === null ? {} : { record: latestInflightRecord },
|
|
38
|
+
resolvedAt,
|
|
39
|
+
resolutionReason: input.resolutionReason,
|
|
40
|
+
...input.status === "completed" ? { value: input.value } : { error: input.error }
|
|
41
|
+
});
|
|
42
|
+
}, `transition task "${input.operationId}" to resolved`, TASK_RESULT_RESOLUTION_RETRY_ATTEMPTS);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
const fallbackInflightRecord = latestInflightRecord ?? await readInflightRecord(storage, input.operationId).catch(() => null);
|
|
45
|
+
await withRetry(async () => {
|
|
46
|
+
await writeTaskResultDeadLetter(options, input, fallbackInflightRecord);
|
|
47
|
+
}, `dead-letter task "${input.operationId}" after result-resolution retries`, TASK_RESULT_RESOLUTION_RETRY_ATTEMPTS);
|
|
48
|
+
console.error(`[weft] Failed to transition task "${input.operationId}" to resolved after retries \u2014 dead-lettered:`, error);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (latestInflightRecord !== null && latestInflightRecord !== void 0)
|
|
52
|
+
recordTaskExecutionLatencyMetric(context.metricsCollector, latestInflightRecord, resolvedAt);
|
|
53
|
+
}
|
|
54
|
+
async function writeTaskResultDeadLetter(options, input, inflightRecord) {
|
|
55
|
+
const storageErrorCode = "result-resolution-storage-exhausted", record = {
|
|
56
|
+
operationId: input.operationId,
|
|
57
|
+
reason: storageErrorCode,
|
|
58
|
+
deadLetteredAt: Date.now(),
|
|
59
|
+
errorMessage: storageErrorCode,
|
|
60
|
+
retryAttempts: TASK_RESULT_RESOLUTION_RETRY_ATTEMPTS,
|
|
61
|
+
status: input.status,
|
|
62
|
+
...inflightRecord?.activityName === void 0 ? {} : { activityName: inflightRecord.activityName },
|
|
63
|
+
...inflightRecord?.queue === void 0 ? {} : { queue: inflightRecord.queue },
|
|
64
|
+
...inflightRecord?.workerId === void 0 ? {} : { workerId: inflightRecord.workerId },
|
|
65
|
+
...inflightRecord?.attempt === void 0 ? {} : { attempt: inflightRecord.attempt },
|
|
66
|
+
...inflightRecord?.visibilityTimeout === void 0 ? {} : { visibilityTimeout: inflightRecord.visibilityTimeout },
|
|
67
|
+
...inflightRecord?.workflowId === void 0 ? {} : { workflowId: inflightRecord.workflowId },
|
|
68
|
+
...inflightRecord?.retryCount === void 0 ? {} : { retryCount: inflightRecord.retryCount },
|
|
69
|
+
...inflightRecord?.requeueCount === void 0 ? {} : { requeueCount: inflightRecord.requeueCount },
|
|
70
|
+
...inflightRecord?.lastRequeueReason === void 0 ? {} : { lastRequeueReason: inflightRecord.lastRequeueReason }
|
|
71
|
+
};
|
|
72
|
+
await writeDeadLetteredTaskRecord(options.engine.storage, record);
|
|
73
|
+
options.engine.dispatchEvent(new TaskResultDeadLetteredEvent({
|
|
74
|
+
operationId: record.operationId,
|
|
75
|
+
workflowId: record.workflowId,
|
|
76
|
+
activityName: record.activityName,
|
|
77
|
+
queue: record.queue,
|
|
78
|
+
workerId: record.workerId,
|
|
79
|
+
errorMessage: record.errorMessage
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
@@ -2,14 +2,33 @@ import type { ServerWebSocket } from 'bun';
|
|
|
2
2
|
import type { Engine } from '../../core/engine.ts';
|
|
3
3
|
import type { WebSocketData } from '../json-rpc-websocket-runtime.ts';
|
|
4
4
|
import type { ServerContext } from './context.ts';
|
|
5
|
+
/**
|
|
6
|
+
* Default per-workflow cap for one-way workflow WebSocket connections
|
|
7
|
+
* (`/stream` and `/watch`). Mirrors the JSON-RPC subscription default so one
|
|
8
|
+
* workflow cannot consume unbounded server sockets.
|
|
9
|
+
*/
|
|
10
|
+
export declare const DEFAULT_MAX_STREAM_CONNECTIONS_PER_WORKFLOW = 100;
|
|
5
11
|
export declare function sendStreamMessage(ws: ServerWebSocket<WebSocketData>, sequence: number, message: string): void;
|
|
12
|
+
export declare function sendWatchMessage(ws: ServerWebSocket<WebSocketData>, sequence: number, message: string): void;
|
|
6
13
|
export declare function getHighestStoredStreamSequence(engine: Engine, workflowId: string, key: string): Promise<number>;
|
|
7
|
-
export declare function
|
|
14
|
+
export declare function getHighestStoredWatchSequence(engine: Engine, workflowId: string): Promise<number>;
|
|
15
|
+
export declare function addStreamSocket(context: ServerContext, workflowId: string, ws: ServerWebSocket<WebSocketData>): boolean;
|
|
16
|
+
export declare function addWatchSocket(context: ServerContext, workflowId: string, ws: ServerWebSocket<WebSocketData>): boolean;
|
|
8
17
|
export declare function removeStreamSocket(context: ServerContext, ws: ServerWebSocket<WebSocketData>): void;
|
|
18
|
+
export declare function removeWatchSocket(context: ServerContext, ws: ServerWebSocket<WebSocketData>): void;
|
|
19
|
+
export declare function removeWorkflowStreamConnection(context: ServerContext, ws: ServerWebSocket<WebSocketData>): void;
|
|
9
20
|
export declare function flushPendingStreamMessages(_context: ServerContext, ws: ServerWebSocket<WebSocketData>): void;
|
|
21
|
+
export declare function flushPendingWatchMessages(_context: ServerContext, ws: ServerWebSocket<WebSocketData>): void;
|
|
10
22
|
export declare function publishTokenMessage(context: ServerContext, workflowId: string, sequence: number, message: string): void;
|
|
23
|
+
export declare function publishWatchMessage(context: ServerContext, workflowId: string, sequence: number, message: string): void;
|
|
11
24
|
/**
|
|
12
25
|
* Send existing token chunks from storage to a newly connected stream client,
|
|
13
26
|
* so it can catch up on tokens emitted before the connection was established.
|
|
14
27
|
*/
|
|
15
28
|
export declare function replayTokenStream(context: ServerContext, engine: Engine, ws: ServerWebSocket<WebSocketData>, workflowId: string): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Send stored raw watch events to a newly connected watch client. The raw
|
|
31
|
+
* watch transport keeps its historical frame shape but now honors the same
|
|
32
|
+
* `resumeFrom` cursor query parameter used by token streams.
|
|
33
|
+
*/
|
|
34
|
+
export declare function replayWatchEvents(context: ServerContext, engine: Engine, ws: ServerWebSocket<WebSocketData>, workflowId: string): Promise<void>;
|