<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Workflow Protocol on Dapr Docs</title><link>https://v1-18.docs.dapr.io/contributing/protocol-reference/workflow-protocol/</link><description>Recent content in Workflow Protocol on Dapr Docs</description><generator>Hugo</generator><language>en</language><atom:link href="https://v1-18.docs.dapr.io/contributing/protocol-reference/workflow-protocol/index.xml" rel="self" type="application/rss+xml"/><item><title>Workflow Protocol - Management API</title><link>https://v1-18.docs.dapr.io/contributing/protocol-reference/workflow-protocol/workflow-protocol-management-api/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://v1-18.docs.dapr.io/contributing/protocol-reference/workflow-protocol/workflow-protocol-management-api/</guid><description>&lt;h1 id="workflow-management-api">Workflow Management API&lt;/h1>
&lt;p>The Workflow Management API allows Dapr clients to control the lifecycle of workflow instances. These APIs are exposed
via the standard Dapr gRPC endpoint and are typically made available via the SDKs.&lt;/p>
&lt;h2 id="grpc-service-definition">gRPC Service Definition&lt;/h2>
&lt;p>The management APIs are part of the &lt;code>Dapr&lt;/code> service in &lt;code>dapr.proto.runtime.v1&lt;/code>. While multiple versions
(Alpha1, Beta1) may exist, the following describes the current implementation logic.&lt;/p>
&lt;h3 id="startworkflow">StartWorkflow&lt;/h3>
&lt;p>Starts a new instance of a workflow.&lt;/p></description></item><item><title>Workflow Protocol - Execution API</title><link>https://v1-18.docs.dapr.io/contributing/protocol-reference/workflow-protocol/workflow-protocol-execution-api/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://v1-18.docs.dapr.io/contributing/protocol-reference/workflow-protocol/workflow-protocol-execution-api/</guid><description>&lt;h1 id="workflow-execution-api-task-hub-protocol">Workflow Execution API (Task Hub Protocol)&lt;/h1>
&lt;p>The Workflow Execution API is a low-level gRPC protocol used by Dapr Workflow SDKs to act as &amp;ldquo;Workers&amp;rdquo;. The SDK
connects to the Dapr sidecar via this protocol to poll for work and report completion.&lt;/p>
&lt;p>The service is named &lt;code>TaskHubSidecarService&lt;/code>.&lt;/p>
&lt;h3 id="service-definition-grpc">Service Definition (gRPC)&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-protobuf" data-lang="protobuf">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#204a87;font-weight:bold">service&lt;/span> &lt;span style="color:#000">TaskHubSidecarService&lt;/span> &lt;span style="color:#000;font-weight:bold">{&lt;/span>&lt;span style="color:#a40000">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a40000">&lt;/span> &lt;span style="color:#204a87;font-weight:bold">rpc&lt;/span> &lt;span style="color:#000">GetWorkItems&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">GetWorkItemsRequest&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#204a87;font-weight:bold">returns&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">stream&lt;/span> &lt;span style="color:#000">WorkItem&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>&lt;span style="color:#a40000">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a40000">&lt;/span> &lt;span style="color:#204a87;font-weight:bold">rpc&lt;/span> &lt;span style="color:#000">CompleteOrchestratorTask&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">OrchestratorResponse&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#204a87;font-weight:bold">returns&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">CompleteBatchResponse&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>&lt;span style="color:#a40000">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a40000">&lt;/span> &lt;span style="color:#204a87;font-weight:bold">rpc&lt;/span> &lt;span style="color:#000">CompleteActivityTask&lt;/span>&lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">ActivityResponse&lt;/span>&lt;span style="color:#000;font-weight:bold">)&lt;/span> &lt;span style="color:#204a87;font-weight:bold">returns&lt;/span> &lt;span style="color:#000;font-weight:bold">(&lt;/span>&lt;span style="color:#000">CompleteBatchResponse&lt;/span>&lt;span style="color:#000;font-weight:bold">);&lt;/span>&lt;span style="color:#a40000">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a40000">&lt;/span> &lt;span style="color:#8f5902;font-style:italic">// ... other management methods
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#8f5902;font-style:italic">&lt;/span>&lt;span style="color:#000;font-weight:bold">}&lt;/span>&lt;span style="color:#a40000">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="worker-lifecycle">Worker Lifecycle&lt;/h2>
&lt;ol>
&lt;li>&lt;strong>Connection&lt;/strong>: The SDK opens a long-running bidirectional stream to &lt;code>GetWorkItems&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Polling&lt;/strong>: The SDK receives &lt;code>WorkItem&lt;/code> messages from the stream.&lt;/li>
&lt;li>&lt;strong>Execution&lt;/strong>:
&lt;ul>
&lt;li>If the work item is an &lt;strong>Orchestration&lt;/strong>, the SDK retrieves and replays the history events to determine the next actions.&lt;/li>
&lt;li>If the work item is an &lt;strong>Activity&lt;/strong>, the SDK executes the activity logic.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Completion&lt;/strong>:
&lt;ul>
&lt;li>For Orchestrations, the SDK calls &lt;code>CompleteOrchestratorTask&lt;/code> with a list of actions to take.&lt;/li>
&lt;li>For Activities, the SDK calls &lt;code>CompleteActivityTask&lt;/code> with the result or failure information.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h2 id="grpc-service-taskhubsidecarservice">gRPC Service: &lt;code>TaskHubSidecarService&lt;/code>&lt;/h2>
&lt;h3 id="getworkitems">GetWorkItems&lt;/h3>
&lt;p>Opens a stream to receive work items for orchestrations and activities.&lt;/p></description></item><item><title>Workflow Protocol - Orchestration Lifecycle</title><link>https://v1-18.docs.dapr.io/contributing/protocol-reference/workflow-protocol/workflow-protocol-orchestration-lifecycle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://v1-18.docs.dapr.io/contributing/protocol-reference/workflow-protocol/workflow-protocol-orchestration-lifecycle/</guid><description>&lt;h1 id="orchestration-lifecycle">Orchestration Lifecycle&lt;/h1>
&lt;p>This document describes the lifecycle of an orchestration at the protocol level, specifically how the Dapr engine and
the SDK interact to execute workflow logic reliably.&lt;/p>
&lt;h2 id="replay-based-execution">Replay-based Execution&lt;/h2>
&lt;p>Dapr Workflows use &lt;strong>event sourcing&lt;/strong> and &lt;strong>replay&lt;/strong> to maintain state. Instead of saving the entire state of the
worker process (stack, variables, etc.), Dapr saves a history of events that have occurred.&lt;/p>
&lt;h3 id="the-replay-loop">The Replay Loop&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>Work Item Arrival&lt;/strong>: The Dapr engine sends an &lt;code>OrchestratorWorkItem&lt;/code> to the SDK via the &lt;code>GetWorkItems&lt;/code> stream.
This work item contains the full history of the workflow instance plus any new events (e.g., an activity completion
or an external event).&lt;/li>
&lt;li>&lt;strong>Reconstruction&lt;/strong>: The SDK starts executing the orchestration function from the very beginning.&lt;/li>
&lt;li>&lt;strong>Deterministic Execution&lt;/strong>: As the function executes, it encounters &amp;ldquo;tasks&amp;rdquo; (e.g., calling an activity, sleeping).
&lt;ul>
&lt;li>For each task, the SDK checks the provided &lt;strong>History&lt;/strong> to see if that task has already completed.&lt;/li>
&lt;li>If the task is in the history, the SDK returns the recorded result immediately without actually re-executing
the task logic.&lt;/li>
&lt;li>If the task is NOT in the history, the SDK records that this task needs to be scheduled and &lt;strong>suspends&lt;/strong>
execution of the orchestration function (typically by throwing a special exception or returning a pending
promise).&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Reporting&lt;/strong>: Once the orchestration function is suspended or completes, the SDK sends a
&lt;code>CompleteOrchestratorTask&lt;/code> request to Dapr. This request contains a list of &lt;strong>Actions&lt;/strong> (e.g., &lt;code>ScheduleTask&lt;/code>,
&lt;code>CreateTimer&lt;/code>) that the engine should perform.&lt;/li>
&lt;li>&lt;strong>State Commitment&lt;/strong>: The Dapr engine receives the actions, updates the workflow history in the state store, and
schedules any requested tasks (e.g., by sending work to an activity worker).&lt;/li>
&lt;/ol>
&lt;h2 id="step-by-step-example">Step-by-Step Example&lt;/h2>
&lt;p>Imagine a workflow: &lt;code>Activity A -&amp;gt; Activity B&lt;/code>.&lt;/p></description></item><item><title>Workflow Protocol - Activity Lifecycle</title><link>https://v1-18.docs.dapr.io/contributing/protocol-reference/workflow-protocol/workflow-protocol-activity-lifecycle/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://v1-18.docs.dapr.io/contributing/protocol-reference/workflow-protocol/workflow-protocol-activity-lifecycle/</guid><description>&lt;h1 id="activity-lifecycle">Activity Lifecycle&lt;/h1>
&lt;p>Activities are the basic units of work in a Dapr Workflow. Unlike orchestrations, activities are not replayed and do
not need to be deterministic. They are executed exactly once per &amp;ldquo;schedule&amp;rdquo; (though retries may occur).&lt;/p>
&lt;h2 id="execution-flow">Execution Flow&lt;/h2>
&lt;ol>
&lt;li>&lt;strong>Scheduling&lt;/strong>: An orchestration requests an activity by sending a &lt;code>ScheduleTask&lt;/code> action to the Dapr engine.&lt;/li>
&lt;li>&lt;strong>Work Item Dispatch&lt;/strong>: The Dapr engine enqueues an activity task. When an activity worker (SDK) is available, the
engine sends an &lt;code>ActivityWorkItem&lt;/code> via the &lt;code>GetWorkItems&lt;/code> stream.&lt;/li>
&lt;li>&lt;strong>Execution&lt;/strong>: The SDK receives the &lt;code>ActivityWorkItem&lt;/code>, which contains:
&lt;ul>
&lt;li>&lt;code>name&lt;/code>: The name of the activity to execute.&lt;/li>
&lt;li>&lt;code>input&lt;/code>: The input data for the activity.&lt;/li>
&lt;li>&lt;code>instance_id&lt;/code>: The ID of the workflow instance that scheduled the activity.&lt;/li>
&lt;li>&lt;code>task_id&lt;/code>: A unique identifier for this specific activity execution.&lt;/li>
&lt;li>&lt;code>task_execution_id&lt;/code>: A unique identifier for the specific &lt;em>attempt&lt;/em> of this activity. This is useful for
implementing idempotency in activity logic.&lt;/li>
&lt;li>&lt;code>completion_token&lt;/code>: An opaque token used to correlate the response with this specific work item.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>Reporting&lt;/strong>: After the activity logic finishes, the SDK sends a &lt;code>CompleteActivityTask&lt;/code> request back to Dapr.
&lt;ul>
&lt;li>&lt;strong>Success&lt;/strong>: The SDK provides the serialized output in the &lt;code>result&lt;/code> field.&lt;/li>
&lt;li>&lt;strong>Failure&lt;/strong>: The SDK provides &lt;code>failure_details&lt;/code> (error message, type, stack trace).&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h2 id="task-execution-ids">Task Execution IDs&lt;/h2>
&lt;p>The &lt;code>task_execution_id&lt;/code> (also known as the Task Execution Key) is a unique, runtime-generated string (typically a UUID)
that identifies a specific &lt;strong>attempt&lt;/strong> to execute an activity task.&lt;/p></description></item><item><title>Workflow Protocol - State &amp; History</title><link>https://v1-18.docs.dapr.io/contributing/protocol-reference/workflow-protocol/workflow-protocol-state-and-history/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://v1-18.docs.dapr.io/contributing/protocol-reference/workflow-protocol/workflow-protocol-state-and-history/</guid><description>&lt;h1 id="state-and-history-management">State and History Management&lt;/h1>
&lt;p>Dapr Workflows are event-sourced, meaning the state of a workflow is derived from a sequence of events. This document
describes how Dapr stores and manages this history and state.&lt;/p>
&lt;h2 id="backend-storage-dapr-actors">Backend Storage: Dapr Actors&lt;/h2>
&lt;p>By default, the Dapr Workflow engine uses &lt;strong>Dapr Actors&lt;/strong> as its storage backend. Each workflow instance is mapped to
a unique actor instance. This provides:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Concurrency Control&lt;/strong>: Actors ensure that only one operation is happening on a workflow instance at a time.&lt;/li>
&lt;li>&lt;strong>Reliability&lt;/strong>: Actor state is persisted in the configured Dapr State Store.&lt;/li>
&lt;li>&lt;strong>Timers&lt;/strong>: Dapr Actors provide durable reminders which are used to implement workflow timers.&lt;/li>
&lt;/ul>
&lt;h2 id="workflow-state-schema">Workflow State Schema&lt;/h2>
&lt;p>The state of a workflow instance (actor) consists of several components:&lt;/p></description></item><item><title>Workflow Protocol - Versioning</title><link>https://v1-18.docs.dapr.io/contributing/protocol-reference/workflow-protocol/workflow-protocol-versioning/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://v1-18.docs.dapr.io/contributing/protocol-reference/workflow-protocol/workflow-protocol-versioning/</guid><description>&lt;h1 id="workflow-versioning">Workflow Versioning&lt;/h1>
&lt;p>Dapr Workflow supports versioning of workflow definitions, allowing you to update workflow logic while existing
instances continue to run on their original logic.&lt;/p>
&lt;h2 id="named-workflow-versioning">Named Workflow Versioning&lt;/h2>
&lt;p>When registering a workflow with the Dapr engine, you can provide a version name. This allows multiple versions of the
same workflow to coexist.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Default Version&lt;/strong>: One version of a workflow can be marked as the default. If a client starts a workflow by name
without specifying a version, the default version is used.&lt;/li>
&lt;li>&lt;strong>Specific Version&lt;/strong>: Clients can request a specific version of a workflow when starting a new instance.&lt;/li>
&lt;/ul>
&lt;h3 id="registration-api">Registration API&lt;/h3>
&lt;p>SDKs register versioned workflows using the &lt;code>AddVersionedOrchestrator&lt;/code> (or similar) method in their task registry.&lt;/p></description></item></channel></rss>