synd_runtime/session/
mod.rs1use std::time::Duration;
2
3use crate::{CapabilitySet, Result};
4#[cfg(test)]
5pub(crate) use renewal::SessionRenewalObserver;
6use renewal::{SessionLeaseRenewal, SessionLeaseRenewalHandle, SessionRenewalSchedule};
7use synd_protocol::{
8 capability,
9 session::{CloseSessionRequest, SessionId, SessionLease},
10};
11
12mod renewal;
13
14pub struct Session {
15 client: synd_client::Client,
16 available_capabilities: CapabilitySet,
17 handle: Handle,
18}
19
20impl Session {
21 pub fn new(
22 client: synd_client::Client,
23 available_capabilities: CapabilitySet,
24 handle: Handle,
25 ) -> Self {
26 Self {
27 client,
28 available_capabilities,
29 handle,
30 }
31 }
32
33 pub fn client(&self) -> &synd_client::Client {
34 &self.client
35 }
36
37 pub fn available_capabilities(&self) -> &CapabilitySet {
38 &self.available_capabilities
39 }
40
41 pub async fn close(self) -> Result<()> {
42 self.handle.close().await
43 }
44}
45
46pub struct Handle {
47 kind: HandleKind,
48}
49
50enum HandleKind {
51 Inert,
52 Daemon(Box<DaemonSessionHandle>),
53}
54
55impl Handle {
56 pub fn inert() -> Self {
57 Self {
58 kind: HandleKind::Inert,
59 }
60 }
61
62 #[cfg(not(test))]
63 pub(crate) fn daemon(
64 client: synd_client::Client,
65 session_id: SessionId,
66 lease: SessionLease,
67 ) -> Self {
68 Self {
69 kind: HandleKind::Daemon(Box::new(DaemonSessionHandle::new(
70 client, session_id, lease,
71 ))),
72 }
73 }
74
75 #[cfg(test)]
76 pub(crate) fn daemon(
77 client: synd_client::Client,
78 session_id: SessionId,
79 lease: SessionLease,
80 renewal_observer: Option<SessionRenewalObserver>,
81 ) -> Self {
82 Self {
83 kind: HandleKind::Daemon(Box::new(DaemonSessionHandle::new(
84 client,
85 session_id,
86 lease,
87 renewal_observer,
88 ))),
89 }
90 }
91
92 pub async fn close(self) -> Result<()> {
93 match self.kind {
94 HandleKind::Inert => Ok(()),
95 HandleKind::Daemon(handle) => handle.close().await,
96 }
97 }
98}
99
100struct DaemonSessionHandle {
102 client: synd_client::Client,
103 session_id: SessionId,
104 renewal: SessionLeaseRenewalHandle,
105}
106
107impl DaemonSessionHandle {
108 #[cfg(not(test))]
109 fn new(client: synd_client::Client, session_id: SessionId, lease: SessionLease) -> Self {
110 let renewal = {
111 let schedule = SessionRenewalSchedule::from_lease(lease);
112 SessionLeaseRenewal::new(client.clone(), session_id.clone(), schedule).spawn()
113 };
114
115 Self {
116 client,
117 session_id,
118 renewal,
119 }
120 }
121
122 #[cfg(test)]
123 fn new(
124 client: synd_client::Client,
125 session_id: SessionId,
126 lease: SessionLease,
127 renewal_observer: Option<SessionRenewalObserver>,
128 ) -> Self {
129 let renewal = {
130 let schedule = SessionRenewalSchedule::from_lease(lease);
131 SessionLeaseRenewal::new(
132 client.clone(),
133 session_id.clone(),
134 schedule,
135 renewal_observer,
136 )
137 .spawn()
138 };
139
140 Self {
141 client,
142 session_id,
143 renewal,
144 }
145 }
146
147 async fn close(self) -> Result<()> {
148 self.renewal.stop().await;
149 self.client
150 .close_session(CloseSessionRequest::new(self.session_id))
151 .await?;
152
153 Ok(())
154 }
155}
156
157#[derive(Debug, Clone)]
158pub struct Config {
159 acquire_timeout: Duration,
160 #[cfg(test)]
161 renewal_observer: Option<SessionRenewalObserver>,
162}
163
164impl Config {
165 pub fn new(acquire_timeout: Duration) -> Self {
166 Self {
167 acquire_timeout,
168 #[cfg(test)]
169 renewal_observer: None,
170 }
171 }
172
173 pub fn acquire_timeout(&self) -> Duration {
174 self.acquire_timeout
175 }
176
177 #[cfg(test)]
178 pub(crate) fn with_renewal_observer(mut self, observer: SessionRenewalObserver) -> Self {
179 self.renewal_observer = Some(observer);
180 self
181 }
182
183 #[cfg(test)]
184 pub(crate) fn renewal_observer(&self) -> Option<SessionRenewalObserver> {
185 self.renewal_observer.clone()
186 }
187}
188
189impl PartialEq for Config {
190 fn eq(&self, other: &Self) -> bool {
191 self.acquire_timeout == other.acquire_timeout
192 }
193}
194
195impl Eq for Config {}
196
197impl Default for Config {
198 fn default() -> Self {
199 Self::new(Duration::from_secs(5))
200 }
201}
202
203#[derive(Debug, Clone, PartialEq, Eq)]
204pub struct Requirements {
205 required_capabilities: CapabilitySet,
206}
207
208impl Requirements {
209 pub fn new(required_capabilities: CapabilitySet) -> Self {
210 Self {
211 required_capabilities,
212 }
213 }
214
215 pub fn required_capabilities(&self) -> &CapabilitySet {
216 &self.required_capabilities
217 }
218}
219
220impl Default for Requirements {
221 fn default() -> Self {
222 Self::new(capability::local_api_capabilities())
223 }
224}