Feat ts durable execution#3134
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
📝 Documentation updates detected! Updated existing suggestions:
Tip: Enable auto-create PR in your Docs Collection to publish suggestions automatically 🤖 |
There was a problem hiding this comment.
Pull request overview
Adds durable execution parity to the TypeScript SDK (matching the Python SDK), including durable event-log interactions, child spawning, memoization, replay/reset, and durable-task eviction support.
Changes:
- Introduces a new durable-task gRPC streaming protocol in the TS durable listener and wires it into
DurableContext(waitFor,spawnChild,memo). - Adds durable eviction support (policy + cache/manager) and worker integration to evict TTL/capacity-eligible waiting durable runs.
- Adds/updates TypeScript E2E examples + tests for durable workflows, durable events, durable sleep, and eviction; plus some new unit tests for timeout resolution.
Reviewed changes
Copilot reviewed 43 out of 45 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| sdks/typescript/src/v1/task.ts | Adds evictionPolicy option to durable task opts. |
| sdks/typescript/src/v1/parent-run-context-vars.ts | Carries durable context through AsyncLocalStorage for child run() routing. |
| sdks/typescript/src/v1/index.ts | Exports durable-related errors and eviction types/config. |
| sdks/typescript/src/v1/examples/e2e-worker.ts | Registers many new durable/eviction example workflows for e2e. |
| sdks/typescript/src/v1/examples/durable_sleep/durable_sleep.e2e.ts | New e2e test validating durable sleep behavior. |
| sdks/typescript/src/v1/examples/durable_eviction/workflow.ts | New durable eviction example workflows (TTL/capacity/non-evictable). |
| sdks/typescript/src/v1/examples/durable_eviction/durable_eviction.e2e.ts | New e2e suite covering eviction + restore flows. |
| sdks/typescript/src/v1/examples/durable_event/workflow.ts | Makes durable event waits awaited; factors event key constant. |
| sdks/typescript/src/v1/examples/durable_event/durable_event.e2e.ts | New e2e suite for durable event wait (with/without filter). |
| sdks/typescript/src/v1/examples/durable/workflow.ts | Expands durable examples: spawn child, memo, non-determinism, replay reset, spawn DAG. |
| sdks/typescript/src/v1/examples/durable/durable.e2e.ts | Expands durable e2e coverage for the new durable behaviors. |
| sdks/typescript/src/v1/examples/durable-event/workflow.ts | Updates hyphenated durable-event example to await waits. |
| sdks/typescript/src/v1/declaration.ts | Adds durable child-run routing when invoked under a durable parent context. |
| sdks/typescript/src/v1/conditions/transformer.ts | Normalizes sleep durations via durationToString when encoding PB conditions. |
| sdks/typescript/src/v1/conditions/sleep-condition.ts | Normalizes readable keys using durationToString. |
| sdks/typescript/src/v1/conditions/contitions.test.ts | Updates expected render output to use normalized duration strings. |
| sdks/typescript/src/v1/client/worker/worker-timeouts.test.ts | New unit tests for timeout resolution helpers. |
| sdks/typescript/src/v1/client/worker/worker-internal.ts | Integrates durable execution: durable listener startup, eviction manager, durable contexts, timeout normalization, improved cancellation semantics. |
| sdks/typescript/src/v1/client/worker/worker-cancel-supervision.test.ts | Updates cancellation supervision test scaffolding for new cleanup path. |
| sdks/typescript/src/v1/client/worker/eviction/index.ts | New export barrel for eviction subsystem. |
| sdks/typescript/src/v1/client/worker/eviction/eviction-policy.ts | New EvictionPolicy type + default durable eviction policy. |
| sdks/typescript/src/v1/client/worker/eviction/eviction-manager.ts | New eviction loop + shutdown eviction. |
| sdks/typescript/src/v1/client/worker/eviction/eviction-cache.ts | New eviction candidate selection logic (TTL/capacity). |
| sdks/typescript/src/v1/client/worker/context.ts | DurableContext now uses durable event-log streaming; adds spawnChild + memo; adds eviction wait-marking; normalizes refreshTimeout durations. |
| sdks/typescript/src/v1/client/features/runs.ts | Adds restoreTask + resetDurableTask helpers. |
| sdks/typescript/src/v1/client/duration.ts | Extends Duration to support object-form durations and adds duration normalization helpers. |
| sdks/typescript/src/v1/client/client.ts | Updates DurableListenerClient construction signature. |
| sdks/typescript/src/util/sleep.ts | Extends sleep helper to accept Duration (string/object) as well as milliseconds. |
| sdks/typescript/src/util/errors/task-run-terminated-error.ts | New shared error type for cancellation/eviction termination. |
| sdks/typescript/src/util/errors/non-determinism-error.ts | New error type for durable non-determinism signaling. |
| sdks/typescript/src/protoc/workflows/workflows.ts | Deduplicates TriggerWorkflowRequest by importing shared trigger proto. |
| sdks/typescript/src/protoc/v1/workflows.ts | Adds EVICTED run status and durable fork RPC message types + admin service method. |
| sdks/typescript/src/protoc/v1/shared/trigger.ts | New shared TriggerWorkflowRequest proto module. |
| sdks/typescript/src/protoc/v1/dispatcher.ts | Adds durable-task streaming protocol messages/RPC and imports shared TriggerWorkflowRequest. |
| sdks/typescript/src/protoc/dispatcher/dispatcher.ts | Extends AssignedAction with durable invocation count; adds restore-evicted-task RPC/types. |
| sdks/typescript/src/legacy/step.ts | Normalizes refreshTimeout duration serialization for legacy context. |
| sdks/typescript/src/legacy/legacy-client.ts | Updates DurableListenerClient construction signature. |
| sdks/typescript/src/clients/rest/generated/data-contracts.ts | Adds EVICTED statuses + durable restore/fork request/response types. |
| sdks/typescript/src/clients/rest/generated/Api.ts | Adds REST endpoints for task restore and durable task fork. |
| sdks/typescript/src/clients/listeners/durable-listener/durable-listener-client.ts | Major rewrite: durable task event-log streaming client + legacy backward compatibility. |
| examples/typescript/e2e-worker.ts | Registers the expanded durable/eviction examples in root examples. |
| examples/typescript/durable_eviction/workflow.ts | New root example workflow for durable eviction. |
| examples/typescript/durable_event/workflow.ts | Updates root durable_event example to await waits + reuse event key constant. |
| examples/typescript/durable/workflow.ts | Expands root durable workflow examples similarly to SDK examples. |
| examples/typescript/durable-event/workflow.ts | Updates root hyphenated durable-event example to await waits. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
mrkaye97
left a comment
There was a problem hiding this comment.
left some comments but looks basically good!
| type PendingCallbackKey = `${TaskExternalId}:${InvocationCount}:${BranchId}:${NodeId}`; | ||
| type PendingEvictionAckKey = `${TaskExternalId}:${InvocationCount}`; | ||
|
|
||
| function ackKey(taskExtId: string, invocationCount: number): PendingEventAckKey { |
There was a problem hiding this comment.
should the types here be taskExtId: TaskExternalId, invocationCount: InvocationCount?
| taskExtId: string, | ||
| invocationCount: number, | ||
| branchId: number, | ||
| nodeId: number |
There was a problem hiding this comment.
same here - I should probably do this in Python too if I haven't
| * @param options - Options for spawning the child workflow. | ||
| * @returns The result of the child workflow. | ||
| */ | ||
| async spawnChild<Q extends JsonObject, P extends JsonObject>( |
There was a problem hiding this comment.
I think in python this is intended to be private (and only called from e.g. workflow.run)
| * @returns The result of the child workflow. | ||
| */ | ||
| async spawnChild<Q extends JsonObject, P extends JsonObject>( | ||
| workflow: string | WorkflowV1<Q, P> | TaskWorkflowDeclaration<Q, P>, |
There was a problem hiding this comment.
I know we've done this some other places, but I reeeaaaalllyyyyy dislike this overload, the whole goal of a lot of the wrapper code in Python is to not be allowing people to do things that rely on e.g. the workflow name, and also the typing is so much worse if we allow this instead of only allowing a Workflow object (in Python we have BaseWorkflow so we don't need the union type either)
| * @param args - The arguments to pass to the function. These form the memoization key. | ||
| * @returns The memoized value, either from durable storage or freshly computed. | ||
| */ | ||
| async memo<R>(fn: (...args: any[]) => Promise<R>, ...args: any[]): Promise<R> { |
There was a problem hiding this comment.
can we do this without any?
|
📝 Documentation updates detected! Updated existing suggestion: Document durable execution with eviction policies, NonDeterminismError, and best practices Tip: Worried about broken links? Ask Promptless to find and fix them automatically 🔗 |
615340a to
57e0ff9
Compare
| if (durableCtx) { | ||
| if (Array.isArray(input)) { | ||
| return durableCtx.spawnChildren( | ||
| input.map((inp) => ({ workflow: this as any, input: inp as any, options })) |
|
📝 Documentation updates detected! Updated existing suggestions:
Tip: Tell your friends working on non-commercial open-source projects to apply for free Promptless access at promptless.ai/oss ❤️ |
Description
Aligns typescript with the current python implementation
Type of change