Files
windmill/backend/windmill-queue/src/flow_status.rs
T
hugocasa 993baf46bd feat(backend): flow streaming (#6520)
* feat(backend): flow streaming

* all streaming languages + sync api

* sqlx

* fix build

* UI and nits

* nit

* feat: stream last flow step

* sqlx

* nit

* use get for stream endpoints + add snippet in UI

* refactor

* nits

* Update backend/windmill-worker/src/common.rs

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>

* nits

---------

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
2025-09-18 15:49:35 +00:00

118 lines
3.5 KiB
Rust

use uuid::Uuid;
use windmill_common::{
error::{self, Error},
flows::Step,
utils::WarnAfterExt,
DB,
};
pub async fn update_flow_status_in_progress(
db: &DB,
_w_id: &str,
flow: Uuid,
job_in_progress: Uuid,
) -> error::Result<Step> {
let step = get_step_of_flow_status(db, flow).await?;
match step {
Step::Step { idx: step, .. } => {
sqlx::query!(
"UPDATE v2_job_status SET
flow_status = jsonb_set(
jsonb_set(flow_status, ARRAY['modules', $3::INTEGER::TEXT, 'job'], to_jsonb($1::UUID::TEXT)),
ARRAY['modules', $3::INTEGER::TEXT, 'type'],
to_jsonb('InProgress'::text)
)
WHERE id = $2",
job_in_progress,
flow,
step as i32
)
.execute(db)
.await?;
}
Step::PreprocessorStep => {
sqlx::query!(
"UPDATE v2_job_status SET
flow_status = jsonb_set(
jsonb_set(flow_status, ARRAY['preprocessor_module', 'job'], to_jsonb($1::UUID::TEXT)),
ARRAY['preprocessor_module', 'type'],
to_jsonb('InProgress'::text)
)
WHERE id = $2",
job_in_progress,
flow
)
.execute(db)
.await?;
}
Step::FailureStep => {
sqlx::query!(
"UPDATE v2_job_status SET
flow_status = jsonb_set(
jsonb_set(flow_status, ARRAY['failure_module', 'job'], to_jsonb($1::UUID::TEXT)),
ARRAY['failure_module', 'type'],
to_jsonb('InProgress'::text)
)
WHERE id = $2",
job_in_progress,
flow
)
.execute(db)
.await?;
}
}
Ok(step)
}
pub async fn update_workflow_as_code_status(
db: &DB,
id: &Uuid,
parent_job: &Uuid,
) -> error::Result<()> {
let _ = sqlx::query_scalar!(
"UPDATE v2_job_status SET
workflow_as_code_status = jsonb_set(
jsonb_set(
COALESCE(workflow_as_code_status, '{}'::jsonb),
array[$1],
COALESCE(workflow_as_code_status->$1, '{}'::jsonb)
),
array[$1, 'started_at'],
to_jsonb(now()::text)
)
WHERE id = $2",
id.to_string(),
parent_job
)
.execute(db)
.warn_after_seconds(5)
.await
.inspect_err(|e| {
tracing::error!(
"Could not update parent job `started_at` in workflow as code status: {}",
e
)
});
Ok(())
}
// TODO: merge as a CTE
#[tracing::instrument(level = "trace", skip_all)]
pub async fn get_step_of_flow_status(db: &DB, id: Uuid) -> error::Result<Step> {
let r = sqlx::query!(
"SELECT (flow_status->'step')::integer as step, jsonb_array_length(flow_status->'modules') as len
FROM v2_job_status WHERE id = $1",
id
)
.fetch_one(db)
.await
.map_err(|e| Error::internal_err(format!("fetching step flow status: {e:#}")))?;
if let Some(step) = r.step {
Ok(Step::from_i32_and_len(step, r.len.unwrap_or(0) as usize))
} else {
Err(Error::internal_err("step is null".to_string()))
}
}