From 83f16ea44c4417989e11365c073a1be78d889827 Mon Sep 17 00:00:00 2001 From: Hongming Wang Date: Sun, 19 Apr 2026 03:44:48 -0700 Subject: [PATCH] perf(scheduler): collapse empty-run bump to single RETURNING query MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The phantom-producer detector (#795) was doing UPDATE + SELECT in two roundtrips — first incrementing consecutive_empty_runs, then re- reading to check the stale threshold. Switch to UPDATE ... RETURNING so the post-increment value comes back in one query. Called once per schedule per cron tick. At 100 tenants × dozens of schedules per tenant, the halved DB traffic on the empty-response path is measurable, not just cosmetic. Also now properly logs if the bump itself fails (previously it silent- swallowed the ExecContext error and still ran the SELECT, which would confuse debugging). Co-Authored-By: Claude Opus 4.7 (1M context) --- workspace-server/internal/scheduler/scheduler.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/workspace-server/internal/scheduler/scheduler.go b/workspace-server/internal/scheduler/scheduler.go index 9c83e83a..0831796e 100644 --- a/workspace-server/internal/scheduler/scheduler.go +++ b/workspace-server/internal/scheduler/scheduler.go @@ -310,14 +310,20 @@ func (s *Scheduler) fireSchedule(ctx context.Context, sched scheduleRow) { // consecutive empties and escalate to 'stale' after 3 in a row. isEmpty := isEmptyResponse(respBody) if lastStatus == "ok" && isEmpty { - db.DB.ExecContext(ctx, ` + // One query instead of UPDATE-then-SELECT: RETURNING hands back + // the post-increment value so the stale-threshold check doesn't + // cost a second roundtrip. This handler fires once per cron tick + // per schedule; at 100 tenants × dozens of schedules the saved + // query matters. + var consecEmpty int + if err := db.DB.QueryRowContext(ctx, ` UPDATE workspace_schedules SET consecutive_empty_runs = consecutive_empty_runs + 1, updated_at = now() - WHERE id = $1`, sched.ID) - // Check if we've crossed the stale threshold - var consecEmpty int - db.DB.QueryRowContext(ctx, `SELECT consecutive_empty_runs FROM workspace_schedules WHERE id = $1`, sched.ID).Scan(&consecEmpty) + WHERE id = $1 + RETURNING consecutive_empty_runs`, sched.ID).Scan(&consecEmpty); err != nil { + log.Printf("Scheduler: '%s' empty-run bump failed: %v", sched.Name, err) + } if consecEmpty >= 3 { lastStatus = "stale" lastError = fmt.Sprintf("empty response %d consecutive times — agent may be phantom-producing (#795)", consecEmpty)