Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 45cc42d

Browse files
committed
feat(workflow): Expose ActivityCancellationType
1 parent c69bb66 commit 45cc42d

File tree

8 files changed

+27
-64
lines changed

8 files changed

+27
-64
lines changed

packages/test/src/activities/index.ts

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -66,21 +66,7 @@ async function signalSchedulingWorkflow(signalName: string) {
6666

6767
export async function fakeProgress(sleepIntervalMs = 1000): Promise<void> {
6868
await signalSchedulingWorkflow('activityStarted');
69-
try {
70-
await fakeProgressInner(sleepIntervalMs);
71-
} catch (err) {
72-
if (err instanceof CancelledError) {
73-
try {
74-
await signalSchedulingWorkflow('activityCancelled');
75-
} catch (signalErr) {
76-
if (signalErr.details !== 'workflow execution already completed') {
77-
// Throw to avoid calling /finish
78-
throw signalErr;
79-
}
80-
}
81-
}
82-
throw err;
83-
}
69+
await fakeProgressInner(sleepIntervalMs);
8470
}
8571

8672
export async function cancellableFetch(url: string, signalWorkflowOnCheckpoint = false): Promise<Uint8Array> {
@@ -108,16 +94,6 @@ export async function cancellableFetch(url: string, signalWorkflowOnCheckpoint =
10894
return Buffer.concat(chunks);
10995
} catch (err) {
11096
if (err.name === 'AbortError' && err.type === 'aborted') {
111-
if (signalWorkflowOnCheckpoint) {
112-
try {
113-
await signalSchedulingWorkflow('activityCancelled');
114-
} catch (signalErr) {
115-
if (signalErr.details !== 'workflow execution already completed') {
116-
// Throw to avoid calling /finish
117-
throw signalErr;
118-
}
119-
}
120-
}
12197
await fetch(`${url}/finish`);
12298
}
12399
throw err;

packages/test/src/interfaces/index.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,13 @@ export interface ActivitySignalHandler extends Workflow {
6363
main(): Promise<void>;
6464
signals: {
6565
activityStarted(): void;
66-
activityCancelled(): void;
6766
};
6867
}
6968

7069
export interface CancellableHTTPRequest extends Workflow {
71-
main(url: string, completeOnActivityCancellation: boolean): Promise<void>;
70+
main(url: string): Promise<void>;
7271
signals: {
7372
activityStarted(): void;
74-
activityCancelled(): void;
7573
};
7674
}
7775

packages/test/src/test-integration.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,15 @@ if (RUN_INTEGRATION_TESTS) {
8787
t.pass();
8888
});
8989

90-
test("cancel-http-request don't waitForActivityCancelled", async (t) => {
90+
test('cancel-http-request', async (t) => {
9191
await withZeroesHTTPServer(async (port, finished) => {
9292
const client = new WorkflowClient();
9393
const url = `http://127.0.0.1:${port}`;
9494
const workflow = client.stub<CancellableHTTPRequest>('cancel-http-request', { taskQueue: 'test' });
95-
await t.throwsAsync(() => workflow.execute(url, false), {
96-
message: 'Activity cancelled',
97-
instanceOf: WorkflowExecutionFailedError,
98-
});
95+
await workflow.execute(url);
9996
await finished;
10097
});
98+
t.pass();
10199
});
102100

103101
test('activity-failure', async (t) => {

packages/test/src/workflows/cancel-fake-progress.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
1-
import { Context, CancelledError, CancellationScope, sleep, Trigger } from '@temporalio/workflow';
1+
import { ActivityCancellationType, Context, CancelledError, CancellationScope, Trigger } from '@temporalio/workflow';
22
import { ActivitySignalHandler } from '../interfaces';
33
import * as activities from '@activities';
44

55
const fakeProgress = Context.configure(activities.fakeProgress, {
66
type: 'remote',
77
startToCloseTimeout: '200s',
88
heartbeatTimeout: '2s',
9+
cancellationType: ActivityCancellationType.WAIT_CANCELLATION_COMPLETED,
910
});
1011

1112
const activityStarted = new Trigger<void>();
12-
const activityCancelled = new Trigger<void>();
1313

1414
const signals = {
1515
activityStarted(): void {
1616
activityStarted.resolve();
1717
},
18-
activityCancelled(): void {
19-
activityCancelled.resolve();
20-
},
2118
};
2219

2320
async function main(): Promise<void> {
@@ -30,15 +27,7 @@ async function main(): Promise<void> {
3027
});
3128
throw new Error('Activity completed instead of being cancelled');
3229
} catch (err) {
33-
if (err instanceof CancelledError) {
34-
await Promise.race([
35-
activityCancelled,
36-
CancellationScope.nonCancellable(async () => {
37-
await sleep(100000);
38-
throw new Error('Confirmation of activity cancellation never arrived');
39-
}),
40-
]);
41-
} else {
30+
if (!(err instanceof CancelledError)) {
4231
throw err;
4332
}
4433
}

packages/test/src/workflows/cancel-http-request.ts

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,23 @@
1-
import { Context, CancellationScope, CancelledError, sleep, Trigger } from '@temporalio/workflow';
1+
import { ActivityCancellationType, Context, CancellationScope, CancelledError, Trigger } from '@temporalio/workflow';
22
import { CancellableHTTPRequest } from '../interfaces';
33
import { cancellableFetch } from '@activities';
44

55
const fetch = Context.configure(cancellableFetch, {
66
type: 'remote',
77
startToCloseTimeout: '20s',
88
heartbeatTimeout: '3s',
9+
cancellationType: ActivityCancellationType.WAIT_CANCELLATION_COMPLETED,
910
});
1011

1112
const activityStarted = new Trigger<void>();
12-
const activityCancelled = new Trigger<void>();
1313

1414
const signals = {
1515
activityStarted(): void {
1616
activityStarted.resolve();
1717
},
18-
activityCancelled(): void {
19-
activityCancelled.resolve();
20-
},
2118
};
2219

23-
async function main(url: string, waitForActivityCancelled: boolean): Promise<void> {
20+
async function main(url: string): Promise<void> {
2421
try {
2522
await CancellationScope.cancellable(async () => {
2623
const promise = fetch(url, true);
@@ -29,18 +26,9 @@ async function main(url: string, waitForActivityCancelled: boolean): Promise<voi
2926
await promise;
3027
});
3128
} catch (err) {
32-
if (err instanceof CancelledError) {
33-
if (waitForActivityCancelled) {
34-
await Promise.race([
35-
activityCancelled,
36-
CancellationScope.nonCancellable(async () => {
37-
await sleep(10000);
38-
throw new Error('Confirmation of activity cancellation never arrived');
39-
}),
40-
]);
41-
}
29+
if (!(err instanceof CancelledError)) {
30+
throw err;
4231
}
43-
throw err;
4432
}
4533
}
4634

packages/workflow/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import './global-overrides';
5252

5353
export {
54+
ActivityCancellationType,
5455
ActivityFunction,
5556
ActivityOptions,
5657
ApplyMode,

packages/workflow/src/interfaces.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@ Note that the Temporal Server doesn't detect Worker process failures directly. I
7272
* @format {@link https://www.npmjs.com/package/ms | ms} formatted string or number of milliseconds
7373
*/
7474
scheduleToCloseTimeout?: string | number;
75+
76+
/**
77+
* Determines what the SDK does when the Activity is cancelled.
78+
* - `TRY_CANCEL` - Initiate a cancellation request and immediately report cancellation to the workflow.
79+
* - `WAIT_CANCELLATION_COMPLETED` - Wait for activity cancellation completion. Note that activity must heartbeat to receive a
80+
* cancellation notification. This can block the cancellation for a long time if activity doesn't
81+
* heartbeat or chooses to ignore the cancellation request.
82+
* - `ABANDON` - Do not request cancellation of the activity and immediately report cancellation to the workflow.
83+
*/
84+
cancellationType?: coresdk.workflow_commands.ActivityCancellationType;
7585
}
7686

7787
/**
@@ -208,3 +218,5 @@ export interface ContinueAsNewOptions {
208218
*/
209219
searchAttributes?: Record<string, any>;
210220
}
221+
222+
export const ActivityCancellationType = coresdk.workflow_commands.ActivityCancellationType;

packages/workflow/src/workflow.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ async function scheduleActivityNextHandler({
144144
scheduleToStartTimeout: msOptionalToTs(options.scheduleToStartTimeout),
145145
namespace: options.namespace,
146146
headerFields: Object.fromEntries(headers.entries()),
147+
cancellationType: options.cancellationType,
147148
},
148149
});
149150
});

0 commit comments

Comments
 (0)