Story: Scheduling subsystem
Table of Contents
This page documents a story in Sprint 13. It captures the goal, current status, acceptance criteria, and the tasks that compose it.
Goal
Stand up the scheduling subsystem end-to-end: ores.scheduler library wrapping pg_cron, a binary-protocol surface, and the message queue that supports it.
Status
| Field | Value |
|---|---|
| State | DONE |
| Parent sprint | Sprint 13 |
| Now | Completed 2026-02-27. |
| Waiting on | None. |
| Next | None. |
| Last touched | 2026-02-27 |
Continued in: Custom MQ tables and in-process scheduler (sprint 14) — replaces the pg_cron-backed scheduler from this story with an in-process boost::asio scheduler loop alongside the custom MQ tables.
Acceptance
- ores.scheduler library with fluent API (Quartz.NET-style).
- Scheduler subsystem 0x9000-0x9FFF on the comms protocol; protocol 45.0.
- Message queue available for async processing.
Tasks
| Task | State | Start | End | Description |
|---|---|---|---|---|
| Add scheduler binary protocol | DONE | 2026-05-20 | 2026-02-26 | Open scheduler subsystem 0x9000-0x9FFF in the comms protocol; four request/response pairs (get_job_definitions / schedule_job / unschedule_job / get_job_history); registrar pattern; rfl::Reflector for cron_expression + job_status placed in ores.scheduler/rfl/reflectors.hpp to avoid circular dep with ores.utility; protocol 45.0 (breaking). |
| Add scheduling support | DONE | 2026-05-20 | 2026-02-27 | ores.scheduler library wraps pg_cron via Quartz.NET-style fluent API: job_definition / job_instance / job_definition_builder / cron_scheduler. Hand-crafted ores_scheduler_job_definitions_tbl linked to cron.job via cron_job_id; reads from cron.job_run_details directly. croncpp for cron_expression with std::expected error handling; utility::uuid::tenant_id for tenant isolation. |
| Add a message queue | DONE | 2026-05-20 | 2026-02-27 | Basic queue infrastructure for asynchronous processing — sets up the foundation that the scheduling subsystem and future trade-import paths will both consume. |
Decisions
- pg_cron, not a separate scheduler
- lifecycles + history live in Postgres where the rest of the state already does.
- croncpp for the expression
- third-party C++ library; bridges the 5-field/6-field cron format difference.
- Hand-crafted job_definitions table
- cron_job_id bigint + is_active integer don't fit the standard codegen templates.
Out of scope
- Scheduler UI (deferred).
See also
None.