new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Temporal · Develop · all subjects

workflows/basics

456 notes in this subject, read out of this brain and free to use. This is page 3 of 8.

MutableSideEffect value comparison behavior

Mutable Side Effects compare the existing value from History with the new function results using an equals function. If the values are equal, it returns the value without recording a new Marker Event. If the values are not equal, it records the new value with the same ID on the History.

SideEffect correct implementation example

The correct way to use SideEffect is to capture the returned EncodedValue and call Get() on it with a pointer to store the result: ```go encodedRandom := workflow.SideEffect(ctx, func(ctx workflow.Context) interface{} { return rand.Intn(100) }) var random int encodedRandom.Get(&random) ```

Go SDK SideEffect function signature and usage

Use the SideEffect function from the go.temporal.io/sdk/workflow package to execute a Side Effect directly in your Workflow. Pass it an instance of context.Context and the function to execute. The SideEffect API returns a Future, an instance of converter.EncodedValue. Use the Get method on the Future to retrieve the result of the Side Effect.

MutableSideEffect reduces event history markers

Mutable Side Effects execute the provided function once and look up the History value with the given Workflow ID. They only record a new Marker Event on the Event History if the value for the Side Effect ID changes or is set the first time, whereas every new regular Side Effect call results in a new Marker being recorded.

Workflow timeout and retry policy example in Go

Example showing how to set Workflow timeouts and retry policy: ```go retrypolicy := &temporal.RetryPolicy{ InitialInterval: time.Second, BackoffCoefficient: 2.0, MaximumInterval: time.Second * 100, } workflowOptions := client.StartWorkflowOptions{ WorkflowExecutionTimeout: 24 * 365 * 10 * time.Hour, // WorkflowRunTimeout: 24 * 365 * 10 * time.Hour, // WorkflowTaskTimeout: 10 * time.Second, RetryPolicy: retrypolicy, } workflowRun, err := c.ExecuteWorkflow(context.Background(), workflowOptions, YourWorkflowDefinition) if err != nil { // ... } ```

RetryPolicy fields for Workflow

RetryPolicy has the following fields: InitialInterval (initial retry interval), BackoffCoefficient (multiplier for exponential backoff), and MaximumInterval (maximum retry interval). These are used to control retry behavior when configured on StartWorkflowOptions.

Workflow Task Timeout in Go

Workflow Task Timeout restricts the maximum amount of time that a Worker can execute a Workflow Task. Set this using the WorkflowTaskTimeout field in StartWorkflowOptions when calling ExecuteWorkflow.

Setting Workflow Timeouts in Go

Create an instance of StartWorkflowOptions from the go.temporal.io/sdk/client package, set the timeout fields (WorkflowExecutionTimeout, WorkflowRunTimeout, or WorkflowTaskTimeout), and pass the instance to the ExecuteWorkflow call.

Workflow Retry Policy in Go

A Retry Policy can work in cooperation with timeouts to provide fine controls to optimize execution experience. Create an instance of RetryPolicy from the go.temporal.io/sdk/temporal package and provide it as the RetryPolicy field of StartWorkflowOptions.

Go NewTimer() function syntax

To set a Timer in Go, use the NewTimer() function and pass the duration you want to wait before continuing. The syntax is: timer := workflow.NewTimer(timerCtx, duration)

Go Sleep() function syntax

To set a sleep duration in Go, use the Sleep() function and pass the duration you want to wait before continuing. The syntax is: sleep = workflow.Sleep(ctx, 10*time.Second). A zero or negative sleep duration causes the function to return immediately.

Example: Getting and setting current workflow details

String currentDetails = Workflow.getCurrentDetails(); Workflow.getLogger(YourWorkflowImpl.class).info("Current details: " + currentDetails); Workflow.setCurrentDetails("Updated workflow details with new status");

Example: Timer with summary

Workflow.newTimer(Duration.ofMinutes(5), TimerOptions.newBuilder() .setSummary("Waiting for payment confirmation") .build()) .get();

Timer setSummary() in workflow

