
    !<i                        U d dl Z d dlZd dlZd dlmZ d dl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mZmZmZmZmZmZmZmZ d dlmZ d dlmZ d dl Z!d d	l"m#Z# d d
l$m%Z%m&Z& ddl'm(Z( ddl)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2 d dl3m4Z4 d dl5m6Z6 d dl7m8Z8 ddl9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@  ejA        eB          ZCejD        eEd<    e#jF        eB          ZGe#jH        eEd<    G d de          ZI ed          ZJ ed          ZKee2         ZLeMZNeMZOePeMeMf         ZQeeReOeQf                  ZSeReNeSf         ZTeeT         ZU G d de          ZVe G d d                      ZW G d de*          ZXe G d d                      ZY G d  d!          ZZdS )"    N)asynccontextmanager)	dataclass)datetime	timedeltatimezone)TracebackType)AsyncGenerator	AwaitableCallable
CollectionHashableIterableMappingNoReturn	ParamSpecProtocolSequence	TypedDictTypeVarcastoverload)BaseContextManagerStore)Self)trace)ConnectionPoolRedis   )uuid7)		ExecutionExecutionStateLiteralOperatorOperatorRestoreStrikeStrikeInstruction
StrikeListTaskFunction)AsyncKeyValue)
RedisStore)MemoryStore)REDIS_DISRUPTIONSSTRIKES_IN_EFFECTTASKS_ADDEDTASKS_CANCELLEDTASKS_REPLACEDTASKS_SCHEDULEDTASKS_STRICKENloggertracerc                   :    e Zd Zdee         dee         defdZdS )_cancel_taskkeysargsreturnc                 
   K   d S N )selfr6   r7   s      /Users/kimhansen/Desktop/03 Workspace/ceo-agents/chl-effectiveness/mcp-servers/whoop/.venv/lib/python3.11/site-packages/docket/docket.py__call__z_cancel_task.__call__@   s      c    N)__name__
__module____qualname__liststrr>   r;   r?   r=   r5   r5   ?   sH        I%)#Y	     r?   r5   PRc                   8    e Zd ZU eed<   eed<   eed<   eed<   dS )RedisStreamPendingMessage
message_idconsumertime_since_deliveredtimes_deliveredN)r@   rA   rB   bytes__annotations__intr;   r?   r=   rH   rH   R   s?         OOOr?   rH   c                   :    e Zd ZU eed<   eed<   ee         ed<   dS )
WorkerInfoname	last_seentasksN)r@   rA   rB   rD   rN   r   setr;   r?   r=   rQ   rQ   Y   s2         
IIIs8OOOOOr?   rQ   c                   F     e Zd ZU eed<   eed<   dedededdf fdZ xZS )RunningExecutionworkerstarted	executionr8   Nc                 J   t                                          |j        |j        |j        |j        |j        |j        |j        |j	        |j
        	  	         |j        | _        |j        | _        |j        | _        |j        | _        |j        | _        || _        || _        d S )N)	docketfunctionr7   kwargskeywhenattempttrace_contextredelivered)super__init__r\   r]   r7   r^   r_   r`   ra   rb   rc   state
started_atcompleted_aterror
result_keyrX   rY   )r<   rZ   rX   rY   	__class__s       r=   re   zRunningExecution.__init__d   s     	#'#%#1!- 	 
	
 
	
 
	
 &/_
+4+?-6-C!*
&/&:r?   )	r@   rA   rB   rD   rN   r   r   re   __classcell__)rk   s   @r=   rW   rW   `   sz         KKK  	
 
         r?   rW   c                   f    e Zd ZU eed<   eed<   ee         ed<   ee         ed<   e	e
         ed<   dS )DocketSnapshottakentotal_tasksfuturerunningworkersN)r@   rA   rB   r   rN   rO   r   r   rW   r   rQ   r;   r?   r=   rn   rn      s[         OOOY&''''
######r?   rn   c                      e Zd ZU dZeeef         ed<   eed<   e	j
        d         ed<   eed<   edz  ed<   dd	 ed
          d ed          dfdededededededz  ddfdZedefd            ZdefdZdee         dz  dedz  dedz  ddfdZedeedf         fd            ZdeddfdZd eddfd!Zdeeef         fd"Z e!	 	 dKde"e#e$e%         f         d#e&dz  d$edz  de"e#e$e'         f         fd%            Z(e!	 	 dKded#e&dz  d$edz  de"d&e$e'         f         fd'            Z(	 	 dKde"e#e$e%         f         ez  d#e&dz  d$edz  de"d&e$e'         f         fd(Z(e!de"e#e$e%         f         d#e&d$ede"e#e$e'         f         fd)            Z)e!ded#e&d$ede"d&e$e'         f         fd*            Z)de"e#e$e%         f         ez  d#e&d$ede"d&e$e'         f         fd+Z)d,e'ddfd-Z*d$eddfd.Z+d$ede'dz  fd/Z,edefd0            Z-edefd1            Z.d$edefd2Z/d$edefd3Z0d$edefd4Z1dLd5Z2d6ed$eddfd7Z3edefd8            Z4	 	 	 	 dMde"e#e$e%         f         ez  dz  d:edz  d;e5e6z  d<e7dz  ddf
d=Z8	 	 	 	 dMde"e#e$e%         f         ez  dz  d:edz  d;e5e6z  d<e7dz  ddf
d>Z9d?e:ddfd@Z;de<fdAZ=de>fdBZ?edefdC            Z@dDedefdEZAdFedefdGZBdeCeD         fdHZEdFedeCeD         fdIZFdefdJZGdS )NDocketa  A Docket represents a collection of tasks that may be scheduled for later
    execution.  With a Docket, you can add, replace, and cancel tasks.
    Example:

    ```python
    @task
    async def my_task(greeting: str, recipient: str) -> None:
        print(f"{greeting}, {recipient}!")

    async with Docket() as docket:
        docket.add(my_task)("Hello", recipient="world")
    ```
    rT   strike_listN_monitor_strikes_task_connection_pool_cancel_task_scriptr\   zredis://localhost:6379/0   )seconds      )minutesrR   urlheartbeat_intervalmissed_heartbeatsexecution_ttlresult_storager8   c                    || _         || _        || _        || _        || _        d| _        |  |                    d          rt                      | _        nt          || d          | _        ddl
m} d |D             | _
        dS )aB  
        Args:
            name: The name of the docket.
            url: The URL of the Redis server or in-memory backend.  For example:
                - "redis://localhost:6379/0"
                - "redis://user:password@localhost:6379/0"
                - "redis://user:password@localhost:6379/0?ssl=true"
                - "rediss://localhost:6379/0"
                - "unix:///path/to/redis.sock"
                - "memory://" (in-memory backend for testing)
            heartbeat_interval: How often workers send heartbeat messages to the docket.
            missed_heartbeats: How many heartbeats a worker can miss before it is
                considered dead.
            execution_ttl: How long to keep completed or failed execution state records
                in Redis before they expire. Defaults to 15 minutes.
        N	memory://z:results)r   default_collectionr   )standard_tasksc                     i | ]
}|j         |S r;   )r@   ).0fns     r=   
<dictcomp>z#Docket.__init__.<locals>.<dictcomp>   s    .X.X.X2r{B.X.X.Xr?   )rR   r   r   r   r   ry   
startswithr*   r   r)   rT   r   )r<   rR   r   r   r   r   r   r   s           r=   re   zDocket.__init__   s    2 	"4!2*#' *>>+&& 	"---D",t,=,=,=# # #D 	*))))).X.X.X.X.X


r?   c                     dS )Nzdocket-workersr;   r<   s    r=   worker_group_namezDocket.worker_group_name   s    r?   c                   K   t                      | _        | j                            d          rw	 ddlm}m} t          t          d          s |            t          _	        t          j	        }t          ||          | _        n@# t          $ r}t          d          |d }~ww xY wt          j        | j                  | _        t          j        |                                           | _        t%          | j        t(                    r | j                                         d {V  n| j                                         d {V  | S )Nr   r   )FakeConnection
FakeServer_memory_server)connection_classserverzTfakeredis is required for memory:// URLs. Install with: pip install pydocket[memory])r&   rv   r   r   fakeredis.aioredisr   r   hasattrru   r   r   rx   ImportErrorfrom_urlasynciocreate_task_monitor_strikesrw   
isinstancer   r   
__aenter__setup)r<   r   r   r   es        r=   r   zDocket.__aenter__   st     %<< 8{++ 	FIIIIIIII
 v'788 9,6JLLF).(6%3F) ) )%%    !A   %3$;DH$E$ED!%,%89N9N9P9P%Q%Q"d)+BCC 	.%002222222222%++---------s   AB 
B$BB$exc_type	exc_value	tracebackc                 f  K   t          | j        t                    r"| j                            |||           d {V  | `| j                                         	 | j         d {V  n# t          j        $ r Y nw xY wt          j	        | j
                                                   d {V  | `
d S r:   )r   r   r   	__aexit__rv   rw   cancelr   CancelledErrorshieldrx   
disconnect)r<   r   r   r   s       r=   r   zDocket.__aexit__   s       d)+BCC 	P%//)YOOOOOOOOO"))+++	,,,,,,,,,% 	 	 	D	 nT2==??@@@@@@@@@!!!s   A) )A;:A;c           	     :  K   t          | j                  }|                                 d {V  	 |W V  t          j        |                    d d d                      d {V  d S # t          j        |                    d d d                      d {V  w xY w)N)connection_pool)r   rx   r   r   r   r   )r<   rs     r=   rediszDocket.redis  s      $"7888llnn	@GGGG.T4!>!>???????????'.T4!>!>??????????s   A) )1Br]   c                 F    ddl m}  ||           || j        |j        <   dS )zdRegister a task with the Docket.

        Args:
            function: The task to register.
        r   )validate_dependenciesN)dependenciesr   rT   r@   )r<   r]   r   s      r=   registerzDocket.register  s<     	877777h'''(0
8$%%%r?   collection_pathc                     |                     d          \  }}}t          j        |          }t          ||          }|D ]}|                     |           dS )z
        Register a collection of tasks.

        Args:
            collection_path: A path in the format "module:collection".
        :N)
