Skip to content
102 changes: 86 additions & 16 deletions docs/develop/dotnet/cancellation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
id: cancellation
title: Interrupt a Workflow - .NET SDK
sidebar_label: Interrupt a Workflow
description: Interrupt Workflow Execution in .NET using the Temporal SDK. Cancel for graceful stops; terminate for forceful stops. Handle Cancellation in Workflow and Activities efficiently.
description:
Interrupt Workflow Execution in .NET using the Temporal SDK. Cancel for graceful stops; terminate for forceful stops.
Handle Cancellation in Workflow and Activities efficiently.
toc_max_heading_level: 4
keywords:
- interrupt workflow execution
Expand Down Expand Up @@ -39,16 +41,15 @@ You can interrupt a Workflow Execution in one of the following ways:
- [Cancel](#cancellation): Canceling a Workflow provides a graceful way to stop Workflow Execution.
- [Terminate](#termination): Terminating a Workflow forcefully stops Workflow Execution.

Terminating a Workflow forcefully stops Workflow Execution.
This action resembles killing a process.
Terminating a Workflow forcefully stops Workflow Execution. This action resembles killing a process.

- The system records a `WorkflowExecutionTerminated` event in the Workflow History.
- The termination forcefully and immediately stops the Workflow Execution.
- The Workflow code gets no chance to handle termination.
- A Workflow Task doesn't get scheduled.

In most cases, canceling is preferable because it allows the Workflow to finish gracefully.
Terminate only if the Workflow is stuck and cannot be canceled normally.
In most cases, canceling is preferable because it allows the Workflow to finish gracefully. Terminate only if the
Workflow is stuck and cannot be canceled normally.

## Cancellation {#cancellation}

Expand All @@ -63,11 +64,12 @@ To give a Workflow and its Activities the ability to be cancelled, do the follow

**How to handle a Cancellation in a Workflow in .NET.**

Workflow Definitions can be written to respond to cancellation requests.
It is common for an Activity to be run on Cancellation to perform cleanup.
Workflow Definitions can be written to respond to cancellation requests. It is common for an Activity to be run on
Cancellation to perform cleanup.

Cancellation Requests on Workflows cancel the `Workflow.CancellationToken`.
This is the token that is implicitly used for all calls within the workflow as well (e.g. Timers, Activities, etc) and therefore cancellation is propagated to them to be handled and bubble out.
Cancellation Requests on Workflows cancel the `Workflow.CancellationToken`. This is the token that is implicitly used
for all calls within the workflow as well (e.g. Timers, Activities, etc) and therefore cancellation is propagated to
them to be handled and bubble out.

```csharp
[WorkflowRun]
Expand Down Expand Up @@ -111,9 +113,10 @@ public async Task RunAsync()

**How to handle a Cancellation in an Activity using the Temporal .NET SDK**

Ensure that the Activity is [Heartbeating](/develop/dotnet/failure-detection#activity-heartbeats) to receive the Cancellation request and stop execution.
Also make sure that the [Heartbeat Timeout](/develop/dotnet/failure-detection#heartbeat-timeout) is set on the Activity Options when calling from the Workflow.
An Activity Cancellation Request cancels the `CancellationToken` on the `ActivityExecutionContext`.
Ensure that the Activity is [Heartbeating](/develop/dotnet/failure-detection#activity-heartbeats) to receive the
Cancellation request and stop execution. Also make sure that the
[Heartbeat Timeout](/develop/dotnet/failure-detection#heartbeat-timeout) is set on the Activity Options when calling
from the Workflow. An Activity Cancellation Request cancels the `CancellationToken` on the `ActivityExecutionContext`.

```csharp
[Activity]
Expand Down Expand Up @@ -150,8 +153,8 @@ await handle.CancelAsync();

**How to request Cancellation of an Activity in .NET using the Temporal .NET SDK**

By default, Activities are automatically cancelled when the Workflow is cancelled since the workflow cancellation token is used by activities by default.
To issue a cancellation explicitly, a new cancellation token can be created.
By default, Activities are automatically cancelled when the Workflow is cancelled since the workflow cancellation token
is used by activities by default. To issue a cancellation explicitly, a new cancellation token can be created.

```csharp
[WorkflowRun]
Expand Down Expand Up @@ -187,7 +190,9 @@ public async Task RunAsync()

**How to Terminate a Workflow Execution in .NET using the Temporal .NET SDK**

To Terminate a Workflow Execution in .NET, use the [TerminateAsync()](https://dotnet.temporal.io/api/Temporalio.Client.WorkflowHandle.html#Temporalio_Client_WorkflowHandle_TerminateAsync_System_String_Temporalio_Client_WorkflowTerminateOptions_) method on the Workflow handle.
To Terminate a Workflow Execution in .NET, use the
[TerminateAsync()](https://dotnet.temporal.io/api/Temporalio.Client.WorkflowHandle.html#Temporalio_Client_WorkflowHandle_TerminateAsync_System_String_Temporalio_Client_WorkflowTerminateOptions_)
method on the Workflow handle.

```csharp
// Get a workflow handle by its workflow ID. This could be made specific to a run by passing run ID.
Expand All @@ -198,4 +203,69 @@ var handle = myClient.GetWorkflowHandle("my-workflow-id");
await handle.TerminateAsync();
```

Workflow Executions can also be Terminated directly from the WebUI. In this case, a custom note can be logged from the UI when that happens.
Workflow Executions can also be Terminated directly from the WebUI. In this case, a custom note can be logged from the
UI when that happens.

## Reset a Workflow Execution {#reset}

Resetting a Workflow Execution terminates the current Workflow Execution and starts a new Workflow Execution from a
point you specify in its Event History. Use reset when a Workflow is blocked due to a non-deterministic error or other
issues that prevent it from completing.

When you reset a Workflow, the Event History up to the reset point is copied to the new Workflow Execution, and the
Workflow resumes from that point with the current code. Reset only works if you've fixed the underlying issue, such as
removing non-deterministic code. Any progress made after the reset point will be discarded. Provide a reason when
resetting, as it will be recorded in the Event History.

<Tabs>

<TabItem value="web-ui" label="Web UI">

1. Navigate to the Workflow Execution details page,
2. Click the **Reset** button in the top right dropdown menu,
3. Select the Event ID to reset to,
4. Provide a reason for the reset,
5. Confirm the reset.

The Web UI shows available reset points and creates a link to the new Workflow Execution after the reset completes.

</TabItem>

<TabItem value="cli" label="Temporal CLI">

Use the `temporal workflow reset` command to reset a Workflow Execution:

```bash
temporal workflow reset \
--workflow-id <workflow-id> \
--event-id <event-id> \
--reason "Reason for reset"
```

For example:

```bash
temporal workflow reset \
--workflow-id my-background-check \
--event-id 4 \
--reason "Fixed non-deterministic code"
```

By default, the command resets the latest Workflow Execution in the `default` Namespace. Use `--run-id` to reset a
specific run. Use `--namespace` to specify a different Namespace:

```bash
temporal workflow reset \
--workflow-id my-background-check \
--event-id 4 \
--reason "Fixed non-deterministic code" \
--namespace my-namespace \
--tls-cert-path /path/to/cert.pem \
--tls-key-path /path/to/key.pem
```

Monitor the new Workflow Execution after resetting to ensure it completes successfully.

</TabItem>

</Tabs>
1 change: 1 addition & 0 deletions docs/develop/dotnet/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ Interrupt a Workflow Execution with a Cancel or Terminate action.
through Workflow cancellation.
- [Terminate a Workflow](/develop/dotnet/cancellation#termination): Interrupt a Workflow Execution and its Activities
through Workflow termination.
- [Reset a Workflow](/develop/dotnet/cancellation#reset): Resume a Workflow Execution from an earlier point in its Event History.

## [Asynchronous Activity completion](/develop/dotnet/asynchronous-activity)

Expand Down
98 changes: 84 additions & 14 deletions docs/develop/go/cancellation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
id: cancellation
title: Interrupt a Workflow - Go SDK
sidebar_label: Interrupt a Workflow Execution
description: Handle Cancellations in Temporal Workflows and Activities, set Activity Heartbeat Timeouts, and send Cancellation requests from a Temporal Client in Go.
description:
Handle Cancellations in Temporal Workflows and Activities, set Activity Heartbeat Timeouts, and send Cancellation
requests from a Temporal Client in Go.
toc_max_heading_level: 4
keywords:
- cancellation
Expand All @@ -26,14 +28,19 @@ This pages shows the following:

**How to handle a Cancellation in a Workflow in Go.**

Workflow Definitions can be written to handle execution cancellation requests with Go's `defer` and the `workflow.NewDisconnectedContext` API.
In the Workflow Definition, there is a special Activity that handles clean up should the execution be cancelled.
Workflow Definitions can be written to handle execution cancellation requests with Go's `defer` and the
`workflow.NewDisconnectedContext` API. In the Workflow Definition, there is a special Activity that handles clean up
should the execution be cancelled.

If the Workflow receives a Cancellation Request, but all Activities gracefully handle the Cancellation, and/or no Activities are skipped then the Workflow status will be Complete.
It is completely up to the needs of the business process and your use case which determines whether you want to return the Cancellation error to show a Canceled status or Complete status regardless of whether a Cancellation has propagated to and/or skipped Activities.
If the Workflow receives a Cancellation Request, but all Activities gracefully handle the Cancellation, and/or no
Activities are skipped then the Workflow status will be Complete. It is completely up to the needs of the business
process and your use case which determines whether you want to return the Cancellation error to show a Canceled status
or Complete status regardless of whether a Cancellation has propagated to and/or skipped Activities.

<!--SNIPSTART go-features-cancellation-workflow {"selectedLines": ["14-15", "18", "20-38", "41", "43-45", "47-50"]}-->

[sample-apps/go/features/cancellation/workflow.go](https://github.com/temporalio/documentation/blob/main/sample-apps/go/features/cancellation/workflow.go)

```go
// ...
// YourWorkflow is a Workflow Definition that shows how it can be canceled.
Expand Down Expand Up @@ -72,6 +79,7 @@ func YourWorkflow(ctx workflow.Context) error {
return err
}
```

<!--SNIPEND-->

## Handle Cancellation in an Activity {#handle-cancellation-in-an-activity}
Expand Down Expand Up @@ -136,13 +144,75 @@ func main() {

## Heartbeating after a Cancellation

Sometimes you may want to continue running your Activity, even after a Cancellation has been issued.
You may want to completely ignore the cancellation and continue Activity
execution, including Heartbeating, or you may want to send one final Heartbeat after Cancellation.
Even though the context is cancelled when the Workflow is Cancelled, you are still able to send
Activity Heartbeats.
Sometimes you may want to continue running your Activity, even after a Cancellation has been issued. You may want to
completely ignore the cancellation and continue Activity execution, including Heartbeating, or you may want to send one
final Heartbeat after Cancellation. Even though the context is cancelled when the Workflow is Cancelled, you are still
able to send Activity Heartbeats.

When you call `activity.RecordHeartbeat` after Cancellation has occurred, a
`WARN RecordActivityHeartbeat with error Error context canceled` message will be logged, and a `context canceled` error
will be returned from the call. However, the Heartbeat **has** still been sent.

## Reset a Workflow Execution {#reset}

Resetting a Workflow Execution terminates the current Workflow Execution and starts a new Workflow Execution from a
point you specify in its Event History. Use reset when a Workflow is blocked due to a non-deterministic error or other
issues that prevent it from completing.

When you reset a Workflow, the Event History up to the reset point is copied to the new Workflow Execution, and the
Workflow resumes from that point with the current code. Reset only works if you've fixed the underlying issue, such as
removing non-deterministic code. Any progress made after the reset point will be discarded. Provide a reason when
resetting, as it will be recorded in the Event History.

<Tabs>

<TabItem value="web-ui" label="Web UI">

1. Navigate to the Workflow Execution details page,
2. Click the **Reset** button in the top right dropdown menu,
3. Select the Event ID to reset to,
4. Provide a reason for the reset,
5. Confirm the reset.

The Web UI shows available reset points and creates a link to the new Workflow Execution after the reset completes.

</TabItem>

<TabItem value="cli" label="Temporal CLI">

Use the `temporal workflow reset` command to reset a Workflow Execution:

```bash
temporal workflow reset \
--workflow-id <workflow-id> \
--event-id <event-id> \
--reason "Reason for reset"
```

For example:

```bash
temporal workflow reset \
--workflow-id my-background-check \
--event-id 4 \
--reason "Fixed non-deterministic code"
```

By default, the command resets the latest Workflow Execution in the `default` Namespace. Use `--run-id` to reset a
specific run. Use `--namespace` to specify a different Namespace:

```bash
temporal workflow reset \
--workflow-id my-background-check \
--event-id 4 \
--reason "Fixed non-deterministic code" \
--namespace my-namespace \
--tls-cert-path /path/to/cert.pem \
--tls-key-path /path/to/key.pem
```

Monitor the new Workflow Execution after resetting to ensure it completes successfully.

</TabItem>

When you call `activity.RecordHeartbeat` after Cancellation has occurred, a
`WARN RecordActivityHeartbeat with error Error context canceled` message will be logged, and a
`context canceled` error will be returned from the call. However, the
Heartbeat **has** still been sent.
</Tabs>
1 change: 1 addition & 0 deletions docs/develop/go/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ Send messages to and read the state of Workflow Executions.
Interrupt a Workflow Execution with a Cancel or Terminate action.

- [Handle a Workflow Cancellation Request](/develop/go/cancellation#handle-cancellation-in-workflow): Interrupt a Workflow Execution and its Activities through Workflow cancellation.
- [Reset a Workflow](/develop/go/cancellation#reset): Resume a Workflow Execution from an earlier point in its Event History.
- [Request Cancellation](/develop/go/cancellation#request-cancellation)

## [Asynchronous Activity completion](/develop/go/asynchronous-activity-completion)
Expand Down
Loading