dust_mail/client/
keep_alive.rs1use std::sync::Arc;
2
3use crate::runtime::{
4 thread::{spawn, RwLock},
5 time::{sleep, Duration},
6 JoinHandle,
7};
8
9use log::{info, trace, warn};
10
11use super::EmailClient;
12
13pub struct KeepAlive {
14 client: Arc<RwLock<EmailClient>>,
15 handle: Option<JoinHandle<()>>,
16}
17
18impl Drop for KeepAlive {
19 fn drop(&mut self) {
20 self.stop();
21 }
22}
23
24impl From<Arc<RwLock<EmailClient>>> for KeepAlive {
25 fn from(client: Arc<RwLock<EmailClient>>) -> Self {
26 Self {
27 client,
28 handle: None,
29 }
30 }
31}
32
33impl KeepAlive {
34 pub fn new(client: &Arc<RwLock<EmailClient>>) -> Self {
35 Self {
36 client: Arc::clone(client),
37 handle: None,
38 }
39 }
40
41 const CHECK_TIME: Duration = Duration::from_secs(5);
42
43 pub fn start(&mut self) {
44 self.stop();
46
47 let client = Arc::clone(&self.client);
48
49 let handle = spawn(async move {
50 loop {
51 sleep(Self::CHECK_TIME).await;
52
53 let read_lock = client.read().await;
54
55 trace!("Checking if keep alive request is needed");
56
57 if read_lock.should_keep_alive() {
58 let mut write_lock = client.write().await;
59
60 info!("Sending keep alive request to mail server");
61
62 if let Err(err) = write_lock.send_keep_alive().await {
63 warn!("Failed to send keep alive request to mail server: {}", err)
64 }
65 }
66 }
67 });
68
69 self.handle = Some(handle);
70 }
71
72 pub fn stop(&mut self) {
73 if let Some(_handle) = &self.handle {
74 info!("Stopping keep alive requests");
75
76 #[cfg(feature = "runtime-tokio")]
77 _handle.abort();
78
79 self.handle = None;
80 }
81 }
82}