1+ import time
12from datetime import timedelta
23from pyres import ResQ , safe_str_to_class
34from pyres import failure
@@ -31,6 +32,8 @@ def __init__(self, queue, payload, resq, worker=None):
3132 self .resq = resq
3233 self ._worker = worker
3334
35+ self .enqueue_timestamp = self ._payload .get ("enqueue_timestamp" )
36+
3437 # Set the default back end, jobs can override when we import them
3538 # inside perform().
3639 failure .backend = RedisBackend
@@ -43,6 +46,20 @@ def perform(self):
4346 """This method converts payload into args and calls the ``perform``
4447 method on the payload class.
4548
49+ Before calling ``perform``, a ``before_perform`` class method
50+ is called, if it exists. It takes a dictionary as an argument;
51+ currently the only things stored on the dictionary are the
52+ args passed into ``perform`` and a timestamp of when the job
53+ was enqueued.
54+
55+ Similarly, an ``after_perform`` class method is called after
56+ ``perform`` is finished. The metadata dictionary contains the
57+ same data, plus a timestamp of when the job was performed, a
58+ ``failed`` boolean value, and if it did fail, a ``retried``
59+ boolean value. This method is called after retry, and is
60+ called regardless of whether an exception is ultimately thrown
61+ by the perform method.
62+
4663 #@ add entry_point loading
4764
4865 """
@@ -51,11 +68,29 @@ def perform(self):
5168 payload_class .resq = self .resq
5269 args = self ._payload .get ("args" )
5370
71+ metadata = dict (args = args )
72+ if self .enqueue_timestamp :
73+ metadata ["enqueue_timestamp" ] = self .enqueue_timestamp
74+
75+ before_perform = getattr (payload_class , "before_perform" , None )
76+ if before_perform :
77+ before_perform (metadata )
78+
79+ metadata ["failed" ] = False
80+ metadata ["perform_timestamp" ] = time .time ()
5481 try :
5582 return payload_class .perform (* args )
5683 except :
84+ metadata ["failed" ] = True
5785 if not self .retry (payload_class , args ):
86+ metadata ["retried" ] = False
5887 raise
88+ else :
89+ metadata ["retried" ] = True
90+ finally :
91+ after_perform = getattr (payload_class , "after_perform" , None )
92+ if after_perform :
93+ after_perform (metadata )
5994
6095 def fail (self , exception ):
6196 """This method provides a way to fail a job and will use whatever
0 commit comments