rpartition	importlibimport_modulegetattrr   )r<   r   module_name_member_namemodule
collectionr]   s           r=   register_collectionzDocket.register_collection  sk     '6&@&@&E&E#Q(55V[11
" 	$ 	$HMM(####	$ 	$r?   c                     d| j         iS )Nzdocket.namerR   r   s    r=   labelszDocket.labels)  s    49
 	
r?   r`   r_   c                     dS )zAdd a task to the Docket.

        Args:
            function: The task function to add.
            when: The time to schedule the task.
            key: The key to schedule the task under.
        Nr;   r<   r]   r`   r_   s       r=   addz
Docket.add.        r?   .c                     dS )zAdd a task to the Docket.

        Args:
            function: The name of a task to add.
            when: The time to schedule the task.
            key: The key to schedule the task under.
        Nr;   r   s       r=   r   z
Docket.add=  r   r?   c                 H    t          t                    r j                 n                                t	          j        t          j                  t          t                                dt          j
        dt          j        dt          f fd}|S )zAdd a task to the Docket.

        Args:
            function: The task to add.
            when: The time to schedule the task.
            key: The key to schedule the task under.
        Nr7   r^   r8   c            	      t  K   t          | |d          }j                            |          rnt                              d|j        j        |j                   t          j	        di 
                                |                                ddi           |S |                    d           d {V  t          j	        di 
                                |                                           t          j	        di 
                                |                                           |S )Nr   ra   '%r is stricken, skipping schedule of %rdocket.wherer\   Freplace)r   rv   is_strickenr2   warningr]   r@   r_   r1   r   r   general_labelsscheduler-   r0   r7   r^   rZ   r]   r_   r<   r`   s      r=   	schedulerzDocket.add.<locals>.schedulerd  sV     !$$TSTUUUI ++I66 !=&/M  
 "++--#2244 '    !  $$U$333333333OAN$++--N93K3K3M3MNOOO#Rdkkmm#Ry7O7O7Q7Q#RSSSr?   )r   rD   rT   r   r   nowr   utcr   rE   r7   r^   r   r<   r]   r`   r_   r   s   ```` r=   r   z
Docket.addL  s     h$$ 	$z(+HHMM(###<<--D;egg,,C	16 	QX 	) 	 	 	 	 	 	 	 	 	8 r?   c                     dS )zReplace a previously scheduled task on the Docket.

        Args:
            function: The task function to replace.
            when: The time to schedule the task.
            key: The key to schedule the task under.
        Nr;   r   s       r=   r   zDocket.replace  r   r?   c                     dS )zReplace a previously scheduled task on the Docket.

        Args:
            function: The name of a task to replace.
            when: The time to schedule the task.
            key: The key to schedule the task under.
        Nr;   r   s       r=   r   zDocket.replace  r   r?   c                      t          t                    r j                 n                                dt          j        dt          j        dt          f fd}|S )zReplace a previously scheduled task on the Docket.

        Args:
            function: The task to replace.
            when: The time to schedule the task.
            key: The key to schedule the task under.
        r7   r^   r8   c            	        K   t          | |d          }j                            |          rnt                              d|j        j        |j                   t          j	        di 
                                |                                ddi           |S |                    d           d {V  t          j	        di 
                                |                                           t          j	        di 
                                |                                           t          j	        di 
                                |                                           |S )Nr   r   r   r   r\   Tr   )r   rv   r   r2   r   r]   r@   r_   r1   r   r   r   r   r/   r.   r0   r   s      r=   r   z!Docket.replace.<locals>.scheduler  s     !$$TSTUUUI ++I66 !=&/M  
 "++--#2244 '    !  $$T$222222222q"QT[[]]"Qi6N6N6P6P"QRRR#Rdkkmm#Ry7O7O7Q7Q#RSSS#Rdkkmm#Ry7O7O7Q7Q#RSSSr?   )r   rD   rT   r   rE   r7   r^   r   r   s   ```` r=   r   zDocket.replace  s     h$$ 	$z(+HHMM(###	16 	QX 	) 	 	 	 	 	 	 	 	 	: r?   rZ   c                   K   t                               di |                                 |                                d|j        j        i          5  | j                            |          rzt          	                    d|j        j        |j
                   t          j        di |                                 |                                ddi           	 d d d            d S |                    d	           d {V  d d d            n# 1 swxY w Y   t          j        di |                                 |                                           d S )
Nzdocket.schedulezcode.function.name
attributesr   r   r   r\   Fr   )r3   start_as_current_spanr   specific_labelsr]   r@   rv   r   r2   r   r_   r1   r   r   r   r0   )r<   rZ   s     r=   r   zDocket.schedule  s     ))++--++-- %i&8&A  * 
 
 	4 	4 ++I66 =&/M  
 "++--#2244 '    /	4 	4 	4 	4 	4 	4 	4 	44 $$U$3333333335	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	48 	AN$++--N93K3K3M3MNOOOOOs   BD*DDDc                   K   t                               di |                                 d|i          5  |                                 4 d{V }|                     ||           d{V  ddd          d{V  n# 1 d{V swxY w Y   ddd           n# 1 swxY w Y   t          j        d|                                            dS )zyCancel a previously scheduled task on the Docket.

        Args:
            key: The key of the task to cancel.
        zdocket.cancelz
