1
- from typing import List , Any , Optional , Union
1
+ from typing import List , Optional , Union
2
2
3
3
import django
4
4
from django .apps import apps
@@ -37,43 +37,33 @@ def register_sentry(sentry_dsn, **opts):
37
37
rq_register_sentry (sentry_dsn , ** opts )
38
38
39
39
40
- def as_text (v : Union [bytes , str ]) -> Optional [str ]:
40
+ def as_str (v : Union [bytes , str ]) -> Optional [str ]:
41
41
"""Converts a bytes value to a string using `utf-8`.
42
42
43
- :param v: The value (bytes or string )
43
+ :param v: The value (None/ bytes/str )
44
44
:raises: ValueError: If the value is not bytes or string
45
45
:returns: Either the decoded string or None
46
46
"""
47
47
if v is None :
48
48
return None
49
- elif isinstance (v , bytes ):
49
+ if isinstance (v , bytes ):
50
50
return v .decode ("utf-8" )
51
- elif isinstance (v , str ):
51
+ if isinstance (v , str ):
52
52
return v
53
- else :
54
- raise ValueError ("Unknown type %r" % type (v ))
55
-
56
-
57
- def compact (lst : List [Any ]) -> List [Any ]:
58
- """Remove `None` values from an iterable object.
59
- :param lst: A list (or list-like) object
60
- :returns: The list without None values
61
- """
62
- return [item for item in lst if item is not None ]
53
+ raise ValueError ("Unknown type %r" % type (v ))
63
54
64
55
65
56
class JobExecution (Job ):
66
- def __eq__ (self , other ):
57
+ def __eq__ (self , other ) -> bool :
67
58
return isinstance (other , Job ) and self .id == other .id
68
59
69
60
@property
70
- def is_scheduled_task (self ):
61
+ def is_scheduled_task (self ) -> bool :
71
62
return self .meta .get ("scheduled_task_id" , None ) is not None
72
63
73
- def is_execution_of (self , scheduled_job ) :
64
+ def is_execution_of (self , task : "ScheduledTask" ) -> bool :
74
65
return (
75
- self .meta .get ("task_type" , None ) == scheduled_job .TASK_TYPE
76
- and self .meta .get ("scheduled_task_id" , None ) == scheduled_job .id
66
+ self .meta .get ("task_type" , None ) == task .TASK_TYPE and self .meta .get ("scheduled_task_id" , None ) == task .id
77
67
)
78
68
79
69
def stop_execution (self , connection : ConnectionType ):
@@ -138,7 +128,7 @@ def _start_scheduler(
138
128
proc = self .scheduler .start ()
139
129
self ._set_property ("scheduler_pid" , proc .pid )
140
130
141
- def execute_job (self , job : "Job" , queue : "Queue" ):
131
+ def execute_job (self , job : "Job" , queue : "Queue" ) -> None :
142
132
if self .fork_job_execution :
143
133
super (DjangoWorker , self ).execute_job (job , queue )
144
134
else :
@@ -150,16 +140,17 @@ def work(self, **kwargs) -> bool:
150
140
kwargs .setdefault ("with_scheduler" , True )
151
141
return super (DjangoWorker , self ).work (** kwargs )
152
142
153
- def _set_property (self , prop_name : str , val , pipeline : Optional [PipelineType ] = None ):
143
+ def _set_property (self , prop_name : str , val , pipeline : Optional [PipelineType ] = None ) -> None :
154
144
connection = pipeline if pipeline is not None else self .connection
155
145
if val is None :
156
146
connection .hdel (self .key , prop_name )
157
147
else :
158
148
connection .hset (self .key , prop_name , val )
159
149
160
- def _get_property (self , prop_name : str , pipeline : Optional [PipelineType ] = None ):
150
+ def _get_property (self , prop_name : str , pipeline : Optional [PipelineType ] = None ) -> Optional [ str ] :
161
151
connection = pipeline if pipeline is not None else self .connection
162
- return as_text (connection .hget (self .key , prop_name ))
152
+ res = connection .hget (self .key , prop_name )
153
+ return as_str (res )
163
154
164
155
def scheduler_pid (self ) -> Optional [int ]:
165
156
if len (self .queues ) == 0 :
@@ -170,6 +161,9 @@ def scheduler_pid(self) -> Optional[int]:
170
161
171
162
172
163
class DjangoQueue (Queue ):
164
+ """A subclass of RQ's QUEUE that allows jobs to be stored temporarily to be enqueued later at the end of Django's
165
+ request/response cycle."""
166
+
173
167
REGISTRIES = dict (
174
168
finished = "finished_job_registry" ,
175
169
failed = "failed_job_registry" ,
@@ -178,12 +172,8 @@ class DjangoQueue(Queue):
178
172
deferred = "deferred_job_registry" ,
179
173
canceled = "canceled_job_registry" ,
180
174
)
181
- """
182
- A subclass of RQ's QUEUE that allows jobs to be stored temporarily to be
183
- enqueued later at the end of Django's request/response cycle.
184
- """
185
175
186
- def __init__ (self , * args , ** kwargs ):
176
+ def __init__ (self , * args , ** kwargs ) -> None :
187
177
kwargs ["job_class" ] = JobExecution
188
178
super (DjangoQueue , self ).__init__ (* args , ** kwargs )
189
179
@@ -196,43 +186,43 @@ def get_registry(self, name: str) -> Union[None, BaseRegistry, "DjangoQueue"]:
196
186
return None
197
187
198
188
@property
199
- def finished_job_registry (self ):
189
+ def finished_job_registry (self ) -> FinishedJobRegistry :
200
190
return FinishedJobRegistry (self .name , self .connection )
201
191
202
192
@property
203
- def started_job_registry (self ):
193
+ def started_job_registry (self ) -> StartedJobRegistry :
204
194
return StartedJobRegistry (
205
195
self .name ,
206
196
self .connection ,
207
197
job_class = JobExecution ,
208
198
)
209
199
210
200
@property
211
- def deferred_job_registry (self ):
201
+ def deferred_job_registry (self ) -> DeferredJobRegistry :
212
202
return DeferredJobRegistry (
213
203
self .name ,
214
204
self .connection ,
215
205
job_class = JobExecution ,
216
206
)
217
207
218
208
@property
219
- def failed_job_registry (self ):
209
+ def failed_job_registry (self ) -> FailedJobRegistry :
220
210
return FailedJobRegistry (
221
211
self .name ,
222
212
self .connection ,
223
213
job_class = JobExecution ,
224
214
)
225
215
226
216
@property
227
- def scheduled_job_registry (self ):
217
+ def scheduled_job_registry (self ) -> ScheduledJobRegistry :
228
218
return ScheduledJobRegistry (
229
219
self .name ,
230
220
self .connection ,
231
221
job_class = JobExecution ,
232
222
)
233
223
234
224
@property
235
- def canceled_job_registry (self ):
225
+ def canceled_job_registry (self ) -> CanceledJobRegistry :
236
226
return CanceledJobRegistry (
237
227
self .name ,
238
228
self .connection ,
@@ -250,24 +240,24 @@ def get_all_job_ids(self) -> List[str]:
250
240
res .extend (self .canceled_job_registry .get_job_ids ())
251
241
return res
252
242
253
- def get_all_jobs (self ):
243
+ def get_all_jobs (self ) -> List [ JobExecution ] :
254
244
job_ids = self .get_all_job_ids ()
255
- return compact ( [self .fetch_job (job_id ) for job_id in job_ids ])
245
+ return list ( filter ( lambda j : j is not None , [self .fetch_job (job_id ) for job_id in job_ids ]) )
256
246
257
- def clean_registries (self ):
247
+ def clean_registries (self ) -> None :
258
248
self .started_job_registry .cleanup ()
259
249
self .failed_job_registry .cleanup ()
260
250
self .finished_job_registry .cleanup ()
261
251
262
- def remove_job_id (self , job_id : str ):
252
+ def remove_job_id (self , job_id : str ) -> None :
263
253
self .connection .lrem (self .key , 0 , job_id )
264
254
265
- def last_job_id (self ):
255
+ def last_job_id (self ) -> Optional [ str ] :
266
256
return self .connection .lindex (self .key , 0 )
267
257
268
258
269
259
class DjangoScheduler (RQScheduler ):
270
- def __init__ (self , * args , ** kwargs ):
260
+ def __init__ (self , * args , ** kwargs ) -> None :
271
261
kwargs .setdefault ("interval" , settings .SCHEDULER_CONFIG .SCHEDULER_INTERVAL )
272
262
super (DjangoScheduler , self ).__init__ (* args , ** kwargs )
273
263
@@ -281,10 +271,10 @@ def reschedule_all_jobs():
281
271
logger .debug (f"Rescheduling { str (item )} " )
282
272
item .save ()
283
273
284
- def work (self ):
274
+ def work (self ) -> None :
285
275
django .setup ()
286
276
super (DjangoScheduler , self ).work ()
287
277
288
- def enqueue_scheduled_jobs (self ):
278
+ def enqueue_scheduled_jobs (self ) -> None :
289
279
self .reschedule_all_jobs ()
290
280
super (DjangoScheduler , self ).enqueue_scheduled_jobs ()
0 commit comments