File tree Expand file tree Collapse file tree 2 files changed +42
-17
lines changed
Expand file tree Collapse file tree 2 files changed +42
-17
lines changed Original file line number Diff line number Diff line change @@ -357,23 +357,26 @@ def _query_requeue_dead_jobs(self):
357357 ELSE exc_info
358358 END)
359359 WHERE
360- id in (
361- SELECT
362- queue_job_id
363- FROM
364- queue_job_lock
365- WHERE
366- queue_job_id in (
367- SELECT
368- id
369- FROM
370- queue_job
371- WHERE
372- state IN ('enqueued','started')
373- AND date_enqueued <
374- (now() AT TIME ZONE 'utc' - INTERVAL '10 sec')
375- )
376- FOR UPDATE SKIP LOCKED
360+ state IN ('enqueued','started')
361+ AND date_enqueued < (now() AT TIME ZONE 'utc' - INTERVAL '10 sec')
362+ AND (
363+ id in (
364+ SELECT
365+ queue_job_id
366+ FROM
367+ queue_job_lock
368+ WHERE
369+ queue_job_lock.queue_job_id = queue_job.id
370+ FOR UPDATE SKIP LOCKED
371+ )
372+ OR NOT EXISTS (
373+ SELECT
374+ 1
375+ FROM
376+ queue_job_lock
377+ WHERE
378+ queue_job_lock.queue_job_id = queue_job.id
379+ )
377380 )
378381 RETURNING uuid
379382 """
@@ -396,6 +399,12 @@ def requeue_dead_jobs(self):
396399 However, when the Odoo server crashes or is otherwise force-stopped,
397400 running jobs are interrupted while the runner has no chance to know
398401 they have been aborted.
402+
403+ This also handles orphaned jobs (enqueued but never started, no lock).
404+ This edge case occurs when the runner marks a job as 'enqueued'
405+ but the HTTP request to start the job never reaches the Odoo server
406+ (e.g., due to server shutdown/crash between setting enqueued and
407+ the controller receiving the request).
399408 """
400409
401410 with closing (self .conn .cursor ()) as cr :
Original file line number Diff line number Diff line change @@ -99,3 +99,19 @@ def test_requeue_dead_jobs(self):
9999
100100 uuids_requeued = self .env .cr .fetchall ()
101101 self .assertTrue (queue_job .uuid in j [0 ] for j in uuids_requeued )
102+
103+ def test_requeue_orphaned_jobs (self ):
104+ queue_job = self ._get_demo_job ("test_enqueued_job" )
105+ job_obj = Job .load (self .env , queue_job .uuid )
106+
107+ # Only enqueued job, don't set it to started to simulate the scenario
108+ # that system shutdown before job is starting
109+ job_obj .set_enqueued ()
110+ job_obj .date_enqueued = datetime .now () - timedelta (minutes = 1 )
111+ job_obj .store ()
112+
113+ # job is now picked up by the requeue query (which includes orphaned jobs)
114+ query = Database (self .env .cr .dbname )._query_requeue_dead_jobs ()
115+ self .env .cr .execute (query )
116+ uuids_requeued = self .env .cr .fetchall ()
117+ self .assertTrue (queue_job .uuid in j [0 ] for j in uuids_requeued )
You can’t perform that action at this time.
0 commit comments