1use std::time::{Duration, Instant};
4
5use crate::arena::Arena;
6use crate::caller::ModuleCaller;
7use crate::error::{ModuleError, Result};
8
9pub struct CallContext<'a> {
10 arena: &'a Arena,
11 backpressure: f32,
12 trace_id: u128,
13 span_id: u64,
14 deadline: Option<Instant>,
15 module_caller: Option<&'a ModuleCaller>,
16}
17
18impl<'a> CallContext<'a> {
19 pub fn new(
20 arena: &'a Arena,
21 backpressure: f32,
22 trace_id: u128,
23 span_id: u64,
24 deadline: Option<Instant>,
25 module_caller: Option<&'a ModuleCaller>,
26 ) -> Self {
27 CallContext {
28 arena,
29 backpressure,
30 trace_id,
31 span_id,
32 deadline,
33 module_caller,
34 }
35 }
36
37 pub fn backpressure(&self) -> f32 {
38 self.backpressure
39 }
40
41 pub fn arena(&self) -> &'a Arena {
42 self.arena
43 }
44
45 pub fn trace_id(&self) -> u128 {
46 self.trace_id
47 }
48
49 pub fn span_id(&self) -> u64 {
50 self.span_id
51 }
52
53 pub fn deadline(&self) -> Option<Instant> {
54 self.deadline
55 }
56
57 pub fn is_expired(&self) -> bool {
58 self.deadline
59 .map(|d| Instant::now() > d)
60 .unwrap_or(false)
61 }
62
63 pub fn remaining_time(&self) -> Option<Duration> {
64 self.deadline.map(|d| {
65 d.checked_duration_since(Instant::now())
66 .unwrap_or(Duration::ZERO)
67 })
68 }
69
70 pub fn module_caller(&self) -> Option<&'a ModuleCaller> {
71 self.module_caller
72 }
73
74 pub async fn call(&self, module: &str, method: &str, args: &[u8]) -> Result<Vec<u8>> {
75 match &self.module_caller {
76 Some(caller) => caller.call(module, method, args).await,
77 None => Err(ModuleError::ServiceUnavailable),
78 }
79 }
80
81 pub async fn call_with_timeout(
82 &self,
83 module: &str,
84 method: &str,
85 args: &[u8],
86 timeout: Duration,
87 ) -> Result<Vec<u8>> {
88 match &self.module_caller {
89 Some(caller) => caller.call_with_timeout(module, method, args, timeout).await,
90 None => Err(ModuleError::ServiceUnavailable),
91 }
92 }
93
94 pub fn set_backpressure(&mut self, backpressure: f32) {
95 self.backpressure = backpressure.clamp(0.0, 1.0);
96 }
97}