
    R3i&                       U d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlmZmZ d dlmZmZmZ d dlmZ d dlmZmZmZmZmZmZmZ d dlZe	j8                  dk  rd dlmZ d d	lm Z  nd d	lm Z  d d
l!m"Z" d dl#m$Z$m%Z%m&Z& ddl'm(Z(m)Z) ddl*m+Z+ d dl,m-Z- d dl.m/Z/m0Z0m1Z1 d dl2m3Z3 ddl4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZC ddlDmEZEmFZFmGZGmHZHmIZI ddlJmKZKmLZLmMZM ddlNmOZOmPZPmQZQmRZRmSZSmTZTmUZUmVZVmWZWmXZXmYZYmZZZm[Z[m\Z\m]Z]  ed      Z^dZ_dZ`eaZbdecd<    G d de      Zd e7        e>       d	 	 	 	 	 	 	 	 	 d'dZe ej                  eg      Zhd ecd<    e"j                  eg      Zjd!ecd"<    G d# d$e      Zk G d% d&      Zly)(    )annotationsN)AsyncExitStackcontextmanager)datetime	timedeltatimezone)TracebackType)Any	GeneratorMappingProtocol	TypeAlias	TypedDictcast)      )ExceptionGroup)	TaskGroup)trace)Status
StatusCodeTracer   )CANCEL_MSG_CLEANUPcancel_task)suppress_instrumentation)Redis)ConnectionError	LockErrorResponseError)Self)AdmissionBlockedCompletionHandlerCurrentExecution
DependencyFailedDependencyFailureHandler	PerpetualRuntimeSharedContext
TaskLoggerTaskOutcomeformat_durationget_single_dependency_of_type'get_single_dependency_parameter_of_typeresolved_dependencies)Docket	ExecutionRedisMessageRedisMessageIDRedisReadGroupResponse)TaskFunctioncompact_signatureget_signature)QUEUE_DEPTHREDIS_DISRUPTIONSSCHEDULE_DEPTHTASK_DURATIONTASK_PUNCTUALITYTASKS_COMPLETEDTASKS_FAILEDTASKS_REDELIVEREDTASKS_RUNNINGTASKS_STARTEDTASKS_STRICKENTASKS_SUCCEEDEDTASKS_SUPERSEDEDhealthcheck_servermetrics_serverd   milliseconds
   r   TaskKeyc                  :    e Zd ZU dZded<   ded<   ded<   ded<   y	)
PubSubMessagez9Message received from Redis pub/sub pattern subscription.strtypebytespatternchannelzbytes | strdataN)__name__
__module____qualname____doc____annotations__     W/mnt/e/genesis-system/.venvs/voice-bridge/lib/python3.12/site-packages/docket/worker.pyrN   rN   e   s    C
INN
r[   rN   )	executionloggerr^   c                D   K   |j                  d| j                         yw)z<Default fallback that logs a warning and completes the task.zqUnknown task %r received - dropping. Register via CLI (--tasks your.module:tasks) or API (docket.register(func)).N)warningfunction_name)r]   r^   argskwargss       r\   default_fallback_taskrd   n   s#      NN	Ws    zlogging.Loggerr   tracerc                       e Zd Z	 	 	 	 	 	 ddZy)_stream_due_tasksc                   K   y wNrZ   )selfkeysrb   s      r\   __call__z_stream_due_tasks.__call__   s	     s   N)rk   	list[str]rb   zlist[str | float]returnztuple[int, int])rU   rV   rW   rl   rZ   r[   r\   rg   rg      s    %6	r[   rg   c                     e Zd ZU dZded<   ded<   ded<   ded	<   ded
<   ded<   ded<   ded<   ded<   ded<   dd ed       ed       ed       ed      dddf		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d8dZed9d       Zd:dZ		 	 	 	 	 	 	 	 d;dZ
d<dZd<d Zedd!dd ed       ed       ed"       ed      dddddd#gdf	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d=d$       Zd>d%Zd>d&Zd'ed(<   d?d)Zd@dAd*Zd@dBd+ZdCd,Z	 	 	 	 	 	 dDd-Zd>d.ZdEd/ZdFd0Zd>d1ZedGd2       ZdHd3ZdId4Zd>d5Zd>d6ZdJd7Z y)KWorkera  A Worker executes tasks on a Docket.  You may run as many workers as you like
    to work a single Docket.

    Example:

    ```python
    async with Docket() as docket:
        async with Worker(docket) as worker:
            await worker.run_forever()
    ```
    r1   docketrO   nameintconcurrencyr   redelivery_timeoutreconnection_delayminimum_check_intervalscheduling_resolutionboolschedule_automatic_tasksenable_internal_instrumentationr6   fallback_taskNrK      )minutesseconds   rI   TFc                    || _         |xs+ t        j                          dt        j                          | _        || _        || _        || _        || _	        || _
        || _        |	| _        |
