
    <i$                        S SK Jr  S SKrS SKrS SKrS SKrS SKrS SKrS SKrSSK	J
r
Jr  \R                  " \5      rSrSr " S S\R"                  R$                  5      r " S S	\R&                  5      rg)
    )annotationsN   )
exceptionsutilsg?c                  ,   ^  \ rS rSrSU 4S jjrSrU =r$ )PubSubWorkerThread   c                l   >  [         TU ]  5         g ! [         a    [        R                  " 5         e f = fN)superrun	Exception_threadinterrupt_main)self	__class__s    K/home/james-whalen/.local/lib/python3.13/site-packages/portalocker/redis.pyr   PubSubWorkerThread.run   s/    	GKM 	""$	s    !3 returnNone)__name__
__module____qualname____firstlineno__r   __static_attributes____classcell__r   s   @r   r   r      s         r   c                  R  ^  \ rS rSr% SrS\S'   S\S'   S\S'   S	\S
'   S\S'   SrS\S'   S\S'   \" SSS9rS\S'   SSSS\	\
S4                 S"U 4S jjjrS#S jrS$S jr\S%S j5       r      S&S jr   S'       S(S jjr      S)S jrS*S jrS*S  jrS!rU =r$ )+	RedisLock   a  
An extremely reliable Redis lock based on pubsub with a keep-alive thread

As opposed to most Redis locking systems based on key/value pairs,
this locking method is based on the pubsub system. The big advantage is
that if the connection gets killed due to network issues, crashing
processes or otherwise, it will still immediately unlock instead of
waiting for a lock timeout.

To make sure both sides of the lock know about the connection state it is
recommended to set the `health_check_interval` when creating the redis
connection..

Args:
    channel: the redis channel to use as locking key.
    connection: an optional redis connection if you already have one
    or if you need to specify the redis connection
    timeout: timeout when trying to acquire a lock
    check_interval: check interval while waiting
    fail_when_locked: after the initial lock failed, return an error
        or lock the file. This does not wait for the timeout.
    thread_sleep_time: sleep time between fetching messages from redis to
        prevent a busy/wait loop. In the case of lock conflicts this
        increases the time it takes to resolve the conflict. This should
        be smaller than the `check_interval` to be useful.
    unavailable_timeout: If the conflicting lock is properly connected
        this should never exceed twice your redis latency. Note that this
        will increase the wait time possibly beyond your `timeout` and is
        always executed if a conflict arises.
    redis_kwargs: The redis connection arguments if no connection is
        given. The `DEFAULT_REDIS_KWARGS` are used as default, if you want
        to override these you need to explicitly specify a value (e.g.
        `health_check_interval=0`)

zdict[str, typing.Any]redis_kwargszPubSubWorkerThread | Nonethreadstrchannelfloattimeoutredis.client.Redis[str] | None
connectionNzredis.client.PubSub | Nonepubsubboolclose_connection
   T)health_check_intervaldecode_responsesz&typing.ClassVar[dict[str, typing.Any]]DEFAULT_REDIS_KWARGSFc	                &  > U(       + U l         S U l        Xl        X l        X`l        Xpl        U=(       d
    [        5       U l        U R                  R                  5        H   u  pU R                  R                  X5        M"     [        TU ]1  UUUS9  g )N)r)   check_intervalfail_when_locked)r.   r%   r'   r+   thread_sleep_timeunavailable_timeoutdictr$   r2   items
setdefaultr   __init__)r   r'   r+   r)   r4   r5   r6   r7   r$   keyvaluer   s              r   r;   RedisLock.__init__P   s     %/$!2#6 (2DF3399;JC((4 < 	)- 	 	
r    c                    U R                   (       d/  [        R                  R                  " S0 U R                  D6U l         U R                   $ )Nr   )r+   redisclientRedisr$   r   s    r   get_connectionRedisLock.get_connectionn   s2    #ll00E43D3DEDOr    c                p   UR                  S5      S:w  a  g UR                  S5      nU(       d  g  [        R                  " U5      nU R                  c   eU R                  R                  US   [        [        R                  " 5       5      5        g ! [         a    [        R                  SU5         g f = f)NtypemessagedatazTypeError while parsing: %rresponse_channel)
getjsonloads	TypeErrorloggerdebugr+   publishr&   time)r   rH   raw_datarI   s       r   channel_handlerRedisLock.channel_handlert   s    ;;v)+;;v&	::h'D
 ***%7 8#diik:JK  	LL6@	s   B  B54B5c                     U R                    S3$ )Nz-lock)r'   rC   s    r   client_nameRedisLock.client_name   s    ,,u%%r    c              #    #    Uc  SnUc  U R                   n[        R                  " 5       U-   nSnU(       d  [        R                  " 5       U:  ap  SnUS:  a  UOU R                   nUS[        R                  " 5       -   -  n[        R                  " U5        Sv   U(       a  MT  [        R                  " 5       U:  a  Mo  g g 7f)N        TFr   g      ?)r6   rR   	monotonicrandomsleep)r   r)   r4   deadlinefirsteffective_interval
sleep_times          r   _timeout_generatorRedisLock._timeout_generator   s      ?G!!33N>>#g-t~~'(2E "A% ++ 
 ,sV]]_/DEJJJz"G et~~'(2s   B!C%C Cc                ~   [         R                  " XR                  S5      n[         R                  " UU R                  S5      n[         R                  " UU R                  5      nU R
                  (       a   S5       eU R                  5       nU R                  X5      nU GH  nUR                  U R                  5      S   S   nU(       aF  [        R                  SUU R                  5        U R                  UU R                  5      (       a  Mp  SnU(       d  UR                  U R                  5        UR                  5       U l        U R
                  R                   " S0 U R                  U R"                  0D6  [%        U R
                  U R&                  S9U l        U R(                  R+                  5         [,        R.                  " S5        UR                  U R                  5      S   S   nUS:X  a  U s  $ U R1                  5         U(       d  GMs  [2        R4                  " 5       e   [2        R4                  " 5       e)	NrZ   zThis lock is already activer   r   z Found %d lock subscribers for %s)ra   {Gz?r   )r   coalescer)   r4   r5   r,   rD   rb   pubsub_numsubr'   rO   rP   check_or_kill_lockr7   client_setnamerW   	subscriberT   r   r6   r%   startrR   r]   releaser   AlreadyLocked)r   r)   r4   r5   r+   timeout_generator_subscriberss           r   acquireRedisLock.acquire   s    ..,,<

 !>>!!

 ;;= ==((*
 33GL"A$224<<@CAFK6LL **,,  "#K ))$*:*:;(//1%%Mt7K7K(LM0KK#55 !!#

4 (66t||DQGJ!#K LLN ..00M #P &&((r    c           
        U R                    S[        R                  " 5        3nUR                  5       nUR                  U5        UR	                  U R                   [
        R                  " [        USS95      5        [        U R                  US-  5      nU R                  UU5       H)  nUR                  US9(       d  M  UR                  5           g   UR                  S5       HZ  nUR                  S5      U R                  :X  d  M$  [         R#                  S	U5        UR%                  UR                  S
5      5        M\     g )N-ping)rJ   rH   r/   )r)   Tr,   namez$Killing unavailable redis client: %rid)r'   r\   r,   rj   rQ   rL   dumpsr8   minr6   rb   get_messagecloseclient_listrK   rW   rO   warningclient_kill_filter)r   r+   r)   rJ   r,   r4   ro   client_s           r   rh   RedisLock.check_or_kill_lock   s    #ll^1V]]_,=>""$)*LLJJ%5"	
 T33Wr\B((
A !!.!99
 "--h7G{{6"d&6&66EwO--KK% 8 r    c                x   U R                   (       aQ  U R                   R                  5         U R                   R                  5         S U l         [        R                  " S5        U R
                  (       aG  U R
                  R                  U R                  5        U R
                  R                  5         S U l        g g )Nre   )	r%   stopjoinrR   r]   r,   unsubscriber'   r{   rC   s    r   rl   RedisLock.release  su    ;;KKKKDKJJt;;KK##DLL1KKDK r    c                $    U R                  5         g r   )rl   rC   s    r   __del__RedisLock.__del__  s    r    )r'   r.   r+   r,   r$   r%   r6   r7   )r'   r&   r+   r*   r)   float | Noner4   r   r5   bool | Noner6   r(   r7   r(   r$   zdict[str, typing.Any] | Noner   r   )r   redis.client.Redis[str])rH   zdict[str, str]r   r   )r   r&   )r)   r   r4   r   r   ztyping.Iterator[int])NNN)r)   r   r4   r   r5   r   r   r"   )r+   r   r)   r(   r   r   r   )r   r   r   r   __doc____annotations__r,   r8   r2   DEFAULT_THREAD_SLEEP_TIMEDEFAULT_UNAVAILABLE_TIMEOUTr;   rD   rT   propertyrW   rb   rq   rh   rl   r   r   r   r   s   @r   r"   r"      so   "H ('%%LN..)-F&-CG D@  6: $'+(-#<%@59

 3
 	

 %
 &
 !
 #
 3
 

 
<L" & &#5A	, !%'+(,	=)=) %=) &	=)
 
=)~#+# # 
	#J
 r    r"   )
__future__r   r   rL   loggingr\   rR   typingr@    r   r   	getLoggerr   rO   r   r   rA   r   LockBaser"   r   r    r   <module>r      sd    "        			8	$  88 p pr    