@temporalio/workflow
Version:
Temporal.io SDK Workflow sub-package
277 lines (276 loc) • 11.8 kB
TypeScript
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 {};