Skip to content

Commit 46957e3

Browse files
authored
fix: Fix bug where cancelled workflow commands were unnecessarily sen… (#745)
1 parent ac1396a commit 46957e3

File tree

4 files changed

+44
-1
lines changed

4 files changed

+44
-1
lines changed

packages/test/src/integration-tests.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,4 +1191,23 @@ export function runIntegrationTests(codec?: PayloadCodec): void {
11911191
);
11921192
});
11931193
}
1194+
1195+
test('issue-731', async (t) => {
1196+
const { client } = t.context;
1197+
const workflowId = uuid4();
1198+
await client.execute(workflows.issue731, {
1199+
taskQueue: 'test',
1200+
workflowId,
1201+
workflowTaskTimeout: '1m', // Give our local activities enough time to run in CI
1202+
});
1203+
const { history } = await client.workflowService.getWorkflowExecutionHistory({
1204+
namespace: 'default',
1205+
execution: { workflowId },
1206+
});
1207+
if (history?.events == null) {
1208+
throw new Error('Expected non null events');
1209+
}
1210+
// Verify only one timer was scheduled
1211+
t.is(history.events.filter(({ timerStartedEventAttributes }) => timerStartedEventAttributes != null).length, 1);
1212+
});
11941213
}

packages/test/src/workflows/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export { interceptedChild, interceptorExample } from './interceptor-example';
4343
export { internalsInterceptorExample } from './internals-interceptor-example';
4444
export * from './interrupt-signal';
4545
export * from './invalid-or-failed-queries';
46+
export * from './issue-731';
4647
export * from './log-before-timing-out';
4748
export * from './log-sink-tester';
4849
export * from './long-history-generator';
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import * as wf from '@temporalio/workflow';
2+
import type * as activities from '../activities';
3+
4+
const { echo } = wf.proxyLocalActivities<typeof activities>({
5+
startToCloseTimeout: '1 minute',
6+
});
7+
8+
/**
9+
* Reproduces https://github.com/temporalio/sdk-typescript/issues/731
10+
*/
11+
export async function issue731(): Promise<void> {
12+
await wf.CancellationScope.cancellable(async () => {
13+
const localActivityPromise = echo('activity');
14+
const sleepPromise = wf.sleep('30s').then(() => 'timer');
15+
const result = await Promise.race([localActivityPromise, sleepPromise]);
16+
if (result === 'timer') {
17+
throw wf.ApplicationFailure.nonRetryable('Timer unexpectedly beat local activity');
18+
}
19+
wf.CancellationScope.current().cancel();
20+
});
21+
22+
await wf.sleep(100);
23+
}

0 commit comments

Comments
 (0)