From 5962ba2fb296deb820cfa954e2ef5372c5b91192 Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Thu, 9 Apr 2026 20:15:55 +0200 Subject: [PATCH] Use correct timezone to compare step scheduling `get_last_workflow_invocation_step_update_time()` returns UTC time (it's set by galaxy.model.orm.now.now()) while datetime.now() is your local time. If your system is not on UTC time this caused 5 minute scheduling delays for steps depending on expression tools that only produce parameters. Fixes the delay observed in https://github.com/galaxyproject/tools-iuc/pull/7314 --- lib/galaxy/model/orm/now.py | 14 +++++++++++--- lib/galaxy/workflow/scheduling_manager.py | 7 ++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/galaxy/model/orm/now.py b/lib/galaxy/model/orm/now.py index d44fa59f6cd..fe8dbfcb280 100644 --- a/lib/galaxy/model/orm/now.py +++ b/lib/galaxy/model/orm/now.py @@ -1,4 +1,7 @@ -from datetime import datetime +from datetime import ( + datetime, + timezone, +) # NOTE REGARDING TIMESTAMPS: # It is currently difficult to have the timestamps calculated by the @@ -7,7 +10,12 @@ from datetime import datetime # relies on the client's clock being set correctly, so if clustering # web servers, use a time server to ensure synchronization -# Return the current time in UTC without any timezone information -now = datetime.utcnow + +def now(): + """ + Return the current time in UTC without any timezone information. + """ + return datetime.now(timezone.utc).replace(tzinfo=None) + __all__ = ("now",) diff --git a/lib/galaxy/workflow/scheduling_manager.py b/lib/galaxy/workflow/scheduling_manager.py index 48951ead46d..3872349cad5 100644 --- a/lib/galaxy/workflow/scheduling_manager.py +++ b/lib/galaxy/workflow/scheduling_manager.py @@ -12,6 +12,7 @@ import galaxy.workflow.schedulers from galaxy import model from galaxy.exceptions import HandlerAssignmentError from galaxy.jobs.handler import InvocationGrabber +from galaxy.model.orm.now import now from galaxy.schema.invocation import ( FailureReason, InvocationFailureDatasetFailed, @@ -341,12 +342,12 @@ class WorkflowRequestMonitor(Monitors): invocation_step_update_time := invocation.get_last_workflow_invocation_step_update_time() ): do_schedule = invocation_step_update_time > last_schedule_time - if not do_schedule and (datetime.now() - last_schedule_time) > self.timedelta: + if not do_schedule and (now() - last_schedule_time) > self.timedelta: # If we haven't scheduled in a while, schedule anyway. log.debug( "Scheduling workflow invocation [%s] after %s seconds without scheduling.", invocation.id, - (datetime.now() - last_schedule_time).total_seconds(), + (now() - last_schedule_time).total_seconds(), ) do_schedule = True return do_schedule @@ -449,7 +450,7 @@ class WorkflowRequestMonitor(Monitors): if i.active and i.id < workflow_invocation.id: return False if self.ready_to_schedule_more(workflow_invocation): - self.update_time_tracking_dict[invocation_id] = datetime.now() + self.update_time_tracking_dict[invocation_id] = now() workflow_scheduler.schedule(workflow_invocation) log.debug("Workflow invocation [%s] scheduled", invocation_id) except Exception: