@temporalio/worker
Version:
Temporal.io SDK Worker sub-package
118 lines • 4.87 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VMWorkflow = exports.VMWorkflowCreator = void 0;
const node_assert_1 = __importDefault(require("node:assert"));
const node_url_1 = require("node:url");
const node_util_1 = require("node:util");
const node_async_hooks_1 = require("node:async_hooks");
const node_vm_1 = __importDefault(require("node:vm"));
const common_1 = require("@temporalio/common");
const core_bridge_1 = require("@temporalio/core-bridge");
const logger_1 = require("../logger");
const vm_shared_1 = require("./vm-shared");
/**
* A WorkflowCreator that creates VMWorkflows in the current isolate
*/
class VMWorkflowCreator {
constructor(script, workflowBundle, isolateExecutionTimeoutMs, registeredActivityNames) {
this.workflowBundle = workflowBundle;
this.isolateExecutionTimeoutMs = isolateExecutionTimeoutMs;
this.registeredActivityNames = registeredActivityNames;
if (!VMWorkflowCreator.unhandledRejectionHandlerHasBeenSet) {
(0, vm_shared_1.setUnhandledRejectionHandler)((runId) => VMWorkflowCreator.workflowByRunId.get(runId));
VMWorkflowCreator.unhandledRejectionHandlerHasBeenSet = true;
}
this.script = script;
}
/**
* Create a workflow with given options
*/
async createWorkflow(options) {
const context = await this.getContext();
this.injectConsole(context);
const { isolateExecutionTimeoutMs } = this;
const workflowModule = new Proxy({}, {
get(_, fn) {
return (...args) => {
context.__TEMPORAL__.args = args;
return node_vm_1.default.runInContext(`__TEMPORAL__.api.${fn}(...__TEMPORAL__.args)`, context, {
timeout: isolateExecutionTimeoutMs,
displayErrors: true,
});
};
},
});
workflowModule.initRuntime({
...options,
sourceMap: this.workflowBundle.sourceMap,
getTimeOfDay: () => (0, logger_1.timeOfDayToBigint)((0, core_bridge_1.getTimeOfDay)()),
registeredActivityNames: this.registeredActivityNames,
});
const activator = context.__TEMPORAL_ACTIVATOR__;
const newVM = new VMWorkflow(options.info.runId, context, activator, workflowModule);
VMWorkflowCreator.workflowByRunId.set(options.info.runId, newVM);
return newVM;
}
async getContext() {
if (this.script === undefined) {
throw new common_1.IllegalStateError('Isolate context provider was destroyed');
}
const globals = {
AsyncLocalStorage: node_async_hooks_1.AsyncLocalStorage,
URL: node_url_1.URL,
URLSearchParams: node_url_1.URLSearchParams,
assert: node_assert_1.default,
__webpack_module_cache__: {},
TextEncoder: node_util_1.TextEncoder,
TextDecoder: node_util_1.TextDecoder,
AbortController,
};
const context = node_vm_1.default.createContext(globals, { microtaskMode: 'afterEvaluate' });
this.script.runInContext(context);
return context;
}
/**
* Inject console.log and friends into a vm context.
*
* Overridable for test purposes.
*/
injectConsole(context) {
(0, vm_shared_1.injectConsole)(context);
}
/**
* Create a new instance, pre-compile scripts from given code.
*
* This method is generic to support subclassing.
*/
static async create(workflowBundle, isolateExecutionTimeoutMs, registeredActivityNames) {
vm_shared_1.globalHandlers.install();
await vm_shared_1.globalHandlers.addWorkflowBundle(workflowBundle);
const script = new node_vm_1.default.Script(workflowBundle.code, { filename: workflowBundle.filename });
return new this(script, workflowBundle, isolateExecutionTimeoutMs, registeredActivityNames);
}
/**
* Cleanup the pre-compiled script
*/
async destroy() {
vm_shared_1.globalHandlers.removeWorkflowBundle(this.workflowBundle);
delete this.script;
}
}
exports.VMWorkflowCreator = VMWorkflowCreator;
VMWorkflowCreator.unhandledRejectionHandlerHasBeenSet = false;
VMWorkflowCreator.workflowByRunId = new Map();
/**
* A Workflow implementation using Node.js' built-in `vm` module
*/
class VMWorkflow extends vm_shared_1.BaseVMWorkflow {
async dispose() {
this.workflowModule.dispose();
VMWorkflowCreator.workflowByRunId.delete(this.runId);
delete this.context;
}
}
exports.VMWorkflow = VMWorkflow;
//# sourceMappingURL=vm.js.map