System Components
The Rhythm architecture is designed around a central Rust-based core that manages workflow state and execution, a custom DSL for orchestration logic, and host-language SDKs for implementing task logic.
Core Engine (Rust)
The core engine is the "brain" of the system. It is responsible for parsing workflow scripts, managing the execution state machine, and interfacing with the database. Because the core is written in Rust, it provides a high-performance, memory-safe foundation that can be embedded into multiple host languages.
Key responsibilities of the Core Engine:
- VM Execution: Runs the custom workflow scripting language.
- Persistence Management: Saves and restores the VM state during
awaitpoints. - Queue Management: Handles the "Work Queue" and "Scheduled Queue" logic.
- Service Layer: Provides the internal API for the Host SDK to interact with executions and signals.
Workflow DSL (.flow)
Workflows in Rhythm are written in a specialized scripting language (a subset of JavaScript) and saved as .flow files. Unlike many durable execution frameworks that rely on event replaying to reconstruct state, Rhythm uses a direct state persistence model.
Features
- Intentionally Limited: Designed for orchestration, not heavy computation.
- Versioned by Hash: Workflow definitions are immutable and identified by the content hash of the script.
- Sandboxed: Scripts run in a restricted environment to ensure reliability and durability.
// Example workflow logic
let result = await Task.run("my-task", { data: Inputs.val });
if (result.success) {
await Signal.when("external-approval");
}
Host SDKs (e.g., Python)
The Host SDK acts as the bridge between your application logic and the Rhythm Core. While workflows orchestrate, Tasks are implemented in your native application language (like Python).
SDK Components
- The Client: Used to start workflows, send signals, and query execution status.
- The Worker: Polls the core for pending work (both workflow steps and task executions) and runs them within the application context.
- Task Decorators: Standard functions in your app marked as Rhythm tasks.
Storage Layer (Postgres)
Rhythm requires a Postgres database to function. It uses the database as a durable state store and a reliable message broker.
| Component | Description |
| :--- | :--- |
| Execution Table | Stores the current status, inputs, and outputs of every task and workflow. |
| Work Queue | A transactional queue for items ready for immediate processing. |
| Scheduled Queue | Stores items intended for future execution (delays and timeouts). |
| Workflow Definitions | A content-addressed store of .flow script versions. |
Internal Services
The Rhythm Application instance manages several specialized services that handle the lifecycle of a workflow.
Execution Service
Manages the creation and lifecycle of Execution objects. It tracks whether an execution is a Task or a Workflow and updates its status (Pending, Running, Suspended, Completed, or Failed).
Scheduler Service
Responsible for "delayed" durability. It manages the scheduled_queue and periodically moves items to the work_queue when their run_at time has passed. This service enables features like Task.delay() and signal timeouts.
Signal Service
Provides the mechanism for external systems to interact with running workflows. When a signal is sent, the Signal Service persists the payload and enqueues the target workflow to wake up and process the new data.
Initialization Service
Handles the "startup" logic of the system, including:
- Auto-migrations: Ensuring the Postgres schema is up to date.
- Workflow Registration: Parsing
.flowfiles and syncing them to the database definitions.