use solti_model::{
AdmissionPolicy, BackoffPolicy, JitterPolicy, RestartPolicy, TaskKind, TaskSpec,
};
use taskvisor::{TaskError, TaskFn, TaskRef};
use tokio_util::sync::CancellationToken;
use tracing::debug;
use crate::logger::object::timezone::sync_local_offset;
pub const TZ_SYNC_SLOT: &str = "solti-logger-tz-sync";
pub const TZ_SYNC_TIMEOUT_MS: u64 = 60_000;
pub const TZ_SYNC_PERIOD_MS: u64 = 3_600_000;
const BACKOFF_FIRST_MS: u64 = 5_000;
const BACKOFF_MAX_MS: u64 = 300_000;
const BACKOFF_FACTOR: f64 = 2.0;
pub fn timezone_sync() -> (TaskRef, TaskSpec) {
let task: TaskRef = TaskFn::arc(TZ_SYNC_SLOT, |ctx: CancellationToken| async move {
debug!("timezone sync started");
if ctx.is_cancelled() {
return Err(TaskError::Canceled);
}
match sync_local_offset() {
Ok(()) => {
debug!("timezone offset sync success");
Ok(())
}
Err(e) => Err(TaskError::Fail {
reason: format!("failed to sync timezone offset: {e}"),
exit_code: None,
}),
}
});
let backoff = BackoffPolicy {
jitter: JitterPolicy::Equal,
first_ms: BACKOFF_FIRST_MS,
max_ms: BACKOFF_MAX_MS,
factor: BACKOFF_FACTOR,
};
let spec = TaskSpec::builder(TZ_SYNC_SLOT, TaskKind::Embedded, TZ_SYNC_TIMEOUT_MS)
.restart(RestartPolicy::periodic(TZ_SYNC_PERIOD_MS))
.backoff(backoff)
.admission(AdmissionPolicy::Replace)
.build()
.expect("timezone sync spec must be valid");
(task, spec)
}