use std::{fmt, sync::Arc};
use crate::{runner, DatabasePool, SessionService, SessionStore};
use std::sync::atomic::{AtomicBool, Ordering};
use tower_layer::Layer;
static KILL_AS_DUP: AtomicBool = AtomicBool::new(false);
#[derive(Clone)]
pub struct SessionLayer<T>
where
T: DatabasePool + Clone + fmt::Debug + std::marker::Sync + std::marker::Send + 'static,
{
session_store: SessionStore<T>,
}
impl<T> SessionLayer<T>
where
T: DatabasePool + Clone + fmt::Debug + std::marker::Sync + std::marker::Send + 'static,
{
#[inline]
pub fn new(session_store: SessionStore<T>) -> Self {
SessionLayer { session_store }
}
}
impl<S, T> Layer<S> for SessionLayer<T>
where
T: DatabasePool + Clone + fmt::Debug + std::marker::Sync + std::marker::Send + 'static,
{
type Service = SessionService<S, T>;
fn layer(&self, inner: S) -> Self::Service {
let kill_as_duplicate = KILL_AS_DUP.load(Ordering::Relaxed);
let service = SessionService {
session_store: self.session_store.clone(),
handle: Arc::new(tokio::spawn(runner(
self.session_store.clone(),
kill_as_duplicate,
))),
inner,
};
KILL_AS_DUP.store(true, Ordering::Relaxed);
service
}
}