@@ -138,6 +138,8 @@ class Worker:
138138 :param burst: whether to stop the worker once all jobs have been run
139139 :param on_startup: coroutine function to run at startup
140140 :param on_shutdown: coroutine function to run at shutdown
141+ :param on_job_start: coroutine function to run on job start
142+ :param on_job_end: coroutine function to run on job end
141143 :param handle_signals: default true, register signal handlers,
142144 set to false when running inside other async framework
143145 :param max_jobs: maximum number of jobs to run at a time
@@ -169,6 +171,8 @@ def __init__(
169171 burst : bool = False ,
170172 on_startup : Optional ['StartupShutdown' ] = None ,
171173 on_shutdown : Optional ['StartupShutdown' ] = None ,
174+ on_job_start : Optional ['StartupShutdown' ] = None ,
175+ on_job_end : Optional ['StartupShutdown' ] = None ,
172176 handle_signals : bool = True ,
173177 max_jobs : int = 10 ,
174178 job_timeout : 'SecondsTimedelta' = 300 ,
@@ -202,6 +206,8 @@ def __init__(
202206 self .burst = burst
203207 self .on_startup = on_startup
204208 self .on_shutdown = on_shutdown
209+ self .on_job_start = on_job_start
210+ self .on_job_end = on_job_end
205211 self .sem = asyncio .BoundedSemaphore (max_jobs )
206212 self .job_timeout_s = to_seconds (job_timeout )
207213 self .keep_result_s = to_seconds (keep_result )
@@ -509,6 +515,10 @@ async def job_failed(exc: BaseException) -> None:
509515 'score' : score ,
510516 }
511517 ctx = {** self .ctx , ** job_ctx }
518+
519+ if self .on_job_start :
520+ await self .on_job_start (ctx )
521+
512522 start_ms = timestamp_ms ()
513523 success = False
514524 try :
@@ -585,6 +595,9 @@ async def job_failed(exc: BaseException) -> None:
585595 serializer = self .job_serializer ,
586596 )
587597
598+ if self .on_job_end :
599+ await self .on_job_end (ctx )
600+
588601 await asyncio .shield (
589602 self .finish_job (
590603 job_id , finish , result_data , result_timeout_s , keep_result_forever , incr_score , keep_in_progress ,
0 commit comments