1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//! Redis ready-queue composite over a SQL [`SchedulerStore`](chronon_core::store::SchedulerStore).
//!
//! **When to use:** production **coordinator–worker** (and embedded) when you want Postgres
//! durability with a Redis claim hot path. Enable **`postgres` and `redis`** on the `chronon`
//! crate.
//!
//! Getting started:
//! [Embedded](https://docs.rs/uf-chronon/latest/chronon/index.html#embedded-one-process) /
//! [Coordinator–worker](https://docs.rs/uf-chronon/latest/chronon/index.html#coordinator-worker-split).
//!
//! ## Stack position
//!
//! ```text
//! chronon (public crate, `postgres` + `redis` features) → chronon-backend-redis → chronon-backend-{postgres,sql-common} → chronon-core
//! ```
//!
//! PostgreSQL holds durable admin/history state; Redis sorted sets (`{prefix}:ready:{pool}`)
//! provide fast, ordered run claims.
//!
//! ## Entry points
//!
//! - [`RedisQueueLayer`] — ZADD / ZPOPMIN queue primitives
//! - [`PostgresRedisSchedulerStore`] — composite store delegating to SQL + Redis
//!
//! ## Prerequisites
//!
//! - Set `CHRONON_POSTGRES_URL` and `CHRONON_REDIS_URL` (or `CHRONON_TEST_*` in tests).
//! - Optional Redis **key prefix** to isolate tenants (`connect(..., Some("myapp"))`).
//!
//! ## Embedded
//!
//! ```ignore
//! use std::sync::Arc;
//! use chronon::prelude::*;
//! use chronon::{PostgresRedisSchedulerStore, PostgresSchedulerStore, RedisQueueLayer};
//!
//! let pg = std::env::var("CHRONON_POSTGRES_URL")?;
//! let redis_url = std::env::var("CHRONON_REDIS_URL")?;
//! let sql: Arc<dyn SchedulerStore> =
//! Arc::new(PostgresSchedulerStore::connect(&pg).await?);
//! let redis = RedisQueueLayer::connect(&redis_url, None).await?;
//! let store = PostgresRedisSchedulerStore::new(sql, redis);
//! let chronon = ChrononBuilder::new()
//! .scheduler_store(Arc::new(store))
//! .context_factory(Arc::new(JsonScriptContextFactory))
//! .embedded()
//! .auto_registry()
//! .build()?;
//! ```
//!
//! Runnable: `cargo run -p uf-chronon --example postgres_redis_boot --features postgres,redis`
//!
//! ## Coordinator binary
//!
//! Shared Postgres + Redis with workers. Tick only:
//!
//! ```ignore
//! use std::sync::Arc;
//! use chronon::prelude::*;
//! use chronon::{PostgresRedisSchedulerStore, PostgresSchedulerStore, RedisQueueLayer};
//!
//! let pg = std::env::var("CHRONON_POSTGRES_URL")?;
//! let redis_url = std::env::var("CHRONON_REDIS_URL")?;
//! let sql: Arc<dyn SchedulerStore> =
//! Arc::new(PostgresSchedulerStore::connect(&pg).await?);
//! let redis = RedisQueueLayer::connect(&redis_url, None).await?;
//! let store = PostgresRedisSchedulerStore::new(sql, redis);
//! let mut chronon = ChrononBuilder::new()
//! .scheduler_store(Arc::new(store))
//! .context_factory(Arc::new(JsonScriptContextFactory))
//! .instance_id("coordinator-0")
//! .coordinator_only()
//! .build()?;
//! chronon.scheduler.init_partitions().await;
//! chronon.run().await?;
//! ```
//!
//! Runnable: `cargo run -p uf-chronon --example coordinator_daemon --features postgres,redis`
//!
//! ## Worker binary
//!
//! Same URLs, unique `CHRONON_INSTANCE_ID`, scripts via `.auto_registry()`:
//!
//! ```ignore
//! use std::sync::Arc;
//! use chronon::prelude::*;
//! use chronon::{PostgresRedisSchedulerStore, PostgresSchedulerStore, RedisQueueLayer};
//!
//! let pg = std::env::var("CHRONON_POSTGRES_URL")?;
//! let redis_url = std::env::var("CHRONON_REDIS_URL")?;
//! let sql: Arc<dyn SchedulerStore> =
//! Arc::new(PostgresSchedulerStore::connect(&pg).await?);
//! let redis = RedisQueueLayer::connect(&redis_url, None).await?;
//! let store = PostgresRedisSchedulerStore::new(sql, redis);
//! let mut chronon = ChrononBuilder::new()
//! .scheduler_store(Arc::new(store))
//! .context_factory(Arc::new(JsonScriptContextFactory))
//! .instance_id(std::env::var("CHRONON_INSTANCE_ID").unwrap_or_else(|_| "worker-1".into()))
//! .auto_registry()
//! .worker(std::env::var("CHRONON_WORKER_POOL").unwrap_or_else(|_| "general".into()))
//! .build()?;
//! chronon.run().await?;
//! ```
//!
//! Runnable: `cargo run -p uf-chronon --example worker_daemon --features postgres,redis`
pub use PostgresRedisSchedulerStore;
pub use RedisQueueLayer;