docket.keyr   Nr   )r3   r   r   r   _cancelr.   r   )r<   r_   r   s      r=   r   zDocket.cancel  s      ));$++--;s;; * 
 
 	/ 	/ zz|| / / / / / / /ull5#........./ / / / / / / / / / / / / / / / / / / / / / / / / / /		/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	At{{}}-----s5   BB/B
B	BB	BB"%B"c           
        K   ddl }|                                 4 d{V }| j         d| } |j        |           d{V }|s	 ddd          d{V  dS |                    d          }|                    d          }|                    d          }|r|r|sl|                     |          }	 |j        |	           d{V }
|
r?|
                    d          }|
                    d          }|
                    d          }|r|r|s	 ddd          d{V  dS |                                }| j                            |          }|sdd}||_        |}|	                    |          }|	                    |          }|                    d	          }|s	 ddd          d{V  dS t          j        t          |                                          t          j        
          }ddlm}  || |||||d          }|                                 d{V  |cddd          d{V  S # 1 d{V swxY w Y   dS )a  Get a task Execution from the Docket by its key.

        Args:
            key: The task key.

        Returns:
            The Execution if found, None if the key doesn't exist.

        Example:
            # Claim check pattern: schedule a task, save the key,
            # then retrieve the execution later to check status or get results
            execution = await docket.add(my_task, key="important-task")(args)
            task_key = execution.key

            # Later, retrieve the execution by key
            execution = await docket.get_execution(task_key)
            if execution:
                await execution.get_result()
        r   N:runs:s   functions   argss   kwargsr8   c                  
   K   d S r:   r;   r;   r?   r=   placeholderz)Docket.get_execution.<locals>.placeholder4  s      Dr?   s   when)tz)r   r   )r\   r]   r7   r^   r_   r`   ra   r8   N)cloudpickler   rR   hgetallgetparked_task_keydecoderT   r@   loadsr   fromtimestampfloatr   r   docket.executionr   sync)r<   r_   r   r   runs_keydatafunction_name	args_datakwargs_data
parked_keyparked_datafunction_name_strr]   r   r7   r^   when_strr`   r   rZ   s                       r=   get_executionzDocket.get_execution  s     ( 	::<< ?	 ?	 ?	 ?	 ?	 ?	 ?	5)00300H&x00000000D ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 !HH[11M))I((9--K ! =	 = =!11#66
$1EM*$=$======= =$/OOK$@$@M + 8 8I"-//)"<"<K  	  /?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	4 !. 4 4 6 6z~~&788H '    (9$& $$Y//D &&{33F xx((H Y?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	Z )%0A0A*B*Bx|TTTD 322222!	!  I .."""""""""?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	 ?	s&   &H<B8H<%A?H<7A2H<<
I	Ic                     | j          dS )Nz:queuer   r   s    r=   	queue_keyzDocket.queue_keyV  s    )####r?   c                     | j          dS )Nz:streamr   r   s    r=   
stream_keyzDocket.stream_keyZ  s    )$$$$r?   c                     | j          d| S )Nz:known:r   r<   r_   s     r=   known_task_keyzDocket.known_task_key^  s    )))C)))r?   c                     | j          d| S )Nr   r   r  s     r=   r   zDocket.parked_task_keya  s    )##c###r?   c                     | j          d| S )Nz:stream-id:r   r  s     r=   stream_id_keyzDocket.stream_id_keyd  s    )-----r?   c                 D  K   	 |                                  4 d{V }|                    | j        | j        dd           d{V  ddd          d{V  dS # 1 d{V swxY w Y   dS # t           j        j        $ r}dt          |          vr Y d}~dS d}~ww xY w)a
  Create stream and consumer group if they don't exist (idempotent).

        This is safe to call from multiple workers racing to initialize - the
        BUSYGROUP error is silently ignored since it just means another worker
        created the group first.
        N0-0T)	groupnamerR   idmkstream	BUSYGROUP)r   xgroup_creater   r   
