UNPKG

@hotmeshio/hotmesh

Version:

Serverless Workflow

103 lines (102 loc) 4.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.startChild = exports.executeChild = exports.execChild = void 0; const common_1 = require("./common"); const context_1 = require("./context"); const didRun_1 = require("./didRun"); /** * Constructs the payload necessary to spawn a child workflow. * @private */ function getChildInterruptPayload(context, options, execIndex) { const { workflowId, originJobId, workflowDimension, expire } = context; let childJobId; if (options.workflowId) { childJobId = options.workflowId; } else if (options.entity) { childJobId = `${options.entity}-${(0, common_1.guid)()}-${workflowDimension}-${execIndex}`; } else { childJobId = `-${options.workflowName}-${(0, common_1.guid)()}-${workflowDimension}-${execIndex}`; } const parentWorkflowId = workflowId; const taskQueueName = options.taskQueue ?? options.entity; const workflowName = options.entity ?? options.workflowName; const workflowTopic = `${taskQueueName}-${workflowName}`; return { arguments: [...(options.args || [])], await: options?.await ?? true, backoffCoefficient: options?.config?.backoffCoefficient ?? common_1.HMSH_MESHFLOW_EXP_BACKOFF, index: execIndex, maximumAttempts: options?.config?.maximumAttempts ?? common_1.HMSH_MESHFLOW_MAX_ATTEMPTS, maximumInterval: (0, common_1.s)(options?.config?.maximumInterval ?? common_1.HMSH_MESHFLOW_MAX_INTERVAL), originJobId: originJobId ?? workflowId, expire: options.expire ?? expire, persistent: options.persistent, signalIn: options.signalIn, parentWorkflowId, workflowDimension: workflowDimension, workflowId: childJobId, workflowTopic, }; } /** * Spawns a child workflow and awaits the result, or if `await` is false, returns immediately. * @template T * @param {WorkflowOptions} options - Workflow options. * @returns {Promise<T>} Result of the child workflow. */ async function execChild(options) { const isStartChild = options.await === false; const prefix = isStartChild ? 'start' : 'child'; const [didRunAlready, execIndex, result] = await (0, didRun_1.didRun)(prefix); const context = (0, context_1.getContext)(); const { canRetry, interruptionRegistry } = context; if (didRunAlready) { if (result?.$error && (!result.$error.is_stream_error || !canRetry)) { if (options?.config?.throwOnError !== false) { const code = result.$error.code; const message = result.$error.message; const stack = result.$error.stack; if (code === common_1.HMSH_CODE_MESHFLOW_FATAL) { throw new common_1.MeshFlowFatalError(message, stack); } else if (code === common_1.HMSH_CODE_MESHFLOW_MAXED) { throw new common_1.MeshFlowMaxedError(message, stack); } else if (code === common_1.HMSH_CODE_MESHFLOW_TIMEOUT) { throw new common_1.MeshFlowTimeoutError(message, stack); } else { throw new common_1.MeshFlowRetryError(message, stack); } } return result.$error; } else if (!result?.$error) { return result.data; } } const interruptionMessage = getChildInterruptPayload(context, options, execIndex); interruptionRegistry.push({ code: common_1.HMSH_CODE_MESHFLOW_CHILD, ...interruptionMessage, }); await (0, common_1.sleepImmediate)(); throw new common_1.MeshFlowChildError(interruptionMessage); } exports.execChild = execChild; /** * Alias for execChild. */ exports.executeChild = execChild; /** * Spawns a child workflow and returns the child Job ID without awaiting its completion. * @param {WorkflowOptions} options - Workflow options. * @returns {Promise<string>} The child job ID. */ async function startChild(options) { return execChild({ ...options, await: false }); } exports.startChild = startChild;