bader_db/
lib.rs

1mod server;
2mod cache;
3mod resp;
4
5use std::time::Duration;
6use std::sync::Arc;
7use tokio::{net::TcpListener, sync::broadcast, signal};
8
9use crate::server::Server;
10use crate::cache::Cache;
11
12pub async fn run_server(socket_addr: &str,
13                        sample: usize,
14                        threshold: f64,
15                        frequency: Duration) {
16
17    // Bind a tcp listener
18    let listener = TcpListener::bind(socket_addr).await.unwrap();
19
20    // Create the shutdown signal which will shutdown when we hit ctrl_c
21    let shutdown = signal::ctrl_c();
22
23    // Channels used for a graceful shutdown
24    let (notify_shutdown, _) = broadcast::channel(1);
25
26    // Create the main_cache arc that we clone in every connection. We only clone a ref to the store
27    // which makes it inexpensive
28    let main_cache = Arc::new(Cache::new(
29        sample,
30        threshold,
31        frequency,
32    ));
33
34    // Create a a cache clone to spawn the cache monitor_for_expiry
35    let clone = main_cache.clone();
36
37    let task = tokio::spawn(async move {
38        clone.monitor_for_expiry().await
39    });
40
41    // Create the server instance
42    let server = Server::new(socket_addr,
43                                 main_cache,
44                                 listener,
45                                 notify_shutdown);
46
47    log::info!("{:?}", "Server is created");
48
49    tokio::select! {
50        res = server.run() => {
51            if let Err(err) = res {
52                log::error!("failed to run the server, error {:?}", err);
53            }
54        }
55        _ = shutdown => {
56            log::info!("shutting down");
57        }
58    }
59
60    let Server {
61        notify_shutdown,
62        ..
63    } = server;
64
65    // closing background monitor
66    task.abort();
67
68    // gracefully exit from all spinning connections
69    drop(notify_shutdown);
70
71    log::info!("{:?}", "Server is closed");
72}