chronon_runtime/
runtime.rs1use std::sync::Arc;
4
5use chronon_core::store::SchedulerStore;
6use chronon_executor::Executor;
7use chronon_scheduler::Scheduler;
8use tokio::sync::Notify;
9
10use crate::builder::DeploymentShape;
11use crate::coordinator_service::CoordinatorService;
12use crate::coordinator::run_coordinator_loops;
13use crate::embedded::run_embedded_loops;
14use crate::events::spawn_event_handler;
15use crate::worker::run_worker_loop;
16
17pub struct Chronon {
22 pub store: Arc<dyn SchedulerStore>,
24 pub scheduler: Arc<Scheduler>,
26 pub executor: Arc<Executor>,
28 pub coordinator: CoordinatorService,
30 pub deployment: DeploymentShape,
32 shutdown: Arc<Notify>,
33 event_rx: Option<tokio::sync::mpsc::UnboundedReceiver<chronon_executor::ExecutorEvent>>,
34}
35
36impl Chronon {
37 pub(crate) fn new(
38 store: Arc<dyn SchedulerStore>,
39 scheduler: Arc<Scheduler>,
40 executor: Arc<Executor>,
41 deployment: DeploymentShape,
42 shutdown: Arc<Notify>,
43 event_rx: tokio::sync::mpsc::UnboundedReceiver<chronon_executor::ExecutorEvent>,
44 ) -> Self {
45 let coordinator = CoordinatorService::new(store.clone());
46 Self {
47 store,
48 scheduler,
49 executor,
50 coordinator,
51 deployment,
52 shutdown,
53 event_rx: Some(event_rx),
54 }
55 }
56
57 pub fn shutdown(&self) {
59 self.shutdown.notify_waiters();
60 }
61
62 pub fn shutdown_handle(&self) -> Arc<Notify> {
64 Arc::clone(&self.shutdown)
65 }
66
67 pub async fn run(&mut self) -> chronon_core::Result<()> {
71 if let Some(rx) = self.event_rx.take() {
72 spawn_event_handler(Arc::clone(&self.store), rx);
73 }
74
75 let shutdown = Arc::clone(&self.shutdown);
76 let scheduler = Arc::clone(&self.scheduler);
77 let executor = Arc::clone(&self.executor);
78 let telemetry = scheduler.telemetry();
79
80 match &self.deployment {
81 DeploymentShape::RemoteClient(_) => {
82 return Err(chronon_core::ChrononError::Internal(
83 "remote client does not run local scheduler loop".into(),
84 ));
85 }
86 DeploymentShape::Embedded => {
87 run_embedded_loops(scheduler, executor, telemetry, shutdown).await;
88 }
89 DeploymentShape::CoordinatorOnly => {
90 run_coordinator_loops(scheduler, telemetry, shutdown).await;
91 }
92 DeploymentShape::Worker(pool) => {
93 run_worker_loop(
94 self.store.clone(),
95 executor,
96 telemetry,
97 pool.clone(),
98 scheduler.instance_id().to_string(),
99 shutdown,
100 )
101 .await;
102 }
103 }
104 Ok(())
105 }
106
107 pub async fn tick_once(&self) -> chronon_core::Result<chronon_scheduler::TickResult> {
109 self.scheduler.tick_once().await
110 }
111
112 pub fn coordinator_service(&self) -> &CoordinatorService {
114 &self.coordinator
115 }
116
117 pub fn executor(&self) -> &Executor {
119 &self.executor
120 }
121}