use crate::{IdWorker, IdWorkerConfig, IdWorkerError, IdWorkerGenerator, ID_WORKER_CONFIG_KEY};
use arc_swap::ArcSwapOption;
use config::Value;
use std::collections::HashMap;
use std::sync::Arc;
use tracing::info;
use wheel_rs::config_utils::has_config_changed;
struct IdWorkerRef(Arc<dyn IdWorker>);
static ID_WORKER: ArcSwapOption<IdWorkerRef> = ArcSwapOption::const_empty();
fn get_id_worker() -> Result<Arc<dyn IdWorker>, IdWorkerError> {
ID_WORKER
.load_full()
.map(|r| Arc::clone(&r.0))
.ok_or(IdWorkerError::GetIdWorker())
}
pub fn setup_id_worker(
id_worker_config: IdWorkerConfig,
changed: &Option<HashMap<String, Value>>,
) -> Result<(), IdWorkerError> {
info!("setup id worker...: {id_worker_config:?}");
if changed
.as_ref()
.map(|changed| has_config_changed(ID_WORKER_CONFIG_KEY, changed))
.unwrap_or(true)
{
let id_worker = IdWorkerGenerator::generate(id_worker_config)?;
ID_WORKER.store(Some(Arc::new(IdWorkerRef(id_worker))));
}
Ok(())
}
pub fn next_id() -> Result<u64, IdWorkerError> {
get_id_worker()?.next_id()
}