chore(alerts): address review nits on the gate alert

Trim the migration column comment to four lines, drop four orphaned sqlx
cache entries left by the concurrency_first_gated_at transition, revert a
stray prettier reflow that rode along in InstanceSetting.svelte, and give
ee-repo-ref.txt its trailing newline.

Bumps ee-repo-ref to the EE commit adding the monitor-only contract doc
on concurrency_gate_alerts.
This commit is contained in:
Ruben Fiszel
2026-07-20 16:35:57 +00:00
parent 1dcd6cd1ab
commit a28c465525
9 changed files with 39 additions and 87 deletions
@@ -1,16 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "\n WITH ping AS (\n UPDATE v2_job_runtime SET ping = null WHERE id = $2\n )\n UPDATE v2_job_queue SET\n running = false,\n started_at = null,\n scheduled_for = $1,\n concurrency_gated_at = now(),\n concurrency_gate_id = $3\n WHERE id = $2",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Timestamptz",
"Uuid",
"Varchar"
]
},
"nullable": []
},
"hash": "4a5bf92b6aa3abb98b118c882673e90b5927755586214b3db62550bf1f8a80a9"
}
@@ -1,16 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO v2_job_queue (id, workspace_id, tag, running, scheduled_for,\n created_at, concurrency_gated_at, concurrency_gate_id)\n VALUES ($1, 'test-workspace', 'python3', false, NOW(),\n NOW() - INTERVAL '1 hour' * $2::bigint, NOW(), $3)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Uuid",
"Int8",
"Varchar"
]
},
"nullable": []
},
"hash": "8210bbfb72beefaad410f5e44b54923af3b13751c2cc1537e36e47777c726b23"
}
@@ -1,17 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO v2_job_queue (id, workspace_id, tag, running, scheduled_for,\n concurrency_gated_at, concurrency_gate_id)\n VALUES ($1, 'test-workspace', $2, false, NOW() - INTERVAL '5 minutes',\n CASE WHEN $3::bigint IS NULL THEN NULL\n ELSE NOW() - INTERVAL '1 second' * $3::bigint END,\n $4)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Uuid",
"Varchar",
"Int8",
"Varchar"
]
},
"nullable": []
},
"hash": "ad143b4b7b6a716326e900d30d8f05f515a2c1bda560368bf5517ba5d18292f3"
}
@@ -1,18 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO v2_job_queue (id, workspace_id, tag, running, scheduled_for,\n created_at, concurrency_gated_at, concurrency_gate_id,\n canceled_by)\n SELECT gen_random_uuid(), 'test-workspace', 'python3', false, NOW(),\n NOW() - INTERVAL '1 hour' * $2::bigint,\n NOW() - INTERVAL '1 minute' * $3::bigint,\n $4,\n CASE WHEN $5 THEN 'canceller' ELSE NULL END\n FROM generate_series(1, $1::bigint)",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int8",
"Int8",
"Int8",
"Varchar",
"Bool"
]
},
"nullable": []
},
"hash": "d6f84be2343bcf21d129b89a1de7cf9e39aee40b4d35ba39015a66d557d0785a"
}
+1 -1
View File
@@ -1 +1 @@
db65192a740d3e248b53e110934ede7925954ecd
2aa9105cbbd5608f0ccf49570362dcef6029e2f0
@@ -1,7 +1,5 @@
-- When the concurrency limiter first parked this job behind a gate. Unlike
-- concurrency_gated_at, which the limiter overwrites on every re-queue, this is
-- set once and never moves, so it marks a job's arrival at the gate rather than
-- its last rejection. The oversubscription alert measures arrival rate from it:
-- created_at misses jobs pushed with a future scheduled_for that only reach the
-- gate long after creation. Nullable so adding it is instant.
-- When the limiter first parked this job behind a gate; set once, never moved
-- (unlike concurrency_gated_at, overwritten each re-queue). The oversubscription
-- alert measures arrival rate from it because created_at misses jobs pushed with
-- a future scheduled_for that reach the gate long after creation.
ALTER TABLE v2_job_queue ADD COLUMN IF NOT EXISTS concurrency_first_gated_at TIMESTAMPTZ;
@@ -28,8 +28,7 @@
#[cfg(all(feature = "private", feature = "enterprise"))]
mod tests {
use windmill_common::secret_backend::{
test_aws_sm_connection, AwsSecretsManagerBackend, AwsSecretsManagerSettings,
SecretBackend,
test_aws_sm_connection, AwsSecretsManagerBackend, AwsSecretsManagerSettings, SecretBackend,
};
fn should_run_aws_sm_tests() -> bool {
@@ -81,10 +80,16 @@ mod tests {
.set_secret("test-ws", "u/admin/my_secret", "super-secret-value")
.await
.unwrap();
let value = backend.get_secret("test-ws", "u/admin/my_secret").await.unwrap();
let value = backend
.get_secret("test-ws", "u/admin/my_secret")
.await
.unwrap();
assert_eq!(value, "super-secret-value");
backend.delete_secret("test-ws", "u/admin/my_secret").await.unwrap();
backend
.delete_secret("test-ws", "u/admin/my_secret")
.await
.unwrap();
println!(" ✓ Create + Get + Delete roundtrip passed");
}
@@ -45,8 +45,16 @@ mod tests {
// A non-delayed job reaches the gate when it is created, so first_gated
// tracks created_at here. The delayed-arrival case sets them apart via
// queue_gated_delayed.
queue_gated_full_delayed(db, n, gate, created_hours_ago, created_hours_ago, mark_mins_ago, canceled)
.await
queue_gated_full_delayed(
db,
n,
gate,
created_hours_ago,
created_hours_ago,
mark_mins_ago,
canceled,
)
.await
}
#[allow(clippy::too_many_arguments)]
@@ -113,7 +121,8 @@ mod tests {
"a gate that cannot drain its backlog must alert, got {messages:?}"
);
assert!(
messages[0].contains("17280") && messages[0].contains("40000")
messages[0].contains("17280")
&& messages[0].contains("40000")
&& messages[0].contains("720"),
"alert must name the backlog and both ceilings it exceeds: {}",
messages[0]
@@ -182,7 +191,11 @@ mod tests {
free_the_lock(&db).await;
queue_gated(&db, 40_000, SLOW_GATE, 0).await;
concurrency_gate_alerts(&db).await;
assert_eq!(alert_messages(&db).await.len(), 1, "expected the initial alert");
assert_eq!(
alert_messages(&db).await.len(),
1,
"expected the initial alert"
);
sqlx::query!("DELETE FROM v2_job_queue")
.execute(&db)
@@ -213,7 +226,10 @@ mod tests {
.await
.expect("read healthchecks")
.unwrap_or(0);
assert_eq!(unresolved, 0, "a fully drained gate must have its alert recovered");
assert_eq!(
unresolved, 0,
"a fully drained gate must have its alert recovered"
);
}
/// The window governs how soon the alert fires, so a gate taking on less than
@@ -771,10 +771,10 @@
/>
<p class="text-xs text-tertiary">
Comma-separated host/IP patterns the proxy still traces but for which it skips
upstream TLS certificate verification. Use for internal endpoints with self-signed
or otherwise untrusted certificates — unlike NO_PROXY above, these requests stay
traced. Same matching as NO_PROXY (<code>example.com</code> matches subdomains;
<code>.example.com</code> matches subdomains only).
upstream TLS certificate verification. Use for internal endpoints with
self-signed or otherwise untrusted certificates — unlike NO_PROXY above, these
requests stay traced. Same matching as NO_PROXY (<code>example.com</code> matches
subdomains; <code>.example.com</code> matches subdomains only).
</p>
</div>
<div class="flex flex-col gap-1">