Temporal Durable Execution Platform
repository·main·Indexed 12 days ago
https://github.com/temporalio/temporalA durable execution platform for building scalable and reliable applications by automatically managing Workflow state and execution. Includes documentation on the Matching Client's partition selection and routing (Basic and Spread Routing), Google Cloud Storage (gstorage) archival configuration, and guides for implementing custom HistoryArchiver and VisibilityArchiver interfaces.
What's inside Temporal
- Temporal is a durable execution platform designed to build scalable, reliable applications. It executes units of application logic called Workflows in a resilient manner, automatically handling intermittent failures and retrying failed operations to ensure application state is preserved through interruptions.
Access Temporal Server documentation and guides
mainThe
docs/directory contains documentation specifically for those working closely with the Temporal server.- For Workflow Authors: If you are primarily interested in authoring workflows rather than managing the server, refer to the Getting Started Guide in the root directory.
- For Server Developers/Architectural Understanding: Visit the
/architecturesection for high-level explanations and diagrams of Temporal's core concepts and technological underpinnings. - For Contributors: Visit the
/developmentsection for instructions on setting up a local development environment and advanced topics like adding migrations or new RPCs. - For Administrators: Visit the
/adminsection for operational guides. Note that current production deployment, configuration, and monitoring guidance is primarily hosted on the official Temporal docs website: https://docs.temporal.io/self-hosted-guide.
What is a Replicator?
mainA Replicator is a specific type of background worker that consumes replication tasks generated by remote Temporal clusters and passes them to a processor so they can be applied to the local Temporal cluster.What is a Temporal Worker?
mainA Temporal Worker is a service role used to host components responsible for performing background processing on a Temporal cluster.What is Workflow Execution Mutable State?
mainMutable State is a collection of persisted data structures that summarize the current state of a Workflow Execution (e.g., identities of in-progress activities, timers, and child workflows).
While this state can be recomputed from the full Workflow History, storing it as Mutable State allows for much faster request handling.
Key characteristics:
- Caching: Mutable State for recently accessed workflows is cached in memory.
- Persistence: To support high-performance backends like Cassandra, Mutable State is often persisted in a single row, mirroring its in-memory layout.
- Implementation: In the Go implementation, it is represented by the
MutableStateImplstruct which implements theMutableStateinterface.
What is CHASM and how does it relate to Temporal Workflows?
mainCHASM (Coordinated Heterogeneous Application State Machines) is a framework designed for high-scale, low-latency state management. While Temporal Workflows are powerful, they can be heavyweight for certain use cases (e.g., handling millions of signals or very large payloads).
CHASM treats a Workflow as just one type of Application State Machine (ASM). An ASM leverages Temporal's underlying infrastructure—such as sharding, routing, atomic storage, and failure recovery—but provides a lighter, typed API that hides distributed systems complexity. This makes it suitable for problems where a full Workflow might be too slow or complex.
What is Nexus RPC?
mainNexus RPC is a service framework designed for long-running, arbitrary-length operations that may extend beyond the lifetime of a traditional RPC. It serves as a connectivity layer for durable executions within and across namespaces, clusters, and regions.
Services can expose two types of operations:
- Sync operations: Traditional synchronous calls.
- Async operations: These provide an operation identifier and a uniform interface to:
- Check the status of an operation or its result.
- Receive a completion callback.
- Cancel the operation.
What is Workflow Execution History?
mainWorkflow Execution History is a linear sequence of History Events that defines the state of a Workflow Execution.
- Event Sourcing: The sequence of History Events is sufficient to recover all relevant information about a workflow, including its Mutable State and pending tasks.
- Topology: While typically linear, the history can have a branching topology if a workflow has been
Resetor subject to conflict resolution. - Terminology Note: In Temporal, an "event" specifically refers to a Workflow History Event (an internal state transition) rather than an external "event-driven architecture" trigger.
- Data: Events can contain associated data, such as payloads submitted in a request.
How Nexus Operations and Callbacks are managed
mainNexus uses state machines to manage the lifecycle of operations and callbacks, ensuring reliability through retries.
Nexus Operations
Managed by the
nexusoperationscomponent. An operation transitions through states likeScheduled$\rightarrow$BackingOff$\rightarrow$Started$\rightarrow$Succeeded/Failed/Canceled/TimedOut.- Retries: Operations are continuously retried using a configurable retry policy until a terminal state is reached.
- Timeouts: The maximum schedule-to-close timeout is enforced by
component.nexusoperations.limit.scheduleToCloseTimeout. - HTTP Timeout: The timeout for a single Nexus HTTP call is
component.nexusoperations.request.timeout(default: 10s).
Callbacks
Callbacks provide a reliable mechanism for delivering workflow outcomes (success, failure, cancellation, or termination).
- Trigger: Currently, the only supported trigger is
workflow closed. - Lifecycle: The
Callbackstate machine moves fromStandby$\rightarrow$Scheduled$\rightarrow$BackingOff$\rightarrow$Succeeded/Failed. - HTTP Timeout: The timeout for a single callback HTTP call is
component.callbacks.request.timeout(default: 10s).
Understanding VersionedTransition and ComponentRef
mainCHASM uses logical clocks to provide total ordering of state changes across distributed systems.
VersionedTransition
Every transition is stamped with a
VersionedTransition, which includes:FailoverVersion: Increments during cross-DC failover.TransitionCount: Increments with every state update within the Execution.
ComponentRef (Callback mechanism)
When a component starts an external task and requires a callback, it creates a
ComponentRef. This is a serialized token containing:ExecutionKeyandComponentPath: To route the callback to the correct node.initialVT: TheVersionedTransitionwhen the node was created (guards against hitting a deleted/recreated node).lastUpdateVT: TheVersionedTransitionwhen the token was issued (guards against stale callbacks updating a node that has already moved past the expected state).
Consistency Check: When a callback arrives, the Engine verifies both
initialVTandlastUpdateVT. If there is a mismatch, the callback is rejected.How the Outbound Task Queue manages external requests
mainThe outbound task queue is an internal, sharded, "immediate" queue within the history service used to target external destinations. It is designed to handle long-running external requests (up to 10 seconds) without blocking other operations.
Isolation Mechanisms:
- Grouping: Tasks are grouped by type, source namespace, and destination to provide isolation. If one destination is down, it won't block others.
- Multi-Cursor: Allows multiple readers to consume the same queue. Slow or unavailable destinations are moved to slower readers. The number of readers per shard is controlled by
history.outboundQueueMaxReaderCount. - Scheduler Stack: Each group passes through a processing stack:
- In-Memory Buffer: Holds tasks if the scheduler cannot immediately spawn a goroutine. Size is configured via
history.outboundQueue.groupLimiter.bufferSize. - Concurrency Limiter: Controls the number of active goroutines per group via
history.outboundQueue.groupLimiter.concurrency. - Rate Limiter: Limits requests per second via
history.outboundQueue.hostScheduler.maxTaskRPS. - Circuit Breaker: Trips after 5 consecutive
DestinationDownErrors (retryable HTTP errors or timeouts) to prevent overwhelming a failing destination. Configured viahistory.outboundQueue.circuitBreakerSettings.
- In-Memory Buffer: Holds tasks if the scheduler cannot immediately spawn a goroutine. Size is configured via
Disabling the Processor: You can disable the outbound queue reader by setting
history.outboundTaskBatchSizeto0.Determine message processing order using `sequencing_id`
mainThe
sequencing_idfield is used to specify the order in which messages must be processed relative to existing events and commands.Supported values:
event_id: Indicates the specific event after which the message should be processed by the worker.command_index: Indicates the specific command after which the message should be processed by the server.
Current Implementation Details:
- Event Ordering: Currently, the server sets
event_idto the ID preceding theWorkflowTaskStartedEvent. This effectively means all messages are processed after all events due to how the server handles the reorder buffer. - Command Ordering: Currently, SDKs do not use
command_indexdirectly. Instead, they use a special command of typeCOMMAND_TYPE_PROTOCOL_MESSAGEto indicate where a message should be processed. If an Update is rejected, this command is not added, and the server assumes the message is rejected. - Query Execution: All SDKs are designed to process all queries last (after both events and messages).