exceptionsResponseErrorrD   )r<   r   r   s      r=   _ensure_stream_and_groupzDocket._ensure_stream_and_groupg  sm     
	zz||       qoo"4!	 &                                       - 	 	 	#a&&(( )(((((	s:   A. *AA. 
A%%A. (A%)A. .BBBr   c           	      b  K   | j         (t          t           |j        d                    | _         | j         }t	          j        t          j                                                  }| j	         d| } || j
        |                     |          |                     |          | j        |                     |          |g||g           d{V  | j        r?t!          | j                                                  } |j        ||           d{V  dS  |j        |           d{V  dS )zCancel a task atomically.

        Handles cancellation regardless of task location:
        - From the stream (using stored message ID)
        - From the queue (scheduled tasks)
        - Cleans up all associated metadata keys
        Na  
                    local stream_key = KEYS[1]
                    -- TODO: Remove in next breaking release (v0.14.0) - legacy key locations
                    local known_key = KEYS[2]
                    local parked_key = KEYS[3]
                    local queue_key = KEYS[4]
                    local stream_id_key = KEYS[5]
                    local runs_key = KEYS[6]
                    local task_key = ARGV[1]
                    local completed_at = ARGV[2]

                    -- Get stream ID (check new location first, then legacy)
                    local message_id = redis.call('HGET', runs_key, 'stream_id')

                    -- TODO: Remove in next breaking release (v0.14.0) - check legacy location
                    if not message_id then
                        message_id = redis.call('GET', stream_id_key)
                    end

                    -- Delete from stream if message ID exists
                    if message_id then
                        redis.call('XDEL', stream_key, message_id)
                    end

                    -- Clean up legacy keys and parked data
                    redis.call('DEL', known_key, parked_key, stream_id_key)
                    redis.call('ZREM', queue_key, task_key)

                    -- Create tombstone: set CANCELLED state with completed_at timestamp
                    redis.call('HSET', runs_key, 'state', 'cancelled', 'completed_at', completed_at)

                    return 'OK'
                    r   )r6   r7   )ry   r   r5   register_scriptr   r   r   r   	isoformatrR   r   r  r   r   r  r   rO   total_secondsexpiredelete)r<   r   r_   cancel_taskrh   r   ttl_secondss          r=   r   zDocket._cancelz  s      #+'+%% $ $'( '(D$P .  |HL11;;==i,,s,, k##C(($$S))""3'' |$

 

 

 
	
 
	
 
	
 
	
 
	
 
	
 
	
  	)d0>>@@AAK%,x55555555555 %,x(((((((((((r?   c                     | j          dS )Nz:strikesr   r   s    r=   
strike_keyzDocket.strike_key      )%%%%r?   ==	parameteroperatorvaluec                    K   t          |t          t          d          f          s|j        }t	          |          }t          ||||          }|                     |           d{V S )zStrike a task from the Docket.

        Args:
            function: The task to strike.
            parameter: The parameter to strike on.
            operator: The operator to use.
            value: The value to strike on.
        N)r   rD   typer@   r"   r$   _send_strike_instruction)r<   r]   r  r  r  strikes         r=   r"  zDocket.strike  ss       (S$t**$566 	)(HH%%)Xu==226:::::::::r?   c                    K   t          |t          t          d          f          s|j        }t	          |          }t          ||||          }|                     |           d{V S )zRestore a previously stricken task to the Docket.

        Args:
            function: The task to restore.
            parameter: The parameter to restore on.
            operator: The operator to use.
            value: The value to restore on.
        N)r   rD   r   r@   r"   r#   r!  )r<   r]   r  r  r  restores         r=   r$  zDocket.restore  ss       (S$t**$566 	)(HH%%(Ix??227;;;;;;;;;r?   instructionc                   K   t                               d|j         i |                                 |                                          5  |                                 4 d {V }|                                } |j        | j        |           d {V  d d d           d {V  n# 1 d {V swxY w Y   | j        	                    |           d d d            d S # 1 swxY w Y   d S )Nzdocket.r   )
r3   r   	directionr   r   
as_messagexaddr  rv   update)r<   r%  r   messages       r=   r!  zDocket._send_strike_instruction  s     ))-k+--++--$$&& * 
 
 
	1 
	1 zz|| ; ; ; ; ; ; ;u%0022 ej':::::::::; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ##K000
	1 
	1 
	1 
	1 
	1 
	1 
	1 
	1 
	1 
	1 
	1 
	1 
	1 
	1 
	1 
	1 
	1 
	1s6   C%*1B-C%-
