1use std::time::{SystemTime, UNIX_EPOCH};
19
20use crate::logger::tracing::debug;
21use serde_json::Value;
22
23use crate::{
24 codegen::Request,
25 context::{Context, RpcContext},
26 filter::{TIMEOUT_COUNTDOWN, TIMEOUT_DEFAULT, TRI_TIMEOUT_DEADLINE_IN_NANOS},
27 status::Status,
28};
29
30use super::Filter;
31
32#[derive(Clone)]
33pub struct ContextFilter {}
34
35impl Filter for ContextFilter {
36 fn call(&mut self, req: Request<()>) -> Result<Request<()>, Status> {
37 let headers = &mut req.metadata.into_headers();
38
39 let timeout = headers.get(TIMEOUT_COUNTDOWN);
40
41 let time = SystemTime::now()
42 .duration_since(UNIX_EPOCH)
43 .unwrap()
44 .as_nanos();
45
46 let mut dead_line_in_nanos = 0_u128;
47
48 if let Some(t) = timeout {
49 let timeout: u128 = t.to_str().unwrap().parse().unwrap();
50 if timeout > 0_u128 {
51 dead_line_in_nanos = time + timeout * 1000000;
52 }
53 } else {
54 let timeout: u128 = TIMEOUT_DEFAULT * 1000000;
55 dead_line_in_nanos = time + timeout;
56 }
57
58 debug!(
59 "ContextFilter tri-timeout-deadline-in-nanos : {}",
60 dead_line_in_nanos
61 );
62 if let Some(at) = RpcContext::get_attachments() {
63 let mut attachments = at.lock().unwrap();
64 attachments.insert(
65 String::from(TRI_TIMEOUT_DEADLINE_IN_NANOS),
66 Value::from(dead_line_in_nanos.to_string()),
67 );
68 }
69
70 Ok(req)
71 }
72}