tc_server/
server.rs

1use std::sync::Arc;
2
3use tokio::time::{Duration, MissedTickBehavior};
4
5use tc_error::*;
6use tc_transact::TxnId;
7use tc_value::Host;
8use tcgeneric::{NetworkTime, PathSegment};
9
10use crate::kernel::Kernel;
11use crate::txn::{Txn, TxnServer};
12use crate::Endpoint;
13
14const GC_INTERVAL: Duration = Duration::from_millis(100);
15
16pub struct Server {
17    kernel: Arc<Kernel>,
18    txn_server: TxnServer,
19}
20
21impl Server {
22    pub(crate) fn new(kernel: Arc<Kernel>, txn_server: TxnServer) -> mdns_sd::Result<Self> {
23        spawn_cleanup_thread(kernel.clone(), txn_server.clone());
24
25        Ok(Self { kernel, txn_server })
26    }
27
28    pub(crate) fn kernel(&self) -> Arc<Kernel> {
29        self.kernel.clone()
30    }
31
32    pub(crate) fn txn_server(&self) -> TxnServer {
33        self.txn_server.clone()
34    }
35
36    pub fn address(&self) -> &Host {
37        self.txn_server.address()
38    }
39
40    pub fn create_txn(&self) -> TCResult<Txn> {
41        self.txn_server.create_txn(NetworkTime::now())
42    }
43
44    pub async fn verify_txn(&self, txn_id: TxnId, token: String) -> TCResult<Txn> {
45        self.txn_server
46            .verify_txn(txn_id, NetworkTime::now(), token)
47            .await
48    }
49
50    pub async fn get_txn(&self, txn_id: TxnId, token: Option<String>) -> TCResult<Txn> {
51        if let Some(token) = token {
52            let now = NetworkTime::now();
53            self.txn_server.verify_txn(txn_id, now, token).await
54        } else {
55            self.txn_server.get_txn(txn_id)
56        }
57    }
58}
59
60impl Server {
61    pub async fn authorize_claim_and_route<'a>(
62        &'a self,
63        path: &'a [PathSegment],
64        txn: &'a Txn,
65    ) -> TCResult<Endpoint<'a>> {
66        self.kernel.route(path, txn).await
67    }
68}
69
70fn spawn_cleanup_thread(kernel: Arc<Kernel>, txn_server: TxnServer) {
71    let mut interval = tokio::time::interval(GC_INTERVAL);
72    interval.set_missed_tick_behavior(MissedTickBehavior::Skip);
73
74    tokio::spawn(async move {
75        loop {
76            interval.tick().await;
77            txn_server.finalize(&kernel, NetworkTime::now()).await;
78        }
79    });
80}