Add ctx.ScheduleNewWorkflow for detached workflows#100
Open
acroca wants to merge 4 commits into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds first-class “detached workflow” scheduling from inside an orchestrator via WorkflowContext.ScheduleNewWorkflow, enabling fire-and-forget spawning without parent linkage (so completion/failure does not flow back to the caller).
Changes:
- Introduces
task.WorkflowContext.ScheduleNewWorkflow(plusworkflow/wrapper) with deterministic default instance ID generation when no instance ID is provided. - Extends the runtime applier to handle
CreateDetachedWorkflowActionby recording aDetachedWorkflowInstanceCreatedevent in the caller and emitting anExecutionStartedevent for the spawned instance with no parent linkage and target-only routing. - Adds unit/integration tests covering detached workflow scheduling, determinism across replay, routing behavior, and execution ID minting.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| workflow/workflow.go | Adds wrapper-level ScheduleNewWorkflow and detached workflow option helpers. |
| task/orchestrator.go | Implements ScheduleNewWorkflow orchestration API, options, and replay retirement logic. |
| backend/runtimestate/applier.go | Applies CreateDetachedWorkflowAction by recording caller history + emitting spawned start message with no parent linkage. |
| tests/runtimestate_test.go | Adds applier-focused tests for detached workflow history/message shaping and routing/execution ID behavior. |
| tests/orchestrations_test.go | Adds end-to-end tests for detached workflow lifecycle, default IDs, non-propagation of failure, and replay determinism. |
| task/detached_workflow_test.go | Adds orchestrator-context unit tests for emitted actions/options and replay retirement behavior. |
| api/protos/orchestrator_actions.pb.go | Updates generated protos to include CreateDetachedWorkflowAction and wiring in WorkflowAction. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: Albert Callarisa <albert@diagrid.io>
JoshVanL
requested changes
May 7, 2026
Signed-off-by: Albert Callarisa <albert@diagrid.io>
javier-aliaga
approved these changes
May 8, 2026
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Albert Callarisa <albert@acroca.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ref: dapr/dapr#9261
Summary
Adds first-class support for spawning a fully decoupled workflow from within another workflow, replacing the prior pattern of wrapping a
WorkflowClient.ScheduleNewWorkflowcall inside an activity.What this does
WorkflowContext.ScheduleNewWorkflow(workflow, opts...) (api.InstanceID, error). Returns the new instance ID synchronously — there is no awaitable Task because the spawned workflow is fire-and-forget.workflow/.CreateDetachedWorkflowAction:DetachedWorkflowInstanceCreatedEventto the caller's history (event id == action id).ExecutionStartedEventfor the new instance withParentInstance == nil, propagatingName,Input,Tags,ScheduledStartTimestamp,ParentTraceContext(action's, with fallback to current trace context), andExecutionId(mints a UUID when absent, matching the client API).SourceAppIDback-reference) so the new workflow looks like a freshly client-scheduled top-level workflow.Versionis intentionally NOT propagated to the spawned StartEvent, matching the existingCreateChildWorkflowprecedent.