use std::sync::Arc;
use chronon_core::store::SchedulerStore;
use chronon_executor::Executor;
use chronon_scheduler::Scheduler;
use tokio::sync::Notify;
use crate::builder::DeploymentShape;
use crate::coordinator_service::CoordinatorService;
use crate::coordinator::run_coordinator_loops;
use crate::embedded::run_embedded_loops;
use crate::events::spawn_event_handler;
use crate::worker::run_worker_loop;
pub struct Chronon {
pub store: Arc<dyn SchedulerStore>,
pub scheduler: Arc<Scheduler>,
pub executor: Arc<Executor>,
pub coordinator: CoordinatorService,
pub deployment: DeploymentShape,
shutdown: Arc<Notify>,
event_rx: Option<tokio::sync::mpsc::UnboundedReceiver<chronon_executor::ExecutorEvent>>,
}
impl Chronon {
pub(crate) fn new(
store: Arc<dyn SchedulerStore>,
scheduler: Arc<Scheduler>,
executor: Arc<Executor>,
deployment: DeploymentShape,
shutdown: Arc<Notify>,
event_rx: tokio::sync::mpsc::UnboundedReceiver<chronon_executor::ExecutorEvent>,
) -> Self {
let coordinator = CoordinatorService::new(store.clone());
Self {
store,
scheduler,
executor,
coordinator,
deployment,
shutdown,
event_rx: Some(event_rx),
}
}
pub fn shutdown(&self) {
self.shutdown.notify_waiters();
}
pub fn shutdown_handle(&self) -> Arc<Notify> {
Arc::clone(&self.shutdown)
}
pub async fn run(&mut self) -> chronon_core::Result<()> {
if let Some(rx) = self.event_rx.take() {
spawn_event_handler(Arc::clone(&self.store), rx);
}
let shutdown = Arc::clone(&self.shutdown);
let scheduler = Arc::clone(&self.scheduler);
let executor = Arc::clone(&self.executor);
let telemetry = scheduler.telemetry();
match &self.deployment {
DeploymentShape::RemoteClient(_) => {
return Err(chronon_core::ChrononError::Internal(
"remote client does not run local scheduler loop".into(),
));
}
DeploymentShape::Embedded => {
run_embedded_loops(scheduler, executor, telemetry, shutdown).await;
}
DeploymentShape::CoordinatorOnly => {
run_coordinator_loops(scheduler, telemetry, shutdown).await;
}
DeploymentShape::Worker(pool) => {
run_worker_loop(
self.store.clone(),
executor,
telemetry,
pool.clone(),
scheduler.instance_id().to_string(),
shutdown,
)
.await;
}
}
Ok(())
}
pub async fn tick_once(&self) -> chronon_core::Result<chronon_scheduler::TickResult> {
self.scheduler.tick_once().await
}
pub fn coordinator_service(&self) -> &CoordinatorService {
&self.coordinator
}
pub fn executor(&self) -> &Executor {
&self.executor
}
}