xs t        | _        y )N#)rq   socketgethostnameosgetpidrr   rt   ru   rv   rw   rx   rz   r{   rd   r|   )rj   rq   rr   rt   ru   rv   rw   rx   rz   r{   r|   s              r\   __init__zWorker.__init__   sx     Cv1134Abiik]C	&"4"4&<#%:"(@%/N,*C.Cr[   c              #  t   K   | j                   st               5  d ddd       yd y# 1 sw Y   yxY ww)a  Suppress OTel auto-instrumentation for internal Redis operations.

        When enable_internal_instrumentation is False (default), this context manager
        suppresses OpenTelemetry auto-instrumentation spans for internal Redis polling
        operations like XREADGROUP, XAUTOCLAIM, and Lua script evaluations. This prevents
        thousands of noisy spans per minute from overwhelming trace storage.

        Task execution spans and user-facing operations (schedule, cancel, etc.) are
        NOT suppressed.
        N)r{   r   rj   s    r\   _maybe_suppress_instrumentationz&Worker._maybe_suppress_instrumentation   s8      33)+    s   8,858c                v   K   t                _         j                  j                          d {    t        j                          _         j                  j                   fd       t        j                          _         j                  j                   fd        j                  j                          t        j                          _	         j                  j                   fd       i  _
         j                  j                   fd       i  _         j                  j                   fd       t        j                   j                          j                  j                   d       _         j                  j                   fd        j                  j#                  t$         j                   t&               t)         j                          _         j                  j                   fd	        j                  j-                   j*                         d {     S 7 7 	w)
Nc                     t         d      S )N_worker_stoppingdelattrr   s   r\   <lambda>z#Worker.__aenter__.<locals>.<lambda>   s    WT3E%F r[   c                     t         d      S )N_worker_doner   r   s   r\   r   z#Worker.__aenter__.<locals>.<lambda>   s    WT>%B r[   c                     t         d      S )N_cancellation_readyr   r   s   r\   r   z#Worker.__aenter__.<locals>.<lambda>   s    WT3H%I r[   c                     t         d      S )N_execution_countsr   r   s   r\   r   z#Worker.__aenter__.<locals>.<lambda>   s    WT3F%G r[   c                     t         d      S )N_tasks_by_keyr   r   s   r\   r   z#Worker.__aenter__.<locals>.<lambda>   s    WT?%C r[   z - heartbeatrr   c                     t         d      S )N_heartbeat_taskr   r   s   r\   r   z#Worker.__aenter__.<locals>.<lambda>       WT3D%E r[   c                     t         d      S )N_shared_contextr   r   s   r\   r   z#Worker.__aenter__.<locals>.<lambda>   r   r[   )r   _stack
__aenter__asyncioEventr   callbackr   setr   r   r   create_task
_heartbeatrq   rr   r   push_async_callbackr   r   r*   r   enter_async_contextr   s   `r\   r   zWorker.__aenter__   s    $&kk$$&&& !(FG#MMOBC#*==? IJ13GH@BCD&22OOt{{'7'7&8$E 
 	EF''--/A	

  -T[[$?EFkk--d.B.BCCC; 	'6 	Ds"   -H9H4G<H9-H7.H97H9c                   K   | j                   j                          | j                  j                          d {    	 | j                  j                  |||       d {    | `y 7 -7 	# | `w xY wwri   )r   r   r   waitr   	__aexit__)rj   exc_type	exc_value	tracebacks       r\   r   zWorker.__aexit__   sj      	!!#$$&&&	++'')YGGG 	' Hs9   8A3A(A3  A,  A*!A, %A3*A, ,A00A3c                V    i | j                   j                         d| j                  iS )Nzdocket.worker)rq   labelsrr   r   s    r\   r   zWorker.labels   s/    
kk  "
TYY
 	
r[   c                    i | j                         | j                  j                  | j                  j                  dS )N)zdocket.queue_keyzdocket.stream_key)r   rq   	queue_key
stream_keyr   s    r\   _log_contextzWorker._log_context   s9    
kkm
 $ 5 5!%!7!7
 	
r[   zredis://localhost:6379/0rH   zdocket.tasks:standard_tasksc                f  K   d}|r6|j                  d      \  }}}t        j                  |      }t        ||      }t	        |      5  t        |      5  t        |||
      4 d{   }|D ]  }|j                  |        t        ||||||||	|
|
      4 d{   }t        j                         }ddfdt        t        d      rF|j                  t        j                  fd       |j                  t        j                  fd	       	 |r)t        j                   |j#                         | d
      n(t        j                   |j%                         | d
       d{    t        t        d      r?|j)                  t        j                         |j)                  t        j                         	 ddd      d{    ddd      d{    ddd       ddd       y7 7 X7 # t        j&                  $ r Y w xY w# t        t        d      r?|j)                  t        j                         |j)                  t        j                         w w xY w7 # 1 d{  7  sw Y   xY w7 # 1 d{  7  sw Y   xY w# 1 sw Y   xY w# 1 sw Y   yxY ww)a  Run a worker as the main entry point (CLI).

        This method installs signal handlers for graceful shutdown since it
        assumes ownership of the event loop. When embedding Docket in another
        framework (e.g., FastAPI with uvicorn), use Worker.run_forever() or
        Worker.run_until_finished() directly - those methods do not install
        signal handlers and rely on the framework to handle shutdown signals.
        N:)port)rr   urlr{   )
