Execute a workflow run sequentially. Steps run in order. Each step: 1. Evaluates `if:` condition (skip if false). 2. Resolves template variables in action fields. 3. Dispatches the action. 4. Stores the step output for use by later steps. On `RequestApproval`: returns `ExecutionResult` with `approval_token = Some(token)`. Caller must persist the approval record and update the run status. Return
(
engine: &WorkflowEngine,
community_id: CommunityId,
run_id: Uuid,
def: &WorkflowDef,
trigger_ctx: &TriggerContext,
)
| 979 | /// [`WorkflowError::CapacityExceeded`] immediately if all permits are taken. |
| 980 | /// Transitions the run to `Running` after acquiring a permit. |
| 981 | pub async fn execute_run( |
| 982 | engine: &WorkflowEngine, |
| 983 | community_id: CommunityId, |
| 984 | run_id: Uuid, |
| 985 | def: &WorkflowDef, |
| 986 | trigger_ctx: &TriggerContext, |
| 987 | ) -> Result<ExecutionResult, (WorkflowError, crate::error::PartialProgress)> { |
| 988 | // Fail fast if all concurrency permits are in use — no queuing. |
| 989 | let _permit = engine.run_semaphore.try_acquire().map_err(|_| { |
| 990 | ( |
| 991 | WorkflowError::CapacityExceeded, |
| 992 | crate::error::PartialProgress::default(), |
| 993 | ) |
| 994 | })?; |
| 995 | |
| 996 | engine |
| 997 | .db |
| 998 | .update_workflow_run( |
| 999 | community_id, |
| 1000 | run_id, |
| 1001 | buzz_db::workflow::RunStatus::Running, |
| 1002 | 0, |
| 1003 | &serde_json::json!([]), |
| 1004 | None, |
| 1005 | ) |
| 1006 | .await |
| 1007 | .map_err(|e| { |
| 1008 | ( |
| 1009 | WorkflowError::from(e), |
| 1010 | crate::error::PartialProgress::default(), |
| 1011 | ) |
| 1012 | })?; |
| 1013 | |
| 1014 | execute_steps(engine, community_id, run_id, def, trigger_ctx, 0, None).await |
| 1015 | } |
| 1016 | |
| 1017 | /// Resume execution from a specific step index (used for approval resume). |
| 1018 | /// |
no test coverage detected