mf_engine/handler/function_v1/
mod.rs1use std::time::{Duration, Instant};
2
3use crate::handler::function_v1::script::Script;
4use crate::handler::node::{NodeRequest, NodeResponse, NodeResult};
5use crate::model::{DecisionNodeKind, FunctionNodeContent};
6use anyhow::anyhow;
7use rquickjs::Runtime;
8use serde_json::json;
9
10pub(crate) mod runtime;
11mod script;
12
13pub struct FunctionHandler {
14 trace: bool,
15 runtime: Runtime,
16}
17
18static MAX_DURATION: Duration = Duration::from_millis(500);
19
20impl FunctionHandler {
21 pub fn new(
22 trace: bool,
23 runtime: Runtime,
24 ) -> Self {
25 Self { trace, runtime }
26 }
27
28 pub async fn handle(
29 &self,
30 request: NodeRequest,
31 ) -> NodeResult {
32 let content = match &request.node.kind {
33 DecisionNodeKind::FunctionNode { content } => match content {
34 FunctionNodeContent::Version1(content) => Ok(content),
35 _ => Err(anyhow!("Unexpected node type")),
36 },
37 _ => Err(anyhow!("Unexpected node type")),
38 }?;
39
40 let start = Instant::now();
41 let interrupt_handler =
42 Box::new(move || start.elapsed() > MAX_DURATION);
43 self.runtime.set_interrupt_handler(Some(interrupt_handler));
44
45 let mut script = Script::new(self.runtime.clone());
46 let result_response = script.call(content, &request.input).await;
47
48 self.runtime.set_interrupt_handler(None);
49
50 let response = result_response?;
51 Ok(NodeResponse {
52 output: response.output,
53 trace_data: self.trace.then(|| json!({ "log": response.log })),
54 })
55 }
56}