Skip to content

Commit 178e98a

Browse files
committed
[IMP] queue_job: let _acquire_job obtain any job in ENQUEUED state
1 parent ea803f3 commit 178e98a

File tree

2 files changed

+45
-29
lines changed

2 files changed

+45
-29
lines changed

queue_job/controllers/main.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828

2929
class RunJobController(http.Controller):
3030
@classmethod
31-
def _acquire_job(cls, env: api.Environment, job_uuid: str) -> Job | None:
31+
def _acquire_job(
32+
cls, env: api.Environment, job_uuid: str | None = None
33+
) -> Job | None:
3234
"""Acquire a job for execution.
3335
3436
- make sure it is in ENQUEUED state
@@ -38,30 +40,32 @@ def _acquire_job(cls, env: api.Environment, job_uuid: str) -> Job | None:
3840
If successful, return the Job instance, otherwise return None. This
3941
function may fail to acquire the job is not in the expected state or is
4042
already locked by another worker.
43+
44+
If no job_uuid is given, acquire any available job in ENQUEUED state.
4145
"""
42-
env.cr.execute(
43-
"SELECT uuid FROM queue_job WHERE uuid=%s AND state=%s "
44-
"FOR UPDATE SKIP LOCKED",
45-
(job_uuid, ENQUEUED),
46-
)
47-
if not env.cr.fetchone():
48-
_logger.warning(
49-
"was requested to run job %s, but it does not exist, "
50-
"or is not in state %s, or is being handled by another worker",
51-
job_uuid,
52-
ENQUEUED,
46+
if job_uuid:
47+
env.cr.execute(
48+
"SELECT uuid FROM queue_job WHERE uuid=%s AND state=%s "
49+
"FOR UPDATE SKIP LOCKED",
50+
(job_uuid, ENQUEUED),
5351
)
52+
else:
53+
env.cr.execute(
54+
"SELECT uuid FROM queue_job WHERE state=%s LIMIT 1 "
55+
"FOR UPDATE SKIP LOCKED",
56+
(ENQUEUED,),
57+
)
58+
job_row = env.cr.fetchone()
59+
if not job_row:
60+
_logger.debug("no job to run")
5461
return None
55-
job = Job.load(env, job_uuid)
62+
job = Job.load(env, job_uuid=job_row[0])
5663
assert job and job.state == ENQUEUED
5764
job.set_started()
5865
job.store()
5966
env.cr.commit()
6067
if not job.lock():
61-
_logger.warning(
62-
"was requested to run job %s, but it could not be locked",
63-
job_uuid,
64-
)
68+
_logger.debug("could not acquire lock for job %s", job.uuid)
6569
return None
6670
return job
6771

test_queue_job/tests/test_acquire_job.py

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# Copyright 2026 ACSONE SA/NV
22
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3-
import logging
43
from unittest import mock
54

65
from odoo.tests import tagged
76

87
from odoo.addons.queue_job.controllers.main import RunJobController
8+
from odoo.addons.queue_job.job import ENQUEUED, STARTED
99

1010
from .common import JobCommonCase
1111

@@ -27,25 +27,37 @@ def test_acquire_enqueued_job(self):
2727
mock_commit.assert_called_once()
2828
self.assertIsNotNone(job)
2929
self.assertEqual(job.uuid, "test_enqueued_job")
30-
self.assertEqual(job.state, "started")
30+
self.assertEqual(job.state, STARTED)
3131
self.assertTrue(
3232
self.env["queue.job.lock"].search(
3333
[("queue_job_id", "=", job_record.id)]
3434
),
3535
"A job lock record should exist at this point",
3636
)
3737

38+
def test_acquire_any_enqueued_job(self):
39+
available_job_uuids = (
40+
self.env["queue.job"].search([("state", "=", ENQUEUED)]).mapped("uuid")
41+
)
42+
with mock.patch.object(
43+
self.env.cr, "commit", mock.Mock(side_effect=self.env.flush_all)
44+
) as mock_commit:
45+
job = RunJobController._acquire_job(self.env)
46+
mock_commit.assert_called_once()
47+
self.assertIsNotNone(job)
48+
self.assertIn(job.uuid, available_job_uuids)
49+
self.assertEqual(job.state, STARTED)
50+
self.assertTrue(
51+
self.env["queue.job.lock"].search(
52+
[("queue_job_id", "=", job.db_record().id)]
53+
),
54+
"A job lock record should exist at this point",
55+
)
56+
3857
def test_acquire_started_job(self):
39-
with (
40-
mock.patch.object(
41-
self.env.cr, "commit", mock.Mock(side_effect=self.env.flush_all)
42-
) as mock_commit,
43-
self.assertLogs(level=logging.WARNING) as logs,
44-
):
58+
with mock.patch.object(
59+
self.env.cr, "commit", mock.Mock(side_effect=self.env.flush_all)
60+
) as mock_commit:
4561
job = RunJobController._acquire_job(self.env, "test_started_job")
4662
mock_commit.assert_not_called()
4763
self.assertIsNone(job)
48-
self.assertIn(
49-
"was requested to run job test_started_job, but it does not exist",
50-
logs.output[0],
51-
)

0 commit comments

Comments
 (0)