Skip to main content

memlink_msdk/
context.rs

1//! Call context for memlink module invocations, providing execution environment and utilities.
2
3use 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}