Quarkus Temporal
A Quarkus extension that lets you utilize Temporal, orchestrating both mission-critical and mainstream workloads.
Installation
If you want to use this extension, you need to add the io.quarkiverse.temporal:quarkus-temporal extension first to your build file.
For instance, with Maven, add the following dependency to your POM file:
<dependency>
<groupId>io.quarkiverse.temporal</groupId>
<artifactId>quarkus-temporal</artifactId>
<version>0.5.1</version>
</dependency>
Getting Started
Activities and workflows are automatically detected. Simply implement an interface annotated with @ActivityInterface or @WorkflowInterface.
Create a Workflow
@WorkflowInterface
public interface SendEmailWorkflow {
@WorkflowMethod
public void run(WorkflowData data);
@QueryMethod
public EmailDetails details();
}
The following workflow definition will be automatically bound to the default worker:
public class SendEmailWorkflowImpl implements SendEmailWorkflow {
@Override
public void run(WorkflowData data) {
}
}
It is possible to associate the workflow with one or more named workers instead by annotating it with @TemporalWorkflow:
@TemporalWorkflow(workers = "named-worker")
public class SendEmailWorkflowImpl implements SendEmailWorkflow {
@Override
public void run(WorkflowData data) {
}
}
If you don’t have control over the workflow class, it is also possible to bind it with a worker using the workflow-classes configuration property of the worker.
quarkus.temporal.worker.namedWorker.workflow-classes[0]=io.quarkiverse.temporal.SendEmailWorkflowImpl
In this case, it will not be associated with the default worker unless you also bind it explicitely:
quarkus.temporal.worker.workflow-classes[0]=io.quarkiverse.temporal.SendEmailWorkflowImpl
Each worker can have at most one implementation of a given workflow, but a workflow can have implementations across multiple workers.
Workflows are not provided as CDI beans because dependency injection into workflow instances is strongly discouraged. Injecting dependencies into workflow instances can lead to changes that are incompatible with persisted histories, resulting in NonDeterministicException errors. To provide external configuration to a workflow in a deterministic way, use a Local Activity that returns the configuration to the workflow. Dependency injection into activity instances is allowed, ensuring that the configuration is persisted into the history and remains consistent during replay.
If your project only contains the workflow interfaces, but does not contain the actual workflow implementations, the plugin will assume that the workflow is bound to the default worker. If this is not the case, you can hint quarkus about which workers this workflow is bound to by annotating the interface with @TemporalWorkflow directly.
@WorkflowInterface
@TemporalWorkflow(workers = "named-worker")
public interface SendEmailWorkflow {
@WorkflowMethod
public void run(WorkflowData data);
@QueryMethod
public EmailDetails details();
}
Create an Activity
@ActivityInterface
public interface SendEmailActivities {
@ActivityMethod
public String sendEmail(EmailDetails details);
}
The following activity definition will be added automatically to the default worker:
public class SendEmailActivitiesImpl implements SendEmailActivities {
@Inject (1)
Mailer mailer;
@Override
public String sendEmail(EmailDetails details) {
}
}
| 1 | CDI Dependency Injection is allowed in activity definition. |
It is possible to associate the activity with one or more named workers instead by annotating it with @TemporalActivity:
@TemporalActivity(workers = "named-worker")
public class SendEmailActivitiesImpl implements SendEmailActivities {
@Override
public String sendEmail(EmailDetails details) {
}
}
If you don’t have control over the activity class, it is also possible to bind it with a worker using the activity-classes configuration property of the worker:
quarkus.temporal.worker.namedWorker.activity-classes[0]=io.quarkiverse.temporal.SendEmailActivitiesImpl
In this case, it will not be associated with the default worker unless you also bind it explicitely:
quarkus.temporal.worker.activity-classes[0]=io.quarkiverse.temporal.SendEmailActivitiesImpl
Similarly, each worker can have at most one implementation of a given activity, but an activity can have implementations across multiple workers.
Using the client
public class MyService {
@Inject
WorkflowClient client; (1)
public void startSubscription(WorkflowData data) {
WorkflowOptions options = WorkflowOptions.newBuilder()
.setWorkflowId(data.getEmail())
.setTaskQueue("<default>") (2)
.build();
SendEmailWorkflow workflow = client.newWorkflowStub(SendEmailWorkflow.class, options);
WorkflowClient.start(workflow::run,data);
}
}
| 1 | The client can be injected as a CDI bean |
| 2 | The default worker queue is <default>. for named worker, use the name of the worker |
Stub Injection
It is also possible to inject a workflow stub directly using the TemporalWorkflowStub qualifier:
public class MyService {
@Inject
@TemporalWorkflowStub(workflowId = "send-email")
SendEmailWorkflow workflow;
public void startSubscription(WorkflowData data) {
workflow.run(data);
}
}
If the workflow is bound to multiple workers, the worker parameter is required:
public class MyService {
@Inject
@TemporalWorkflowStub(worker = "<default>", workflowId = "send-email")
SendEmailWorkflow workflow;
public void startSubscription(WorkflowData data) {
workflow.run(data);
}
}
The workflowId can be set at runtime by injecting a TemporalInstance:
public class MyService {
@Inject
@TemporalWorkflowStub
TemporalInstance<SimpleWorkflow> instance;
public void startSubscription(WorkflowData data) {
SendEmailWorkflow workflow = instance.workflowId("the-workflow-id");
workflow.run(data);
}
}
OpenTelemetry
To wire up Temporal to forward traces and spans to Quarkus OpenTelemetry simply add the OpenTelemetry extension to your application.
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-opentelemetry</artifactId>
</dependency>
This will enable it by default you can disable it with:
quarkus.temporal.telemetry.enabled=false
quarkus.otel.instrument.grpc=false
quarkus.otel.instrument.vertx-http=false
Micrometer Metrics
To wire up Temporal to forward Micrometer metrics to Quarkus OpenTelemetry simply add the Micrometer extension to your application.
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-micrometer-registry-prometheus</artifactId>
</dependency>
This will enable it by default you can disable it with:
quarkus.temporal.metrics.enabled=false
Context Propagation
You can use an MDC (Mapped Diagnostic Context) Propagator to propagate information from the workflow client to workflow execution, workflow to activity, workflow to child workflow, and workflow to child thread created using Async.
To enable the MDC propagator or any custom propagators simply produce a CDI bean implementing the ContextPropagator interface.
package om.yourcompany;
import java.util.HashMap;
import java.util.Map;
import jakarta.inject.Singleton;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import com.google.protobuf.ByteString;
import io.quarkus.arc.Unremovable;
import io.temporal.api.common.v1.Payload;
import io.temporal.common.context.ContextPropagator;
import io.temporal.common.converter.GlobalDataConverter;
import lombok.extern.slf4j.Slf4j;
/**
* A {@link ContextPropagator} implementation that propagates the SLF4J MDC
* (Mapped Diagnostic Context) across Temporal workflow and activity boundaries.
* This class ensures that MDC entries with keys starting with "X-" are
* propagated.
*/
@Slf4j
@Singleton
@Unremovable
public class MDCContextPropagator implements ContextPropagator {
public MDCContextPropagator() {
super();
}
/**
* Gets the name of the context propagator.
*
* @return the name of the context propagator, which is the fully qualified
* class name.
*/
@Override
public String getName() {
return this.getClass().getName();
}
/**
* Retrieves the current MDC context to be propagated.
*
* @return a map containing the current MDC context, filtered to include
* only entries with keys starting with "X-".
*/
@Override
public Object getCurrentContext() {
Map<String, String> context = new HashMap<>();
Map<String, String> mdcContext = MDC.getCopyOfContextMap();
if (mdcContext != null) {
mdcContext.entrySet().stream()
.filter(entry -> entry.getKey().startsWith("X-"))
.forEach(entry -> context.put(entry.getKey(), entry.getValue()));
}
return context;
}
/**
* Sets the current MDC context from the given context map.
*
* @param context the context map containing MDC entries to be set.
*/
@Override
public void setCurrentContext(Object context) {
if (context instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, String> contextMap = (Map<String, String>) context;
contextMap.forEach(MDC::put);
}
}
/**
* Serializes the given context map to a map of Payloads.
*
* @param context the context map containing MDC entries to be serialized.
* @return a map of Payloads representing the serialized context.
*/
@Override
public Map<String, Payload> serializeContext(Object context) {
if (!(context instanceof Map)) {
return new HashMap<>();
}
@SuppressWarnings("unchecked")
Map<String, String> contextMap = (Map<String, String>) context;
Map<String, Payload> serializedContext = new HashMap<>();
contextMap.forEach((key, value) -> GlobalDataConverter.get().toPayload(value)
.ifPresent(payload -> serializedContext.put(key, payload)));
return serializedContext;
}
/**
* Deserializes the given map of Payloads to a context map.
*
* @param context the map of Payloads to be deserialized.
* @return a context map containing the deserialized MDC entries.
*/
@Override
public Object deserializeContext(Map<String, Payload> context) {
Map<String, String> contextMap = new HashMap<>();
context.forEach((key, payload) -> {
try {
Object payloadValue = StringUtils.EMPTY; // default value
// Convert data to string to compare
ByteString data = payload.getData();
// Check the value to see if it "empty"
if (!data.isEmpty()) {
// Check if the value isn't {}'s
if (!StringUtils.equals("{}", data.toStringUtf8())) {
payloadValue = GlobalDataConverter.get().fromPayload(payload, Object.class, Object.class);
}
}
// Add the value into the map
contextMap.put(key, payloadValue.toString());
} catch (Exception e) {
log.warn("Couldn't parse MDC Context Data Key {}", key);
}
});
return contextMap;
}
}
Interceptors
Interceptors are a mechanism for modifying inbound and outbound SDK calls. Interceptors are commonly used to add tracing and authorization to the scheduling and execution of Workflows and Activities. You can compare these to "middleware" in other frameworks.
To enable interceptors simply produce a CDI bean implementing the WorkflowClientInterceptor interface or WorkerInterceptor interface. Interceptors can be ordered by declaring a @Priority on each interceptor, so they are executed in that order.
package com.yourcompany;
import java.util.Optional;
import jakarta.annotation.Priority;
import jakarta.inject.Singleton;
import io.quarkus.arc.Unremovable;
import io.temporal.api.common.v1.WorkflowExecution;
import io.temporal.client.ActivityCompletionClient;
import io.temporal.client.WorkflowOptions;
import io.temporal.client.WorkflowStub;
import io.temporal.common.interceptors.WorkflowClientCallsInterceptor;
import io.temporal.common.interceptors.WorkflowClientInterceptor;
@Singleton
@Unremovable
@Priority(1)
public class TestWorkflowClientInterceptor implements WorkflowClientInterceptor {
@Override
public WorkflowStub newUntypedWorkflowStub(String workflowType, WorkflowOptions options, WorkflowStub next) {
return next;
}
@Override
public WorkflowStub newUntypedWorkflowStub(WorkflowExecution execution, Optional<String> workflowType, WorkflowStub next) {
return next;
}
@Override
public ActivityCompletionClient newActivityCompletionClient(ActivityCompletionClient next) {
return next;
}
@Override
public WorkflowClientCallsInterceptor workflowClientCallsInterceptor(WorkflowClientCallsInterceptor next) {
return next;
}
}
Data Converter
You can customize how data is serialized and deserialized by providing a custom DataConverter. To do this, create a CDI producer for the DataConverter:
@ApplicationScoped
public class CustomDataConverterProducer {
@Produces
public DataConverter produceDataConverter() {
return new CustomDataConverter();
}
}
The produced DataConverter will be automatically used by the WorkflowClient. You can customize the DataConverter by adding your own PayloadConverter implementations or by using the existing ones:
@ApplicationScoped
public class TemporalKotlinDataConverterProducer {
@Produces
public DataConverter produceDataConverter() {
// Create a custom ObjectMapper based on the DefaultObjectMapper
ObjectMapper objectMapper = JacksonJsonPayloadConverter.newDefaultObjectMapper()
.findAndRegisterModules()
// or more specifically
// .registerKotlinModule()
// .registerModule(ParameterNamesModule())
// Create JacksonJsonPayloadConverter with custom ObjectMapper
JacksonJsonPayloadConverter jacksonConverter =
new JacksonJsonPayloadConverter(objectMapper);
// Use the custom converter in the DataConverter
return DefaultDataConverter.newDefaultInstance()
.withPayloadConverterOverrides(jacksonConverter);
}
}
Temporal Cloud
You may be using the Temporal Cloud offering instead of self-hosting. Temporal Cloud supports both TLS and API key authentication.
TLS Authentication
You must provide your own CA certificates. These certificates are needed to create a Namespace, which are in turn used to grant Temporal Clients and Workers access to it. You will need:
-
The full Namespace ID from the Cloud Namespace details page such as
<namespace>.<account> -
The gRPC endpoint from the Cloud Namespace details page such as
<namespace>.<account>.tmprl.cloud:7233 -
Your mTLS private key
-
Your mTLS x509 Certificate
To configure with Quarkus Temporal TLS:
quarkus.temporal.namespace=your-namespace.123def
quarkus.temporal.connection.target=your-namespace.123def.tmprl.cloud:7233
quarkus.temporal.connection.mtls.client-cert-path=/your-temporal-x509.cert
quarkus.temporal.connection.mtls.client-key-path=/your-temporal.key
quarkus.temporal.connection.mtls.password=Passw0rd
API Key Authentication
Each Temporal Cloud API key is a unique identity linked to role-based access control (RBAC) settings to ensure secure and appropriate access.
You will need:
-
The full Namespace ID from the Cloud Namespace details page such as
<namespace>.<account> -
The gRPC endpoint from the Cloud Namespace details page such as
<region>.<cloud_provider>.api.temporal.io:7233. -
Your API key
To configure with Quarkus Temporal API key:
quarkus.temporal.namespace=<namespace>.<account>
quarkus.temporal.connection.target=<region>.<cloud_provider>.api.temporal.io:7233
quarkus.temporal.connection.api-key=<api-key>
Temporal Startup Resilience
By default, Temporal workers are started during Quarkus startup. If Temporal is unreachable, startup fails.
Default behavior:
-
quarkus.temporal.worker-factory.fail-on-startup-error=true -
quarkus.temporal.worker-factory.startup-max-attempts=1 -
quarkus.temporal.worker-factory.startup-retry-delay=2s -
quarkus.temporal.worker-factory.startup-background-retry-enabled=false
Use this mode when you want startup to retry a fixed number of times and then continue:
quarkus.temporal.worker-factory.fail-on-startup-error=false
quarkus.temporal.worker-factory.startup-max-attempts=10
quarkus.temporal.worker-factory.startup-retry-delay=5s
quarkus.temporal.worker-factory.startup-background-retry-enabled=false
|
In this mode, after the configured attempts are exhausted, Quarkus starts (because |
Use this mode when you want Quarkus to start immediately and workers to retry in the background until Temporal is available:
quarkus.temporal.worker-factory.fail-on-startup-error=false
quarkus.temporal.worker-factory.startup-background-retry-enabled=true
quarkus.temporal.worker-factory.startup-retry-delay=5s
|
Use this second mode for continuous polling/retry until Temporal is reachable. |
Notes:
-
Background retry requires
fail-on-startup-error=false. -
In background retry mode,
startup-max-attemptsis ignored and retries continue until success or shutdown.
Dev Services
Temporal Dev Services starts a local Temporal development server with Docker or Podman when no quarkus.temporal.connection.target is configured. It is enabled by default in dev and test modes and automatically supplies the dynamically mapped gRPC address to the Temporal client. The same container also serves the Temporal Web UI.
No configuration is required for the usual local-development case:
./mvnw quarkus:dev
The first application starts the temporalio/temporal container image; later applications in dev mode reuse it by default.
Temporal Web UI
The Dev Service runs temporal server start-dev, which serves the Temporal Web UI from the same container as the gRPC endpoint. Nothing else has to be started: no second container, no docker-compose.yaml, and no manual Docker network.
The quickest way to open it is from the Quarkus Dev UI:
-
Start the application with
./mvnw quarkus:dev. -
Browse to the Quarkus Dev UI at
http://localhost:8080/q/dev-ui. -
On the Temporal card, click Temporal Web UI.
The card also lists the discovered workflows and workers of the application.
Dev Services publishes the resolved address as the quarkus.temporal.devservices.web-ui-url configuration property, which is what the Dev UI card links to. The Web UI listens on port 8233 inside the container and is mapped to a random free host port, so the address changes between runs and is not worth bookmarking. To look it up from the command line:
# Look for the mapping of container port 8233, for example
# 0.0.0.0:32768->7233/tcp, 0.0.0.0:32769->8233/tcp
# means the Web UI is available at http://localhost:32769
docker ps
quarkus.temporal.devservices.port fixes the host port of the gRPC endpoint only; the Web UI port is always assigned dynamically.
When several applications share one Temporal container, they also share its Web UI, so workflows started by any of them are visible there.
Configure the server
Use the following properties in application.properties to control the Dev Service:
# Disable automatic Temporal startup.
quarkus.temporal.devservices.enabled=false
# Use a different Temporal image or a fixed host port for gRPC.
quarkus.temporal.devservices.image-name=temporalio/temporal:latest
quarkus.temporal.devservices.port=7233
# Ensure these namespaces exist in the Dev Service.
quarkus.temporal.devservices.namespaces=payments-dev,reporting-dev
# Reuse a dev-mode container started by another local application.
quarkus.temporal.devservices.shared=true
quarkus.temporal.devservices.service-name=temporal
# Retain the container after dev mode exits when Testcontainers reuse is enabled.
quarkus.temporal.devservices.reuse=true
# Forward Temporal container logs to the application log.
quarkus.temporal.devservices.show-logs=true
Set quarkus.temporal.connection.target to use an existing Temporal server instead. Doing so takes precedence over Dev Services. Dev Services is also disabled when quarkus.temporal.enable-mock=true.
Share across applications
In dev mode, shared defaults to true. Applications with the same service-name reuse one running Temporal container. Change the name when a group of applications needs its own isolated server:
quarkus.temporal.devservices.service-name=payments
Set quarkus.temporal.devservices.shared=false to always start a separate container. Sharing is intentionally disabled in test mode, so tests start an isolated Temporal container.
As with other Quarkus shared Dev Services, discovery happens at application startup. When no shared container exists yet, start one application first before starting several applications concurrently; otherwise, simultaneous first starts can each create a container.
Shared dev-mode containers can be retained when an application stops so that other local applications can continue using them. This requires enabling Testcontainers reuse in ~/.testcontainers.properties:
testcontainers.reuse.enable=true
quarkus.temporal.devservices.reuse defaults to true, matching Quarkus datasource Dev Services. Testcontainers reuse is disabled by default, so containers are stopped when dev mode ends unless it is explicitly enabled. Set this property to false to disable reuse for Temporal only. Stop reusable containers manually when they are no longer needed.
Provision development namespaces
quarkus.temporal.devservices.namespaces creates any listed namespaces after the Dev Service starts. Existing namespaces and the built-in default namespace are left unchanged. Namespace provisioning is limited to Dev Services; it never runs against a server selected with quarkus.temporal.connection.target.
Namespace provisioning also runs when an application discovers a shared container. This lets each application declare the namespaces it needs while using the same local Temporal server.
Extension Configuration Reference
Configuration property fixed at build time - All other configuration properties are overridable at runtime
Configuration property |
Type |
Default |
|---|---|---|
The value configuring the Environment variable: |
int |
|
Whether to start a Temporal development server when no Temporal connection target is configured. Environment variable: |
boolean |
|
The container image used to start the Temporal development server. Environment variable: |
string |
|
Optional fixed host port for Temporal’s gRPC endpoint. By default a random available port is used. Environment variable: |
int |
|
The label value used to identify a shared Temporal Dev Service container. Environment variable: |
string |
|
Whether to discover and use a Temporal Dev Service container started by another application in dev mode. Environment variable: |
boolean |
|
Whether a shared dev-mode container should be reusable after the application that started it exits. Requires Testcontainers reuse to be enabled in Environment variable: |
boolean |
|
Whether to forward Temporal development server container logs to the application log. Environment variable: |
boolean |
|
Namespaces to create in the Temporal development server. Existing namespaces are left unchanged. Environment variable: |
list of string |
|
The Web UI URL automatically supplied by the Temporal Dev Service for the Dev UI card. Environment variable: |
string |
|
enable mock for testing Environment variable: |
boolean |
|
either use a channel managed by temporal client (built-in) or use a channel managed by quarkus (quarkus-managed). In this case the channel can be configured using quarkus.grpc.clients.temporal-client. Environment variable: |
|
|
If Temporal registers in the health check by pinging the service. Environment variable: |
boolean |
|
Enable OpenTelemetry instrumentation, enabled by default if OpenTelemetry capability is detected. Environment variable: |
boolean |
|
enable mock for testing Environment variable: |
boolean |
|
A Namespace is a unit of isolation within the Temporal Platform. Environment variable: |
string |
|
Override human-readable identity of the worker. Identity is used to identify a worker and is recorded in the workflow history events. For example when a worker gets an activity task the correspondent ActivityTaskStarted event contains the worker identity as a field. Default is whatever (ManagementFactory. getRuntimeMXBean().getName() returns. Environment variable: |
string |
|
Enable Micrometer, enabled by default if Micrometer capability is detected. Environment variable: |
boolean |
|
The interval at which we report metrics to the metric registry. Default is 15 seconds. Environment variable: |
|
|
When set blocks shutdown until all tasks are completed or timeout is reached. Environment variable: |
||
Explicitly bind a workflow with this worker Environment variable: |
list of string |
|
Explicitly bind a workflow with this worker Environment variable: |
list of string |
|
Task queue name worker uses to poll. It uses this name for both workflow and activity task queue polls. Default is worker name Environment variable: |
string |
|
Maximum number of activities started per second by this worker. Default is 0 which means unlimited. Environment variable: |
double |
|
Maximum number of activities executed in parallel. Default is 200, which is chosen if set to zero. Environment variable: |
int |
|
Maximum number of simultaneously executed workflow tasks. Default is 200, which is chosen if set to zero. Environment variable: |
int |
|
Maximum number of local activities executed in parallel. Default is 200, which is chosen if set to zero. Environment variable: |
int |
|
Sets the rate limiting on number of activities that can be executed per second. This is managed by the server and controls activities per second for the entire task queue across all the workers. Notice that the number is represented in double, so that you can set it to less than 1 if needed. For example, set the number to 0.1 means you want your activity to be executed once every 10 seconds. This can be used to protect down stream services from flooding. The zero value of these uses the default value. Default is unlimited. Environment variable: |
double |
|
Sets the maximum number of simultaneous long poll requests to the Temporal Server to retrieve workflow tasks. Changing this value will affect the rate at which the worker is able to consume tasks from a task queue. Due to internal logic where pollers alternate between sticky and non-sticky queues, this value cannot be 1 and will be adjusted to 2 if set to that value. Default is 5, which is chosen if set to zero. Environment variable: |
int |
|
Number of simultaneous poll requests on activity task queue. Consider incrementing if the worker is not throttled due to Environment variable: |
int |
|
If set to true worker would only handle workflow tasks and local activities. Non-local activities will not be executed by this worker. Default is false. Environment variable: |
boolean |
|
Time period in ms that will be used to detect workflows deadlock. Default is 1000ms, which is chosen if set to zero. Specifies an amount of time in milliseconds that workflow tasks are allowed to execute without interruption. If workflow task runs longer than specified interval without yielding (like calling an Activity), it will fail automatically. Environment variable: |
long |
|
The maximum amount of time between sending each pending heartbeat to the server. Regardless of heartbeat timeout, no pending heartbeat will wait longer than this amount of time to send. Default is 60s, which is chosen if set to null or 0. Environment variable: |
|
|
The default amount of time between sending each pending heartbeat to the server. This is used if the ActivityOptions do not provide a HeartbeatTimeout. Otherwise, the interval becomes a value a bit smaller than the given HeartbeatTimeout. Default is 30s, which is chosen if set to null or 0. Environment variable: |
|
|
Timeout for a workflow task routed to the "sticky worker" - host that has the workflow instance cached in memory. Once it times out, then it can be picked up by any worker. Default value is 5 seconds. Environment variable: |
|
|
Disable eager activities. If set to true, eager execution will not be requested for activities requested from workflows bound to this Worker. Eager activity execution means the server returns requested eager activities directly from the workflow task back to this worker which is faster than non-eager which may be dispatched to a separate worker. Defaults to false, meaning that eager activity execution is permitted Environment variable: |
boolean |
|
During graceful shutdown, as when calling WorkerFactory. shutdown(), if the workflow cache is enabled, this timeout controls how long to wait for the sticky task queue to drain before shutting down the worker. If set the worker will stop making new poll requests on the normal task queue, but will continue to poll the sticky task queue until the timeout is reached. This value should always be greater than clients rpc long poll timeout, which can be set via WorkflowServiceStubsOptions. Builder. setRpcLongPollTimeout(Duration). Default is not to wait. Environment variable: |
|
|
Override identity of the worker primary specified in a WorkflowClient options. Environment variable: |
string |
|
Specifies server behavior if a completed workflow with the same id exists. Note that under no conditions Temporal allows two workflows with the same namespace and workflow id run simultaneously. See @line setWorkflowIdConflictPolicy for handling a workflow id duplication with a Running workflow. Default value if not set: AllowDuplicate Environment variable: |
|
|
Specifies server behavior if a Running workflow with the same id exists. See setWorkflowIdReusePolicy for handling a workflow id duplication with a Closed workflow. Cannot be set when workflow-id-reuse-policy is WorkflowIdReusePolicy. Default value if not set: Fail Environment variable: |
|
|
The time after which a workflow run is automatically terminated by Temporal service with WORKFLOW_EXECUTION_TIMED_OUT status. The default is set to the same value as the Workflow Execution Timeout. Environment variable: |
||
The time after which workflow execution (which includes run retries and continue as new) is automatically terminated by Temporal service with WORKFLOW_EXECUTION_TIMED_OUT status. The default value is ∞ (infinite) - [TO DO]: check with temporal how to set this infinite value Environment variable: |
||
Maximum execution time of a single Workflow Task. In the majority of cases there is no need to change this timeout. Note that this timeout is not related to the overall Workflow duration in any way. It defines for how long the Workflow can get blocked in the case of a Workflow Worker crash. The default value is 10 seconds. Maximum value allowed by the Temporal Server is 1 minute. Environment variable: |
|
|
cron schedule Environment variable: |
string |
|
If WorkflowClient is used to create a WorkerFactory that is started has a non-paused worker on the right task queue has available workflow task executor slots and such a WorkflowClient is used to start a workflow, then the first workflow task could be dispatched on this local worker with the response to the start call if Server supports it. This option can be used to disable this mechanism. Default is true Environment variable: |
boolean |
|
Time to wait before dispatching the first workflow task. If the workflow gets a signal before the delay, a workflow task will be dispatched and the rest of the delay will be ignored. A signal from signal with start will not trigger a workflow task. Cannot be set the same time as a CronSchedule. Environment variable: |
||
This property is deprecated: Use Assigns a unique identifier to this worker. The identifier must remain consistent with the code the worker utilizes for workflows, activities, and interceptors. For further details, refer to: Temporal Build ID. A Build ID is required if Environment variable: |
string |
|
This property is deprecated: Use Opts the worker in to the Build-ID-based versioning feature. This ensures that the worker will only receive tasks which it is compatible with. For more information see: TODO: Doc link Defaults to false Environment variable: |
boolean |
|
Type |
Default |
|
Sets a target string, which can be either a valid Environment variable: |
string |
|
Sets option to enable SSL/ TLS/ HTTPS for gRPC. Environment variable: |
boolean |
|
Temporal Cloud API key is a unique identity linked to role-based access control (RBAC) settings to ensure secure and appropriate access. Environment variable: |
string |
|
Interval of the first retry, on regular failures. If coefficient is 1.0 then it is used for all retries. Defaults to 100ms. Environment variable: |
|
|
Interval of the first retry, on congestion related failures (i. e. RESOURCE_EXHAUSTED errors). If coefficient is 1.0 then it is used for all retries. Defaults to 1000ms. Environment variable: |
|
|
Maximum time to retry. When exceeded the retries stop even if maximum retries is not reached yet. Defaults to 1 minute. Environment variable: |
|
|
Coefficient used to calculate the next retry interval. The next retry interval is previous interval multiplied by this coefficient. Must be 1 or larger. Default is 1.5. Environment variable: |
double |
|
When exceeded the amount of attempts, stop. Even if expiration time is not reached. Default is unlimited which is chosen if set to 0. Environment variable: |
int |
|
Maximum interval between retries. Exponential backoff leads to interval increase. This value is the cap of the increase. Default is 50x of initial interval. Can’t be less than initial-interval Environment variable: |
||
Maximum amount of jitter to apply. 0.2 means that actual retry time can be +/- 20% of the calculated time. Set to 0 to disable jitter. Must be lower than 1. Default is 0.2. Environment variable: |
double |
|
Makes request that receives a server response with gRPC code and failure of detailsClass type non-retryable. Environment variable: |
list of |
|
Path to the client certificate. Environment variable: |
path |
|
Path to the client key. Environment variable: |
path |
|
Password for the client key. Environment variable: |
string |
|
Sets the rpc timeout value for the following long poll based operations: PollWorkflowTaskQueue, PollActivityTaskQueue, GetWorkflowExecutionHistory. If not set uses Temporal default timeout of 70 seconds. Environment variable: |
||
Type |
Default |
|
The deployment name, which groups related workers across versions. If set, Environment variable: |
string |
|
The Build ID identifying a specific release of your worker code within a deployment. If set, Environment variable: |
string |
|
The deployment version, combining a deployment name and a Build ID (format: Environment variable: |
string |
|
If true, opts this worker into the Worker Deployment Versioning feature. Requires Environment variable: |
boolean |
|
Configuration of default versioning behavior for workflows registered on the worker. Environment variable: |
|
|
Type |
Default |
|
List of application failures types to not retry Environment variable: |
list of string |
|
Interval of the first retry. If coefficient is 1.0 then it is used for all retries. Default is 1 second. Environment variable: |
|
|
Coefficient used to calculate the next retry interval. The next retry interval is previous interval multiplied by this coefficient. Must be 1 or larger. Default is 2.0. Environment variable: |
double |
|
When exceeded the amount of attempts, stop. Even if expiration time is not reached. Default is unlimited if set to 0. Environment variable: |
int |
|
Maximum interval between retries. Exponential backoff leads to interval increase. This value is the cap of the increase. Default is 100x of initial interval. Can’t be less than initialInterval Environment variable: |
||
Configuration for the worker factory that drives how workflows and activities are executed |
Type |
Default |
Use virtual threads for workflow execution. Default is false. Environment variable: |
boolean |
|
Maximum number of threads the worker factory can use to run workflows. Default is 600. Environment variable: |
int |
|
Number of workflow instances to keep in cache per worker factory. Default is 600. Environment variable: |
int |
|
Controls whether application startup fails when Temporal workers cannot start (for example, when the Temporal server is unreachable). Set to false to let the application continue booting without started workers. Environment variable: |
boolean |
|
Maximum number of attempts to start workers during application startup. This is useful when Temporal is temporarily unavailable at boot time. Ignored when startupBackgroundRetryEnabled is true. Environment variable: |
int |
|
Delay between startup retry attempts when worker startup fails. Environment variable: |
|
|
When enabled (and failOnStartupError is false), worker startup retries run in the background and do not block application startup. Environment variable: |
boolean |
|
|
About the Duration format
To write duration values, use the standard You can also use a simplified format, starting with a number:
In other cases, the simplified format is translated to the
|