UNPKG

@temporalio/workflow

Version:
277 lines (276 loc) 11.8 kB
import type { RawSourceMap } from 'source-map'; import { FailureConverter, PayloadConverter, HandlerUnfinishedPolicy, Workflow, WorkflowQueryAnnotatedType, WorkflowSignalAnnotatedType, WorkflowUpdateAnnotatedType, ProtoFailure, WorkflowUpdateType, WorkflowUpdateValidatorType } from '@temporalio/common'; import type { coresdk } from '@temporalio/proto'; import { RNG } from './alea'; import { RootCancellationScope } from './cancellation-scope'; import { QueryInput, SignalInput, UpdateInput, WorkflowExecuteInput, WorkflowInterceptors } from './interceptors'; import { DefaultSignalHandler, StackTraceFileLocation, WorkflowInfo, WorkflowCreateOptionsInternal, ActivationCompletion } from './interfaces'; import { type SinkCall } from './sinks'; import { SdkFlag } from './flags'; export interface Stack { formatted: string; structured: StackTraceFileLocation[]; } /** * Global store to track promise stacks for stack trace query */ export interface PromiseStackStore { childToParent: Map<Promise<unknown>, Set<Promise<unknown>>>; promiseToStack: Map<Promise<unknown>, Stack>; } export interface Completion { resolve(val: unknown): unknown; reject(reason: unknown): unknown; } export interface Condition { fn(): boolean; resolve(): void; } export type ActivationHandlerFunction<K extends keyof coresdk.workflow_activation.IWorkflowActivationJob> = (activation: NonNullable<coresdk.workflow_activation.IWorkflowActivationJob[K]>) => void; /** * Verifies all activation job handling methods are implemented */ export type ActivationHandler = { [P in keyof coresdk.workflow_activation.IWorkflowActivationJob]: ActivationHandlerFunction<P>; }; /** * Information about an update or signal handler execution. */ interface MessageHandlerExecution { name: string; unfinishedPolicy: HandlerUnfinishedPolicy; id?: string; } /** * Keeps all of the Workflow runtime state like pending completions for activities and timers. * * Implements handlers for all workflow activation jobs. * * Note that most methods in this class are meant to be called only from within the VM. * * However, a few methods may be called directly from outside the VM (essentially from `vm-shared.ts`). * These methods are specifically marked with a comment and require careful consideration, as the * execution context may not properly reflect that of the target workflow execution (e.g.: with Reusable * VMs, the `global` may not have been swapped to those of that workflow execution; the active microtask * queue may be that of the thread/process, rather than the queue of that VM context; etc). Consequently, * methods that are meant to be called from outside of the VM must not do any of the following: * * - Access any global variable; * - Create Promise objects, use async/await, or otherwise schedule microtasks; * - Call user-defined functions, including any form of interceptor. */ export declare class Activator implements ActivationHandler { /** * Cache for modules - referenced in reusable-vm.ts */ readonly moduleCache: Map<string, unknown>; /** * Map of task sequence to a Completion */ readonly completions: { timer: Map<number, Completion>; activity: Map<number, Completion>; childWorkflowStart: Map<number, Completion>; childWorkflowComplete: Map<number, Completion>; signalWorkflow: Map<number, Completion>; cancelWorkflow: Map<number, Completion>; }; /** * Holds buffered Update calls until a handler is registered */ readonly bufferedUpdates: coresdk.workflow_activation.IDoUpdate[]; /** * Holds buffered signal calls until a handler is registered */ readonly bufferedSignals: coresdk.workflow_activation.ISignalWorkflow[]; /** * Mapping of update name to handler and validator */ readonly updateHandlers: Map<string, WorkflowUpdateAnnotatedType>; /** * Mapping of signal name to handler */ readonly signalHandlers: Map<string, WorkflowSignalAnnotatedType>; /** * Mapping of in-progress updates to handler execution information. */ readonly inProgressUpdates: Map<string, MessageHandlerExecution>; /** * Mapping of in-progress signals to handler execution information. */ readonly inProgressSignals: Map<number, MessageHandlerExecution>; /** * A sequence number providing unique identifiers for signal handler executions. */ protected signalHandlerExecutionSeq: number; /** * A signal handler that catches calls for non-registered signal names. */ defaultSignalHandler?: DefaultSignalHandler; /** * Source map file for looking up the source files in response to __enhanced_stack_trace */ protected readonly sourceMap: RawSourceMap; /** * Whether or not to send the sources in enhanced stack trace query responses */ protected readonly showStackTraceSources: boolean; readonly promiseStackStore: PromiseStackStore; readonly rootScope: RootCancellationScope; /** * Mapping of query name to handler */ readonly queryHandlers: Map<string, WorkflowQueryAnnotatedType>; /** * Loaded in {@link initRuntime} */ readonly interceptors: Required<WorkflowInterceptors>; /** * Buffer that stores all generated commands, reset after each activation */ protected commands: coresdk.workflow_commands.IWorkflowCommand[]; /** * Stores all {@link condition}s that haven't been unblocked yet */ readonly blockedConditions: Map<number, Condition>; /** * Is this Workflow completed? * * A Workflow will be considered completed if it generates a command that the * system considers as a final Workflow command (e.g. * completeWorkflowExecution or failWorkflowExecution). */ completed: boolean; /** * Was this Workflow cancelled? */ protected cancelled: boolean; /** * The next (incremental) sequence to assign when generating completable commands */ nextSeqs: { timer: number; activity: number; childWorkflow: number; signalWorkflow: number; cancelWorkflow: number; condition: number; stack: number; }; /** * This is set every time the workflow executes an activation * May be accessed and modified from outside the VM. */ now: number; /** * Reference to the current Workflow, initialized when a Workflow is started */ workflow?: Workflow; /** * Information about the current Workflow * May be accessed from outside the VM. */ info: WorkflowInfo; /** * A deterministic RNG, used by the isolate's overridden Math.random */ random: RNG; payloadConverter: PayloadConverter; failureConverter: FailureConverter; /** * Patches we know the status of for this workflow, as in {@link patched} */ private readonly knownPresentPatches; /** * Patches we sent to core {@link patched} */ private readonly sentPatches; private readonly knownFlags; /** * Buffered sink calls per activation */ sinkCalls: SinkCall[]; /** * A nanosecond resolution time function, externally injected */ readonly getTimeOfDay: () => bigint; readonly registeredActivityNames: Set<string>; constructor({ info, now, showStackTraceSources, sourceMap, getTimeOfDay, randomnessSeed, registeredActivityNames, }: WorkflowCreateOptionsInternal); /** * May be invoked from outside the VM. */ mutateWorkflowInfo(fn: (info: WorkflowInfo) => WorkflowInfo): void; protected getStackTraces(): Stack[]; /** * May be invoked from outside the VM. */ getAndResetSinkCalls(): SinkCall[]; /** * Buffer a Workflow command to be collected at the end of the current activation. * * Prevents commands from being added after Workflow completion. */ pushCommand(cmd: coresdk.workflow_commands.IWorkflowCommand, complete?: boolean): void; concludeActivation(): ActivationCompletion; startWorkflowNextHandler({ args }: WorkflowExecuteInput): Promise<any>; startWorkflow(activation: coresdk.workflow_activation.IInitializeWorkflow): void; initializeWorkflow(activation: coresdk.workflow_activation.IInitializeWorkflow): void; cancelWorkflow(_activation: coresdk.workflow_activation.ICancelWorkflow): void; fireTimer(activation: coresdk.workflow_activation.IFireTimer): void; resolveActivity(activation: coresdk.workflow_activation.IResolveActivity): void; resolveNexusOperationStart(_activation: coresdk.workflow_activation.IResolveNexusOperationStart): void; resolveNexusOperation(_activation: coresdk.workflow_activation.IResolveNexusOperation): void; resolveChildWorkflowExecutionStart(activation: coresdk.workflow_activation.IResolveChildWorkflowExecutionStart): void; resolveChildWorkflowExecution(activation: coresdk.workflow_activation.IResolveChildWorkflowExecution): void; protected queryWorkflowNextHandler({ queryName, args }: QueryInput): Promise<unknown>; queryWorkflow(activation: coresdk.workflow_activation.IQueryWorkflow): void; doUpdate(activation: coresdk.workflow_activation.IDoUpdate): void; protected updateNextHandler(handler: WorkflowUpdateType, { args }: UpdateInput): Promise<unknown>; protected validateUpdateNextHandler(validator: WorkflowUpdateValidatorType | undefined, { args }: UpdateInput): void; dispatchBufferedUpdates(): void; rejectBufferedUpdates(): void; signalWorkflowNextHandler({ signalName, args }: SignalInput): Promise<void>; signalWorkflow(activation: coresdk.workflow_activation.ISignalWorkflow): void; dispatchBufferedSignals(): void; resolveSignalExternalWorkflow(activation: coresdk.workflow_activation.IResolveSignalExternalWorkflow): void; resolveRequestCancelExternalWorkflow(activation: coresdk.workflow_activation.IResolveRequestCancelExternalWorkflow): void; warnIfUnfinishedHandlers(): void; updateRandomSeed(activation: coresdk.workflow_activation.IUpdateRandomSeed): void; notifyHasPatch(activation: coresdk.workflow_activation.INotifyHasPatch): void; patchInternal(patchId: string, deprecated: boolean): boolean; /** * Called early while handling an activation to register known flags. * May be invoked from outside the VM. */ addKnownFlags(flags: number[]): void; /** * Check if an SDK Flag may be considered as enabled for the current Workflow Task. * * SDK flags play a role similar to the `patched()` API, but are meant for internal usage by the * SDK itself. They make it possible for the SDK to evolve its behaviors over time, while still * maintaining compatibility with Workflow histories produced by older SDKs, without causing * determinism violations. * * May be invoked from outside the VM. */ hasFlag(flag: SdkFlag): boolean; removeFromCache(): void; /** * Transforms failures into a command to be sent to the server. * Used to handle any failure emitted by the Workflow. */ handleWorkflowFailure(error: unknown): Promise<void>; private completeQuery; private failQuery; private acceptUpdate; private completeUpdate; private rejectUpdate; /** Consume a completion if it exists in Workflow state */ private maybeConsumeCompletion; /** Consume a completion if it exists in Workflow state, throws if it doesn't */ private consumeCompletion; private completeWorkflow; errorToFailure(err: unknown): ProtoFailure; failureToError(failure: ProtoFailure): Error; } export {};