Class Workflow
- java.lang.Object
-
- io.temporal.workflow.Workflow
-
public final class Workflow extends java.lang.Object
This class contains methods exposing Temporal API for Workflows, like- Creation and scheduling of activities, child workflows, external workflows, continue-as-new runs
- Operations over workflow elements, like Side Effects, Timers, Versions,
CancellationScope
- Accessing and updating of the workflow data, like
WorkflowInfo
, Memos and Search Attributes - Deterministic implementation of popular non-deterministic API working with time, logging and generation of random values
For an overview of Temporal JavaSDK Workflows, see
io.temporal.workflow
For methods providing Temporal Workflow alternatives to threading and asynchronous invocations, see
Async
- See Also:
io.temporal.workflow
-
-
Field Summary
Fields Modifier and Type Field Description static int
DEFAULT_VERSION
-
Method Summary
All Methods Static Methods Concrete Methods Deprecated Methods Modifier and Type Method Description static void
applyActivityOptions(java.util.Map<java.lang.String,ActivityOptions> activityTypeToOptions)
Adds activity options per activity type that will be used for an activity stub that has noActivityOptions
specified.
This method refines an original set ofMap<String, ActivityOptions>
provided byWorkflowImplementationOptions.getActivityOptions()
These more specific options take precedence over more generic settingsetDefaultActivityOptions(io.temporal.activity.ActivityOptions)
static void
applyLocalActivityOptions(java.util.Map<java.lang.String,LocalActivityOptions> activityTypeToOptions)
Adds local activity options per activity type that will be used for a local activity stub that has noLocalActivityOptions
specified.
This method refines an original set ofMap<String, LocalActivityOptions>
provided byWorkflowImplementationOptions.getLocalActivityOptions()
These more specific options take precedence over more generic settingsetDefaultLocalActivityOptions(io.temporal.activity.LocalActivityOptions)
static boolean
await(java.time.Duration timeout, java.util.function.Supplier<java.lang.Boolean> unblockCondition)
Block current workflow thread until unblockCondition is evaluated to true or timeoutMillis passes.static void
await(java.util.function.Supplier<java.lang.Boolean> unblockCondition)
Block current thread until unblockCondition is evaluated to true.static void
continueAsNew(ContinueAsNewOptions options, java.lang.Object... args)
Continues the current workflow execution as a new run with the same workflowType and overriddenoptions
.static void
continueAsNew(java.lang.Object... args)
Continues the current workflow execution as a new run with the same options.static void
continueAsNew(java.lang.String workflowType, ContinueAsNewOptions options, java.lang.Object... args)
Continues the current workflow execution as a new run possibly overriding the workflow type and options.static void
continueAsNew(java.util.Optional<java.lang.String> workflowType, java.util.Optional<ContinueAsNewOptions> options, java.lang.Object... args)
Deprecated.static long
currentTimeMillis()
Must be used to get current time instead ofSystem.currentTimeMillis()
to guarantee determinism.static WorkflowInfo
getInfo()
static <R> R
getLastCompletionResult(java.lang.Class<R> resultClass)
GetLastCompletionResult extract last completion result from previous run for this cron workflow.static <R> R
getLastCompletionResult(java.lang.Class<R> resultClass, java.lang.reflect.Type resultType)
GetLastCompletionResult extract last completion result from previous run for this cron workflow.static org.slf4j.Logger
getLogger(java.lang.Class<?> clazz)
Get logger to use inside workflow.static org.slf4j.Logger
getLogger(java.lang.String name)
Get logger to use inside workflow.static <T> java.lang.Object
getMemo(java.lang.String key, java.lang.Class<T> valueClass)
Extract deserialized Memo associated with given keystatic <T> T
getMemo(java.lang.String key, java.lang.Class<T> valueClass, java.lang.reflect.Type genericType)
Extract Memo associated with the given key and deserialized into an object of generic type as is done here:DataConverter.fromPayloads(int, java.util.Optional, java.lang.Class, java.lang.reflect.Type)
Ex: To deserialize intoHashMap<String, Integer>
Workflow.getMemo(key, Map.class, new TypeToken<HashMap<String, Integer>>() {}.getType())
static com.uber.m3.tally.Scope
getMetricsScope()
Get scope for reporting business metrics in workflow logic.static java.util.Optional<java.lang.Exception>
getPreviousRunFailure()
Extract the latest failure from a previous run of this workflow.static <T> T
getSearchAttribute(java.lang.String name)
Deprecated.usegetTypedSearchAttributes()
instead.static java.util.Map<java.lang.String,java.util.List<?>>
getSearchAttributes()
Deprecated.usegetTypedSearchAttributes()
instead.static <T> java.util.List<T>
getSearchAttributeValues(java.lang.String name)
Deprecated.usegetTypedSearchAttributes()
instead.static SearchAttributes
getTypedSearchAttributes()
Get immutable set of search attributes.static int
getVersion(java.lang.String changeId, int minSupported, int maxSupported)
getVersion
is used to safely perform backwards incompatible changes to workflow definitions.static Promise<io.temporal.api.common.v1.WorkflowExecution>
getWorkflowExecution(java.lang.Object childWorkflowStub)
Extracts workflow execution from a stub created throughnewChildWorkflowStub(Class, ChildWorkflowOptions)
ornewExternalWorkflowStub(Class, String)
.static boolean
isReplaying()
Deprecated.static <R> R
mutableSideEffect(java.lang.String id, java.lang.Class<R> resultClass, java.lang.reflect.Type resultType, java.util.function.BiPredicate<R,R> updated, Functions.Func<R> func)
mutableSideEffect
is similar tosideEffect(Class, Functions.Func)
in allowing calls of non-deterministic functions from workflow code.static <R> R
mutableSideEffect(java.lang.String id, java.lang.Class<R> resultClass, java.util.function.BiPredicate<R,R> updated, Functions.Func<R> func)
mutableSideEffect
is similar tosideEffect(Class, Functions.Func)
in allowing calls of non-deterministic functions from workflow code.static <T> T
newActivityStub(java.lang.Class<T> activityInterface)
Creates client stub to activities that implement given interface.static <T> T
newActivityStub(java.lang.Class<T> activityInterface, ActivityOptions options)
Creates client stub to activities that implement given interfacestatic <T> T
newActivityStub(java.lang.Class<T> activityInterface, ActivityOptions options, java.util.Map<java.lang.String,ActivityOptions> activityMethodOptions)
Creates client stub to activities that implement given interface.static CancellationScope
newCancellationScope(Functions.Proc1<CancellationScope> proc)
Wraps a procedure in a CancellationScope.static CancellationScope
newCancellationScope(java.lang.Runnable runnable)
Wraps the Runnable method argument in aCancellationScope
.static <T> T
newChildWorkflowStub(java.lang.Class<T> workflowInterface)
Creates client stub that can be used to start a child workflow that implements the given interface using parent options.static <T> T
newChildWorkflowStub(java.lang.Class<T> workflowInterface, ChildWorkflowOptions options)
Creates client stub that can be used to start a child workflow that implements given interface.static <T> T
newContinueAsNewStub(java.lang.Class<T> workflowInterface)
Creates a client stub that can be used to continue this workflow as a new run.static <T> T
newContinueAsNewStub(java.lang.Class<T> workflowInterface, ContinueAsNewOptions options)
Creates a client stub that can be used to continue this workflow as a new run.static CancellationScope
newDetachedCancellationScope(java.lang.Runnable runnable)
Creates a CancellationScopeRunnable.run()
that is not linked to a parent scope must be called to execute the code the scope wraps.static <R> R
newExternalWorkflowStub(java.lang.Class<? extends R> workflowInterface, io.temporal.api.common.v1.WorkflowExecution execution)
Creates client stub that can be used to communicate to an existing workflow execution.static <R> R
newExternalWorkflowStub(java.lang.Class<? extends R> workflowInterface, java.lang.String workflowId)
Creates client stub that can be used to communicate to an existing workflow execution.static <E> Promise<E>
newFailedPromise(java.lang.Exception failure)
static <T> T
newLocalActivityStub(java.lang.Class<T> activityInterface)
Creates client stub to local activities that implement given interface.static <T> T
newLocalActivityStub(java.lang.Class<T> activityInterface, LocalActivityOptions options)
Creates client stub to local activities that implement given interface.static <T> T
newLocalActivityStub(java.lang.Class<T> activityInterface, LocalActivityOptions options, java.util.Map<java.lang.String,LocalActivityOptions> activityMethodOptions)
Creates client stub to local activities that implement given interface.static <E> CompletablePromise<E>
newPromise()
static <E> Promise<E>
newPromise(E value)
static <E> WorkflowQueue<E>
newQueue(int capacity)
Deprecated.usenewWorkflowQueue(int)
instead.static java.util.Random
newRandom()
Replay safe random numbers generator.static Promise<java.lang.Void>
newTimer(java.time.Duration delay)
Create new timer.static ActivityStub
newUntypedActivityStub(ActivityOptions options)
Creates non typed client stub to activities.static ChildWorkflowStub
newUntypedChildWorkflowStub(java.lang.String workflowType)
Creates untyped client stub that can be used to start and signal a child workflow.static ChildWorkflowStub
newUntypedChildWorkflowStub(java.lang.String workflowType, ChildWorkflowOptions options)
Creates untyped client stub that can be used to start and signal a child workflow.static ExternalWorkflowStub
newUntypedExternalWorkflowStub(io.temporal.api.common.v1.WorkflowExecution execution)
Creates untyped client stub that can be used to signal or cancel an existing workflow execution.static ExternalWorkflowStub
newUntypedExternalWorkflowStub(java.lang.String workflowId)
Creates untyped client stub that can be used to signal or cancel an existing workflow execution.static ActivityStub
newUntypedLocalActivityStub(LocalActivityOptions options)
Creates non typed client stub to local activities.static <E> WorkflowQueue<E>
newWorkflowQueue(int capacity)
Create a new instance of aWorkflowQueue
implementation that is adapted to be used from a workflow code.static java.util.UUID
randomUUID()
Replay safe way to generate UUID.static void
registerListener(java.lang.Object listener)
Registers an implementation object.static <R> R
retry(RetryOptions options, java.util.Optional<java.time.Duration> expiration, Functions.Func<R> fn)
Invokes function retrying in case of failures according to retry options.static void
retry(RetryOptions options, java.util.Optional<java.time.Duration> expiration, Functions.Proc proc)
Invokes function retrying in case of failures according to retry options.static void
setActivityOptions(java.util.Map<java.lang.String,ActivityOptions> activityMethodOptions)
Deprecated.static void
setDefaultActivityOptions(ActivityOptions defaultActivityOptions)
Sets the default activity options that will be used for activity stubs that have noActivityOptions
specified.
This overrides a value provided byWorkflowImplementationOptions.getDefaultActivityOptions()
.
A more specific per-activity-type option specified inWorkflowImplementationOptions.getActivityOptions()
orapplyActivityOptions(Map)
takes precedence over this setting.static void
setDefaultLocalActivityOptions(LocalActivityOptions defaultLocalActivityOptions)
Sets the default local activity options that will be used for activity stubs that have noLocalActivityOptions
specified.
This overrides a value provided byWorkflowImplementationOptions.getDefaultLocalActivityOptions()
.
A more specific per-activity-type option specified inWorkflowImplementationOptions.getLocalActivityOptions()
orapplyLocalActivityOptions(Map)
takes precedence over this setting.static <R> R
sideEffect(java.lang.Class<R> resultClass, Functions.Func<R> func)
Executes the provided function once, records its result into the workflow history.static <R> R
sideEffect(java.lang.Class<R> resultClass, java.lang.reflect.Type resultType, Functions.Func<R> func)
Executes the provided function once, records its result into the workflow history.static void
sleep(long millis)
Must be called instead ofThread.sleep(long)
to guarantee determinism.static void
sleep(java.time.Duration duration)
Must be called instead ofThread.sleep(long)
to guarantee determinism.static void
upsertSearchAttributes(java.util.Map<java.lang.String,?> searchAttributes)
Deprecated.static void
upsertTypedSearchAttributes(SearchAttributeUpdate<?>... searchAttributeUpdates)
Updates Workflow Search Attributes by applyingsearchAttributeUpdates
to the existing Search Attributes set attached to the workflow.static java.lang.RuntimeException
wrap(java.lang.Exception e)
If there is a need to return a checked exception from a workflow implementation do not add the exception to a method signature but wrap it using this method before rethrowing.
-
-
-
Field Detail
-
DEFAULT_VERSION
public static final int DEFAULT_VERSION
- See Also:
- Constant Field Values
-
-
Method Detail
-
newActivityStub
public static <T> T newActivityStub(java.lang.Class<T> activityInterface)
Creates client stub to activities that implement given interface. `- Parameters:
activityInterface
- interface type implemented by activities
-
newActivityStub
public static <T> T newActivityStub(java.lang.Class<T> activityInterface, ActivityOptions options)
Creates client stub to activities that implement given interface- Parameters:
activityInterface
- interface type implemented by activities.options
- options that together with the properties ofActivityMethod
specify the activity invocation parameters
-
newActivityStub
public static <T> T newActivityStub(java.lang.Class<T> activityInterface, ActivityOptions options, java.util.Map<java.lang.String,ActivityOptions> activityMethodOptions)
Creates client stub to activities that implement given interface.- Parameters:
activityInterface
- interface type implemented by activitiesoptions
- options that together with the properties ofActivityMethod
specify the activity invocation parametersactivityMethodOptions
- activity method-specific invocation parameters
-
newUntypedActivityStub
public static ActivityStub newUntypedActivityStub(ActivityOptions options)
Creates non typed client stub to activities. Allows executing activities by their string name.- Parameters:
options
- specify the activity invocation parameters.
-
newLocalActivityStub
public static <T> T newLocalActivityStub(java.lang.Class<T> activityInterface)
Creates client stub to local activities that implement given interface.- Parameters:
activityInterface
- interface type implemented by activities
-
newLocalActivityStub
public static <T> T newLocalActivityStub(java.lang.Class<T> activityInterface, LocalActivityOptions options)
Creates client stub to local activities that implement given interface. A local activity is similar to a regular activity, but with some key differences: 1. Local activity is scheduled and run by the workflow worker locally. 2. Local activity does not need Temporal server to schedule activity task and does not rely on activity worker. 3. Local activity is for short living activities (usually finishes within seconds). 4. Local activity cannot heartbeat.- Parameters:
activityInterface
- interface type implemented by activitiesoptions
- options that together with the properties ofActivityMethod
specify the activity invocation parameters.
-
newLocalActivityStub
public static <T> T newLocalActivityStub(java.lang.Class<T> activityInterface, LocalActivityOptions options, java.util.Map<java.lang.String,LocalActivityOptions> activityMethodOptions)
Creates client stub to local activities that implement given interface.- Parameters:
activityInterface
- interface type implemented by activitiesoptions
- options that together with the properties ofActivityMethod
specify the activity invocation parametersactivityMethodOptions
- activity method-specific invocation parameters
-
newUntypedLocalActivityStub
public static ActivityStub newUntypedLocalActivityStub(LocalActivityOptions options)
Creates non typed client stub to local activities. Allows executing activities by their string name.- Parameters:
options
- specify the local activity invocation parameters.
-
newChildWorkflowStub
public static <T> T newChildWorkflowStub(java.lang.Class<T> workflowInterface)
Creates client stub that can be used to start a child workflow that implements the given interface using parent options. UsenewExternalWorkflowStub(Class, String)
to get a stub to signal a workflow without starting it.- Parameters:
workflowInterface
- interface type implemented by activities
-
newChildWorkflowStub
public static <T> T newChildWorkflowStub(java.lang.Class<T> workflowInterface, ChildWorkflowOptions options)
Creates client stub that can be used to start a child workflow that implements given interface. UsenewExternalWorkflowStub(Class, String)
to get a stub to signal a workflow without starting it.- Parameters:
workflowInterface
- interface type implemented by activitiesoptions
- options passed to the child workflow.
-
newExternalWorkflowStub
public static <R> R newExternalWorkflowStub(java.lang.Class<? extends R> workflowInterface, java.lang.String workflowId)
Creates client stub that can be used to communicate to an existing workflow execution.- Parameters:
workflowInterface
- interface type implemented by activitiesworkflowId
- id of the workflow to communicate with.
-
newExternalWorkflowStub
public static <R> R newExternalWorkflowStub(java.lang.Class<? extends R> workflowInterface, io.temporal.api.common.v1.WorkflowExecution execution)
Creates client stub that can be used to communicate to an existing workflow execution.- Parameters:
workflowInterface
- interface type implemented by activitiesexecution
- execution of the workflow to communicate with.
-
getWorkflowExecution
public static Promise<io.temporal.api.common.v1.WorkflowExecution> getWorkflowExecution(java.lang.Object childWorkflowStub)
Extracts workflow execution from a stub created throughnewChildWorkflowStub(Class, ChildWorkflowOptions)
ornewExternalWorkflowStub(Class, String)
. Wrapped in a Promise as child workflow start is asynchronous.
-
newUntypedChildWorkflowStub
public static ChildWorkflowStub newUntypedChildWorkflowStub(java.lang.String workflowType, ChildWorkflowOptions options)
Creates untyped client stub that can be used to start and signal a child workflow.- Parameters:
workflowType
- name of the workflow type to start.options
- options passed to the child workflow.
-
newUntypedChildWorkflowStub
public static ChildWorkflowStub newUntypedChildWorkflowStub(java.lang.String workflowType)
Creates untyped client stub that can be used to start and signal a child workflow. All options are inherited from the parent.- Parameters:
workflowType
- name of the workflow type to start.
-
newUntypedExternalWorkflowStub
public static ExternalWorkflowStub newUntypedExternalWorkflowStub(io.temporal.api.common.v1.WorkflowExecution execution)
Creates untyped client stub that can be used to signal or cancel an existing workflow execution.- Parameters:
execution
- execution of the workflow to communicate with.
-
newUntypedExternalWorkflowStub
public static ExternalWorkflowStub newUntypedExternalWorkflowStub(java.lang.String workflowId)
Creates untyped client stub that can be used to signal or cancel an existing workflow execution.- Parameters:
workflowId
- id of the workflow to communicate with.
-
newContinueAsNewStub
public static <T> T newContinueAsNewStub(java.lang.Class<T> workflowInterface, ContinueAsNewOptions options)
Creates a client stub that can be used to continue this workflow as a new run.- Parameters:
workflowInterface
- an interface type implemented by the next run of the workflow
-
newContinueAsNewStub
public static <T> T newContinueAsNewStub(java.lang.Class<T> workflowInterface)
Creates a client stub that can be used to continue this workflow as a new run.- Parameters:
workflowInterface
- an interface type implemented by the next run of the workflow
-
continueAsNew
public static void continueAsNew(java.lang.Object... args)
Continues the current workflow execution as a new run with the same options.- Parameters:
args
- arguments of the next run.- See Also:
newContinueAsNewStub(Class)
-
continueAsNew
public static void continueAsNew(@Nullable ContinueAsNewOptions options, java.lang.Object... args)
Continues the current workflow execution as a new run with the same workflowType and overriddenoptions
.- Parameters:
options
- option overrides for the next run, can contain null if no overrides are neededargs
- arguments of the next run.- See Also:
newContinueAsNewStub(Class, ContinueAsNewOptions)
-
continueAsNew
@Deprecated public static void continueAsNew(java.util.Optional<java.lang.String> workflowType, java.util.Optional<ContinueAsNewOptions> options, java.lang.Object... args)
Deprecated.Continues the current workflow execution as a new run possibly overriding the workflow type and options.- Parameters:
workflowType
- workflow type override for the next run, can contain null if no override is neededoptions
- option overrides for the next run, can contain null if no overrides are neededargs
- arguments of the next run.- See Also:
newContinueAsNewStub(Class)
-
continueAsNew
public static void continueAsNew(@Nullable java.lang.String workflowType, @Nullable ContinueAsNewOptions options, java.lang.Object... args)
Continues the current workflow execution as a new run possibly overriding the workflow type and options.- Parameters:
workflowType
- workflow type override for the next run, can be null of no override is neededoptions
- option overrides for the next run, can be null if no overrides are neededargs
- arguments of the next run.- See Also:
newContinueAsNewStub(Class)
-
getInfo
public static WorkflowInfo getInfo()
-
getMemo
public static <T> java.lang.Object getMemo(java.lang.String key, java.lang.Class<T> valueClass)
Extract deserialized Memo associated with given key- Parameters:
key
- memo keyvalueClass
- Java class to deserialize into- Returns:
- deserialized Memo or null if the key is not present in the memo
-
getMemo
public static <T> T getMemo(java.lang.String key, java.lang.Class<T> valueClass, java.lang.reflect.Type genericType)
Extract Memo associated with the given key and deserialized into an object of generic type as is done here:DataConverter.fromPayloads(int, java.util.Optional, java.lang.Class, java.lang.reflect.Type)
Ex: To deserialize intoHashMap<String, Integer>
Workflow.getMemo(key, Map.class, new TypeToken<HashMap<String, Integer>>() {}.getType())
- Parameters:
key
- memo keyvalueClass
- Java class to deserialize intogenericType
- type parameter for the generic class- Returns:
- deserialized Memo or null if the key is not present in the memo
-
newCancellationScope
public static CancellationScope newCancellationScope(java.lang.Runnable runnable)
Wraps the Runnable method argument in aCancellationScope
. TheRunnable.run()
callsRunnable.run()
on the wrapped Runnable. The returned CancellationScope can be used to cancel the wrapped code. The cancellation semantic depends on the operation the code is blocked on. For example activity or child workflow is first canceled then throws aCanceledFailure
. The same applies forsleep(long)
operation. When an activity or a child workflow is invoked asynchronously then they get canceled and aPromise
that contains their result will throwCanceledFailure
whenPromise.get()
is called.The new cancellation scope
CancellationScope.current()
is linked to the parent one. If the parent one is canceled then all the children scopes are wrapped within a root cancellation scope which gets canceled when a workflow is canceled through the Temporal CancelWorkflowExecution API. To perform cleanup operations that require blocking after the current scope is canceled use a scope created throughnewDetachedCancellationScope(Runnable)
.Example of running activities in parallel and cancelling them after a specified timeout.
List<Promise<String>> results = new ArrayList<>(); CancellationScope scope = Workflow.newDetachedCancellationScope(() -> { Async.function(activities::a1); Async.function(activities::a2); }); scope.run(); // returns immediately as the activities are invoked asynchronously Workflow.sleep(Duration.ofHours(1)); // Cancels any activity in the scope that is still running scope.cancel("one hour passed");
- Parameters:
runnable
- parameter to wrap in a cancellation scope.- Returns:
- wrapped parameter.
-
newCancellationScope
public static CancellationScope newCancellationScope(Functions.Proc1<CancellationScope> proc)
Wraps a procedure in a CancellationScope. The procedure receives the wrapping CancellationScope as a parameter. Useful when cancellation is requested from within the wrapped code. The following example cancels the sibling activity on any failure.Workflow.newCancellationScope( (scope) -> { Promise
p1 = Async.proc(activities::a1).exceptionally(ex-> { scope.cancel("a1 failed"); return null; }); Promise p2 = Async.proc(activities::a2).exceptionally(ex-> { scope.cancel("a2 failed"); return null; }); Promise.allOf(p1, p2).get(); }) .run(); - Parameters:
proc
- code to wrap in the cancellation scope- Returns:
- wrapped proc
-
newDetachedCancellationScope
public static CancellationScope newDetachedCancellationScope(java.lang.Runnable runnable)
Creates a CancellationScopeRunnable.run()
that is not linked to a parent scope must be called to execute the code the scope wraps. The detached scope is needed to execute cleanup code after a workflow is canceled which cancels the root scope that wraps the @WorkflowMethod invocation. Here is an example usage:try { // workflow logic } catch (CanceledFailure e) { CancellationScope detached = Workflow.newDetachedCancellationScope(() -> { // cleanup logic }); detached.run(); }
- Parameters:
runnable
- parameter to wrap in a cancellation scope.- Returns:
- wrapped parameter.
- See Also:
newCancellationScope(Runnable)
-
newTimer
public static Promise<java.lang.Void> newTimer(java.time.Duration delay)
Create new timer. Note that Temporal service time resolution is in seconds. So all durations are rounded up to the nearest second.- Returns:
- feature that becomes ready when at least specified number of seconds passes. promise is
failed with
CanceledFailure
if enclosing scope is canceled.
-
newQueue
@Deprecated public static <E> WorkflowQueue<E> newQueue(int capacity)
Deprecated.usenewWorkflowQueue(int)
instead. An implementation returned by this method has a bug.
-
newWorkflowQueue
public static <E> WorkflowQueue<E> newWorkflowQueue(int capacity)
Create a new instance of aWorkflowQueue
implementation that is adapted to be used from a workflow code.- Parameters:
capacity
- the maximum size of the queue- Returns:
- new instance of
WorkflowQueue
-
newPromise
public static <E> CompletablePromise<E> newPromise()
-
newPromise
public static <E> Promise<E> newPromise(E value)
-
newFailedPromise
public static <E> Promise<E> newFailedPromise(java.lang.Exception failure)
-
registerListener
public static void registerListener(java.lang.Object listener)
Registers an implementation object. The object must implement at least one interface annotated withWorkflowInterface
. All its methods annotated with @SignalMethod
and @QueryMethod
are registered.There is no need to register the top level workflow implementation object as it is done implicitly by the framework on object startup.
An attempt to register a duplicated query is going to fail with
IllegalArgumentException
-
currentTimeMillis
public static long currentTimeMillis()
Must be used to get current time instead ofSystem.currentTimeMillis()
to guarantee determinism.
-
sleep
public static void sleep(java.time.Duration duration)
Must be called instead ofThread.sleep(long)
to guarantee determinism.
-
sleep
public static void sleep(long millis)
Must be called instead ofThread.sleep(long)
to guarantee determinism.
-
await
public static void await(java.util.function.Supplier<java.lang.Boolean> unblockCondition)
Block current thread until unblockCondition is evaluated to true.- Parameters:
unblockCondition
- condition that should return true to indicate that thread should unblock. The condition is called on every state transition, so it should never call any blocking operations or contain code that mutates any workflow state. It should also not contain any time based conditions. Useawait(Duration, Supplier)
for those instead.- Throws:
CanceledFailure
- if thread (or currentCancellationScope
was canceled).
-
await
public static boolean await(java.time.Duration timeout, java.util.function.Supplier<java.lang.Boolean> unblockCondition)
Block current workflow thread until unblockCondition is evaluated to true or timeoutMillis passes.- Parameters:
timeout
- time to unblock even if unblockCondition is not satisfied.unblockCondition
- condition that should return true to indicate that thread should unblock. The condition is called on every state transition, so it should not contain any code that mutates any workflow state. It should also not contain any time based conditions. Use timeout parameter for those.- Returns:
- false if timed out.
- Throws:
CanceledFailure
- if thread (or currentCancellationScope
was canceled).
-
retry
public static <R> R retry(RetryOptions options, java.util.Optional<java.time.Duration> expiration, Functions.Func<R> fn)
Invokes function retrying in case of failures according to retry options. Synchronous variant. UseAsync.retry(RetryOptions, Optional, Functions.Func)
for asynchronous functions.- Parameters:
options
- retry options that specify retry policyexpiration
- stop retrying after this interval if providedfn
- function to invoke and retry- Returns:
- result of the function or the last failure.
-
retry
public static void retry(RetryOptions options, java.util.Optional<java.time.Duration> expiration, Functions.Proc proc)
Invokes function retrying in case of failures according to retry options. Synchronous variant. UseAsync.retry(RetryOptions, Optional, Functions.Func)
for asynchronous functions.- Parameters:
options
- retry options that specify retry policyexpiration
- if specified stop retrying after this intervalproc
- procedure to invoke and retry
-
wrap
public static java.lang.RuntimeException wrap(java.lang.Exception e)
If there is a need to return a checked exception from a workflow implementation do not add the exception to a method signature but wrap it using this method before rethrowing. The library code will unwrap it automatically using when propagating exception to a remote caller.RuntimeException
are just returned from this method without modification.The reason for such design is that returning originally thrown exception from a remote call (which child workflow and activity invocations are ) would not allow adding context information about a failure, like activity and child workflow id. So stubs always throw a subclass of
ActivityFailure
from calls to an activity and subclass ofChildWorkflowFailure
from calls to a child workflow. The original exception is attached as a cause to these wrapper exceptions. So as exceptions are always wrapped adding checked ones to method signature causes more pain than benefit.try { return someCall(); } catch (Exception e) { throw Workflow.wrap(e); }
- Returns:
- CheckedExceptionWrapper if e is checked or original exception if e extends RuntimeException.
-
randomUUID
public static java.util.UUID randomUUID()
Replay safe way to generate UUID.Must be used instead of
UUID.randomUUID()
which relies on a random generator, thus leads to non-deterministic code which is prohibited inside a workflow.
-
newRandom
public static java.util.Random newRandom()
Replay safe random numbers generator. Seeded differently for each workflow instance.
-
isReplaying
@Deprecated public static boolean isReplaying()
Deprecated.True if workflow code is being replayed.Warning! Never make workflow logic depend on this flag as it is going to break determinism. The only reasonable uses for this flag are deduping external never failing side effects like logging or metric reporting.
This method always returns false if called from a non workflow thread.
-
sideEffect
public static <R> R sideEffect(java.lang.Class<R> resultClass, Functions.Func<R> func)
Executes the provided function once, records its result into the workflow history. The recorded result on history will be returned without executing the provided function during replay. This guarantees the deterministic requirement for workflow as the exact same result will be returned in replay. Common use case is to run some short non-deterministic code in workflow, like getting random number. The only way to fail SideEffect is to panic which causes workflow task failure. The workflow task after timeout is rescheduled and re-executed giving SideEffect another chance to succeed.Caution: do not use sideEffect function to modify any workflow state. Only use the SideEffect's return value. For example this code is BROKEN:
On replay the provided function is not executed, the random will always be 0, and the workflow could take a different path breaking the determinism.// Bad example: AtomicInteger random = new AtomicInteger(); Workflow.sideEffect(() -> { random.set(random.nextInt(100)); return null; }); // random will always be 0 in replay, thus this code is non-deterministic if random.get() < 50 { .... } else { .... }
Here is the correct way to use sideEffect:
If function throws any exception it is not delivered to the workflow code. It is wrapped in// Good example: int random = Workflow.sideEffect(Integer.class, () -> random.nextInt(100)); if random < 50 { .... } else { .... }
Error
causing failure of the current workflow task.- Parameters:
resultClass
- type of the side effectfunc
- function that returns side effect value- Returns:
- value of the side effect
- See Also:
mutableSideEffect(String, Class, BiPredicate, Functions.Func)
-
sideEffect
public static <R> R sideEffect(java.lang.Class<R> resultClass, java.lang.reflect.Type resultType, Functions.Func<R> func)
Executes the provided function once, records its result into the workflow history. The recorded result on history will be returned without executing the provided function during replay. This guarantees the deterministic requirement for workflow as the exact same result will be returned in replay. Common use case is to run some short non-deterministic code in workflow, like getting random number. The only way to fail SideEffect is to panic which causes workflow task failure. The workflow task after timeout is rescheduled and re-executed giving SideEffect another chance to succeed.Caution: do not use sideEffect function to modify any workflow state. Only use the SideEffect's return value. For example this code is BROKEN:
On replay the provided function is not executed, the random will always be 0, and the workflow could take a different path breaking the determinism.// Bad example: AtomicInteger random = new AtomicInteger(); Workflow.sideEffect(() -> { random.set(random.nextInt(100)); return null; }); // random will always be 0 in replay, thus this code is non-deterministic if random.get() < 50 { .... } else { .... }
Here is the correct way to use sideEffect:
If function throws any exception it is not delivered to the workflow code. It is wrapped in// Good example: int random = Workflow.sideEffect(Integer.class, () -> random.nextInt(100)); if random < 50 { .... } else { .... }
Error
causing failure of the current workflow task.- Parameters:
resultClass
- class of the side effectresultType
- type of the side effect. Differs from resultClass for generic types.func
- function that returns side effect value- Returns:
- value of the side effect
- See Also:
mutableSideEffect(String, Class, BiPredicate, Functions.Func)
-
mutableSideEffect
public static <R> R mutableSideEffect(java.lang.String id, java.lang.Class<R> resultClass, java.util.function.BiPredicate<R,R> updated, Functions.Func<R> func)
mutableSideEffect
is similar tosideEffect(Class, Functions.Func)
in allowing calls of non-deterministic functions from workflow code.The difference between
mutableSideEffect
andsideEffect(Class, Functions.Func)
is that every newsideEffect
call in non-replay mode results in a new marker event recorded into the history. However,mutableSideEffect
only records a new marker if a value has changed. During the replay,mutableSideEffect
will not execute the function again, but it will return the exact same value as it was returning during the non-replay run.One good use case of
mutableSideEffect
is to access a dynamically changing config without breaking determinism. Even if called very frequently the config value is recorded only when it changes not causing any performance degradation due to a large history size.Caution: do not use
mutableSideEffect
function to modify any workflow state. Only use the mutableSideEffect's return value.If function throws any exception it is not delivered to the workflow code. It is wrapped in
Error
causing failure of the current workflow task.- Parameters:
id
- unique identifier of this side effectupdated
- used to decide if a new value should be recorded. A func result is recorded only if call to updated with stored and a new value as arguments returns true. It is not called for the first value.resultClass
- class of the side effectfunc
- function that produces a value. This function can contain non-deterministic code.- See Also:
sideEffect(Class, Functions.Func)
-
mutableSideEffect
public static <R> R mutableSideEffect(java.lang.String id, java.lang.Class<R> resultClass, java.lang.reflect.Type resultType, java.util.function.BiPredicate<R,R> updated, Functions.Func<R> func)
mutableSideEffect
is similar tosideEffect(Class, Functions.Func)
in allowing calls of non-deterministic functions from workflow code.The difference between
mutableSideEffect
andsideEffect(Class, Functions.Func)
is that every newsideEffect
call in non-replay mode results in a new marker event recorded into the history. However,mutableSideEffect
only records a new marker if a value has changed. During the replay,mutableSideEffect
will not execute the function again, but it will return the exact same value as it was returning during the non-replay run.One good use case of
mutableSideEffect
is to access a dynamically changing config without breaking determinism. Even if called very frequently the config value is recorded only when it changes not causing any performance degradation due to a large history size.Caution: do not use
mutableSideEffect
function to modify any workflow state. Only use the mutableSideEffect's return value.If function throws any exception it is not delivered to the workflow code. It is wrapped in
Error
causing failure of the current workflow task.- Parameters:
id
- unique identifier of this side effectupdated
- used to decide if a new value should be recorded. A func result is recorded only if call to updated with stored and a new value as arguments returns true. It is not called for the first value.resultClass
- class of the side effectresultType
- type of the side effect. Differs from resultClass for generic types.func
- function that produces a value. This function can contain non-deterministic code.- See Also:
sideEffect(Class, Functions.Func)
-
getVersion
public static int getVersion(java.lang.String changeId, int minSupported, int maxSupported)
getVersion
is used to safely perform backwards incompatible changes to workflow definitions. It is not allowed to update workflow code while there are workflows running as it is going to break determinism. The solution is to have both old code that is used to replay existing workflows as well as the new one that is used when it is executed for the first time.\getVersion
returns maxSupported version when is executed for the first time. This version is recorded into the workflow history as a marker event. Even if maxSupported version is changed the version that was recorded is returned on replay. DefaultVersion constant contains version of code that wasn't versioned before.For example initially workflow has the following code:
it should be updated toresult = testActivities.activity1();
The backwards compatible way to execute the update isresult = testActivities.activity2();
Then later if we want to have another change:int version = Workflow.getVersion("fooChange", Workflow.DEFAULT_VERSION, 1); String result; if (version == Workflow.DEFAULT_VERSION) { result = testActivities.activity1(); } else { result = testActivities.activity2(); }
Later when there are no workflow executions running DefaultVersion the correspondent branch can be removed:int version = Workflow.getVersion("fooChange", Workflow.DEFAULT_VERSION, 2); String result; if (version == Workflow.DEFAULT_VERSION) { result = testActivities.activity1(); } else if (version == 1) { result = testActivities.activity2(); } else { result = testActivities.activity3(); }
It is recommended to keep the GetVersion() call even if single branch is left:int version = Workflow.getVersion("fooChange", 1, 2); String result; if (version == 1) { result = testActivities.activity2(); } else { result = testActivities.activity3(); }
The reason to keep it is: 1) it ensures that if there is older version execution still running, it will fail here and not proceed; 2) if you ever need to make more changes for “fooChange”, for example change activity3 to activity4, you just need to update the maxVersion from 2 to 3.Workflow.getVersion("fooChange", 2, 2); result = testActivities.activity3();
Note that, you only need to preserve the first call to GetVersion() for each changeId. All subsequent call to GetVersion() with same changeId are safe to remove. However, if you really want to get rid of the first GetVersion() call as well, you can do so, but you need to make sure: 1) all older version executions are completed; 2) you can no longer use “fooChange” as changeId. If you ever need to make changes to that same part, you would need to use a different changeId like “fooChange-fix2”, and start minVersion from DefaultVersion again.
- Parameters:
changeId
- identifier of a particular change. All calls to getVersion that share a changeId are guaranteed to return the same version number. Use this to perform multiple coordinated changes that should be enabled together.minSupported
- min version supported for the changemaxSupported
- max version supported for the change, this version is used as the current one during the original execution.- Returns:
maxSupported
when is originally executed. Original version recorded in the history on replays.
-
getMetricsScope
public static com.uber.m3.tally.Scope getMetricsScope()
Get scope for reporting business metrics in workflow logic. This should be used instead of creating new metrics scopes as it is able to dedupe metrics during replay.The original metrics scope is set through
ServiceStubsOptions.Builder.setMetricsScope(Scope)
when a worker starts up.
-
getLogger
public static org.slf4j.Logger getLogger(java.lang.Class<?> clazz)
Get logger to use inside workflow. Logs in replay mode are omitted unlessWorkerFactoryOptions.Builder.setEnableLoggingInReplay(boolean)
is set totrue
.- Parameters:
clazz
- class name to appear in logging.- Returns:
- logger to use in workflow logic.
-
getLogger
public static org.slf4j.Logger getLogger(java.lang.String name)
Get logger to use inside workflow. Logs in replay mode are omitted unlessWorkerFactoryOptions.Builder.setEnableLoggingInReplay(boolean)
is set totrue
.- Parameters:
name
- name to appear in logging.- Returns:
- logger to use in workflow logic.
-
getLastCompletionResult
public static <R> R getLastCompletionResult(java.lang.Class<R> resultClass)
GetLastCompletionResult extract last completion result from previous run for this cron workflow. This is used in combination with cron schedule. A workflow can be started with an optional cron schedule. If a cron workflow wants to pass some data to next schedule, it can return any data and that data will become available when next run starts.- Parameters:
resultClass
- class of the return data from last run- Returns:
- result of last run
- See Also:
WorkflowOptions.Builder.setCronSchedule(String)
-
getPreviousRunFailure
public static java.util.Optional<java.lang.Exception> getPreviousRunFailure()
Extract the latest failure from a previous run of this workflow. If any previous run of this workflow has failed, this function returns that failure. If no previous runs have failed, an empty optional is returned. The run you are calling this from may have been created as a retry of the previous failed run or as a next cron invocation for cron workflows.- Returns:
- The last
Exception
that occurred in this workflow, if there has been one.
-
getLastCompletionResult
public static <R> R getLastCompletionResult(java.lang.Class<R> resultClass, java.lang.reflect.Type resultType)
GetLastCompletionResult extract last completion result from previous run for this cron workflow. This is used in combination with cron schedule. A workflow can be started with an optional cron schedule. If a cron workflow wants to pass some data to next schedule, it can return any data and that data will become available when next run starts.- Parameters:
resultClass
- class of the return data from last runresultType
- type of the return data from last run. Differs from resultClass for generic types.- Returns:
- result of last run
-
getSearchAttribute
@Deprecated @Nullable public static <T> T getSearchAttribute(java.lang.String name)
Deprecated.usegetTypedSearchAttributes()
instead.Get a single search attribute.- Parameters:
name
- search attribute name- Returns:
- deserialized search attribute value
- Throws:
java.lang.IllegalStateException
- if the search attribute value is a collection of multiple (> 1) elements
-
getSearchAttributeValues
@Deprecated @Nullable public static <T> java.util.List<T> getSearchAttributeValues(java.lang.String name)
Deprecated.usegetTypedSearchAttributes()
instead.Collection returned from this method is immutable. To modify search attributes associated with this workflow useupsertSearchAttributes(Map)
.Note: This method never returns an empty list. Empty list is considered an absent value for search attributes and will be returned as
null
.- Parameters:
name
- search attribute name- Returns:
- immutable list of deserialized search attribute values
-
getSearchAttributes
@Deprecated @Nonnull public static java.util.Map<java.lang.String,java.util.List<?>> getSearchAttributes()
Deprecated.usegetTypedSearchAttributes()
instead.Map returned from this method is immutable. To modify search attributes associated with this workflow useupsertSearchAttributes(Map)
.- Returns:
- immutable map of search attribute names to deserialized values.
-
getTypedSearchAttributes
@Nonnull public static SearchAttributes getTypedSearchAttributes()
Get immutable set of search attributes. To modify search attributes associated with this workflow useupsertTypedSearchAttributes(io.temporal.common.SearchAttributeUpdate<?>...)
.- Returns:
- immutable set of search attributes.
-
upsertSearchAttributes
@Deprecated public static void upsertSearchAttributes(java.util.Map<java.lang.String,?> searchAttributes)
Deprecated.Updates Workflow Search Attributes by mergingsearchAttributes
to the existing Search Attributes map attached to the workflow. Search Attributes are additional indexed information attributed to workflow and used for search and visibility.The search attributes can be used in query of List/Scan/Count workflow APIs. The key and its value type must be registered on Temporal server side.
Supported Java types of the value:
String
Long
,Integer
,Short
,Byte
Boolean
Double
OffsetDateTime
Collection
of the types aboveSearchAttribute.UNSET_VALUE
can be used to unset or remove the search attribute
will eventually have search attributes as:Map<String, Object> attr1 = new HashMap<>(); attr1.put("CustomIntField", 1); attr1.put("CustomBoolField", true); Workflow.upsertSearchAttributes(attr1); Map<String, Object> attr2 = new HashMap<>(); attr2.put("CustomIntField", Lists.newArrayList(1, 2)); attr2.put("CustomKeywordField", "Seattle"); Workflow.upsertSearchAttributes(attr2);
{ "CustomIntField": 1, 2, "CustomBoolField": true, "CustomKeywordField": "Seattle", }
- Parameters:
searchAttributes
- map of String to Object value that can be used to search in list APIs
-
upsertTypedSearchAttributes
public static void upsertTypedSearchAttributes(SearchAttributeUpdate<?>... searchAttributeUpdates)
Updates Workflow Search Attributes by applyingsearchAttributeUpdates
to the existing Search Attributes set attached to the workflow. Search Attributes are additional indexed information attributed to workflow and used for search and visibility.The search attributes can be used in query of List/Scan/Count workflow APIs. The key and its value type must be registered on Temporal server side.
- Parameters:
searchAttributeUpdates
- set of updates to apply to search attributes.
-
setDefaultActivityOptions
public static void setDefaultActivityOptions(ActivityOptions defaultActivityOptions)
Sets the default activity options that will be used for activity stubs that have noActivityOptions
specified.
This overrides a value provided byWorkflowImplementationOptions.getDefaultActivityOptions()
.
A more specific per-activity-type option specified inWorkflowImplementationOptions.getActivityOptions()
orapplyActivityOptions(Map)
takes precedence over this setting.- Parameters:
defaultActivityOptions
-ActivityOptions
to be used as a default
-
setActivityOptions
@Deprecated public static void setActivityOptions(java.util.Map<java.lang.String,ActivityOptions> activityMethodOptions)
Deprecated.
-
applyActivityOptions
public static void applyActivityOptions(java.util.Map<java.lang.String,ActivityOptions> activityTypeToOptions)
Adds activity options per activity type that will be used for an activity stub that has noActivityOptions
specified.
This method refines an original set ofMap<String, ActivityOptions>
provided byWorkflowImplementationOptions.getActivityOptions()
These more specific options take precedence over more generic settingsetDefaultActivityOptions(io.temporal.activity.ActivityOptions)
If an activity type already has a
ActivityOptions
set by an earlier call to this method or fromWorkflowImplementationOptions.getDefaultActivityOptions()
, newActivityOptions
fromactivityTypeToOptions
will be merged into the old ones usingActivityOptions.Builder.mergeActivityOptions(ActivityOptions)
- Parameters:
activityTypeToOptions
- a map of activity types toActivityOptions
-
setDefaultLocalActivityOptions
public static void setDefaultLocalActivityOptions(LocalActivityOptions defaultLocalActivityOptions)
Sets the default local activity options that will be used for activity stubs that have noLocalActivityOptions
specified.
This overrides a value provided byWorkflowImplementationOptions.getDefaultLocalActivityOptions()
.
A more specific per-activity-type option specified inWorkflowImplementationOptions.getLocalActivityOptions()
orapplyLocalActivityOptions(Map)
takes precedence over this setting.- Parameters:
defaultLocalActivityOptions
-LocalActivityOptions
to be used as a default
-
applyLocalActivityOptions
public static void applyLocalActivityOptions(java.util.Map<java.lang.String,LocalActivityOptions> activityTypeToOptions)
Adds local activity options per activity type that will be used for a local activity stub that has noLocalActivityOptions
specified.
This method refines an original set ofMap<String, LocalActivityOptions>
provided byWorkflowImplementationOptions.getLocalActivityOptions()
These more specific options take precedence over more generic settingsetDefaultLocalActivityOptions(io.temporal.activity.LocalActivityOptions)
If an activity type already has a
LocalActivityOptions
set by an earlier call to this method or fromWorkflowImplementationOptions.getDefaultLocalActivityOptions()
, newLocalActivityOptions
fromactivityTypeToOptions
will be merged into the old ones usingLocalActivityOptions.Builder.mergeActivityOptions(LocalActivityOptions)
- Parameters:
activityTypeToOptions
- a map of activity types toLocalActivityOptions
-
-