From 88c9450f6aba5cc92a1cd76609de594d0c89b069 Mon Sep 17 00:00:00 2001 From: Luke Ramsden Date: Thu, 28 Nov 2024 12:14:40 +0000 Subject: [PATCH] feat(worker): expose AbortController to the worker sandbox --- .../test-worker-exposes-abortcontroller.ts | 23 +++++++++++++++++++ .../test/src/workflows/abort-controller.ts | 16 +++++++++++++ packages/test/src/workflows/index.ts | 1 + packages/worker/src/workflow/reusable-vm.ts | 1 + packages/worker/src/workflow/vm.ts | 1 + 5 files changed, 42 insertions(+) create mode 100644 packages/test/src/test-worker-exposes-abortcontroller.ts create mode 100644 packages/test/src/workflows/abort-controller.ts diff --git a/packages/test/src/test-worker-exposes-abortcontroller.ts b/packages/test/src/test-worker-exposes-abortcontroller.ts new file mode 100644 index 000000000..259f2e2c8 --- /dev/null +++ b/packages/test/src/test-worker-exposes-abortcontroller.ts @@ -0,0 +1,23 @@ +import test from 'ava'; +import { v4 as uuid4 } from 'uuid'; +import { Client } from '@temporalio/client'; +import { RUN_INTEGRATION_TESTS, Worker } from './helpers'; +import { defaultOptions } from './mock-native-worker'; +import { abortController } from './workflows'; + + +if (RUN_INTEGRATION_TESTS) { + test(`Worker runtime exposes AbortController as a global`, async (t) => { + const worker = await Worker.create({ ...defaultOptions, taskQueue: 'test-worker-exposes-abortcontroller' }); + const client = new Client(); + const result = await worker.runUntil( + client.workflow.execute(abortController, { + args: [], + taskQueue: 'test-worker-exposes-abortcontroller', + workflowId: uuid4(), + workflowExecutionTimeout: '5s', + }) + ); + t.is(result, 'abort successful'); + }); +} diff --git a/packages/test/src/workflows/abort-controller.ts b/packages/test/src/workflows/abort-controller.ts new file mode 100644 index 000000000..f2e501bbd --- /dev/null +++ b/packages/test/src/workflows/abort-controller.ts @@ -0,0 +1,16 @@ +export async function abortController(): Promise { + let aborted: string | null = null; + + const controller = new AbortController(); + const { signal } = controller; + + const abortEventListener = () => { + aborted = signal.reason; + }; + + signal.addEventListener("abort", abortEventListener); + controller.abort("abort successful"); + signal.removeEventListener("abort", abortEventListener); + + return aborted; +} diff --git a/packages/test/src/workflows/index.ts b/packages/test/src/workflows/index.ts index 45c5c1ff5..5f20c90ad 100644 --- a/packages/test/src/workflows/index.ts +++ b/packages/test/src/workflows/index.ts @@ -1,3 +1,4 @@ +export * from './abort-controller'; export * from './activity-failure'; export * from './activity-failures'; export * from './args-and-return'; diff --git a/packages/worker/src/workflow/reusable-vm.ts b/packages/worker/src/workflow/reusable-vm.ts index 885ee679a..52b7713f6 100644 --- a/packages/worker/src/workflow/reusable-vm.ts +++ b/packages/worker/src/workflow/reusable-vm.ts @@ -78,6 +78,7 @@ export class ReusableVMWorkflowCreator implements WorkflowCreator { __webpack_module_cache__, TextEncoder, TextDecoder, + AbortController, }; this._context = vm.createContext(globals, { microtaskMode: 'afterEvaluate' }); this.injectConsole(); diff --git a/packages/worker/src/workflow/vm.ts b/packages/worker/src/workflow/vm.ts index fea1cb339..c986e9005 100644 --- a/packages/worker/src/workflow/vm.ts +++ b/packages/worker/src/workflow/vm.ts @@ -86,6 +86,7 @@ export class VMWorkflowCreator implements WorkflowCreator { __webpack_module_cache__: {}, TextEncoder, TextDecoder, + AbortController, }; const context = vm.createContext(globals, { microtaskMode: 'afterEvaluate' }); this.script.runInContext(context);