rq   rr   rt   ru   rv   rw   rx   rz   r{   r|   c                z    t         j                  d|        r"j                         sj                          y y y )Nz,Received %s, initiating graceful shutdown...)r^   infodonecancel)sig_namerun_tasks    r\   handle_shutdownz#Worker.run.<locals>.handle_shutdownH  s2    JH $HMMO$OO- -<8r[   SIGTERMc                       d      S )Nr   rZ   r   s   r\   r   zWorker.run.<locals>.<lambda>Q  s    OI4N r[   c                       d      S )NSIGINTrZ   r   s   r\   r   zWorker.run.<locals>.<lambda>T  s    ?83L r[   z	 - workerr   )r   rO   rn   None)
rpartition	importlibimport_modulegetattrrF   rG   r1   register_collectionrp   r   get_running_loophasattrsignaladd_signal_handlerr   r   r   run_until_finishedrun_foreverCancelledErrorremove_signal_handler)clsdocket_namer   rr   rt   ru   rv   rw   rx   rz   r{   until_finishedhealthcheck_portmetrics_porttasksr|   resolved_fallback_taskmodule_name_member_namemodulerq   	task_pathworkerloopr   r   s                            @@r\   runz
Worker.run  s    8 7;*7*B*B3*G'KK,,[9F%,V[%A" $45@	F-@	F  0O <F <F !& :I..y9: %!$/+=+=/E.C1I8W&<4F 4F  
 #335D:>H. vy1//"NN,N //"MM+LF)'.':': & 9 9 ;(3}I%>(H
 (/':': & 2 2 4(3}I%>(H ' #695 66v~~F 66v}}Ei4F 4F<F <F	@	F @	F @	F<F4F\ '"11  #695 66v~~F 66v}}E 6e4F 4F 4F 4F<F <F <F <F	@	F @	F @	F @	Fs  AJ1J%J+G6
,J/2J!G9"J%A3I-	AG>1G<2G>6AI-	JI+
JJ J!J%J%-	J16J9J<G>>HHHHAI((I-	+J-I?3I64I?;JJJ
JJJJ"	J%%J.*J1c                B   K   | j                  d       d{   S 7 w)z8Run the worker until there are no more tasks to process.FforeverN_runr   s    r\   r   zWorker.run_until_finishedj  s     YYuY----   c                B   K   | j                  d       d{   S 7 w)zRun the worker indefinitely.Tr   Nr   r   s    r\   r   zWorker.run_forevern  s     YYtY,,,,r   zdict[str, int]r   c                   K   D ci c]  }|d c} _         d fd} j                  j                  j                  |       	  j	                          d{     j                  j                  j                  |       i  _         yc c}w 7 6#  j                  j                  j                  |       i  _         w xY ww)al  
        Run the worker until there are no more tasks to process, but limit specified
        task keys to a maximum number of iterations.

        This is particularly useful for testing self-perpetuating tasks that would
        otherwise run indefinitely.

        Args:
            iterations_by_key: Maps task keys to their maximum allowed executions
        r   c                T    | j                   }|vryj                  |   |   k\  ryy)NFT)keyr   )r]   r   iterations_by_keyrj   s     r\   has_reached_max_iterationsz6Worker.run_at_most.<locals>.has_reached_max_iterations  s7    --C++%%c*.?.DDr[   N)r]   r2   rn   ry   )r   rq   strike_listadd_conditionr   remove_condition)rj   r   r   r   s   ``  r\   run_at_mostzWorker.run_at_mostt  s      5F!FS#q&!F		 	--.HI	())+++KK##445OP%'D"% "G ,KK##445OP%'D"s9   C
B4CB BB  2CB .CCc                  K   | j                          	 	 | j                  j                         4 d {   }| j                  ||       d {   cd d d       d {    S 7 07 7 	# 1 d {  7  sw Y   nxY wn# t        $ r t        j                  d| j                                t        j                  d| j                  d       t        j                  | j                  j                                d {  7   Y nw xY ww)NTr   r   z,Error connecting to redis, retrying in %s...exc_info)_startup_logrq   redis_worker_loopr   r:   addr   r^   r`   rv   r   sleeptotal_seconds)rj   r   r   s      r\   r   zWorker._run  s     
M;;,,. K K%!%!2!25'!2!JJK K KJK K K K K" M!%%a7B++!  
 mmD$;$;$I$I$KLLLM	 s   DB  A$B  A*A&A*B  A(B  #D$B  &A*(B  *A<0A31A<8B  ?D A?D?D DDDDc           	        K    j                   j                           j                  j                           j                  j                          i i  j                   j                         d fd}d fdd fd	 d	 	 	 	 	 	 	 d fd}d fd}d fd	 t               4 d {   }|j                   j                          j                  j                   d        j                  j                          d {     j                  r j                          d {    |j                   j                         j                  j                   d	       |j                   j                         j                  j                   d
       d} j                   j                   }|s|sr |       s |        d {     j                  t#              z
  dk  r6t%        j&                   j(                  j+                                d {    ofD ]E  }	 |	       d {   D ])  \  }
}|
dk(  }|D ]  \  }}|s	 ||||       d {     + dk  sE n |ss |        d {   }|s|sr |       sω j                   j-                          d d d       d {    r,t%        j4                  ddi d {     |        d {     j                  j-                          y 7 ]7 7 7 A7 7 7 7 7 a# 1 d {  7  sw Y   qxY w# t$        j.                  $ r& r!t0        j3                  dt#                     Y w xY w7 7 # r.t%        j4                  ddi d {  7    |        d {  7    j                  j-                          w xY ww)Nc                   K   t         j                  d       j                         4 d {   } | j                  j                  j
                         | j                  j                  j                         | j                          d {   }|d   }|d   }|dkD  xs |dkD  cd d d       d {    S 7 7 -7 	# 1 d {  7  sw Y   y xY ww)NzChecking for workextrar   r   )	r^   debugpipelinexlenrq   r   zcardr   execute)r  results
stream_len	queue_lenlog_contextr   rj   s       r\   check_for_workz+Worker._worker_loop.<locals>.check_for_work  s     LL,KL@~~' 7 78dkk445t{{445+3+;+;+=%=$QZ
#AJ	!A~6Q7 7 7 &>7 7 7 7sW   ,CB=CACB?C+C7C8C?CCC	C
CCc           
     4  K   t         j                  d       	 j                         5  | j                  j                  j
                  j                  j                  j                  t        j                  j                         dz        d       d {   ^}}}d d d        dfgS 7 # 1 sw Y   xY w# t        $ rL}dt        |      v r9j                  j                          d {  7    |        d {  7  cY d }~S  d }~ww xY ww)NzGetting redeliveriesr     z0-0)rr   	groupnameconsumernamemin_idle_timestart_idcountNOGROUP   __redelivery__)r^   r   r   
