use std::sync::Arc;
use everruns_core::error::Result;
use everruns_core::platform_store::PlatformStore;
use everruns_core::traits::SessionScheduleStore;
use everruns_core::typed_id::{PrincipalId, SessionId};
use everruns_runtime::{PlatformStoreFactory, RuntimeBackends, ScheduleStoreFactory};
use crate::db::SqliteDb;
use crate::platform_store::{LocalPlatformStore, LocalSessionRunner};
use crate::profile::LocalProfile;
use crate::schedule_store::LocalScheduleStore;
use crate::task_registry::LocalSessionTaskRegistry;
pub struct LocalBackends {
pub runtime_backends: RuntimeBackends,
pub db: SqliteDb,
pub task_registry: Arc<LocalSessionTaskRegistry>,
pub profile: LocalProfile,
org_id: i64,
}
impl LocalBackends {
pub fn new(profile: LocalProfile, runtime_backends: RuntimeBackends) -> Result<Self> {
profile
.ensure_dirs()
.map_err(|e| everruns_core::AgentLoopError::config(e.to_string()))?;
let db = SqliteDb::open(profile.db_path()).map_err(everruns_core::AgentLoopError::from)?;
Self::with_db(profile, runtime_backends, db)
}
pub fn with_db(
profile: LocalProfile,
runtime_backends: RuntimeBackends,
db: SqliteDb,
) -> Result<Self> {
let org_id = everruns_runtime::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 with_platform_runner(mut self, runner: Arc<dyn LocalSessionRunner>) -> Self {
let base_url = self.profile.base_url.clone();
let factory: PlatformStoreFactory =
Arc::new(move |_org_id: i64, _session_id: SessionId| {
Arc::new(LocalPlatformStore::new(runner.clone(), base_url.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
}
}