Skip to content

Commit 03849bf

Browse files
committed
[IMP] queue_job: prevent commit during queue job execution
This would release the job lock, causing spurious restarts by the dead jobs requeuer.
1 parent d2a8e90 commit 03849bf

1 file changed

Lines changed: 28 additions & 7 deletions

File tree

queue_job/controllers/main.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import random
77
import time
88
import traceback
9+
from contextlib import contextmanager
910
from io import StringIO
1011

1112
from psycopg2 import OperationalError, errorcodes
@@ -26,6 +27,24 @@
2627
DEPENDS_MAX_TRIES_ON_CONCURRENCY_FAILURE = 5
2728

2829

30+
@contextmanager
31+
def _prevent_commit(cr):
32+
"""Context manager to prevent commits on a cursor.
33+
34+
Commiting while the job is not finished would release the job lock, causing
35+
it to be started again by the dead jobs requeuer.
36+
"""
37+
def forbidden_commit(*args, **kwargs):
38+
raise RuntimeError("Commit is forbidden in queue jobs")
39+
40+
original_commit = cr.commit
41+
cr.commit = forbidden_commit
42+
try:
43+
yield
44+
finally:
45+
cr.commit = original_commit
46+
47+
2948
class RunJobController(http.Controller):
3049
@classmethod
3150
def _acquire_job(cls, env: api.Environment, job_uuid: str) -> Job | None:
@@ -69,13 +88,15 @@ def _acquire_job(cls, env: api.Environment, job_uuid: str) -> Job | None:
6988
def _try_perform_job(cls, env, job):
7089
"""Try to perform the job, mark it done and commit if successful."""
7190
_logger.debug("%s started", job)
72-
job.perform()
73-
# Triggers any stored computed fields before calling 'set_done'
74-
# so that will be part of the 'exec_time'
75-
env.flush_all()
76-
job.set_done()
77-
job.store()
78-
env.flush_all()
91+
assert env is job.env # TODO refactor
92+
with _prevent_commit(env.cr):
93+
job.perform()
94+
# Triggers any stored computed fields before calling 'set_done'
95+
# so that will be part of the 'exec_time'
96+
env.flush_all()
97+
job.set_done()
98+
job.store()
99+
env.flush_all()
79100
env.cr.commit()
80101
_logger.debug("%s done", job)
81102

0 commit comments

Comments
 (0)