fix(server): load only due tasks during scheduler ticks - #9925
Conversation
|
This PR is too large for Bugbot to review. It changes 99,212 lines and 4,021,181 characters. Split the change into smaller pull requests to get a review. |
|
Macroscope has since reviewed this pull request. An earlier review was skipped by a cost limit; a review has now completed, so that notice no longer applies. |
b82facd to
2ac9bfe
Compare
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — The production change narrows scheduler polling to enabled, non-running tasks whose next run is due while preserving existing dispatch, API listing, and recovery paths. A focused in-memory test covers the relevant task categories, and no defaults, schema, static-analysis overrides, or sensitive areas are touched. You can add or adjust custom eligibility rules. Learn more. |
aa837b8 to
f106115
Compare
…apping' into landing/pr-9925
Dismissing prior approval to re-evaluate d05a0ba
The five-second scheduler tick reads and decodes every scheduled task, including disabled and future tasks. Select only enabled, due, non-running rows using the existing partial due-task index, preserving task order and lenient handling of malformed due rows. API listing and one-time startup recovery retain their full reads.
Validation: seven focused scheduler/query tests pass, including due, disabled, future, running, and malformed records. SQLite EXPLAIN confirms use of idx_scheduled_tasks_due. Server typecheck, formatting, targeted lint, and diff check pass. No schema changes or live state writes.
Targets Julius’s V2 branch in #2829 at 2ac9bfe; addresses audit F22. Direct Claude Opus 5 high review was attempted but exited 1 before model execution because OAuth expired; no Claude review is claimed.
Implemented with Codex workers and reviewed with GPT-6 in Codex/T3.
Current-base verification
Updated to exact V2 base
415ed0f73b97f1655b6282492f81d0b2bba3a9ccat head6c21fce33e87b5e1c96c7ead729f4531990d9773. The original leaf plus this base synthesizes cleanly as tree6b21f30c377ac1228d0ee443007977c1c8f3ee4e; current V2 base does not containloadDueScheduledTasksor its service integration regression.ScheduledTaskService.tsand its test.The service still owns the captured SQL client and preserves full reads for API listing and startup recovery. No schema or live-state write was made. Fresh independent Claude review remains unavailable because OAuth is signed out; no Claude review is claimed. Refreshed by GPT-6 in the Codex harness.
Note
Load only due tasks in
ScheduledTaskService.runDueTasksscheduler tickloadDueScheduledTasks, which selects only enabled rows withnext_run_atat or before the supplied timestamp and excludes rows whose last run is already running.runDueTasksnow captures the local current time once and passes its ISO representation to bound the SQL query, while retaining the epoch-based due check on decoded task values.Macroscope summarized 6c21fce.
Note
Medium Risk
Changes scheduler polling and SQL filtering for when tasks fire; behavior should match prior filters but any query/index mismatch could miss or duplicate runs.
Overview
Scheduler ticks no longer scan every scheduled task row. Each poll now calls exported
loadDueScheduledTasks, which selects only enabled rows withnext_run_atset and not after the current time, excluding tasks alreadyrunning, ordered like the API list. That path is meant to use the existingidx_scheduled_tasks_dueindex instead of a full-table read.Lenient row decoding for the poller (skip bad rows with a warning) moves into
loadDueScheduledTasks; the internallistTasksLenienthelper that loaded all rows is removed.runDueTasksloads candidates through the new query, then still applies in-memory due/missed-run logic. APIlistand startup stuck-run recovery keep full-table reads with strict decoding.A new
ScheduledTaskService.testeffect test seeds disabled, future, running, and malformed due rows and asserts only the valid due task is returned.Reviewed by Cursor Bugbot for commit f106115. Bugbot is set up for automated code reviews on this repo. Configure here.