Skip to main content

Class: CancellationScope

workflow.CancellationScope

Cancellation Scopes provide the mechanic by which a Workflow may gracefully handle incoming requests for cancellation (e.g. in response to WorkflowHandle.cancel or through the UI or CLI), as well as request cancelation of cancellable operations it owns (e.g. Activities, Timers, Child Workflows, etc).

Cancellation Scopes form a tree, with the Workflow's main function running in the root scope of that tree. By default, cancellation propagates down from a parent scope to its children and its cancellable operations. A non-cancellable scope can receive cancellation requests, but is never effectively considered as cancelled, thus shieldding its children and cancellable operations from propagation of cancellation requests it receives.

Scopes are created using the CancellationScope constructor or the static helper methods cancellable, nonCancellable and withTimeout. withTimeout creates a scope that automatically cancels itself after some duration.

Cancellation of a cancellable scope results in all operations created directly in that scope to throw a CancelledFailure (either directly, or as the cause of an ActivityFailure or a ChildWorkflowFailure). Further attempt to create new cancellable scopes or cancellable operations within a scope that has already been cancelled will also immediately throw a CancelledFailure exception. It is however possible to create a non-cancellable scope at that point; this is often used to execute rollback or cleanup operations. For example:

async function myWorkflow(...): Promise<void> {
try {
// This activity runs in the root cancellation scope. Therefore, a cancelation request on
// the Workflow execution (e.g. through the UI or CLI) automatically propagates to this
// activity. Assuming that the activity properly handle the cancellation request, then the
// call below will throw an `ActivityFailure` exception, with `cause` sets to an
// instance of `CancelledFailure`.
await someActivity();
} catch (e) {
if (isCancellation(e)) {
// Run cleanup activity in a non-cancellable scope
await CancellationScope.nonCancellable(async () => {
await cleanupActivity();
}
} else {
throw e;
}
}
}

A cancellable scope may be programatically cancelled by calling scope.cancel()`. This may be used, for example, to explicitly request cancellation of an Activity or Child Workflow:

const cancellableActivityScope = new CancellationScope();
const activityPromise = cancellableActivityScope.run(() => someActivity());
cancellableActivityScope.cancel(); // Cancels the activity
await activityPromise; // Throws `ActivityFailure` with `cause` set to `CancelledFailure`

Constructors

constructor

new CancellationScope(options?): CancellationScope

Parameters

NameType
options?CancellationScopeOptions

Returns

CancellationScope

Properties

cancelRequested

Readonly cancelRequested: Promise<never>

A Promise that throws when a cancellable scope receives a cancellation request, either directly (i.e. scope.cancel()), or indirectly (by cancelling a cancellable parent scope).

Note that a non-cancellable scope may receive cancellation requests, resulting in the cancelRequested promise for that scope to throw, though the scope will not effectively get cancelled (i.e. consideredCancelled will still return false, and cancellation will not be propagated to child scopes and contained operations).


cancellable

Readonly cancellable: boolean

If false, then this scope will never be considered cancelled, even if a cancellation request is received (either directly by calling scope.cancel() or indirectly by cancelling a cancellable parent scope). This effectively shields the scope's children and cancellable operations from propagation of cancellation requests made on the non-cancellable scope.

Note that the Promise returned by the run function of non-cancellable scope may still throw a CancelledFailure if such an exception is thrown from within that scope (e.g. by directly cancelling a cancellable child scope).


parent

Optional Readonly parent: CancellationScope

An optional CancellationScope (useful for running background tasks), defaults to CancellationScope.current()

Accessors

consideredCancelled

get consideredCancelled(): boolean

Whether the scope was effectively cancelled. A non-cancellable scope can never be considered cancelled.

Returns

boolean

Methods

cancel

cancel(): void

Request to cancel the scope and linked children

Returns

void


run

run<T>(fn): Promise<T>

Activate the scope as current and run fn

Any timers, Activities, Triggers and CancellationScopes created in the body of fn automatically link their cancellation to this scope.

Type parameters

Name
T

Parameters

NameType
fn() => Promise<T>

Returns

Promise<T>

the result of fn


cancellable

cancellable<T>(fn): Promise<T>

Alias to new CancellationScope({ cancellable: true }).run(fn)

Type parameters

Name
T

Parameters

NameType
fn() => Promise<T>

Returns

Promise<T>


current

current(): CancellationScope

Get the current "active" scope

Returns

CancellationScope


nonCancellable

nonCancellable<T>(fn): Promise<T>

Alias to new CancellationScope({ cancellable: false }).run(fn)

Type parameters

Name
T

Parameters

NameType
fn() => Promise<T>

Returns

Promise<T>


withTimeout

withTimeout<T>(timeout, fn): Promise<T>

Alias to new CancellationScope({ cancellable: true, timeout }).run(fn)

Type parameters

Name
T

Parameters

NameType
timeoutDuration
fn() => Promise<T>

Returns

Promise<T>