B7	7C%:B7	;C%%C),C)c           
        K   d}	 	 |                                  4 d {V }	 |                    | j        |idd           d {V }|D ]\  }}|D ]\  }}|}t          j        |          }| j                            |           t                              d|j	        dk    rdnd	|
                                |                                 
           t          j        |j	        dk    rdndi |                                 |                                           ό׌# 1 d {V swxY w Y   n# t           j        j        $ rS t!          j        dd| j        i           t                              d           t'          j        d           d {V  Y nCt*          $ r7 t                              d           t'          j        d           d {V  Y nw xY w)Nr  Td   i`  )countblockz%s %rr"  Striking	Restoring)extrar   r\   z*Connection error, sleeping for 1 second...zError monitoring strikes)r   xreadr  r%   from_messagerv   r*  r2   infor'  	call_reprr   r,   r   r  ConnectionErrorr+   rR   r   r   sleep	Exception	exception)	r<   last_idr   streamsr   messagesrI   r+  r%  s	            r=   r   zDocket._monitor_strikes  s     '	'&'::<< " " " " " " "1"@A!_g6"%"( AH A A ; ; ; ; ; ;
 ,3 " "KAx7? " " 3
G*4.?.LW.U.U $ 0 7 7 D D D &$+ ,7+@H+L+L )3
-8$/$9$9$;$;*.++-- !, 	!" 	!" 	!" !2 5)4)>()J)JAAPR%&*.++--%&*5*<*<*>*>%&!" !" !" !"""" " " " " " " " " " " " " " "> #3 ' ' '!%a(DI)>???KLLLmA&&&&&&&&&&& ' ' '  !;<<<mA&&&&&&&&&&&'K'	's6   D4 DD""
D,,D4 /D,0D4 4A$G=GGc           	         K   | j                             d          r|                                  d{V  g }g }|                                 4 d{V }|                                4 d{V }|                    | j                   |                    | j                   |	                    | j        | j
        ddd           |                    | j        ddd           |                    | j        dd	           t          j        t          j                  }	 |                                 d{V \  }}}}	}
n# t          j        j        $ rz}t)          |          }d
|v sd|v r]|                                  d{V  |                                  d{V cY d}~cddd          d{V  cddd          d{V  S  d}~ww xY w|
D ]<}|                    |                     |                                                     =d |                                 d{V D             }ddd          d{V  n# 1 d{V swxY w Y   ddd          d{V  n# 1 d{V swxY w Y   ||z   }d |D             }|	D ]\  }}t3          j        | |           d{V }||v rd||         d                                         }|t7          ||         d                   z
  }|                    t;          |||                     |                    |           |D ]2}t3          j        | |           d{V }|                    |           3|                                  d{V }t?          |||||          S )zGet a snapshot of the Docket, including which tasks are scheduled or currently
        running, as well as which workers are active.

        Returns:
            A snapshot of the Docket.
        r   N-+i  )minmaxr.  )r.  r   r3  NOGROUPXPENDINGc                     g | ]}||S r;   r;   )r   ms     r=   
<listcomp>z#Docket.snapshot.<locals>.<listcomp>q  s-     7 7 7177 7 7r?   c                      i | ]}|d          |S )rI   r;   )r   pendings     r=   r   z#Docket.snapshot.<locals>.<dictcomp>w  s2     K
 K
 K
/6GL!7K
 K
 K
r?   rJ   rK   )milliseconds) r   r   r  r   pipelinexlenr   zcardr   xpending_ranger   xrangezranger   r   r   r   executer  r  rD   snapshotr   r   r   r   r5  r   appendrW   rs   rn   )r<   rr   rq   r   rL  r   total_stream_messagestotal_schedule_messagespending_messagesstream_messagesscheduled_task_keysr   	error_strtask_keyqueued_messagesrp   pending_lookuprI   r+  rZ   worker_namerY   rs   s                          r=   rS  zDocket.snapshot0  s      8{++ 	2//111111111*,"$::<< 3	 3	 3	 3	 3	 3	 3	1zz|| 2 2 2 2 2 2 2xdo...t~...''O* (    cFFF2666 l8<00 '..00000000-/('++'5    !$AI I--y1H1H";;=========%)]]__44444444444O2 2 2 2 2 2 2 2 2 2 2 2 23	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	R  !4 N NH$$T%9%9(//:K:K%L%LMMMM
7 7%-%5%5%7%77777777 7 7a2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 23	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	 3	j ,.EEK
 K
:JK
 K
 K
 $3 		) 		)J'4T7CCCCCCCCI^++,Z8DKKMM	!/
!;<R!S! ! !  /	;PPQQQQi((((& 	% 	%G'4T7CCCCCCCCIMM)$$$$&&&&&&c;IIIsu   I,0B1I	" EI	GA
G!G"I	&I,GGA&I	7I,	
I	I,I	I,,
I69I6c                     | j          dS )Nz:workersr   r   s    r=   workers_setzDocket.workers_set  r  r?   r^  c                     | j          d| S )Nz:worker-tasks:r   )r<   r^  s     r=   worker_tasks_setzDocket.worker_tasks_set  s    )88;888r?   	task_namec                     | j          d| S )Nz:task-workers:r   )r<   rc  s     r=   task_workers_setzDocket.task_workers_set  s    )669666r?   c                 "  K   g }t          j        t          j                                                  | j                                        | j        z  z
  }|                                 4 d{V }|	                    | j
        d|           d{V  |                    | j
        ddd           d{V D ]\  }}|                                }t          j        |t          j                  }d t          t          t                    |                    |                     |                     d{V           D             }|                    t)          |||                     	 ddd          d{V  n# 1 d{V swxY w Y   |S )zGet a list of all workers that have sent heartbeats to the Docket.

        Returns:
            A list of all workers that have sent heartbeats to the Docket.
        Nr   r3  T
withscoresc                 6    h | ]}|                                 S r;   r   r   task_name_bytess     r=   	<setcomp>z!Docket.workers.<locals>.<setcomp>  4     ( ( (' $**,,( ( (r?   )r   r   r   r   	timestampr   r  r   r   zremrangebyscorer`  rQ  r   r   r   rU   rM   smembersrb  rT  rQ   )	r<   rs   oldestr   worker_name_byteslast_seen_timestampr^  rS   
task_namess	            r=   rs   zDocket.workers  sf      %'hl++5577#1133d6LL
 ::<< 	O 	O 	O 	O 	O 	O 	O1$$T%5q&AAAAAAAAA
 AB !RD AI A A ; ; ; ; ; ; O O6!#6 06688$23FUU	( (+/E
!**T5J5J;5W5W*X*X$X$X$X$X$X$X, ,( ( (
 z+y*MMNNNNO	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O* s   1C:E>>
FFc                 Z  K   g }t          j        t          j                                                  | j                                        | j        z  z
  }|                                 4 d{V }|	                    | 
                    |          d|           d{V  |                    | 
                    |          ddd           d{V D ]\  }}|                                }t          j        |t          j                  }d t          t          t                    |                    |                     |                     d{V           D             }	|                    t)          |||	                     	 ddd          d{V  n# 1 d{V swxY w Y   |S )zGet a list of all workers that are able to execute a given task.

        Args:
            task_name: The name of the task.

        Returns:
            A list of all workers that are able to execute the given task.
        Nr   r3  Trg  c                 6    h | ]}|                                 S r;   rj  rk  s     r=   rm  z&Docket.task_workers.<locals>.<setcomp>  rn  r?   )r   r   r   r   ro  r   r  r   r   rp  re  rQ  r   r   r   rU   rM   rq  rb  rT  rQ   )
r<   rc  rs   rr  r   rs  rt  r^  rS   ru  s
             r=   task_workerszDocket.task_workers  s|      %'hl++5577#1133d6LL
 ::<< 	O 	O 	O 	O 	O 	O 	O1$$T%:%:9%E%Eq&QQQQQQQQQ
 AB%%i00!RD AI A A ; ; ; ; ; ; O O6!#6 06688$23FUU	( (+/E
!**T5J5J;5W5W*X*X$X$X$X$X$X$X, ,( ( (
 z+y*MMNNNNO	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O* s   1DF
F$'F$c           	      J  K   t                               d|                                           5  |                                 4 d{V } |j                    4 d{V }|                    | j                   |                    | j                   |	                    | j        dd           |
                                 d{V \  }}}ddd          d{V  n# 1 d{V swxY w Y   g }|dk    rV |j        | j        dd           d{V }|D ]6\  }}	d|	v r-|                    |	d                                                    7 |j                    4 d{V }|dk    r|                    | j        dd	
           |                    | j                   |D ]}
|
                                }|                    |                     |                     |                    |                     |                     |                    |                     |                     | j         d| }| j        r=t+          | j                                                  }|                    ||           |                    |           |D ]g}| j         d| }| j        r=t+          | j                                                  }|                    ||           R|                    |           h|
                                 d{V  ||z   }|cddd          d{V  cddd          d{V  cddd           S # 1 d{V swxY w Y   	 ddd          d{V  n# 1 d{V swxY w Y   ddd           dS # 1 swxY w Y   dS )aA  Clear all queued and scheduled tasks from the docket.

        This removes all tasks from the stream (immediate tasks) and queue
        (scheduled tasks), along with their associated parked data. Running
        tasks are not affected.

        Returns:
            The total number of tasks that were cleared.
        zdocket.clearr   Nr   r3  r@  rA  s   keyF)maxlenapproximater   )r3   r   r   r   rL  rM  r   rN  r   rQ  rR  rP  rT  r   xtrimr  r   r  r  rR   r   rO   r  r  )r<   r   rL  stream_countqueue_countscheduled_keysstream_keysr>  rI   fields	key_bytesr_   r   r  total_cleareds                  r=   clearzDocket.clear  s      )){{}} * 
 
 <	) <	) zz|| 8) 8) 8) 8) 8) 8) 8)u)5>++ 	Y 	Y 	Y 	Y 	Y 	Y 	YxMM$/222NN4>222OODNAr:::
 GOFVFVFXFX@X@X@X@X@X@X=L+~	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y *,!##%1U\$/3%L%LLLLLLLH.6 H H*
F!V++'..vf~/D/D/F/FGGG)5>++ ") ") ") ") ") ") ")x $a'' tqeTTTOODN333 &4 6 6	'..00 (<(<S(A(ABBB (;(;C(@(@AAA (:(:3(?(?@@@ '+i#<#<s#<#<- 6*-d.@.N.N.P.P*Q*QK$OOHkBBBB$OOH5555  + 6 6&*i#<#<s#<#<- 6*-d.@.N.N.P.P*Q*QK$OOHkBBBB$OOH5555"**,,,,,,,,,$0;$>M(E") ") ") ") ") ") ") ") ") ") ") ") ")-8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8)	<	) <	) <	) <	) <	) <	) <	) <	)4") ") ") ") ") ") ") ") ") ") ") ") ") ") ")-8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8) 8)	<	) <	) <	) <	) <	) <	) <	) <	) <	) <	) <	) <	) <	) <	) <	) <	) <	) <	)s   NM:"A/C#M:#
C--M:0C-1A6M:'F>M%M:7N
M  M:#M $M:(N:
N	NN	NNN)NNr   )NNr  N)Hr@   rA   rB   __doc__dictrD   r'   rN   r&   r   Taskr   r5   r   rO   r(   re   propertyr   r   r   r   BaseExceptionr   r   r   r	   r   r   r   r   r   r   r   r   rE   r
   rF   r   r   r   r   r   r   r   r   r   r  r   r  r  r   r  r"   r!   r   r"  r$  r%   r!  r   r   rn   rS  r`  rb  re  r   rQ   rs   rx  r  r;   r?   r=   ru   ru      sq          \!"""""<----$$$$%,,,, -(1	!(<(<(<!"#,9R#8#8#8/3*Y *Y*Y *Y &	*Y
 *Y !*Y &,*Y 
*Y *Y *Y *YX  3       X !$ ! ! ! !F"}%," !4'" !4'	"
 
" " " "( @^E4K8 @ @ @ @
1 
1$ 
1 
1 
1 
1$3 $4 $ $ $ $
S) 
 
 
 

  !%	 1il?+ o 4Z	
 
!Yy))	*   X  !%	  o 4Z	
 
#y++	,   X" !%	4 41il?+c14 o4 4Z	4
 
#y++	,4 4 4 4l 1il?+  	
 
!Yy))	*   X   	
 