When creating a TimerOptions within a Workflow using Workflow.newTimer(), use setSummary() to attach a summary to the timer. The input format for setSummary() is a string, limited to 200 bytes. The summary text is shown in the Timeline tab on the Workflow details page.

Example: Workflow startup with static summary and details

WorkflowOptions options = WorkflowOptions.newBuilder() .setWorkflowId("your-workflow-id") .setTaskQueue("your-task-queue") .setStaticSummary("Order processing for customer #12345") .setStaticDetails("Processing premium order with expedited shipping") .build(); YourWorkflow workflow = workflowClient.newWorkflowStub(YourWorkflow.class, options); String result = workflow.yourWorkflowMethod("workflow input");

Workflow interface definition in Java

Define Workflows as an interface annotated with @WorkflowInterface. Use @WorkflowMethod to annotate the workflow method. Example: @WorkflowInterface public interface SayHelloWorkflow { @WorkflowMethod String sayHello(String name); }

Create workflow stub from client

Use client.newWorkflowStub(WorkflowInterface.class, WorkflowOptions) to create a workflow stub. Example: SayHelloWorkflow workflow = client.newWorkflowStub(SayHelloWorkflow.class, WorkflowOptions.newBuilder().setTaskQueue("my-task-queue").setWorkflowId("say-hello-workflow-id").build());

Set workflow ID in workflow options

Specify a unique workflow ID for a workflow execution using WorkflowOptions.newBuilder().setWorkflowId("workflow-id").build().

Workflow code must be deterministic

Workflow code must be deterministic. If you need to call non-deterministic functions such as non-seeded random or UUID.randomUUID() directly from Workflow code, the Temporal SDK provides replay-safe replacements.

Use Activities for non-deterministic operations

For operations like calling external APIs, invoking LLMs, querying databases, or performing I/O, use Activities. Activities run outside Workflow replay and are retried reliably.

Use DynamicWorkflow for default Workflow handling

Use DynamicWorkflow when you need a default Workflow that can handle all Workflow Types that are not registered with a Worker. A single implementation can implement a Workflow Type which by definition is dynamically loaded from some external source. All standard WorkflowOptions and determinism rules apply to Dynamic Workflow implementations.

Workflow logic must not use mutable global variables

Do not use mutable global variables in your Workflow implementations. This ensures that multiple Workflow instances are fully isolated.

Use Workflow.currentTimeMillis() instead of System.currentTimeMillis()

Use Workflow.currentTimeMillis() instead of System.currentTimeMillis() or Instant.now() to get the current time inside a Workflow. It returns the time of the last Workflow Task, which is consistent across replays.

Use Workflow.newRandom() for random numbers

Use Workflow.newRandom() to get a Random instance seeded per Workflow Execution for replay-safe random number generation.

Default Workflow Type naming

The Workflow Type defaults to the short name of the Workflow interface. For example, a Workflow interface named NotifyUserAccounts has a default Workflow Type of NotifyUserAccounts.

Custom Workflow Type with @WorkflowMethod name parameter

To set a custom Workflow Type, use the @WorkflowMethod annotation with the name parameter. Example: ```java @WorkflowInterface public interface NotifyUserAccounts { @WorkflowMethod(name = "your-workflow") void notify(String[] accountIds); } ``` When set this way, the name parameter does not have to start with an uppercase letter.

Workflow concurrency features

Only use concurrency features provided by the Workflow class. Multi-threaded code inside a Workflow is executed one thread at a time and under a global lock, so there is no need for explicit synchronization. Call Workflow.sleep instead of Thread.sleep; use Promise and CompletablePromise instead of Future and CompletableFuture; use WorkflowQueue instead of BlockingQueue.

@WorkflowInit constructor example

Example of using @WorkflowInit annotation: ```java public static class GreetingWorkflowImpl implements GreetingWorkflow { private final String nameWithTitle; private boolean titleHasBeenChecked; @WorkflowInit public GreetingWorkflowImpl(String input) { this.nameWithTitle = "Knight " + input; this.titleHasBeenChecked = false; } @Override public String getGreeting(String input) { Workflow.await(() -> titleHasBeenChecked); return "Hello " + nameWithTitle; } } ``` Note that the constructor and @WorkflowMethod must have the same parameters.

