From 95904dbaae1fd7933e2b6ec6304aeb58c14a7ffd Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Sat, 21 Sep 2019 10:51:21 +0200 Subject: [PATCH 2/3] misc: prevent locking all jobs (#36215) .first() does list(qs)[:1] which will select all target jobs, we must add a LIMIT 1 before .first() to lock only the job we are looking for. Ordering is necessary as .first() will do an .order_by('pk') on an unordered queryset to get a deterministic result in all cases and ordering a sliced queryset is not possible. --- passerelle/base/models.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/passerelle/base/models.py b/passerelle/base/models.py index 2cd47981..5f0d6b9b 100644 --- a/passerelle/base/models.py +++ b/passerelle/base/models.py @@ -501,12 +501,13 @@ class BaseResource(models.Model): skipped_jobs = [] while True: with transaction.atomic(): - # lock a job + # lock a runnable job job = self.jobs_set().exclude( pk__in=skipped_jobs ).filter( status='registered' - ).select_for_update(**skip_locked).first() + ).select_for_update(**skip_locked + ).order_by('pk')[:1].first() if not job: break job.status = 'running' -- 2.23.0