use std::sync::Arc;
use everruns_core::session_services::SessionScheduleStore;
use everruns_host::{HostBackends, ScheduleStoreFactory};
use everruns_platform::{PlatformHostBackendsExt, PlatformStore, PlatformStoreFactory};
use everruns_provider::error::Result;
use everruns_provider::typed_id::{PrincipalId, SessionId};
use super::db::SqliteDb;
use super::platform_store::{LocalPlatformStore, LocalSessionRunner};
use super::profile::LocalProfile;
use super::schedule_runner::{
LocalScheduleRunner, LocalScheduleRunnerConfig, LocalScheduleRunnerHandle,
};
use super::schedule_store::LocalScheduleStore;
use super::task_registry::LocalSessionTaskRegistry;
pub struct LocalBackends {
pub runtime_backends: HostBackends,
pub db: SqliteDb,
pub task_registry: Arc<LocalSessionTaskRegistry>,
pub profile: LocalProfile,
org_id: i64,
}
impl LocalBackends {
pub fn new(profile: LocalProfile, runtime_backends: HostBackends) -> Result<Self> {
profile
.ensure_dirs()
.map_err(|e| everruns_provider::error::AgentLoopError::config(e.to_string()))?;
let db = SqliteDb::open(profile.db_path())
.map_err(everruns_provider::error::AgentLoopError::from)?;
Self::with_db(profile, runtime_backends, db)
}
pub fn with_db(
profile: LocalProfile,
runtime_backends: HostBackends,
db: SqliteDb,
) -> Result<Self> {
let org_id = everruns_host::in_process_internal_org_id(&profile.org_public_id);
let task_registry = Arc::new(LocalSessionTaskRegistry::new(db.clone())?);
LocalScheduleStore::new(db.clone(), org_id, profile.owner_principal_id)?;
let schedule_db = db.clone();
let owner = profile.owner_principal_id;
let schedule_factory: ScheduleStoreFactory = Arc::new(move |org_id: i64| {
Arc::new(LocalScheduleStore::scoped(
schedule_db.clone(),
org_id,
owner,
)) as Arc<dyn SessionScheduleStore>
});
let runtime_backends = runtime_backends
.with_session_task_registry(task_registry.clone())
.with_schedule_store_factory(schedule_factory);
Ok(Self {
runtime_backends,
db,
task_registry,
profile,
org_id,
})
}
pub fn schedule_store(&self) -> Result<LocalScheduleStore> {
LocalScheduleStore::new(
self.db.clone(),
self.org_id,
self.profile.owner_principal_id,
)
}
pub fn start_schedule_runner(
&self,
runner: Arc<dyn LocalSessionRunner>,
) -> Result<LocalScheduleRunnerHandle> {
self.start_schedule_runner_with_config(runner, LocalScheduleRunnerConfig::default())
}
pub fn start_schedule_runner_with_config(
&self,
runner: Arc<dyn LocalSessionRunner>,
config: LocalScheduleRunnerConfig,
) -> Result<LocalScheduleRunnerHandle> {
LocalScheduleRunner::new(self.schedule_store()?, runner)
.with_config(config)
.start()
.map_err(everruns_provider::error::AgentLoopError::from)
}
pub fn with_platform_runner(mut self, runner: Arc<dyn LocalSessionRunner>) -> Self {
let factory: PlatformStoreFactory =
Arc::new(move |_org_id: i64, _session_id: SessionId| {
Arc::new(LocalPlatformStore::new(runner.clone())) as Arc<dyn PlatformStore>
});
self.runtime_backends = self.runtime_backends.with_platform_store_factory(factory);
self
}
pub fn org_id(&self) -> i64 {
self.org_id
}
pub fn owner_principal_id(&self) -> PrincipalId {
self.profile.owner_principal_id
}
}