# Cancellation Equivalent of Golang SDK

**URL:** <https://community.temporal.io/t/cancellation-equivalent-of-golang-sdk/1279>\
**Category:** Community Support\
**Tags:** go-sdk, general-impl\
**Created:** [January 7, 2021, 9:47pm UTC](https://community.temporal.io/t/cancellation-equivalent-of-golang-sdk/1279 "2021-01-07T21:47:34Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Shannon\_Tan](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/shannon_tan/32/131_2.png) [@Shannon\_Tan](https://community.temporal.io/u/Shannon_Tan)\
**Post date:** [January 7, 2021, 9:47pm UTC](https://community.temporal.io/t/cancellation-equivalent-of-golang-sdk/1279/1 "2021-01-07T21:47:34Z")

</div>

In this doc: [Workflows | Temporal Documentation](https://docs.temporal.io/docs/workflows), there’s a code snippet about a Subscription Workflow. The code snippet includes a try catch block: `catch (CancellationException e)`.

Is this CancellationException one thrown by Temporal, or one thrown by the application? If thrown by Temporal, is there an equivalent construct in the Golang SDK? How does this work? If it is thrown by the application, then I think I understand.

What if someone cancels the workflow via another Temporal client (front-end, CLI, etc.)? If we wanted to kick off activities as a result of this forced workflow cancellation, we’d have to wrap this subscription workflow in a parent workflow right?

Btw, I saw this here: [Design patterns for cleanup during cancellation](https://community.temporal.io/t/design-patterns-for-cleanup-during-cancellation/128), and I didn’t think it was identical so hence the new post.

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [January 8, 2021, 12:39am UTC](https://community.temporal.io/t/cancellation-equivalent-of-golang-sdk/1279/3 "2021-01-08T00:39:13Z")

</div>

Java and Go use very different approaches for cancellation. The reason is that Go has a standard mechanism to cancel function execution through [Context](https://blog.golang.org/context). Java doesn’t have any standard way to cancel the execution of some code. Thread interrupt and the related exceptions are more like an annoyance than a real cancellation mechanism.

# Go

Go uses `workflow.Context` for cancellation. `workflow.Context` behaves exactly as the standard `context.Context` with the only difference is that `Done()` method returns the `Channel` interface instead of the native Go channel. To cancel an activity for example cancel the context that was used to invoke that activity:

```Go
	ctx, cancelFunc := workflow.WithCancel(ctx)
	err := workflow.ExecuteActivity(ctx, foo).Get(null)
	if _, ok := err.(*CanceledError); ok {
                // Activity was canceled
	}

	...
	// Trigger cancellation of activity context from a different goroutine
	cancelFunc()

```

# Java

As Java doesn’t have any standard patterns around code cancellation Temporal introduced its own mechanism. Any part of the workflow code can be made cancellable by wrapping it in a [CancellationScope](https://github.com/temporalio/sdk-java/blob/master/temporal-sdk/src/main/java/io/temporal/workflow/CancellationScope.java). Then call to `CancellationScope.cancel()` will cancel the wrapped code.

```Java
      CancellationScope scope = Workflow.newCancellationScope(() -> {
         try {
             activity.foo())
         } catch (CanceledFailure e) {
             // Activity was canceled
         }
      });
      scope.run();
      ...
      // From a different thread (for example signal method):
      scope.cancel();

```

# Workflow Cancellation

The above samples demonstrate explicit cancellation requested by the workflow code itself. What does happen when a whole workflow gets a cancellation request through `tctl` or any other client?

In the case of Go, the root workflow context passed to the workflow function gets canceled.

In the case of Java, the root `CancellationScope` is canceled. The main workflow method (annotated with `@WorflowMethod`) is always invoked in the context of a root `CancellationScope`. So any cancellable code in the workflow gets notified when the root context is canceled.

# Cleanup

It is not possible to execute any activities using a canceled context in the case of Go. They will immediately fail with `CanceledError.` It is also not possible to invoke any activities inside a canceled `CancellationScope` in the case of Java. Any such invocation will immediately throw `CanceledFailure`.

This represents a problem that canceled workflow cannot execute any cleanup logic that executes activities. The solution is to use a disconnected context in Go (created through `workflow.NewDisconnectedContext`) and a disconnected cancellation scope (created through `Workflow.newDetachedCancellationScope`) in Java for such cleanup operations.

---

<div class="post-metadata">

**Author:** ![tempuser](https://avatars.discourse-cdn.com/v4/letter/t/9dc877/32.png) [@tempuser](https://community.temporal.io/u/tempuser)\
**Post date:** [April 30, 2021, 3:26am UTC](https://community.temporal.io/t/cancellation-equivalent-of-golang-sdk/1279/4 "2021-04-30T03:26:47Z")

</div>

> [@maxim](#):
>
> Workflow.newDisconnectedScope

Hi Maxim,

I can’t seem to find Workflow.newDisconnectedScope. Is it Workflow.newDetachedCancellationScope?

Thanks,  
Richard

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [April 30, 2021, 3:34am UTC](https://community.temporal.io/t/cancellation-equivalent-of-golang-sdk/1279/5 "2021-04-30T03:34:02Z")

</div>

@tempuser thanks for pointing this out. Indeed in Java it is `Workflow.newDetachedCancellationScope`.
