use std::sync::{Arc, Mutex, OnceLock};
use apcore::{Config, Executor, Registry, ACL};
use crate::config::get_apcore_settings;
static REGISTRY: OnceLock<Arc<Mutex<Registry>>> = OnceLock::new();
static EXECUTOR: OnceLock<Arc<Executor>> = OnceLock::new();
pub fn get_registry() -> Arc<Mutex<Registry>> {
REGISTRY
.get_or_init(|| {
tracing::debug!("Initializing apcore Registry");
Arc::new(Mutex::new(Registry::new()))
})
.clone()
}
pub fn get_executor() -> Arc<Executor> {
EXECUTOR
.get_or_init(|| {
tracing::debug!("Initializing apcore Executor");
let registry = Registry::new();
let config = build_config();
match load_acl() {
Some(acl) => Arc::new(Executor::with_options(
registry,
config,
None,
Some(acl),
None,
)),
None => Arc::new(Executor::new(registry, config)),
}
})
.clone()
}
fn load_acl() -> Option<ACL> {
let settings = get_apcore_settings();
let path = settings.acl_path.as_deref()?;
match ACL::load(path) {
Ok(acl) => {
tracing::info!(acl_path = path, "Loaded ACL for executor");
Some(acl)
}
Err(e) => {
tracing::error!(acl_path = path, error = %e.message, "Failed to load ACL; proceeding without access control");
None
}
}
}
fn build_config() -> Config {
let settings = get_apcore_settings();
let mut config = Config::from_defaults();
config.modules_path = Some(settings.module_dir.clone());
config.observability.tracing.enabled = settings.tracing;
config.observability.metrics.enabled = settings.metrics;
config
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_registry_returns_same_instance() {
let r1 = get_registry();
let r2 = get_registry();
assert!(Arc::ptr_eq(&r1, &r2));
}
}