Resume execution from a specific step index (used for approval resume). Acquires a concurrency permit from `engine.run_semaphore` before executing — returns [`WorkflowError::CapacityExceeded`] immediately if all permits are taken. Transitions the run to `Running` after acquiring a permit, so that approval-resumed runs correctly reflect their active state. `initial_outputs` should be reconstruct
(
engine: &WorkflowEngine,
community_id: CommunityId,
run_id: Uuid,
def: &WorkflowDef,
trigger_ctx: &TriggerContext,
start_index: usize,
initial_outputs: Option<HashMap<Str
| 1027 | /// calling this function on resume, so that steps after the resume point can |
| 1028 | /// reference `{{steps.PREV_STEP.output.X}}` correctly. |
| 1029 | pub async fn execute_from_step( |
| 1030 | engine: &WorkflowEngine, |
| 1031 | community_id: CommunityId, |
| 1032 | run_id: Uuid, |
| 1033 | def: &WorkflowDef, |
| 1034 | trigger_ctx: &TriggerContext, |
| 1035 | start_index: usize, |
| 1036 | initial_outputs: Option<HashMap<String, JsonValue>>, |
| 1037 | ) -> Result<ExecutionResult, (WorkflowError, crate::error::PartialProgress)> { |
| 1038 | // Fail fast if all concurrency permits are in use — no queuing. |
| 1039 | let _permit = engine.run_semaphore.try_acquire().map_err(|_| { |
| 1040 | ( |
| 1041 | WorkflowError::CapacityExceeded, |
| 1042 | crate::error::PartialProgress::default(), |
| 1043 | ) |
| 1044 | })?; |
| 1045 | |
| 1046 | // Mark run as Running now that we have a permit (resume from approval). |
| 1047 | // Preserve the existing execution trace from pre-approval steps. |
| 1048 | let existing_trace = match engine.db.get_workflow_run(community_id, run_id).await { |
| 1049 | Ok(r) => r.execution_trace, |
| 1050 | Err(e) => { |
| 1051 | warn!( |
| 1052 | run_id = %run_id, |
| 1053 | "Failed to read existing trace for resume — pre-approval trace will be lost: {e}" |
| 1054 | ); |
| 1055 | serde_json::json!([]) |
| 1056 | } |
| 1057 | }; |
| 1058 | engine |
| 1059 | .db |
| 1060 | .update_workflow_run( |
| 1061 | community_id, |
| 1062 | run_id, |
| 1063 | buzz_db::workflow::RunStatus::Running, |
| 1064 | start_index as i32, |
| 1065 | &existing_trace, |
| 1066 | None, |
| 1067 | ) |
| 1068 | .await |
| 1069 | .map_err(|e| { |
| 1070 | ( |
| 1071 | WorkflowError::from(e), |
| 1072 | crate::error::PartialProgress::default(), |
| 1073 | ) |
| 1074 | })?; |
| 1075 | |
| 1076 | execute_steps( |
| 1077 | engine, |
| 1078 | community_id, |
| 1079 | run_id, |
| 1080 | def, |
| 1081 | trigger_ctx, |
| 1082 | start_index, |
| 1083 | initial_outputs, |
| 1084 | ) |
| 1085 | .await |
| 1086 | } |
no test coverage detected