1
+ import datetime
1
2
import os
2
3
from functools import wraps
3
4
from huey import (
@@ -198,9 +199,13 @@ def on_interrupted(signal_name, task_obj, exception_obj=None, /, *, huey=None):
198
199
assert hasattr (huey , 'enqueue' ) and callable (huey .enqueue )
199
200
huey .enqueue (task_obj )
200
201
202
+ storage_key_prefix = 'task_history:'
203
+
201
204
def historical_task (signal_name , task_obj , exception_obj = None , / , * , huey = None ):
202
205
signal_time = utils .time_clock ()
206
+ signal_dt = datetime .datetime .now (datetime .timezone .utc )
203
207
208
+ from common .models import TaskHistory
204
209
add_to_elapsed_signals = frozenset ((
205
210
signals .SIGNAL_INTERRUPTED ,
206
211
signals .SIGNAL_ERROR ,
@@ -214,7 +219,7 @@ def historical_task(signal_name, task_obj, exception_obj=None, /, *, huey=None):
214
219
signals .SIGNAL_EXECUTING ,
215
220
signals .SIGNAL_RETRYING ,
216
221
)) | add_to_elapsed_signals
217
- storage_key = f'task_history: { task_obj .id } '
222
+ storage_key = f'{ storage_key_prefix } { task_obj .id } '
218
223
task_obj_attr = '_signals_history'
219
224
220
225
history = getattr (task_obj , task_obj_attr , None )
@@ -224,13 +229,15 @@ def historical_task(signal_name, task_obj, exception_obj=None, /, *, huey=None):
224
229
key = storage_key ,
225
230
peek = True ,
226
231
) or dict (
232
+ created = signal_dt ,
227
233
data = task_obj .data ,
228
234
elapsed = 0 ,
229
235
module = task_obj .__module__ ,
230
236
name = task_obj .name ,
231
237
)
232
238
setattr (task_obj , task_obj_attr , history )
233
239
assert history is not None
240
+ history ['modified' ] = signal_dt
234
241
235
242
if signal_name in recorded_signals :
236
243
history [signal_name ] = signal_time
@@ -240,12 +247,61 @@ def historical_task(signal_name, task_obj, exception_obj=None, /, *, huey=None):
240
247
huey .get (key = storage_key )
241
248
else :
242
249
huey .put (key = storage_key , data = history )
250
+ th , created = TaskHistory .objects .get_or_create (
251
+ task_id = str (task_obj .id ),
252
+ name = f"{ task_obj .__module__ } .{ task_obj .name } " ,
253
+ queue = huey .name ,
254
+ )
255
+ th .priority = task_obj .priority
256
+ th .task_params = list ((
257
+ list (task_obj .args ),
258
+ repr (task_obj .kwargs ),
259
+ ))
260
+ if signal_name == signals .SIGNAL_EXECUTING :
261
+ th .attempts += 1
262
+ th .start_at = signal_dt
263
+ elif exception_obj is not None :
264
+ th .failed_at = signal_dt
265
+ th .last_error = str (exception_obj )
266
+ elif signal_name == signals .SIGNAL_ENQUEUED :
267
+ from sync .models import Media , Source
268
+ if not th .verbose_name and task_obj .args :
269
+ key = task_obj .args [0 ]
270
+ for model in (Media , Source ,):
271
+ try :
272
+ model_instance = model .objects .get (pk = key )
273
+ except model .DoesNotExist :
274
+ pass
275
+ else :
276
+ if hasattr (model_instance , 'key' ):
277
+ th .verbose_name = f'{ th .name } with: { model_instance .key } '
278
+ if hasattr (model_instance , 'name' ):
279
+ th .verbose_name += f' / { model_instance .name } '
280
+ th .end_at = signal_dt
281
+ th .save ()
243
282
244
283
# Registration of shared signal handlers
245
284
246
285
def register_huey_signals ():
247
- from django_huey import DJANGO_HUEY , signal
286
+ from django_huey import DJANGO_HUEY , get_queue , signal
248
287
for qn in DJANGO_HUEY .get ('queues' , dict ()):
249
288
signal (signals .SIGNAL_INTERRUPTED , queue = qn )(on_interrupted )
250
289
signal (queue = qn )(historical_task )
251
290
291
+ # clean up old history and results from storage
292
+ q = get_queue (qn )
293
+ now_time = utils .time_clock ()
294
+ for key in q .all_results ().keys ():
295
+ if not key .startswith (storage_key_prefix ):
296
+ continue
297
+ history = q .get (peek = True , key = key )
298
+ if not isinstance (history , dict ):
299
+ continue
300
+ age = datetime .timedelta (
301
+ seconds = (now_time - history .get (signals .SIGNAL_EXECUTING , now_time )),
302
+ )
303
+ if age > datetime .timedelta (days = 7 ):
304
+ result_key = key [len (storage_key_prefix ) :]
305
+ q .get (peek = False , key = result_key )
306
+ q .get (peek = False , key = key )
307
+
0 commit comments