xautoclaimrq   r   worker_group_namerr   rs   ru   r   r    rO   _ensure_stream_and_group)r   r   redeliverieseavailable_slotsget_redeliveriesr  rj   s       r\   r  z-Worker._worker_loop.<locals>.get_redeliveries  s    LL/{LC99; 
050@0@![[33"&++"?"?%)YY&) 33AACdJ' "'- 1A 	1 	+'A|a
  '566	+
 
 ! A&++>>@@@!1%!8888	s|   DC  A1B4B2B4%C  -D2B44B=9C   	D	*D3C64DDD	D
DDDDc           
       K   t         j                  d       j                  j                  j	                  d      }	 j                         5  | j                  j                  j                  j                  j                  j                  di|rdn%t        j                  j                         dz               d {   }d d d        |r7s5t!        j"                  j                  j                                d {    S 7 G# 1 sw Y   FxY w# t        $ rL}dt        |      v r9j                  j                          d {  7    |        d {  7  cY d }~S  d }~ww xY w7 lw)	NzGetting new deliveriesr   z	memory://>r   r  )r  r  streamsblockr  r  )r^   r   rq   r   
startswithr   
xreadgroupr  rr   r   rs   rw   r   r    rO   r  r   r   )r   	is_memoryresultr  r  get_new_deliveriesr  rj   s       r\   r"  z/Worker._worker_loop.<locals>.get_new_deliveries  s?    LL1LE 22;?I99; 	#(#3#3"&++"?"?%)YY!%!7!7 =$   !<!<!J!J!Lt!ST- $4 $ F	 mmD$?$?$M$M$OPPPM!	 	 ! A&++>>@@@!3E!::::	 Qs   =E7D A6DDDD 4E7E5	E7DDD 	E2&*E-EE-!E$"E-&E2'E7,E--E22E7c                ^  K   t        j                  j                  ||j                         d {   }t	        j
                  j                  |      j                  j                   d|j                         }| |<   ||<   |j                  |j                  <   dz  y 7 vw)N)redeliveredr|   z - task:r   r   )
r2   from_messagerq   r|   r   r   _executerr   r   r   )	
message_idmessageis_redeliveryr]   taskactive_tasksr  rj   task_executionss	        r\   
start_taskz'Worker._worker_loop.<locals>.start_task  s     
 (44)"00	 I &&i((())--AD ",L$-OD!04Dy}}- q O!s   1B-B+A7B-c                 x  K   D  ch c]  } | j                         s|  }} |D ]f  } j                  |       }
j                  |       }	j                  j                  |j                  d        	 |  d {     |       d {    h y c c} w 7 7 # t        $ r}t
        j                  d|j                  j                         t        j                  t        j                        t        z   |j                  _        |j                  j                  |       d {  7   Y d }~d }~ww xY ww)Nu7   🔒 Task %s blocked by admission control, reschedulingr   )reschedule_message)r   popr   r   r"   r^   r   r]   r   nowr   utcADMISSION_BLOCKED_RETRY_DELAYwhenschedule)r*  completed_tasksr'  r]   r  ack_messager+  r  r   rj   r,  s        r\   process_completed_tasksz4Worker._worker_loop.<locals>.process_completed_tasks  s    0<L		tLOL' N)--d3
