The task broker is the seam between Aether’s scheduling engine and the workers that execute tasks. The engine decides which tasks to run and when; the broker decides where and how they run. This boundary is the only point in the system where the deployment topology is encoded — swap the broker implementation and the same workflow definitions execute in-process, over a message queue, or across a fleet of remote workers, without touching a single workflow document or executor plugin.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/BabySid/aether/llms.txt
Use this file to discover all available pages before exploring further.
The TaskBroker interface
- Engine-side methods
- Worker-side methods
Dispatch — the engine calls this when a task becomes ready to run. The broker decides how to deliver the assignment: enqueue it to a channel, push to Redis, publish to a message queue, or invoke an HTTP endpoint. The engine does not care.Cancel — the engine calls this when a workflow is cancelled or a task times out. The broker propagates the signal however it can: cancel a Go context, send a remote kill signal, or mark the task for rejection in a queue.FetchTask, StartTask, and CompleteTask simultaneously.
Callback types
Two function types connect the broker to the engine’s internal lifecycle handlers:TaskBroker interface contract. They are convenience types for local implementations that invoke engine callbacks directly. Distributed implementations typically publish events to a message bus instead and let a separate consumer call into the engine.
TaskAssignment: the fat assignment
TaskAssignment carries everything a worker needs to execute a task. Workers are fully self-contained — they never call back into store.Store. This design:
- Eliminates distributed coupling between workers and the store
- Makes workers simple, testable, and independently deployable
- Allows a single broker interface to serve both local and remote topologies
TaskResult
WorkflowRunID is mirrored from the assignment so the engine can locate the correct scope for advancing the workflow without an additional store round-trip. Phase and Metrics are not included — they are framework concerns derived by the engine from ExecOutputs.Code.
Local vs distributed broker patterns
Local broker
Routes tasks through an in-process channel. Workers run as goroutines.
StartTask and CompleteTask directly invoke the engine’s OnTaskStarted and OnTaskCompleted callbacks. Zero network latency; single process.Distributed broker
Routes tasks through an external medium (Redis, RabbitMQ, Kafka, gRPC).
Dispatch publishes to the queue; a separate consumer process calls FetchTask, executes the task, and calls CompleteTask, which publishes the result to a result queue consumed by the engine. Multiple workers, multiple processes.TaskBroker interface encodes no assumptions about which pattern is in use. Both patterns are valid implementations of the same interface.
Engine option
WithTaskBroker is required. The engine will fail at startup without a broker.
Reference implementation: LocalBroker
The playgroundLocalBroker is a complete, production-quality local implementation. Study it to understand the threading model and callback contract.
Dispatch
Creates a per-task context (with optional timeout derived fromassignment.Timeout), stores the cancel function for later Cancel calls, and sends the assignment to a buffered channel.
Cancel
Looks up the cancel function bytaskRunID and invokes it, propagating cancellation to the task’s context.
FetchTask
Blocks on the channel until an assignment arrives or the context is cancelled.StartTask and CompleteTask
StartTask directly invokes the StartHandler (the engine’s OnTaskStarted). CompleteTask cleans up per-task state and invokes the CompletionHandler (the engine’s OnTaskCompleted).
Close
Cancels all in-flight task contexts, closes the task channel, and signals the worker to stop.Thread-safety requirements
YourTaskBroker implementation must protect all shared state with appropriate synchronisation. In LocalBroker, taskCtxs and cancels are protected by mu because Dispatch (engine goroutine) and Cancel (engine goroutine) may race with CleanupTask (worker goroutines calling CompleteTask). The channel itself is safe for concurrent send and receive.