@@ -44,17 +44,16 @@ def perform_job(job_model: JobModel, connection: ConnectionType) -> Any: # noqa
44
44
45
45
try :
46
46
result = job_model .func (* job_model .args , ** job_model .kwargs )
47
+ job_model .save (connection = connection , save_all = True )
47
48
if asyncio .iscoroutine (result ):
48
49
loop = asyncio .new_event_loop ()
49
50
coro_result = loop .run_until_complete (result )
50
51
result = coro_result
51
- if job_model .success_callback :
52
- job_model .success_callback (job_model , connection , result )
52
+ job_model .call_success_callback (job_model , connection , result )
53
53
return result
54
54
except Exception as e :
55
55
logger .error (f"Job { job_model .name } failed with exception: { e } " , exc_info = True )
56
- if job_model .failure_callback :
57
- job_model .failure_callback (job_model , connection , * sys .exc_info ())
56
+ job_model .call_failure_callback (job_model , connection , * sys .exc_info ())
58
57
raise
59
58
finally :
60
59
assert job_model is _job_stack .pop ()
@@ -90,6 +89,15 @@ def __init__(self, connection: ConnectionType, name: str, is_async: bool = True)
90
89
self .scheduled_job_registry = ScheduledJobRegistry (connection = self .connection , name = self .name )
91
90
self .canceled_job_registry = CanceledJobRegistry (connection = self .connection , name = self .name )
92
91
92
+ def refresh_connection (self , connection : ConnectionType ) -> None :
93
+ self .connection = connection
94
+ self .queued_job_registry .connection = connection
95
+ self .active_job_registry .connection = connection
96
+ self .failed_job_registry .connection = connection
97
+ self .finished_job_registry .connection = connection
98
+ self .scheduled_job_registry .connection = connection
99
+ self .canceled_job_registry .connection = connection
100
+
93
101
def __len__ (self ) -> int :
94
102
return self .count
95
103
@@ -111,43 +119,27 @@ def clean_registries(self, timestamp: Optional[float] = None) -> None:
111
119
self .connection , before_score
112
120
)
113
121
114
- with self .connection .pipeline () as pipeline :
115
- for job_name , job_score in started_jobs :
116
- job = JobModel .get (job_name , connection = self .connection )
117
- if job is None or job .failure_callback is None or job_score + job .timeout > before_score :
118
- continue
122
+ for job_name , job_score in started_jobs :
123
+ job = JobModel .get (job_name , connection = self .connection )
124
+ if job is None or not job .has_failure_callback or job_score + job .timeout > before_score :
125
+ continue
119
126
120
- logger .debug (f"Running failure callbacks for { job .name } " )
121
- try :
122
- job .failure_callback (job , self .connection , traceback .extract_stack ())
123
- except Exception : # noqa
124
- logger .exception (f"Job { self .name } : error while executing failure callback" )
125
- raise
127
+ logger .debug (f"Running failure callbacks for { job .name } " )
128
+ try :
129
+ job .call_failure_callback (job , self .connection , traceback .extract_stack ())
130
+ except Exception : # noqa
131
+ logger .exception (f"Job { self .name } : error while executing failure callback" )
132
+ raise
126
133
127
- else :
128
- logger .warning (
129
- f"Queue cleanup: Moving job to { self .failed_job_registry .key } (due to AbandonedJobError)"
130
- )
131
- exc_string = (
132
- f"Moved to { self .failed_job_registry .key } , due to AbandonedJobError, at { datetime .now ()} "
133
- )
134
- job .status = JobStatus .FAILED
135
- score = current_timestamp () + SCHEDULER_CONFIG .DEFAULT_FAILURE_TTL
136
- Result .create (
137
- connection = pipeline ,
138
- job_name = job .name ,
139
- worker_name = job .worker_name ,
140
- _type = ResultType .FAILED ,
141
- ttl = SCHEDULER_CONFIG .DEFAULT_FAILURE_TTL ,
142
- exc_string = exc_string ,
143
- )
144
- self .failed_job_registry .add (pipeline , job .name , score )
145
- job .expire (connection = pipeline , ttl = SCHEDULER_CONFIG .DEFAULT_FAILURE_TTL )
146
- job .save (connection = pipeline )
134
+ else :
135
+ logger .warning (
136
+ f"Queue cleanup: Moving job to { self .failed_job_registry .key } (due to AbandonedJobError)"
137
+ )
138
+ exc_string = f"Moved to { self .failed_job_registry .key } , due to AbandonedJobError, at { datetime .now ()} "
139
+ self .job_handle_failure (JobStatus .FAILED , job , exc_string )
147
140
148
141
for registry in self .REGISTRIES .values ():
149
142
getattr (self , registry ).cleanup (connection = self .connection , timestamp = before_score )
150
- pipeline .execute ()
151
143
152
144
def first_queued_job_name (self ) -> Optional [str ]:
153
145
return self .queued_job_registry .get_first ()
@@ -248,37 +240,35 @@ def create_and_enqueue_job(
248
240
raise TypeError (f"Invalid type for when=`{ when } `" )
249
241
return job_model
250
242
251
- def job_handle_success (
252
- self , job : JobModel , result : Any , job_info_ttl : int , result_ttl : int , connection : ConnectionType
253
- ) -> None :
243
+ def job_handle_success (self , job : JobModel , result : Any , job_info_ttl : int , result_ttl : int ) -> None :
254
244
"""Saves and cleanup job after successful execution"""
255
245
job .after_execution (
256
246
job_info_ttl ,
257
247
JobStatus .FINISHED ,
258
248
prev_registry = self .active_job_registry ,
259
249
new_registry = self .finished_job_registry ,
260
- connection = connection ,
250
+ connection = self . connection ,
261
251
)
262
252
Result .create (
263
- connection ,
253
+ self . connection ,
264
254
job_name = job .name ,
265
255
worker_name = job .worker_name ,
266
256
_type = ResultType .SUCCESSFUL ,
267
257
return_value = result ,
268
258
ttl = result_ttl ,
269
259
)
270
260
271
- def job_handle_failure (self , status : JobStatus , job : JobModel , exc_string : str , connection : ConnectionType ) -> None :
261
+ def job_handle_failure (self , status : JobStatus , job : JobModel , exc_string : str ) -> None :
272
262
# Does not set job status since the job might be stopped
273
263
job .after_execution (
274
264
SCHEDULER_CONFIG .DEFAULT_FAILURE_TTL ,
275
265
status ,
276
266
prev_registry = self .active_job_registry ,
277
267
new_registry = self .failed_job_registry ,
278
- connection = connection ,
268
+ connection = self . connection ,
279
269
)
280
270
Result .create (
281
- connection ,
271
+ self . connection ,
282
272
job .name ,
283
273
job .worker_name ,
284
274
ResultType .FAILED ,
@@ -291,19 +281,11 @@ def run_sync(self, job: JobModel) -> JobModel:
291
281
job .prepare_for_execution ("sync" , self .active_job_registry , self .connection )
292
282
try :
293
283
result = perform_job (job , self .connection )
294
-
295
- with self .connection .pipeline () as pipeline :
296
- self .job_handle_success (
297
- job , result = result , job_info_ttl = job .job_info_ttl , result_ttl = job .success_ttl , connection = pipeline
298
- )
299
-
300
- pipeline .execute ()
284
+ self .job_handle_success (job , result = result , job_info_ttl = job .job_info_ttl , result_ttl = job .success_ttl )
301
285
except Exception as e : # noqa
302
286
logger .warning (f"Job { job .name } failed with exception: { e } " )
303
- with self .connection .pipeline () as pipeline :
304
- exc_string = "" .join (traceback .format_exception (* sys .exc_info ()))
305
- self .job_handle_failure (JobStatus .FAILED , job , exc_string , pipeline )
306
- pipeline .execute ()
287
+ exc_string = "" .join (traceback .format_exception (* sys .exc_info ()))
288
+ self .job_handle_failure (JobStatus .FAILED , job , exc_string )
307
289
return job
308
290
309
291
@classmethod
0 commit comments