Skip to main content

bpm_engine_runtime/
process_start_handler.rs

1//! ProcessStartHandler: ProcessStarted -> create instance + initial token, emit TokenArrived.
2
3use async_trait::async_trait;
4use bpm_engine_core::{
5    payloads, EngineEvent, InstanceState, ProcessInstance, Token, TokenMode, TokenStatus,
6};
7use tracing::info;
8
9use super::handler::{EngineContext, EventHandler};
10
11pub struct ProcessStartHandler;
12
13#[async_trait]
14impl EventHandler for ProcessStartHandler {
15    async fn handle(&self, event: &EngineEvent, ctx: &mut EngineContext) -> Vec<EngineEvent> {
16        let EngineEvent::ProcessStarted(e) = event else {
17            return vec![];
18        };
19        info!(instance_id = %e.instance_id, process_id = %e.process_id, "process started");
20        let Some(process_store) = ctx.process_store.as_ref() else {
21            return vec![];
22        };
23        let Some(process_def_store) = ctx.process_def_store.as_ref() else {
24            return vec![];
25        };
26        let Some(def) = process_def_store.load(&e.process_id).await.ok().flatten() else {
27            return vec![];
28        };
29        let token_id = uuid::Uuid::new_v4().to_string();
30        let variables = e.initial_variables.clone().unwrap_or_default();
31        let instance = ProcessInstance {
32            id: e.instance_id.clone(),
33            process_def_id: e.process_id.clone(),
34            tenant_id: ctx.tenant_id.clone(),
35            tokens: vec![Token {
36                id: token_id.clone(),
37                node_id: def.start.to_string(),
38                status: TokenStatus::Ready,
39                mode: TokenMode::Forward,
40                version: 0,
41                attempt: 0,
42                parallel_group_id: None,
43                updated_at: None,
44            }],
45            variables,
46            state: InstanceState::Running,
47            version: 0,
48        };
49        let _ = process_store.save(&instance).await;
50        vec![EngineEvent::TokenArrived(payloads::TokenArrived {
51            instance_id: e.instance_id.clone(),
52            token_id,
53            node_id: def.start.to_string(),
54        })]
55    }
56}