#y++	,   X/1il?+c1/ / 	/
 
#y++	,/ / / /bP	 Pd P P P P>. . . . . .Us Uy4/? U U U Un $3 $ $ $ X$ %C % % % X%*# *# * * * *$3 $3 $ $ $ $. . . . . .   &J)5 J)s J)t J) J) J) J)X &C & & & X&
 <@ $/3!%; ;1il?+c1D8; :; _,	;
 $; 
; ; ; ;2 <@ $/3!%< <1il?+c1D8< :< _,	<
 $< 
< < < <.1:K 1PT 1 1 1 1)' )' )' )' )'V\J \J \J \J \J| &S & & & X&9C 9C 9 9 9 97# 7# 7 7 7 7!z*5 ! ! ! !F#C #Jz4J # # # #JF)S F) F) F) F) F) F)r?   ru   )[r   r   logging
contextlibr   dataclassesr   r   r   r   typesr   typingr	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   key_value.aio.stores.baser   typing_extensionsr   redis.exceptionsr   opentelemetryr   redis.asyncior   r   _uuid7r   rZ   r   r    r!   r"   r#   r$   r%   r&   r'   !key_value.aio.protocols.key_valuer(   key_value.aio.stores.redisr)   key_value.aio.stores.memoryr*   instrumentationr+   r,   r-   r.   r/   r0   r1   	getLoggerr@   r2   LoggerrN   
get_tracerr3   Tracerr5   rE   rF   TaskCollectionrM   RedisStreamIDRedisMessageIDr  RedisMessagetupleRedisMessagesRedisStreamRedisReadGroupResponserH   rQ   rW   rn   ru   r;   r?   r=   <module>r     s`         * * * * * * ! ! ! ! ! ! 2 2 2 2 2 2 2 2 2 2                                       $ > = = = = = " " " " " "           / / / / / / / /      
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 < ; ; ; ; ; 1 1 1 1 1 1 3 3 3 3 3 3                  +*844 4 4 4'u'11 1 1 1    8    IcNNGCLL,'E5L!~|;<=M=01!+.     	               y   B $ $ $ $ $ $ $ $\) \) \) \) \) \) \) \) \) \)r?   