+//5	""&&y}}d;NJJ%eZ888N M 8' 	NLLQ) !  !X\\25RR KK$ ++..*.MMM	Nsp   D:BBAD:2B7B8BB	BD:BB	D7"BD2&D)'D2,D:2D77D:c                  K   t         j                  d       | j                         4 d {   }|j                  j                  j
                  j                  j                  |       |j                  j                  j
                  |       |j                          d {    d d d       d {    y 7 7 7 	# 1 d {  7  sw Y   y xY ww)NzAcknowledging messager   )	r^   r   r  xackrq   r   r  xdelr  )r   r'  r  r  rj   s      r\   r7  z(Worker._worker_loop.<locals>.ack_message  s     LL0LD~~' 
) 
)8KK**KK11
 KK** &&(((
) 
) 
) )
) 
) 
) 
)sW   ,CB>CA5C(C )C-C8C9C CCC
CCCz - cancellation listenerr   z - schedulerz - lease renewalTr   r  z0Shutdown requested, finishing %d active tasks...r   return_exceptions)rn   ry   )r   r   rn   r5   F)r'  r4   r(  r3   r)  ry   rn   r   rn   r   )r   r   r'  r4   rn   r   )r   clearr   r   rt   r   r   r   _cancellation_listenerrq   rr   r   rz   '_schedule_all_automatic_perpetual_tasks_scheduler_loop_renew_leasesis_setlenr   r   rw   r   r   r   r^   r   gather)rj   r   r   r	  r-  r8  infrahas_workstoppingsourcer   messagesr)  r'  r(  r7  r+  r  r"  r  r  r,  s   ``             @@@@@@@r\   r   zWorker._worker_loop  s    ##%!  &&(AC?A**'')	7	7 	7*	 	: #(	!&	!!	!  	! 		! 	!.	N 	N(	)?	$ { /, /,e!!//1 KK,,--EF "  ..3355500FFHHH!!((/ KK,,-\: "  !!&&ul; KK,,--=> " 
 "&0077(lHJ1333&*&6&6\9J&JO&!+%mmD,G,G,U,U,WXXX #35G"H 
":@-4G U0J,6:K,KM7? U 3
G'.$,&0Wm&T T T	UU +a/!
" #<)7)9#9- (lHJ2 %%))+_/, /,t nnlKdKKK-///!!#}/, 6 I 4
 Y 5H !U $:Y/, /, /, /,b %% 	F%%  	 L/ nnlKdKKK-///!!#sG  B-O9M L$M AL:!L'"#L:L*B&L:,L--AL:>L0?L:L2'L:>L4?L:L:L6L:1L:M L8M O5N6ONO$M 'L:*L:-L:0L:2L:4L:6L:8M :M MMM 6NN NN OOO*N-+O:N=; OOc                  K   t        t        |j                  d            }| j                         }| j                  j                         sO	 t        j                  d|       | j                         5   || j                  j                  | j                  j                  gt        j                  t        j                        j!                         | j                  j"                  g       d{   \  }}ddd       dkD  rCt        j                  d|| j                  j                  | j                  j                  |       	 t)        j*                  | j                  j-                         | j.                  j1                                d{    yyy7 # 1 sw Y   xY w# t$        $ r t        j'                  dd	|
       Y w xY w7 <# t(        j2                  $ r Y nw xY w| j                  j                         sow)z7Loop that moves due tasks from the queue to the stream.a  
            local total_work = redis.call('ZCARD', KEYS[1])
            local due_work = 0

            if total_work > 0 then
                local tasks = redis.call('ZRANGEBYSCORE', KEYS[1], 0, ARGV[1])

                for i, key in ipairs(tasks) do
                    local hash_key = ARGV[2] .. ":" .. key
                    local task_data = redis.call('HGETALL', hash_key)

                    if #task_data > 0 then
                        local task = {}
                        for j = 1, #task_data, 2 do
                            task[task_data[j]] = task_data[j+1]
                        end

                        redis.call('XADD', KEYS[2], '*',
                            'key', task['key'],
                            'when', task['when'],
                            'function', task['function'],
                            'args', task['args'],
                            'kwargs', task['kwargs'],
                            'attempt', task['attempt'],
                            'generation', task['generation'] or '0'
                        )
                        redis.call('DEL', hash_key)

                        -- Set run state to queued
                        local run_key = ARGV[2] .. ":runs:" .. task['key']
                        redis.call('HSET', run_key, 'state', 'queued')

                        -- Publish state change event to pub/sub
                        local channel = ARGV[2] .. ":state:" .. task['key']
                        local payload = '{"type":"state","key":"' .. task['key'] .. '","state":"queued","when":"' .. task['when'] .. '"}'
                        redis.call('PUBLISH', channel, payload)

                        due_work = due_work + 1
                    end
                end
            end

            if due_work > 0 then
                redis.call('ZREMRANGEBYSCORE', KEYS[1], 0, ARGV[1])
            end

            return {total_work, due_work}
            zScheduling due tasksr   )rk   rb   Nr   z#Moved %d/%d due tasks from %s to %szError in scheduler loopTr   r   timeout)r   rg   register_scriptr   r   rD  r^   r   r   rq   r   r   r   r1  r   r2  	timestampprefix	Exception	exceptionr   wait_forr   rx   r   TimeoutError)rj   r   stream_due_tasksr  
total_workdue_works         r\   rB  zWorker._scheduler_loop`  s     /3!!/69/
v '')''..03;G99; 1A"kk33T[[5K5KL$LL6@@B KK..2 ,(J a<LL= "--..) !  &&))..0 66DDF   E 1, $    -!% ! 
 '' G ''..0s   AH
'F+ 5A=F2F3F:AF+ A
G GG H
FF($F+ +!GH
GH
G G*'H
)G**H
c           	       K   | j                   j                         dz  }| j                  j                         s:	 t	        j
                  | j                  j                         |       d{    yyy7 # t        j                  $ r Y nw xY wt        |j                               }|s	 | j                         5  |j                  | j                  j                  | j                  j                  | j                  d|d       d{  7   ddd       n# 1 sw Y   nxY wn&# t         $ r t"        j%                  dd       Y nw xY w| j                  j                         s.w)	zPeriodically renew leases on stream messages.

        Calls XCLAIM with idle=0 to reset the message's idle time, preventing
        XAUTOCLAIM from reclaiming it while we're still processing.
           rN  Nr   )rr   r  r  r  message_idsidlezFailed to renew leasesTr   )ru   r   r   rD  r   rU  r   rV  listvaluesr   xclaimrq   r   r  rr   rS  r^   r`   )rj   r   active_messagesrenewal_intervalr\  s        r\   rC  zWorker._renew_leases  sN      22@@BQF''..0&&))..0:J    1
 ''  5578KH99; ,,![[33"&++"?"?%)YY&'$/ '       H7$GH5 ''..0s   8E)2A7 -A5.A7 2E)5A7 7B
E)BE)-D& =AD
DD	D& D"D& %E)& E	E)E		E)c           	       K   | j                   j                          d {    | j                   j                         4 d {   }	 |j                  | j                   j	                  d      t
        d      4 d {    | j                   j                  j                         D ]c  }t        |t              }||j                  s#|j                  } | j                   j                  ||j                  |              d {    e d d d       d {    d d d       d {    y 7 7 7 7 .7 # 1 d {  7  sw Y   .xY w# t        $ r Y d d d       d {  7   y w xY w7 E# 1 d {  7  sw Y   y xY ww)Nzperpetual:lockF)rO  blocking)r4  r   )rq   wait_for_strikes_loadedr   lockr   (AUTOMATIC_PERPETUAL_LOCK_TIMEOUT_SECONDSr   r_  r/   r(   	automaticrU   r   initial_whenr   )rj   r   task_function	perpetualr   s        r\   rA  z.Worker._schedule_all_automatic_perpetual_tasks  ss     kk11333;;$$& 	 	% ::KKOO$45D" &     
 *.):):)A)A)C 	 $K)9%	 %0Y5H5H"/"8"8C#$++// -I4J4JPS #2 # #     	    	 	 	 	4	           %	 	 	"#	 	 	 	s   FD."FD1FE0	5E>D3?E:D9=D9
