From f86393e1bc269a9d8f0d316952c89e39127fe532 Mon Sep 17 00:00:00 2001 From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com> Date: Thu, 1 Oct 2026 19:27:20 +0530 Subject: [PATCH] fix(plugins): stop failing runs queued in the worker's first second On start, the plugins worker fails queued runs created before it started, as interrupted. It compared created_at, which SQLite's CURRENT_TIMESTAMP stores as whole-second text, with a bound datetime that SQLAlchemy writes with a fraction. SQLite compared them as text, and the shorter value sorts first, so a run queued in the same second the worker started counted as older. It was failed and withdrawn before it ran. Compare against datetime(started) so both sides use the same format. --- surfsense_local/backend/modules/plugins/interrupted_runs.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/surfsense_local/backend/modules/plugins/interrupted_runs.py b/surfsense_local/backend/modules/plugins/interrupted_runs.py index 9ab3cf49b..49dd08415 100644 --- a/surfsense_local/backend/modules/plugins/interrupted_runs.py +++ b/surfsense_local/backend/modules/plugins/interrupted_runs.py @@ -1,7 +1,7 @@ from datetime import UTC, datetime import psutil -from sqlalchemy import and_, or_, select +from sqlalchemy import and_, func, or_, select from modules.plugins.models import PluginRun, PluginRunStatus from shared.config import get_storage_settings @@ -26,7 +26,9 @@ def fail_interrupted_runs() -> None: PluginRun.status == PluginRunStatus.RUNNING, and_( PluginRun.status == PluginRunStatus.QUEUED, - PluginRun.created_at < started, + # created_at is CURRENT_TIMESTAMP text, whole seconds; + # raw, it sorts before a bound datetime of the same second. + PluginRun.created_at < func.datetime(started), ), ) )