Skip to main content

syncweb_core/sync/
sessions.rs

1use std::sync::{Mutex, OnceLock};
2
3use iroh_docs::NamespaceId;
4use tokio::sync::mpsc;
5
6use super::SyncCommand;
7
8type CancelSender = mpsc::UnboundedSender<SyncCommand>;
9type Registry = Vec<(NamespaceId, CancelSender)>;
10
11static REGISTRY: OnceLock<Mutex<Registry>> = OnceLock::new();
12
13fn registry() -> &'static Mutex<Registry> {
14    REGISTRY.get_or_init(|| Mutex::new(Vec::new()))
15}
16
17pub struct ActiveSession {
18    namespace: NamespaceId,
19}
20
21impl ActiveSession {
22    #[must_use]
23    pub fn register(namespace: NamespaceId, cancel: CancelSender) -> Self {
24        if let Ok(mut guard) = registry().lock() {
25            guard.retain(|(id, _)| *id != namespace);
26            guard.push((namespace, cancel));
27        }
28        Self { namespace }
29    }
30}
31
32impl Drop for ActiveSession {
33    fn drop(&mut self) {
34        if let Ok(mut guard) = registry().lock() {
35            guard.retain(|(id, _)| *id != self.namespace);
36        }
37    }
38}
39
40#[must_use]
41pub fn cancel_session(namespace: NamespaceId) -> bool {
42    if let Ok(mut guard) = registry().lock()
43        && let Some(pos) = guard.iter().position(|(id, _)| *id == namespace)
44    {
45        let (_, cancel) = guard.remove(pos);
46        return cancel.send(SyncCommand::Cancel).is_ok();
47    }
48    false
49}
50
51#[must_use]
52pub fn is_active(namespace: NamespaceId) -> bool {
53    registry()
54        .lock()
55        .is_ok_and(|guard| guard.iter().any(|(id, _)| *id == namespace))
56}