mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-23 08:03:33 +00:00
fix: stop holding a pool connection while waiting for another (#11902)
* fix: stop holding a pool connection while waiting for another Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: count only earlier occurrences as schedule handler history Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: update ee-repo-ref to ac53164fd27fe962a020f3ee944949df1f760603 This commit updates the EE repository reference after PR #904 was merged in windmill-ee-private. Previous ee-repo-ref: 047764f902f10fce0156138c4240ba5d1a2e969a New ee-repo-ref: ac53164fd27fe962a020f3ee944949df1f760603 Automated by sync-ee-ref workflow. --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
windmill-internal-app[bot]
parent
613adb5287
commit
2c559b452f
@@ -1641,6 +1641,7 @@ async fn commit_completed_job<T: Serialize + Send + Sync + ValidableJson>(
|
||||
}
|
||||
|
||||
let mut _skip_downstream_error_handlers = false;
|
||||
let mut schedule_for_handlers = None;
|
||||
if completed_job.is_flow_step() {
|
||||
if let Some(parent_job) = monitor_parent {
|
||||
let r = sqlx::query_scalar!(
|
||||
@@ -1720,49 +1721,9 @@ async fn commit_completed_job<T: Serialize + Send + Sync + ValidableJson>(
|
||||
// per-occurrence failure/recovery status across the whole retry
|
||||
// chain, so multi-count/exact handler policies work even though
|
||||
// each attempt is its own completed job.
|
||||
#[cfg(all(feature = "enterprise", feature = "private"))]
|
||||
if !retry_pending {
|
||||
if let Err(err) = crate::jobs_ee::apply_schedule_handlers(
|
||||
db,
|
||||
&schedule,
|
||||
&script_path,
|
||||
&completed_job.workspace_id,
|
||||
success,
|
||||
result,
|
||||
job_id,
|
||||
// Current occurrence's root: the terminal native-retry
|
||||
// attempt's parent, else the job itself.
|
||||
completed_job.parent_job.unwrap_or(job_id),
|
||||
completed_job.started_at.unwrap_or(chrono::Utc::now()),
|
||||
completed_job.priority,
|
||||
)
|
||||
.warn_after_seconds(10)
|
||||
.await
|
||||
{
|
||||
if !success {
|
||||
tracing::error!("Could not apply schedule error handler: {}", err);
|
||||
let base_url = windmill_common::BASE_URL.load();
|
||||
let w_id: &String = &completed_job.workspace_id;
|
||||
if !matches!(err, Error::QuotaExceeded(_)) {
|
||||
report_error_to_workspace_handler_or_critical_side_channel(
|
||||
&completed_job,
|
||||
db,
|
||||
format!(
|
||||
"Failed to push schedule error handler job to handle failed job ({base_url}/run/{}?workspace={w_id}): {}",
|
||||
completed_job.id,
|
||||
err
|
||||
),
|
||||
)
|
||||
.warn_after_seconds(10)
|
||||
.await;
|
||||
}
|
||||
} else {
|
||||
tracing::error!("Could not apply schedule recovery handler: {}", err);
|
||||
}
|
||||
};
|
||||
schedule_for_handlers = Some((schedule, script_path));
|
||||
}
|
||||
#[cfg(not(all(feature = "enterprise", feature = "private")))]
|
||||
let _ = retry_pending;
|
||||
} else {
|
||||
tracing::error!(
|
||||
"Schedule {schedule_path} in {} not found. Impossible to schedule again and apply schedule handlers",
|
||||
@@ -1824,6 +1785,52 @@ async fn commit_completed_job<T: Serialize + Send + Sync + ValidableJson>(
|
||||
|
||||
tx.commit().warn_after_seconds(10).await?;
|
||||
|
||||
// The handlers read and push through `db`, so they run after the commit: inside the
|
||||
// transaction they would hold its connection while waiting for more from the same pool.
|
||||
#[cfg(all(feature = "enterprise", feature = "private"))]
|
||||
if let Some((schedule, script_path)) = schedule_for_handlers {
|
||||
if let Err(err) = crate::jobs_ee::apply_schedule_handlers(
|
||||
db,
|
||||
&schedule,
|
||||
script_path,
|
||||
&completed_job.workspace_id,
|
||||
success,
|
||||
result,
|
||||
job_id,
|
||||
// Current occurrence's root: the terminal native-retry
|
||||
// attempt's parent, else the job itself.
|
||||
completed_job.parent_job.unwrap_or(job_id),
|
||||
completed_job.started_at.unwrap_or(chrono::Utc::now()),
|
||||
completed_job.priority,
|
||||
)
|
||||
.warn_after_seconds(10)
|
||||
.await
|
||||
{
|
||||
if !success {
|
||||
tracing::error!("Could not apply schedule error handler: {}", err);
|
||||
let base_url = windmill_common::BASE_URL.load();
|
||||
let w_id: &String = &completed_job.workspace_id;
|
||||
if !matches!(err, Error::QuotaExceeded(_)) {
|
||||
report_error_to_workspace_handler_or_critical_side_channel(
|
||||
&completed_job,
|
||||
db,
|
||||
format!(
|
||||
"Failed to push schedule error handler job to handle failed job ({base_url}/run/{}?workspace={w_id}): {}",
|
||||
completed_job.id,
|
||||
err
|
||||
),
|
||||
)
|
||||
.warn_after_seconds(10)
|
||||
.await;
|
||||
}
|
||||
} else {
|
||||
tracing::error!("Could not apply schedule recovery handler: {}", err);
|
||||
}
|
||||
};
|
||||
}
|
||||
#[cfg(not(all(feature = "enterprise", feature = "private")))]
|
||||
let _ = schedule_for_handlers;
|
||||
|
||||
log_completed_job(completed_job, completed.duration_ms, success);
|
||||
// tracing::info!("completed job: {:?}", start.elapsed().as_micros());
|
||||
Ok((
|
||||
|
||||
@@ -339,7 +339,7 @@ mod native_retry {
|
||||
// -> failure: handler child must NOT count as a recovery
|
||||
// f: root fails, only a WAC inline child (unmarked) succeeds
|
||||
// -> failure: WAC inline child must NOT count as a recovery
|
||||
// d: the current occurrence (excluded by `j.id != $4`)
|
||||
// d: the current occurrence (excluded with any later one by the created_at bound)
|
||||
let (a, b, c, e, f, d) = (
|
||||
Uuid::new_v4(),
|
||||
Uuid::new_v4(),
|
||||
@@ -371,7 +371,8 @@ mod native_retry {
|
||||
))
|
||||
FROM v2_job j JOIN v2_job_completed USING (id)
|
||||
WHERE j.workspace_id = $1 AND trigger_kind = 'schedule' AND trigger = $2
|
||||
AND parent_job IS NULL AND runnable_path = $3 AND j.id != $4
|
||||
AND parent_job IS NULL AND runnable_path = $3
|
||||
AND j.created_at < (SELECT created_at FROM v2_job WHERE id = $4)
|
||||
ORDER BY created_at DESC",
|
||||
)
|
||||
.bind(WS)
|
||||
|
||||
Reference in New Issue
Block a user