Skip to content

Commit 97b716d

Browse files
committed
Merge PR #781 into 14.0
Signed-off-by sbidoul
2 parents 0c5f515 + c72ae6b commit 97b716d

File tree

1 file changed

+39
-16
lines changed

1 file changed

+39
-16
lines changed

queue_job/jobrunner/channels.py

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# Copyright 2015-2016 Camptocamp SA
33
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html)
44
import logging
5+
from collections import namedtuple
56
from functools import total_ordering
67
from heapq import heappop, heappush
78
from weakref import WeakValueDictionary
@@ -10,6 +11,7 @@
1011
from ..job import CANCELLED, DONE, ENQUEUED, FAILED, PENDING, STARTED, WAIT_DEPENDENCIES
1112

1213
NOT_DONE = (WAIT_DEPENDENCIES, PENDING, ENQUEUED, STARTED, FAILED)
14+
JobSortingKey = namedtuple("SortingKey", "eta priority date_created seq")
1315

1416
_logger = logging.getLogger(__name__)
1517

@@ -108,7 +110,7 @@ class ChannelJob:
108110
job that are necessary to prioritise them.
109111
110112
Channel jobs are comparable according to the following rules:
111-
* jobs with an eta come before all other jobs
113+
* jobs with an eta cannot be compared with jobs without
112114
* then jobs with a smaller eta come first
113115
* then jobs with a smaller priority come first
114116
* then jobs with a smaller creation time come first
@@ -135,14 +137,18 @@ class ChannelJob:
135137
>>> j3 < j1
136138
True
137139
138-
j4 and j5 comes even before j3, because they have an eta
140+
j4 and j5 have an eta, they cannot be compared with j3
139141
140142
>>> j4 = ChannelJob(None, None, 4,
141143
... seq=0, date_created=4, priority=9, eta=9)
142144
>>> j5 = ChannelJob(None, None, 5,
143145
... seq=0, date_created=5, priority=9, eta=9)
144-
>>> j4 < j5 < j3
146+
>>> j4 < j5
145147
True
148+
>>> j4 < j3
149+
Traceback (most recent call last):
150+
...
151+
TypeError: '<' not supported between instances of 'int' and 'NoneType'
146152
147153
j6 has same date_created and priority as j5 but a smaller eta
148154
@@ -153,7 +159,7 @@ class ChannelJob:
153159
154160
Here is the complete suite:
155161
156-
>>> j6 < j4 < j5 < j3 < j1 < j2
162+
>>> j6 < j4 < j5 and j3 < j1 < j2
157163
True
158164
159165
j0 has the same properties as j1 but they are not considered
@@ -173,14 +179,13 @@ class ChannelJob:
173179
174180
"""
175181

182+
__slots__ = ("db_name", "channel", "uuid", "_sorting_key", "__weakref__")
183+
176184
def __init__(self, db_name, channel, uuid, seq, date_created, priority, eta):
177185
self.db_name = db_name
178186
self.channel = channel
179187
self.uuid = uuid
180-
self.seq = seq
181-
self.date_created = date_created
182-
self.priority = priority
183-
self.eta = eta
188+
self._sorting_key = JobSortingKey(eta, priority, date_created, seq)
184189

185190
def __repr__(self):
186191
return "<ChannelJob %s>" % self.uuid
@@ -191,18 +196,36 @@ def __eq__(self, other):
191196
def __hash__(self):
192197
return id(self)
193198

199+
def set_no_eta(self):
200+
self._sorting_key = JobSortingKey(None, *self._sorting_key[1:])
201+
202+
@property
203+
def seq(self):
204+
return self._sorting_key.seq
205+
206+
@property
207+
def date_created(self):
208+
return self._sorting_key.date_created
209+
210+
@property
211+
def priority(self):
212+
return self._sorting_key.priority
213+
214+
@property
215+
def eta(self):
216+
return self._sorting_key.eta
217+
194218
def sorting_key(self):
195-
return self.eta, self.priority, self.date_created, self.seq
219+
# DEPRECATED
220+
return self._sorting_key
196221

197222
def sorting_key_ignoring_eta(self):
198-
return self.priority, self.date_created, self.seq
223+
return self._sorting_key[1:]
199224

200225
def __lt__(self, other):
201-
if self.eta and not other.eta:
202-
return True
203-
elif not self.eta and other.eta:
204-
return False
205-
return self.sorting_key() < other.sorting_key()
226+
# Do not compare job where ETA is set with job where it is not
227+
# If one job 'eta' is set, and the other is None, it raises TypeError
228+
return self._sorting_key < other._sorting_key
206229

207230

208231
class ChannelQueue:
@@ -312,7 +335,7 @@ def remove(self, job):
312335
def pop(self, now):
313336
while self._eta_queue and self._eta_queue[0].eta <= now:
314337
eta_job = self._eta_queue.pop()
315-
eta_job.eta = None
338+
eta_job.set_no_eta()
316339
self._queue.add(eta_job)
317340
if self.sequential and self._eta_queue and self._queue:
318341
eta_job = self._eta_queue[0]

0 commit comments

Comments
 (0)