@temporalio/workflow
Version:
Temporal.io SDK Workflow sub-package
578 lines (577 loc) • 24.2 kB
TypeScript
import type { RawSourceMap } from 'source-map';
import type { RetryPolicy, CommonWorkflowOptions, HandlerUnfinishedPolicy, SearchAttributes, SignalDefinition, UpdateDefinition, QueryDefinition, Duration, VersioningIntent, TypedSearchAttributes, SearchAttributePair, Priority, WorkerDeploymentVersion, VersioningBehavior, InitialVersioningBehavior, SuggestContinueAsNewReason } from '@temporalio/common';
import type { coresdk } from '@temporalio/proto';
/**
* Workflow Execution information
*/
export interface WorkflowInfo {
/**
* ID of the Workflow, this can be set by the client during Workflow creation.
* A single Workflow may run multiple times e.g. when scheduled with cron.
*/
readonly workflowId: string;
/**
* ID of a single Workflow run
*/
readonly runId: string;
/**
* Workflow function's name
*/
readonly workflowType: string;
/**
* Indexed information attached to the Workflow Execution
*
* This value may change during the lifetime of an Execution.
* @deprecated Use {@link typedSearchAttributes} instead.
*/
readonly searchAttributes: SearchAttributes;
/**
* Indexed information attached to the Workflow Execution, exposed through an interface.
*
* This value may change during the lifetime of an Execution.
*/
readonly typedSearchAttributes: TypedSearchAttributes;
/**
* Non-indexed information attached to the Workflow Execution
*/
readonly memo?: Record<string, unknown>;
/**
* Parent Workflow info (present if this is a Child Workflow)
*/
readonly parent?: ParentWorkflowInfo;
/**
* The root workflow execution, defined as follows:
* 1. A workflow without a parent workflow is its own root workflow.
* 2. A workflow with a parent workflow has the same root workflow as
* its parent.
*
* When there is no parent workflow, i.e., the workflow is its own root workflow,
* this field is `undefined`.
*
* Note that Continue-as-New (or reset) propagates the workflow parentage relationship,
* and therefore, whether the new workflow has the same root workflow as the original one
* depends on whether it had a parent.
*
*/
readonly root?: RootWorkflowInfo;
/**
* Result from the previous Run (present if this is a Cron Workflow or was Continued As New).
*
* An array of values, since other SDKs may return multiple values from a Workflow.
*/
readonly lastResult?: unknown;
/**
* Failure from the previous Run (present when this Run is a retry, or the last Run of a Cron Workflow failed)
*/
readonly lastFailure?: Error;
/**
* Length of Workflow history up until the current Workflow Task.
*
* This value changes during the lifetime of an Execution.
*
* You may safely use this information to decide when to {@link continueAsNew}.
*/
readonly historyLength: number;
/**
* Size of Workflow history in bytes until the current Workflow Task.
*
* This value changes during the lifetime of an Execution.
*
* Supported only on Temporal Server 1.20+, always zero on older servers.
*
* You may safely use this information to decide when to {@link continueAsNew}.
*/
readonly historySize: number;
/**
* A hint provided by the current WorkflowTaskStarted event recommending whether to
* {@link continueAsNew}.
*
* This value changes during the lifetime of an Execution.
*
* Supported only on Temporal Server 1.20+, always `false` on older servers.
*/
readonly continueAsNewSuggested: boolean;
/**
* Whether the workflow's Target Worker Deployment Version has changed from its Pinned Version.
* When true, the workflow should consider continuing-as-new with
* `initialVersioningBehavior: 'AUTO_UPGRADE'` to move to the new version.
*
* This value changes during the lifetime of an Execution.
*
* @experimental Upgrade-on-Continue-as-New is experimental and may change.
*/
readonly targetWorkerDeploymentVersionChanged: boolean;
/**
* Reason(s) why continue as new is suggested. Can potentially be multiple reasons.
*
* @experimental May be removed or changed in the future.
*/
readonly suggestedContinueAsNewReasons?: SuggestContinueAsNewReason[];
/**
* Task queue this Workflow is executing on
*/
readonly taskQueue: string;
/**
* Namespace this Workflow is executing in
*/
readonly namespace: string;
/**
* Run Id of the first Run in this Execution Chain
*/
readonly firstExecutionRunId: string;
/**
* The last Run Id in this Execution Chain
*/
readonly continuedFromExecutionRunId?: string;
/**
* Time at which this [Workflow Execution Chain](https://docs.temporal.io/workflows#workflow-execution-chain) was started
*/
readonly startTime: Date;
/**
* Time at which the current Workflow Run started
*/
readonly runStartTime: Date;
/**
* Milliseconds after which the Workflow Execution is automatically terminated by Temporal Server. Set via {@link WorkflowOptions.workflowExecutionTimeout}.
*/
readonly executionTimeoutMs?: number;
/**
* Time at which the Workflow Execution expires
*/
readonly executionExpirationTime?: Date;
/**
* Milliseconds after which the Workflow Run is automatically terminated by Temporal Server. Set via {@link WorkflowOptions.workflowRunTimeout}.
*/
readonly runTimeoutMs?: number;
/**
* Maximum execution time of a Workflow Task in milliseconds. Set via {@link WorkflowOptions.workflowTaskTimeout}.
*/
readonly taskTimeoutMs: number;
/**
* Retry Policy for this Execution. Set via {@link WorkflowOptions.retry}.
*/
readonly retryPolicy?: RetryPolicy;
/**
* Starts at 1 and increments for every retry if there is a `retryPolicy`
*/
readonly attempt: number;
/**
* Cron Schedule for this Execution. Set via {@link WorkflowOptions.cronSchedule}.
*/
readonly cronSchedule?: string;
/**
* Milliseconds between Cron Runs
*/
readonly cronScheduleToScheduleInterval?: number;
/**
* The Build ID of the worker which executed the current Workflow Task. May be undefined if the
* task was completed by a worker without a Build ID. If this worker is the one executing this
* task for the first time and has a Build ID set, then its ID will be used. This value may change
* over the lifetime of the workflow run, but is deterministic and safe to use for branching.
*
* @deprecated Use `currentDeploymentVersion` instead
*/
readonly currentBuildId?: string;
/**
* The Deployment Version of the worker which executed the current Workflow Task. May be undefined
* if the task was completed by a worker without a Deployment Version. If this worker is the one
* executing this task for the first time and has a Deployment Version set, then its ID will be
* used. This value may change over the lifetime of the workflow run, but is deterministic and
* safe to use for branching.
*/
readonly currentDeploymentVersion?: WorkerDeploymentVersion;
readonly unsafe: UnsafeWorkflowInfo;
/**
* Priority of this workflow
*/
readonly priority?: Priority;
}
/**
* Unsafe information about the current Workflow Execution.
*
* Never rely on this information in Workflow logic as it will cause non-deterministic behavior.
*/
export interface UnsafeWorkflowInfo {
/**
* Current system time in milliseconds
*
* The safe version of time is `new Date()` and `Date.now()`, which are set on the first invocation of a Workflow
* Task and stay constant for the duration of the Task and during replay.
*/
readonly now: () => number;
/**
* Whether the workflow is currently replaying.
*/
readonly isReplaying: boolean;
/**
* Whether the workflow is currently replaying history events.
*
* This is similar to {@link isReplaying}, but returns `false` during query handlers and update
* validators, which are live read-only operations that should not be considered as replaying
* history events.
*
* When this property is true, workflow log messages are suppressed and sinks defined with
* callDuringReplay=false won't get processed.
*/
readonly isReplayingHistoryEvents: boolean;
}
/**
* Information about a workflow update.
*/
export interface UpdateInfo {
/**
* A workflow-unique identifier for this update.
*/
readonly id: string;
/**
* The update type name.
*/
readonly name: string;
}
export interface ParentWorkflowInfo {
workflowId: string;
runId: string;
namespace: string;
}
export interface RootWorkflowInfo {
workflowId: string;
runId: string;
}
/**
* Not an actual error, used by the Workflow runtime to abort execution when {@link continueAsNew} is called
*/
export declare class ContinueAsNew extends Error {
readonly command: coresdk.workflow_commands.IContinueAsNewWorkflowExecution;
constructor(command: coresdk.workflow_commands.IContinueAsNewWorkflowExecution);
}
/**
* Options for continuing a Workflow as new
*/
export interface ContinueAsNewOptions {
/**
* A string representing the Workflow type name, e.g. the filename in the Node.js SDK or class name in Java
*/
workflowType?: string;
/**
* Task queue to continue the Workflow in
*/
taskQueue?: string;
/**
* Timeout for the entire Workflow run
* @format {@link https://www.npmjs.com/package/ms | ms-formatted string}
*/
workflowRunTimeout?: Duration;
/**
* Timeout for a single Workflow task
* @format {@link https://www.npmjs.com/package/ms | ms-formatted string}
*/
workflowTaskTimeout?: Duration;
/**
* Non-searchable attributes to attach to next Workflow run
*/
memo?: Record<string, unknown>;
/**
* Searchable attributes to attach to next Workflow run
* @deprecated Use {@link typedSearchAttributes} instead.
*/
searchAttributes?: SearchAttributes;
/**
* Specifies additional indexed information to attach to the Workflow Execution. More info:
* https://docs.temporal.io/docs/typescript/search-attributes
*
* Values are always converted using {@link JsonPayloadConverter}, even when a custom data converter is provided.
* Note that search attributes are not encoded, as such, do not include any sensitive information.
*
* If both {@link searchAttributes} and {@link typedSearchAttributes} are provided, conflicting keys will be overwritten
* by {@link typedSearchAttributes}.
*/
typedSearchAttributes?: SearchAttributePair[] | TypedSearchAttributes;
/**
* When using the Worker Versioning feature, specifies whether this Workflow should
* Continue-as-New onto a worker with a compatible Build Id or not. See {@link VersioningIntent}.
*
* @default 'COMPATIBLE'
*
* @deprecated Worker Versioning is now deprecated. Please use the Worker Deployment API instead: https://docs.temporal.io/worker-deployments
*/
versioningIntent?: VersioningIntent;
/**
* Defines the versioning behavior to be used by the first task of a new workflow run in a continue-as-new chain.
*
* @experimental Versioning semantics with continue-as-new are experimental and may change in the future.
*/
initialVersioningBehavior?: InitialVersioningBehavior;
}
/**
* Determines:
* - whether cancellation requests should be propagated from the Parent Workflow to the Child, and
* - whether and when should the Child's cancellation be reported back to the Parent Workflow
* (i.e. at which moment should the {@link executeChild}'s or {@link ChildWorkflowHandle.result}'s
* promise fail with a `ChildWorkflowFailure`, with `cause` set to a `CancelledFailure`).
*
* Note that this setting only applies to cancellation originating from an external request for the
* Parent Workflow itself, or from internal cancellation of the `CancellationScope` in which the
* Child Workflow call was made. Eventual Cancellation of a Child Workflow on completion of the
* Parent Workflow is controlled by the {@link ParentClosePolicy} setting.
*
* @default ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED
*/
export declare const ChildWorkflowCancellationType: {
/**
* Do not propagate cancellation requests to the Child, and immediately report cancellation
* to the caller.
*/
readonly ABANDON: "ABANDON";
/**
* Propagate cancellation request from the Parent Workflow to the Child, yet _immediately_ report
* cancellation to the caller, i.e. without waiting for the server to confirm the cancellation
* request.
*
* Note that this cancellation type provides no guarantee, from the Parent-side, that the
* cancellation request will actually be atomically added to the Child workflow's history.
* In particular, the Child may complete (either successfully or uncessfully) before the
* cancellation is delivered, resulting in a situation where the Parent workflow thinks its child
* was cancelled, but the child actually completed successfully.
*
* To guarantee that the Child will eventually be notified of the cancellation request,
* use {@link WAIT_CANCELLATION_REQUESTED}.
*/
readonly TRY_CANCEL: "TRY_CANCEL";
/**
* Propagate cancellation request from the Parent Workflow to the Child, then wait for the server
* to confirm that the Child Workflow cancellation request was recorded in its history.
*
* This cancellation type guarantees that the Child will eventually be notified of the
* cancellation request (that is, unless the Child terminates inbetween due to unexpected causes).
*/
readonly WAIT_CANCELLATION_REQUESTED: "WAIT_CANCELLATION_REQUESTED";
/**
* Propagate cancellation request from the Parent Workflow to the Child, then wait for completion
* of the Child Workflow.
*
* The Child may respect cancellation, in which case the Parent's `executeChild` or
* `ChildWorkflowHandle.result` promise will fail with a `ChildWorkflowFailure`, with `cause`
* set to a `CancelledFailure`. On the other hand, the Child may ignore the cancellation request,
* in which case the corresponding promise will either resolve with a result (if Child completed
* successfully) or reject with a different cause (if Child completed uncessfully).
*
* @default
*/
readonly WAIT_CANCELLATION_COMPLETED: "WAIT_CANCELLATION_COMPLETED";
};
export type ChildWorkflowCancellationType = (typeof ChildWorkflowCancellationType)[keyof typeof ChildWorkflowCancellationType];
export declare const encodeChildWorkflowCancellationType: (input: coresdk.child_workflow.ChildWorkflowCancellationType | import("@temporalio/common/lib/type-helpers").RemovePrefix<"", "ABANDON" | "TRY_CANCEL" | "WAIT_CANCELLATION_REQUESTED" | "WAIT_CANCELLATION_COMPLETED"> | null | undefined) => coresdk.child_workflow.ChildWorkflowCancellationType | undefined, decodeChildWorkflowCancellationType: (input: coresdk.child_workflow.ChildWorkflowCancellationType | null | undefined) => import("@temporalio/common/lib/type-helpers").RemovePrefix<"", "ABANDON" | "TRY_CANCEL" | "WAIT_CANCELLATION_REQUESTED" | "WAIT_CANCELLATION_COMPLETED"> | undefined;
/**
* How a Child Workflow reacts to the Parent Workflow reaching a Closed state.
*
* @see {@link https://docs.temporal.io/concepts/what-is-a-parent-close-policy/ | Parent Close Policy}
*/
export declare const ParentClosePolicy: {
/**
* When the Parent is Closed, the Child is Terminated.
*
* @default
*/
readonly TERMINATE: "TERMINATE";
/**
* When the Parent is Closed, nothing is done to the Child.
*/
readonly ABANDON: "ABANDON";
/**
* When the Parent is Closed, the Child is Cancelled.
*/
readonly REQUEST_CANCEL: "REQUEST_CANCEL";
/**
* If a `ParentClosePolicy` is set to this, or is not set at all, the server default value will be used.
*
* @deprecated Either leave property `undefined`, or set an explicit policy instead.
*/
readonly PARENT_CLOSE_POLICY_UNSPECIFIED: undefined;
/**
* When the Parent is Closed, the Child is Terminated.
*
* @deprecated Use {@link ParentClosePolicy.TERMINATE} instead.
*/
readonly PARENT_CLOSE_POLICY_TERMINATE: "TERMINATE";
/**
* When the Parent is Closed, nothing is done to the Child.
*
* @deprecated Use {@link ParentClosePolicy.ABANDON} instead.
*/
readonly PARENT_CLOSE_POLICY_ABANDON: "ABANDON";
/**
* When the Parent is Closed, the Child is Cancelled.
*
* @deprecated Use {@link ParentClosePolicy.REQUEST_CANCEL} instead.
*/
readonly PARENT_CLOSE_POLICY_REQUEST_CANCEL: "REQUEST_CANCEL";
};
export type ParentClosePolicy = (typeof ParentClosePolicy)[keyof typeof ParentClosePolicy];
export declare const encodeParentClosePolicy: (input: "ABANDON" | "TERMINATE" | "REQUEST_CANCEL" | "PARENT_CLOSE_POLICY_TERMINATE" | "PARENT_CLOSE_POLICY_ABANDON" | "PARENT_CLOSE_POLICY_REQUEST_CANCEL" | coresdk.child_workflow.ParentClosePolicy | null | undefined) => coresdk.child_workflow.ParentClosePolicy | undefined, decodeParentClosePolicy: (input: coresdk.child_workflow.ParentClosePolicy | null | undefined) => "ABANDON" | "TERMINATE" | "REQUEST_CANCEL" | undefined;
export interface ChildWorkflowOptions extends Omit<CommonWorkflowOptions, 'workflowIdConflictPolicy'> {
/**
* Workflow id to use when starting. If not specified a UUID is generated. Note that it is
* dangerous as in case of client side retries no deduplication will happen based on the
* generated id. So prefer assigning business meaningful ids if possible.
*/
workflowId?: string;
/**
* Task queue to use for Workflow tasks. It should match a task queue specified when creating a
* `Worker` that hosts the Workflow code.
*
* By default, a child is scheduled on the same Task Queue as the parent.
*/
taskQueue?: string;
/**
* Determines:
* - whether cancellation requests should be propagated from the Parent Workflow to the Child, and
* - whether and when should the Child's cancellation be reported back to the Parent Workflow
* (i.e. at which moment should the {@link executeChild}'s or {@link ChildWorkflowHandle.result}'s
* promise fail with a `ChildWorkflowFailure`, with `cause` set to a `CancelledFailure`).
*
* Note that this setting only applies to cancellation originating from an external request for the
* Parent Workflow itself, or from internal cancellation of the `CancellationScope` in which the
* Child Workflow call was made. Eventual Cancellation of a Child Workflow on completion of the
* Parent Workflow is controlled by the {@link ParentClosePolicy} setting.
*
* @default ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED
*/
cancellationType?: ChildWorkflowCancellationType;
/**
* Specifies how the Child reacts to the Parent Workflow reaching a Closed state.
*
* @default ParentClosePolicy.PARENT_CLOSE_POLICY_TERMINATE
*/
parentClosePolicy?: ParentClosePolicy;
/**
* When using the Worker Versioning feature, specifies whether this Child Workflow should run on
* a worker with a compatible Build Id or not. See {@link VersioningIntent}.
*
* @default 'COMPATIBLE'
*
* @deprecated Worker Versioning is now deprecated. Please use the Worker Deployment API instead: https://docs.temporal.io/worker-deployments
*/
versioningIntent?: VersioningIntent;
}
export type RequiredChildWorkflowOptions = Required<Pick<ChildWorkflowOptions, 'workflowId' | 'cancellationType'>> & {
args: unknown[];
};
export type ChildWorkflowOptionsWithDefaults = ChildWorkflowOptions & RequiredChildWorkflowOptions;
export interface StackTraceSDKInfo {
name: string;
version: string;
}
/**
* Represents a slice of a file starting at lineOffset
*/
export interface StackTraceFileSlice {
/**
* Only used possible to trim the file without breaking syntax highlighting.
*/
line_offset: number;
/**
* slice of a file with `\n` (newline) line terminator.
*/
content: string;
}
/**
* A pointer to a location in a file
*/
export interface StackTraceFileLocation {
/**
* Path to source file (absolute or relative).
* When using a relative path, make sure all paths are relative to the same root.
*/
file_path?: string;
/**
* If possible, SDK should send this, required for displaying the code location.
*/
line?: number;
/**
* If possible, SDK should send this.
*/
column?: number;
/**
* Function name this line belongs to (if applicable).
* Used for falling back to stack trace view.
*/
function_name?: string;
/**
* Flag to mark this as internal SDK code and hide by default in the UI.
*/
internal_code: boolean;
}
export interface StackTrace {
locations: StackTraceFileLocation[];
}
/**
* Used as the result for the enhanced stack trace query
*/
export interface EnhancedStackTrace {
sdk: StackTraceSDKInfo;
/**
* Mapping of file path to file contents.
* SDK may choose to send no, some or all sources.
* Sources might be trimmed, and some time only the file(s) of the top element of the trace will be sent.
*/
sources: Record<string, StackTraceFileSlice[]>;
stacks: StackTrace[];
}
export interface WorkflowCreateOptions {
info: WorkflowInfo;
randomnessSeed: number[];
now: number;
showStackTraceSources: boolean;
}
export interface WorkflowCreateOptionsInternal extends WorkflowCreateOptions {
sourceMap: RawSourceMap;
registeredActivityNames: Set<string>;
getTimeOfDay(): bigint;
stackTracesEnabled: boolean;
}
/**
* A handler function capable of accepting the arguments for a given UpdateDefinition, SignalDefinition or QueryDefinition.
*/
export type Handler<Ret, Args extends any[], T extends UpdateDefinition<Ret, Args> | SignalDefinition<Args> | QueryDefinition<Ret, Args>> = T extends UpdateDefinition<infer R, infer A> ? (...args: A) => R | Promise<R> : T extends SignalDefinition<infer A> ? (...args: A) => void | Promise<void> : T extends QueryDefinition<infer R, infer A> ? (...args: A) => R : never;
/**
* A handler function accepting signal calls for non-registered signal names.
*/
export type DefaultSignalHandler = (signalName: string, ...args: unknown[]) => void | Promise<void>;
/**
* A handler function accepting update calls for non-registered update names.
*/
export type DefaultUpdateHandler = (updateName: string, ...args: unknown[]) => Promise<unknown> | unknown;
/**
* A handler function accepting query calls for non-registered query names.
*/
export type DefaultQueryHandler = (queryName: string, ...args: unknown[]) => unknown;
/**
* A validation function capable of accepting the arguments for a given UpdateDefinition.
*/
export type UpdateValidator<Args extends any[]> = (...args: Args) => void;
/**
* A description of a query handler.
*/
export type QueryHandlerOptions = {
description?: string;
};
/**
* A description of a signal handler.
*/
export type SignalHandlerOptions = {
description?: string;
unfinishedPolicy?: HandlerUnfinishedPolicy;
};
/**
* A validator and description of an update handler.
*/
export type UpdateHandlerOptions<Args extends any[]> = {
validator?: UpdateValidator<Args>;
description?: string;
unfinishedPolicy?: HandlerUnfinishedPolicy;
};
export interface ActivationCompletion {
commands: coresdk.workflow_commands.IWorkflowCommand[];
usedInternalFlags: number[];
versioningBehavior?: VersioningBehavior;
}