Workflow.currentTimeMillis() example

Example of getting current time in a Workflow: ```java long currentTime = Workflow.currentTimeMillis(); ```

Use Workflow.randomUUID() for UUIDs

Use Workflow.randomUUID() instead of UUID.randomUUID() to generate replay-safe unique identifiers.

Workflow method parameters recommendation

A method annotated with @WorkflowMethod can have any number of parameters. We recommend passing a single parameter that contains all the input fields to allow for adding fields in a backward-compatible manner.

Custom Workflow parameter example

Example of passing a custom object to a Workflow method: ```java @WorkflowInterface public interface YourWorkflow { @WorkflowMethod String yourWFMethod(CustomObj customobj); } ```

Random and UUID example

Example of generating random numbers and UUIDs in a Workflow: ```java int value = Workflow.newRandom().nextInt(100); UUID uniqueId = Workflow.randomUUID(); ```

Workflow parameters must be serializable

All Workflow Definition parameters must be serializable by the default Jackson JSON Payload Converter. We strongly recommend using objects as parameters so that individual fields may be altered without breaking the Workflow signature.

Workflow interface inheritance example with Signals and Queries

Example of reusable Workflow interface with inheritance: ```java public interface Retryable { @SignalMethod void retryNow(); } @WorkflowInterface public interface FileProcessingWorkflow extends Retryable { @WorkflowMethod String processFile(Arguments args); @QueryMethod(name="history") List<String> getHistory(); @QueryMethod String getStatus(); @SignalMethod void abandon(); } ```

WorkflowUnsafe.isReplaying() example

Example of using isReplaying() to emit metrics only on first execution: ```java import io.temporal.workflow.unsafe.WorkflowUnsafe; if (!WorkflowUnsafe.isReplaying()) { emitMetric("workflow_started", 1); } ```

Workflow return values must be serializable

Workflow return values must also be serializable. Workflow method arguments and return values must be serializable and deserializable using the provided DataConverter.

Dynamic Workflows do not use @WorkflowMethod

When using dynamic Workflows, do not specify a @WorkflowMethod annotation. Instead, implement the DynamicWorkflow interface directly in the Workflow implementation code.

Calling Activities in Workflows

To call Activities in your Workflow, call the Activity implementation. Use ExternalWorkflowStub to start or send Signals from within a Workflow to other running Workflow Executions.

@WorkflowMethod does not apply to inherited interfaces

The interface inheritance approach does not apply to @WorkflowMethod annotations. When using a base interface, it should not include any @WorkflowMethod methods. Attempting to register multiple implementations that both inherit a @WorkflowMethod will fail with IllegalStateException.

Workflow implementation example in Java

Example of a Workflow implementation: ```java public static class GreetingWorkflowImpl implements GreetingWorkflow { // implementation code } ```

DynamicWorkflow execute return type

The execute method for DynamicWorkflow can return type Object. Ensure that your Client can handle an Object type return or is able to convert the Object type response.

Workflow interface inheritance

Workflow interfaces can form inheritance hierarchies to create reusable components across multiple Workflow interfaces. This is useful for scenarios like creating a common Signal that multiple workflows share.

Never branch Workflow logic on replay status

Never use isReplaying() to affect Workflow business logic. Branching on replay status breaks determinism.

Workflow Definition structure in Java

A Workflow Definition in the Java SDK comprises a Workflow interface annotated with @WorkflowInterface and a Workflow implementation that implements the Workflow interface. The Workflow interface must have only one method annotated with @WorkflowMethod.

@WorkflowMethod identifies workflow entry point

The @WorkflowMethod annotation identifies the method that is the starting point of the Workflow Execution. The Workflow Execution completes when this method completes.

Use Workflow.sleep() instead of Thread.sleep()

Use Workflow.sleep() instead of Thread.sleep() for waiting within a Workflow.

Workflow interface example in Java

Example of a Workflow interface definition: ```java @WorkflowInterface public interface YourWorkflow { @WorkflowMethod String yourWFMethod(Arguments args); } ```