<D9D5
D9ED7EF(E.)F1F3E5D97E9E	?E E	E	E+E0F#E&$F*E++E0.F0F6E97F>Fc                  K   t         j                  d| j                                | j                  j	                  |j
                        }|j                  |dd       d {    | j                  j                  |j
                        }| j                  j                  |j
                        }|j                  ||       d {    y 7 i7 w)NzDeleting known taskr   known	stream_id)
r^   r   r   rq   runs_keyr   hdelknown_task_keystream_id_keydelete)rj   r   r]   ro  rq  rr  s         r\   _delete_known_taskzWorker._delete_known_task	  s     *$2C2C2EF;;''	6jj7K888 33IMMB11)--@ll>=999 	9
 	:s%   A!C#C$A#CCCCc           
     x  K   i | j                         |j                         }i | j                         |j                         }|j	                         }| j
                  j                  j                  |      r| j
                  j                         4 d {   }| j                  ||       d {    d d d       d {    |j                          d {    t        j                  d||       t        j                  d|ddiz         y |j                  | j                          d {   s4t        j#                  d||       t%        j                  d|ddiz         y |j&                  | j(                  v r!| j(                  |j&                  xx   dz  cc<   t+        j*                         }||j,                  j/                         z
  }i |d|i}d}t1        j                  d|       |j2                  rt5        j                  d|       t7        j                  d|       t9        j:                  ||       |j<                  dkD  rd	nd
}	t        j#                  d|	t?        |      ||       i }
t@        jC                  |jD                  tF        jH                  jJ                  i | j                         |j                         d|jD                  i|jM                               5 }	 tO        | |      4 d {   }
|
jQ                         D ci c]  \  }}tS        |tT              r|| }}}|jW                         D ](  }tS        |jX                  tZ              s|jX                   |rRt]        ddj_                  |ja                               z   |jW                         D cg c]  }|jX                   c}      i |jb                  |
}te        |
tf              }|r1|ji                  ||jj                  |jl                  |       d {   }n$ |jj                  |jl                  i | d {   }t+        j*                         |z
  x}|d<   to        j                  d|       |jq                  ts        tt        jv                               te        |
tx              }t{        t}        |      |      }|r5|j                  ||       d {   r|j                  d        d {    nd }|| j
                  j                  rt        j                  |      }t        j                  |      j                  d      }|j&                  }t        | j
                  j                  j                               }| j
                  j                  j                  |d|i|       d {    |j                  |       d {    t        j#                  dt?        |      ||       d d d       d {    t7        j                  d|       t        j                  d|       t        j:                  ||       	 d d d        y 7 7 7 # 1 d {  7  sw Y   xY w7 7 @7 qc c}}w c c}w 7 k7 I7 7 7 7 7 # 1 d {  7  sw Y   xY w# tZ        $ r  t        j                  $ r t+        j*                         |z
  x}|d<   |jq                  ts        tt        jv                               |j                          d {  7   t        j#                  dt?        |      ||       Y Dt        $ r}t+        j*                         |z
  x}|d<   t        j                  d|       |j                  |       |jq                  ts        tt        j                  t        |                   t{        t}        |      |      }te        |
t              }|r|j                  ||       d {  7  rnLte        |
tx              }|r|j                  ||       d {  7  rn"t        j                  dt?        |      ||       d }| j
                  j                  rt        j                  |      }t        j                  |      j                  d      }|j&                  }t        | j
                  j                  j                               }| j
                  j                  j                  |d|i|       d {  7   t        |      j                   dt        |       }|j                  ||       d {  7   Y d }~Zd }~ww xY w# t7        j                  d|       t        j                  d|       t        j:                  ||       w xY w# 1 sw Y   y xY ww)Nu   🗙 %sr   r   zdocket.wherer   u   ↬ %s (superseded)punctualityg        u   ↬u   ↪z
