voidcrawl_mcp/
sessions.rs1use std::{collections::HashMap, path::PathBuf, sync::Arc};
8
9use tempfile::TempDir;
10use tokio::sync::{Mutex, RwLock};
11use void_crawl_core::{BrowserSession, DownloadCapture, Page};
12
13pub type SessionId = String;
14
15#[derive(Debug)]
18pub struct PendingDownload {
19 pub capture: DownloadCapture,
20 pub quarantine: TempDir,
21 pub output_dir: PathBuf,
22 pub max_bytes: u64,
23}
24
25#[derive(Debug)]
27pub struct DedicatedSession {
28 pub session: Arc<BrowserSession>,
29 pub page: Mutex<Page>,
30 pub pending_download: Mutex<Option<PendingDownload>>,
32}
33
34#[derive(Debug, Default)]
36pub struct SessionRegistry {
37 inner: RwLock<HashMap<SessionId, Arc<DedicatedSession>>>,
38}
39
40impl SessionRegistry {
41 pub async fn insert(&self, id: SessionId, session: Arc<DedicatedSession>) {
42 self.inner.write().await.insert(id, session);
43 }
44
45 pub async fn get(&self, id: &str) -> Option<Arc<DedicatedSession>> {
46 self.inner.read().await.get(id).cloned()
47 }
48
49 pub async fn remove(&self, id: &str) -> Option<Arc<DedicatedSession>> {
50 self.inner.write().await.remove(id)
51 }
52
53 pub async fn len(&self) -> usize {
54 self.inner.read().await.len()
55 }
56
57 pub async fn is_empty(&self) -> bool {
58 self.inner.read().await.is_empty()
59 }
60
61 pub async fn drain(&self) -> Vec<Arc<DedicatedSession>> {
63 self.inner.write().await.drain().map(|(_, v)| v).collect()
64 }
65}