syncweb_core/sync/
sessions.rs1use 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}