Use Temporal async functions instead of native Java threads

Use Async.function or Async.procedure provided by the Temporal SDK to execute code asynchronously instead of native Java Thread or other multi-threaded classes like ThreadPoolExecutor.

Terminate a Workflow Execution using WorkflowStub

To terminate a Workflow Execution in Java, use the terminate() function on the WorkflowStub with a reason string. Example: WorkflowStub untyped = WorkflowStub.fromTyped(myWorkflowStub); untyped.terminate("Sample reason");

Cancellation scopes overview

In the Java SDK, Workflows are represented internally by a tree of cancellation scopes, each with cancellation behaviors you can specify. By default, everything runs in the "root" scope. Scopes are created using the Workflow.newCancellationScope constructor. Scopes can be nested, and cancellation propagates from outer scopes to inner ones. A Workflow's method runs in the outermost scope.

Cancel a Workflow Execution using DestroyWorkflowThreadError

When you want to interrupt a Workflow Execution using an error, throw the DestroyWorkflowThreadError. Make sure there isn't any code on that thread to catch this error or it could cause issues with the Temporal service. Workflow code should only ever catch Exception, never Throwable or Error.

CancellationScope API methods

The Java SDK provides the following CancellationScope APIs: CancellationScope.current() gets the current scope. scope.cancel() cancels all operations inside a scope. scope.getCancellationRequest() returns a promise that resolves when a scope cancellation is requested, such as when Workflow code calls cancel() or the entire Workflow is cancelled by an external client.

Handle cancellation with CanceledFailure exception

Cancellations are handled by catching CanceledFailure exceptions thrown by cancelable operations in a Workflow.

Cancel a Workflow Execution using WorkflowStub

To cancel a Workflow Execution in Java, use the cancel() function on the WorkflowStub. Example: WorkflowStub workflowStub = WorkflowStub.fromTyped(workflow); workflowStub.cancel();

Java SDK Workflow documentation sections

The Java SDK documentation covers the following workflow topics: Workflow basics, Child Workflows, Continue-As-New, Message passing, Cancellation, Timeouts, Schedules, Timers, Side effects, Versioning, and Workflow Streams.

Java SDK Workflow.continueAsNew() method

Inside your Workflow, call the Workflow.continueAsNew(ContinueAsNewOptions options, Object... args) function with the same type. This stops the Workflow right away and starts a new one. Example: Workflow.continueAsNew(new ClusterManagerInput(Optional.of(state), input.isTestContinueAsNew()));

Create a Schedule with ScheduleClient

To create a Scheduled Workflow Execution in Java, use the createSchedule() method on the ScheduleClient. When creating the ScheduleClient, you can set a custom Namespace using ScheduleClientOptions. Schedules must be initialized with a Schedule ID. The Schedule is configured using Schedule.newBuilder() with an action (ScheduleActionStartWorkflow) and a spec (ScheduleSpec). Example: ScheduleClient scheduleClient = ScheduleClient.newInstance(service, ScheduleClientOptions.newBuilder().setNamespace("custom_namespace").build()); ScheduleHandle handle = scheduleClient.createSchedule("ScheduleId", schedule, ScheduleOptions.newBuilder().build());

Backfill a Schedule in Java

The backfill action executes Actions ahead of their specified time range, which is useful when you need to execute a missed or delayed Action, or when you want to test the Workflow before its scheduled time. Use the backfill() method on the ScheduleHandle. Example: ScheduleHandle handle = client.getHandle("schedule-id"); Instant now = Instant.now(); handle.backfill(Arrays.asList(new ScheduleBackfill(now.minusMillis(5500), now.minusMillis(2500)), new ScheduleBackfill(now.minusMillis(2500), now)));

Delete a Schedule in Java

To delete a Scheduled Workflow Execution in Java, use the delete() method on the ScheduleHandle. When you delete a Schedule, it does not affect any Workflows that were already started by the Schedule. Example: ScheduleHandle handle = client.getHandle("schedule-id"); handle.delete();

Give your agent this brain