Skip to main content

deribit_websocket/session/
ws_session.rs

1//! WebSocket session management
2
3use crate::config::WebSocketConfig;
4use crate::model::ConnectionState;
5use crate::model::subscription::SubscriptionManager;
6use std::sync::Arc;
7use tokio::sync::Mutex;
8
9/// WebSocket session manager
10#[derive(Debug)]
11pub struct WebSocketSession {
12    config: Arc<WebSocketConfig>,
13    state: Arc<Mutex<ConnectionState>>,
14    subscription_manager: Arc<Mutex<SubscriptionManager>>,
15}
16
17impl WebSocketSession {
18    /// Create a new WebSocket session.
19    ///
20    /// Accepts anything convertible into `Arc<WebSocketConfig>`, which
21    /// via Rust's blanket `impl<T> From<T> for Arc<T>` covers both an
22    /// owned `WebSocketConfig` (wrapped once here) and an existing
23    /// `Arc<WebSocketConfig>` shared with
24    /// [`crate::client::DeribitWebSocketClient`] (zero extra copies).
25    /// This keeps the constructor backward-compatible with pre-existing
26    /// owned-value call sites while also giving the client a zero-copy
27    /// path for its shared configuration.
28    pub fn new(
29        config: impl Into<Arc<WebSocketConfig>>,
30        subscription_manager: Arc<Mutex<SubscriptionManager>>,
31    ) -> Self {
32        Self {
33            config: config.into(),
34            state: Arc::new(Mutex::new(ConnectionState::Disconnected)),
35            subscription_manager,
36        }
37    }
38
39    /// Get the current connection state
40    pub async fn state(&self) -> ConnectionState {
41        self.state.lock().await.clone()
42    }
43
44    /// Set the connection state
45    pub async fn set_state(&self, new_state: ConnectionState) {
46        *self.state.lock().await = new_state;
47    }
48
49    /// Get the configuration
50    pub fn config(&self) -> &WebSocketConfig {
51        &self.config
52    }
53
54    /// Get the subscription manager
55    pub fn subscription_manager(&self) -> Arc<Mutex<SubscriptionManager>> {
56        Arc::clone(&self.subscription_manager)
57    }
58
59    /// Check if session is connected
60    pub async fn is_connected(&self) -> bool {
61        matches!(
62            *self.state.lock().await,
63            ConnectionState::Connected | ConnectionState::Authenticated
64        )
65    }
66
67    /// Check if session is authenticated
68    pub async fn is_authenticated(&self) -> bool {
69        matches!(*self.state.lock().await, ConnectionState::Authenticated)
70    }
71
72    /// Mark session as authenticated
73    pub async fn mark_authenticated(&self) {
74        self.set_state(ConnectionState::Authenticated).await;
75    }
76
77    /// Mark session as disconnected
78    pub async fn mark_disconnected(&self) {
79        self.set_state(ConnectionState::Disconnected).await;
80        // Deactivate all subscriptions but preserve their entries so
81        // `reactivate_subscriptions` can restore them on reconnect.
82        self.subscription_manager.lock().await.deactivate_all();
83    }
84
85    /// Reactivate subscriptions after reconnection
86    pub async fn reactivate_subscriptions(&self) {
87        self.subscription_manager.lock().await.reactivate_all();
88    }
89}