Chronon

Scheduled orchestration from Rust macros to runtime UI

Chronon schedules cron and run-once jobs with typed script handlers, durable job and run history, and optional coordinator and worker processes.

Why this family exists

Chronon provides a SchedulerStore port for mem, SQLite, PostgreSQL, or PostgreSQL with Redis, plus #[chronon::script] typed parameters and builders for embedded, coordinator, worker, or remote-client topologies. Jobs reference stable script names; each run records one attempt with status and timings; revisions version config changes.

Where it lands

Unified Field schedules Chronon scripts alongside product UI so recurring cleanup, scans, and Gluon scale targets share the same Valence-aware runtime context as interactive requests.
Define scripts with #[chronon::script], upsert Job records with Cron, Manual, or run-once schedules, and let Chronon::builder() wire the store, context factory, and auto-registry. Host ContextFactory reconstructs execution context from stored JSON so identity at schedule time can differ from run time. The capacity campaign runs 500 midnight jobs with recurring schedules on embedded SQLite and on coordinator-worker hosts. Resources also keeps the 16-cell store-claim component study. Published as uf-chronon; Rust imports use chronon::.

In the workspace

Unified Field schedules Chronon scripts alongside product UI so recurring cleanup, scans, and Gluon scale targets share the same Valence-aware runtime context as interactive requests.

Code sample

From the upstream getting-started docs — see also all code recipes on Resources.
Chronon scriptChronon
Cron job + typed #[chronon::script]
use std::sync::Arc;
use chronon::prelude::*;
use chronon::InMemorySchedulerStore;

#[chronon::script(name = "nightly_cleanup")]
async fn nightly_cleanup(
    ctx: Box<dyn ScriptContext>,
    retention_days: u32,
) -> chronon::Result<()> {
    println!("{}: retaining {retention_days} days", ctx.label());
    Ok(())
}

#[tokio::main]
async fn main() -> chronon::Result<()> {
    let chronon = Chronon::builder()
        .scheduler_store(Arc::new(InMemorySchedulerStore::new()))
        .context_factory(Arc::new(JsonScriptContextFactory))
        .embedded()
        .auto_registry()
        .build()?;

    let mut nightly = Job::new("nightly-schedule", "nightly_cleanup");
    nightly.schedule_kind = ScheduleKind::Cron;
    nightly.cron_expr = Some("0 2 * * *".into());
    nightly.timezone = Some("UTC".into());
    nightly.params_json = serde_json::json!({ "retention_days": 7 });
    chronon.coordinator_service().upsert_job(nightly).await?;

    chronon.run().await
}