%s [%s] %szcode.function.name)kind
attributeslinksz1Failed to resolve dependencies for parameter(s): z, durationr   )rz  r!  )
result_keyasciirT   )ttlu   ↩ [%s] %su   ✗ [%s] %s (cancelled))rz  rT  z: )Zr   specific_labelsr   general_labels	call_reprrq   r   is_strickenr   rt  mark_as_cancelledr^   r`   rC   r   claimrr   r   rE   r   r   timer4  rQ  rB   r$  r@   rA   r=   recordattemptr-   re   start_as_current_spanra   r   SpanKindCONSUMERincoming_span_linksr0   items
isinstancer&   r_  errorr"   r   joinrk   rc   r.   r)   r   functionrb   rD   
set_statusr   r   OKr#   r,   r   on_completemark_as_completedexecution_ttlcloudpickledumpsbase64	b64encodedecoders   r   result_storageputr   r   rS  r?   record_exceptionERRORrO   r'   handle_failurerT  rP   rU   mark_as_failedr>   r<   )rj   r]   r  counter_labelscallr   startrv  rz  arrowdependenciesspankvdependency_failuresfailure
dependencyfinal_kwargsruntimer!  completion_handleroutcomer{  pickled_resultencoded_resultttl_secondsr  failure_handlerpickled_exceptionencoded_exception	error_msgs                                  r\   r&  zWorker._execute  s 	    L**,L	0I0I0KLHDKKMHY-E-E-GH""$;;""..y9{{((* @ @e--eY???@ @ --///NN9d+N>q.NH3M"MN __TYY///KK-t;KG  Nnh5O$OP==D222""9==1Q61		inn6688AAm[A!^,  !!!^4!^,^<"**Q.E%!=t; 	 	
 /1))##((++-++- %i&=&=
 //1 * 	
 h	? ^?0yA Q Q\ %1$6$6$8+ Aq%a)9: 1+' + $7#=#=#? 0%gmm5EF")--/0 +, S"&)),?,D,D,F"G!H
 3F2L2L2N$. !+ 0 0	 	 $Hi&6&6#G,#GL <L'RG'.{{%%..%NN(	( " (:y'9'9&^^(/;( " :>u9LLH{:6#''>:OOF:==$9: *G$&7*& *!*8!<%G *4F4R4R!75 / / (99T9JJJ &*
!-$++2K2K-8->->v-FN-3-=-=n-M-T-T '.N *3J*-dkk.G.G.U.U.W*XK"&++"<"<"@"@ *V^,D+ #A #   (99Z9PPP)+H5 "-	 $ YQ Qv !!"n5##A~6$$X~>Qh	? h	?G@?@ @ @ @ 0 0JQ+$"""/ K QWQ Q Q Qd $ )) 
59YY[55HH;z2z}} 5611333-#H-%	    9U59YY[55HH;z2  N3%%a(z'7'7Q @A%&x8 #@ .# #_-K-Kw. ( (
  *G$&7*& *4F4R4R!75 / /  (()+H5 "-	 )  "&J{{00,7,=,=a,@),2,<,<=N,O,V,V#-) &/]]
&)$++*C*C*Q*Q*S&T"kk88<<&1B(C =   
 $(7#3#3"4Bs1vh ?I#2292TTTs9Uv !!"n5##A~6$$X~>Qh	? h	?s  Bf:Yf:Y4Y5Y9f:Yf:Y0Af:3Y34F?f:3f.5Z+Y6Z+	ZY9
:0Z+AZ2Y?AZZ$Z>Z?BZZ
Z5Z6B>Z4Z5ZZ&Z5Z+ ZZ+Af.
f:Yf:Y- Y#!Y-(	f:3f:6Z+9ZZ
ZZZZZ+Z(	ZZ(	$Z++A3e$\!'e$e'		e$B3e`.e4`75Ced>eeee'e$$e''Af++f..f73f:c           
         t         j                  d| j                         | j                  j                  j                         D ].  \  }}t         j                  d|t        t        |                   0 y )Nz,Starting worker %r with the following tasks:z* %s(%s))r^   r   rr   rq   r   r  r7   r8   )rj   	task_namer*  s      r\   r   zWorker._startup_log  sX    BDIIN#{{00668 	WOItKK
I/@tAT/UV	Wr[   c                .    | j                   j                  S ri   )rq   workers_setr   s    r\   r  zWorker.workers_set  s    {{&&&r[   c                8    | j                   j                  |      S ri   )rq   worker_tasks_set)rj   worker_names     r\   r  zWorker.worker_tasks_set  s    {{++K88r[   c                8    | j                   j                  |      S ri   )rq   task_workers_set)rj   r  s     r\   r  zWorker.task_workers_set  s    {{++I66r[   c                	  K   	 	 t        j                  t        j                        j	                         }| j
                  j                  | j
                  j                  z  }||j                         z
  }t        | j
                  j                        }| j
                  j                         4 d {   }| j                         5  |j                         4 d {   }|j                  | j                  d|       |j!                  | j                  | j"                  |i       |D ]D  }| j%                  |      }|j                  |d|       |j!                  || j"                  |i       F  |j&                  | j)                  | j"                        g|  |j+                  | j)                  | j"                        t-        |t/        t0                           |j3                          d {    d d d       d {    |j                         4 d {   }|j5                  | j
                  j6                         |j9                  | j
                  j:                  d|       |j9                  | j
                  j:                  |d       |j3                          d {   }	d d d       d {    d d d        	d   }
|	d   }|	d   }t=        j>                  |
|z   | j
                  jA                                tC        j>                  || j
                  jA                                d d d       d {    tE        jV                  | j
                  j                  j                                d {    ~7 7 7 7 # 1 d {  7  sw Y   xY w7 7 7 # 1 d {  7  sw Y   xY w# 1 sw Y   	xY w7 # 1 d {  7  sw Y   xY w# tD        jF                  $ r Y y tH        $ rN tK        jL                  d| jA                                tN        jQ                  dd| jS                                Y tT        $ r* tN        jQ                  dd| jS                                Y @w xY w7 
w)	NTr   r   z+infr      zError sending worker heartbeatrM  ),r   r1  r   r2  rQ  rq   heartbeat_intervalmissed_heartbeatsr   r^  r   r   r   r  zremrangebyscorer  zaddrr   r  saddr  expiremaxr   MINIMUM_TTL_SECONDSr  r  r   zcountr   r9   r   r   r;   r   r   r   r:   r   r^   rT  r   rS  r   )rj   r1  maximum_ageoldest
task_namesrr  r  r  r  stream_depthoverdue_depthschedule_depths                r\   r   zWorker._heartbeat  s    :ll8<<0::<KK22T[[5R5RR  {88::!$++"3"34
;;,,. !M !M!==? J#$::< 5 58$55d6F6F6R$MM$*:*:TYY<LM-7 R	373H3H3S 0 ( 9 9:JAv V (.>C@P QR
 *HMM$*?*?		*JXZX$OO $ 5 5dii @ #$/CV1W!" #+"2"2"444#5 5& $%::< J J8$MM$++*@*@A$OODKK,A,A1cJ$OODKK,A,A3O7?7G7G7I1IGJ J)J6 $+1:L$+AJM%,QZNOOL=$@$++BTBTBVW"&&~t{{7I7I7KLC!M !Mf -- > > L L NOOO{ !M5" 5#5 5 5 5&J
 2JJ J J J)J J!M !M !M !MF )) " !%%a7  4!++- ! 
    4!++- !  Ps_  RB.O& 3N4O& 7OON
O!DN2N
3N7ONON$
OBN,&N'
'N,+O6N*7O;A6O1O& <O=O& :R;R<RO& ONON!NN!	O'N,*O,N?2N53N?:OO	OO& O#OO#O& &R9R;ARR.R>RRRc                  K   | j                   j                  d      }| j                         }| j                  j	                         s	 | j                   j                         4 d{   }|j                  |       d{    | j                  j                          | j                  j	                         sY|j                  dd       d{   }|!|d   dk(  r| j                  |       d{    | j                  j	                         sYddd      d{    | j                  j	                         syy7 7 7 s7 R7 )# 1 d{  7  sw Y   9xY w# t        $ rx | j                  j	                         rY yt        j                  d| j                                t        j!                  d	|
       t#        j$                  d       d{  7   Y t&        $ rV | j                  j	                         rY yt        j)                  dd|       t#        j$                  d       d{  7   Y w xY ww)z:Listen for cancellation signals and cancel matching tasks.zcancel:*NTg?)ignore_subscribe_messagesrO  rP   pmessager   z@Redis connection error in cancellation listener, reconnecting...r   zError in cancellation listenerrM  )rq   r   r   r   rD  _pubsub
psubscriber   r   get_message_handle_cancellationr   r:   r   r   r^   r`   r   r   rS  rT  )rj   cancel_patternr  pubsubr(  s        r\   r@  zWorker._cancellation_listener7  s    4'')''..0';;..0 	E 	EF ++N;;;,,002"33::<(.(:(:6:C ); ) # #.76?j3P"&";";G"DDD #33::<		E 	E ''..0	E;# E	E 	E 	E 	E # '((//1!%%a7V%   mmA&&& '((//1  4!% ! 
 mmA&&&'s   AH?	E 'D?(E +E	 EAE	E"E	2E3E	E EE "H?=H??E E	E	E	E 	EEEE #H<H?AH<GH<H?"H< H?0H<2H53H<8H?;H<<H?c                  K   |d   }t        |t              r|j                         n|}| j                  j	                  |      x}r7t
        j                  d|| j                                |j                          yyw)z>Handle a cancellation message by cancelling the matching task.rT   zCancelling running task %rr   N)	r  rQ   r  r   getr^   r   r   r   )rj   r(  rT   r   r*  s        r\   r  zWorker._handle_cancellation[  st     v(24(?t{{}T%%))#..4.KK,'')  
 KKM /s   A=A?)rq   r1   rr   
str | Nonert   rs   ru   r   rv   r   rw   r   rx   r   rz   ry   r{   ry   r|   zTaskFunction | Nonern   r   )rn   zGenerator[None, None, None])rn   r!   )r   ztype[BaseException] | Noner   zBaseException | Noner   zTracebackType | Nonern   r   )rn   zMapping[str, str]) r   rO   r   rO   rr   r  rt   rs   ru   r   rv   r   rw   r   rx   r   rz   ry   r{   ry   r   ry   r   
int | Noner   r  r   rm   r|   r  rn   r   r>  )r   zMapping[str, int]rn   r   r=  )r   ry   rn   r   )r   r   r   ry   )r   r   rn   r   )r   r   ra  z(dict[asyncio.Task[None], RedisMessageID]rn   r   )r   r   r]   r2   rn   r   )r]   r2   rn   r   )rn   rO   )r  rO   rn   rO   )r  rO   rn   rO   )r(  rN   rn   r   )!rU   rV   rW   rX   rY   r   r   r   r   r   r   r   r   classmethodr   r   r   r   r   r   rB  rC  rA  rt  r&  r   propertyr  r  r  r   r@  r  rZ   r[   r\   rp   rp      s   
 N
I!!!!%%$$""%))
  (1!(<(1!(<,53,G+4#+F)-05-1DD D 	D
 &D &D !*D  )D #'D *.D +D 
D0  "B, ( (	
 
 

  $-(1!(<(1!(<,53,G+4#+F)-05$'+#'9:$(!aFaF aF 	aF
 aF &aF &aF !*aF  )aF #'aF *.aF aF %aF !aF aF  "!aF" 
#aF aFF.- &%(>M {$zdL(H(H B(H 
	(HT2	:R?hW
 ' '97>P@"'Hr[   rp   )
rb   r
   r]   r2   r^   z%logging.LoggerAdapter[logging.Logger]rc   r
   rn   r   )m
__future__r   r   r  r   loggingr   r   r   sysr  
contextlibr   r   r   r   r   typesr	   typingr
   r   r   r   r   r   r   r  version_infoexceptiongroupr   	taskgroupr   opentelemetryr   opentelemetry.tracer   r   r   _cancellationr   r   
_telemetryr   redis.asyncior   redis.exceptionsr   r   r    typing_extensionsr!   r  r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   rq   r1   r2   r3   r4   r5   r]   r6   r7   r8   instrumentationr9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   r3  rg  r  rO   rL   rY   rN   rd   	getLoggerrU   r^   
get_tracerre   rg   rp   rZ   r[   r\   <module>r     su   "     	   
  5 2 2    g-#!  : : : 0  F F "    "  F E    * !*s ;  ,. (   I  ,-4>L 2 	
 
 +**84 4!!!(+ + ` `r[   