From 5be1f853653bdb9c6c3aaab2c2d524aa56493549 Mon Sep 17 00:00:00 2001 From: nate Date: Wed, 18 Mar 2026 19:04:30 +0400 Subject: [PATCH] fix: run cert expiry check concurrently to avoid delaying results --- apps/monitor/src/runner.rs | 34 +++++++++++++++++++++++----------- deploy.sh | 22 ++++++++++++++++++++-- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/apps/monitor/src/runner.rs b/apps/monitor/src/runner.rs index 1bd1ada..bc09273 100644 --- a/apps/monitor/src/runner.rs +++ b/apps/monitor/src/runner.rs @@ -195,29 +195,35 @@ async fn run_check(client: &reqwest::Client, monitor: &Monitor, scheduled_at: Op Ok((status_code, headers, body)) => { let status = status_code; - // Only attempt cert check after a successful response - let cert_expiry_days = if is_https { - match tokio::time::timeout( - std::time::Duration::from_secs(5), - check_cert_expiry(&url_for_cert), - ).await { - Ok(Ok(days)) => days, - _ => None, - } + // Start cert expiry check in background — don't block result posting. + // We'll use None for cert_expiry_days in query evaluation since it + // shouldn't delay the main result by seconds of extra TLS handshake. + let cert_handle = if is_https { + Some(tokio::spawn(async move { + match tokio::time::timeout( + std::time::Duration::from_secs(5), + check_cert_expiry(&url_for_cert), + ).await { + Ok(Ok(days)) => days, + _ => None, + } + })) } else { None }; let query = &monitor.query; - // Evaluate query if present + // Evaluate query if present (cert_expiry_days not yet available — + // $certExpiry queries will use None here; the actual value is + // attached to the result once the background check completes) let (up, query_error) = if let Some(q) = query { let response = Response { status, body: body.clone(), headers: headers.clone(), latency_ms: Some(latency_ms), - cert_expiry_days, + cert_expiry_days: None, }; match query::evaluate(q, &response) { Ok(result) => (result, None), @@ -232,6 +238,12 @@ async fn run_check(client: &reqwest::Client, monitor: &Monitor, scheduled_at: Op (status < 400, None) }; + // Await the cert check now (it's been running concurrently during query eval) + let cert_expiry_days = match cert_handle { + Some(h) => h.await.unwrap_or(None), + None => None, + }; + let meta = json!({ "headers": headers, "body_preview": &body[..body.len().min(500)], diff --git a/deploy.sh b/deploy.sh index e4c02bc..c6add7c 100755 --- a/deploy.sh +++ b/deploy.sh @@ -1,8 +1,9 @@ #!/bin/bash # PingQL Deploy Script -# Usage: ./deploy.sh [web|api|monitor|db|all] [...] +# Usage: ./deploy.sh [web|api|monitor|db|nuke-db|all] [...] # Example: ./deploy.sh web api # Example: ./deploy.sh all +# Example: ./deploy.sh nuke-db (wipes all data — NOT included in "all") set -e @@ -18,6 +19,22 @@ deploy_db() { $SSH $DB_HOST "systemctl restart postgresql && echo 'PostgreSQL restarted'" } +nuke_db() { + echo "⚠️ This will drop all tables in the pingql database, deleting ALL data." + echo " Tables will be recreated on next API/web restart via migrate()." + read -p "Type 'yes' to confirm: " confirm + if [ "$confirm" != "yes" ]; then + echo "Aborted." + return + fi + echo "[nuke-db] Dropping all tables on database-eu-central..." + $SSH $DB_HOST bash << 'REMOTE' + sudo -u postgres psql -d pingql -c "DROP TABLE IF EXISTS pings, api_keys, monitors, accounts CASCADE;" + echo "All tables dropped" +REMOTE + echo "[nuke-db] Done. Tables will be recreated on next API/web restart." +} + deploy_api() { echo "[api] Deploying to api-eu-central..." $SSH $API_HOST bash << 'REMOTE' @@ -76,8 +93,9 @@ for arg in "$@"; do api) deploy_api ;; web) deploy_web ;; monitor) deploy_monitor ;; + nuke-db) nuke_db ;; all) deploy_db; deploy_api; deploy_web; deploy_monitor ;; - *) echo "Unknown target: $arg (valid: web, api, monitor, db, all)"; exit 1 ;; + *) echo "Unknown target: $arg (valid: web, api, monitor, db, nuke-db, all)"; exit 1 ;; esac done