use alloc::sync::Arc;
use core::sync::atomic::{AtomicBool, Ordering};
use core::time::Duration;
#[derive(Debug, Clone)]
pub enum RetentionPolicy {
TimeBased(Duration),
CountBased(usize),
Hybrid(Duration, usize),
}
pub struct LifecycleManager {
retention_period: Duration,
cleanup_interval: Duration,
running: Arc<AtomicBool>,
cleanup_callback: Option<Arc<dyn Fn() + Send + Sync + 'static>>,
}
impl LifecycleManager {
pub fn new(retention_period: Duration) -> Self {
Self {
retention_period,
cleanup_interval: Duration::from_secs(5 * 60), running: Arc::new(AtomicBool::new(false)),
cleanup_callback: None,
}
}
pub fn set_cleanup_interval(&mut self, interval: Duration) {
self.cleanup_interval = interval;
}
pub fn set_cleanup_callback<F>(&mut self, callback: F)
where
F: Fn() + Send + Sync + 'static,
{
self.cleanup_callback = Some(Arc::new(callback));
}
pub fn get_current_timestamp() -> u64 {
#[cfg(feature = "std")]
{
use std::time::SystemTime;
SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap_or(std::time::Duration::ZERO)
.as_secs()
}
#[cfg(not(feature = "std"))]
{
0
}
}
pub fn is_expired(&self, timestamp: u64) -> bool {
let now = Self::get_current_timestamp();
let expire_time = now - self.retention_period.as_secs();
timestamp < expire_time
}
pub fn start(&self) {
if self.running.load(Ordering::SeqCst) {
return;
}
self.running.store(true, Ordering::SeqCst);
#[cfg(feature = "std")]
{
let cleanup_interval = self.cleanup_interval;
let running = self.running.clone();
let cleanup = self.cleanup_callback.clone();
std::thread::spawn(move || {
while running.load(Ordering::SeqCst) {
if let Some(callback) = cleanup.as_ref() {
callback();
}
std::thread::sleep(cleanup_interval);
}
});
}
}
pub fn stop(&self) {
self.running.store(false, Ordering::SeqCst);
}
pub fn cleanup(&self) {
if let Some(callback) = &self.cleanup_callback {
callback();
}
}
}