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); /// Sessions Layer used with Axum to activate the Service. /// /// # Examples /// ```rust ignore /// use session::{SessionNullPool, SessionConfig, SessionStore, SessionLayer}; /// use uuid::Uuid; /// /// let config = SessionConfig::default(); /// let session_store = SessionStore::::new(None, config).await.unwrap(); /// let layer = SessionLayer::new(session_store); /// ``` /// #[derive(Clone)] pub struct SessionLayer where T: DatabasePool + Clone + fmt::Debug + std::marker::Sync + std::marker::Send + 'static, { session_store: SessionStore, } impl SessionLayer where T: DatabasePool + Clone + fmt::Debug + std::marker::Sync + std::marker::Send + 'static, { /// Constructs a SessionLayer used with Axum to activate the Service. /// /// # Examples /// ```rust ignore /// use session::{SessionNullPool, SessionConfig, SessionStore, SessionLayer}; /// use uuid::Uuid; /// /// let config = SessionConfig::default(); /// let session_store = SessionStore::::new(None, config).await.unwrap(); /// let layer = SessionLayer::new(session_store); /// ``` /// #[inline] pub fn new(session_store: SessionStore) -> Self { SessionLayer { session_store } } } impl Layer for SessionLayer where T: DatabasePool + Clone + fmt::Debug + std::marker::Sync + std::marker::Send + 'static, { type Service = SessionService; 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 } }