Ë
    •Kêjy  ã                  ó  — U d Z ddlmZ g d¢ZddlZddlZddlmZ ddlm	Z	 ddl
mZ ddlmZ dd	lmZmZmZmZ dd
lmZ ddlmZ erddlmZ ed   Zed   ZdZded<   dZded<   dZded<   dZded<   dZ ded<   dZ!ded<   dZ"ded<   dZ#ded <   d!Z$ded"<   d#Z%ded$<    G d%„ d&e&«      Z' G d'„ d(e«      Z( e	d)¬*«       G d+„ d,«      «       Z)d9d-„Z*d:d.„Z+d;d/„Z,d<d0„Z-d=d1„Z. G d2„ d3«      Z/ G d4„ d5«      Z0 G d6„ d7«      Z1g d8¢Z2y)>a;  
The generation-log protocol behind :class:`~filelock.SoftReadWriteLock`.

The lock's whole state is a sequence of immutable snapshots, ``gen/<N>``, each naming the writer and the readers that
hold the lock at generation ``N``. Every transition is one atomic publication of the next snapshot: a participant reads
the latest generation, derives the successor it wants, and links a fully written temporary file to ``gen/<N+1>``. The
link fails if a peer got there first, so the participant re-reads and tries again. No step is ever half done: a crash
leaves at most an unlinked temporary file, never a state that another participant must repair before it can proceed.

Liveness rests on a nonce, not a clock. Each participant keeps ``holders/<token>`` and rewrites its nonce every
heartbeat. A contender records the bytes it read there and the moment it read them on its own monotonic clock; a
member whose bytes have not changed for ``stale_threshold`` is evicted by committing a snapshot without it. Two hosts
never compare clocks, so a skewed file server or a suspended virtual machine cannot make a live holder look dead.

The generation number is monotonic and unique to one transition within one incarnation of the log, so the generation at
which a hold was granted fences it: a resource that rejects anything carrying a lower generation than the highest it has
accepted refuses a holder that paused past its expiry and resumed. A random epoch file names the incarnation, so a
participant that outlives a removal of the log reads the new one instead of continuing the old numbering into it.
é    )Úannotations)Ú
contextlibzfilelock._errorzfilelock._identityÚmathÚpathlibÚsecretsN)Úsuppress)Ú	dataclass)Úisfinite)ÚPath)ÚTYPE_CHECKINGÚFinalÚLiteralÚProtocol)ÚSoftFileLockProtocolError)Ú	host_name)ÚCallable)ÚreadÚwrite)ÚokÚlostÚ	transientzfilelock-rw/1z
Final[str]Ú	_PROTOCOLé   z
Final[int]Ú_GENERATION_DIGITSé    Ú_TOKEN_HEX_LENGTHi   Ú_MAX_RECORD_SIZEé@   Ú_RETAINED_GENERATIONSÚgenÚ_GENERATIONS_DIRECTORYÚepochÚ_EPOCH_NAMEÚHEADÚ
_HEAD_NAMEÚholdersÚ_HOLDERS_DIRECTORYz.commit-Ú_TEMPORARY_PREFIXc                  ó   — e Zd ZdZy)ÚTreeReplacedErrorz£
    Raised by a ``Files`` implementation when a protocol directory is not a real directory (a symlink, a junction, a
    file) or belongs to another account.
    N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© ó    ú`/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/filelock/_soft_rw/_protocol.pyr*   r*   >   s   „ òr0   r*   c                  ó\   — e Zd ZdZdd„Zddœdd„Zdd„Zdd„Zdd„Zdd	„Z	dd
„Z
ddœdd„Zy)ÚFilesz`The filesystem operations the protocol runs on; :mod:`._storage` implements them over :mod:`os`.c                 ó   — y)z\The file's bytes, ``None`` when it does not exist, or ``b""`` when it is not a regular file.Nr/   ©ÚselfÚpaths     r1   r   z
Files.readH   ó   � r0   F©Údurablec                ó   — y)a  
        Create the file exclusively with the whole record written; raise ``FileExistsError`` when it exists.

        The returned device and inode (the kernel's identity for a file, independent of its name) let ``overwrite``
        check that the name still leads to this file.

        *durable* flushes it to stable storage first, for a record that outlives the host that wrote it: a generation a
        crash left empty would wedge every other participant. A holder record dies with its writer, so it skips that.
        Nr/   )r6   r7   Údatar:   s       r1   ÚcreatezFiles.createK   r8   r0   c                 ó   — y)zjHard-link *source* to *target* without replacing; ``True`` when *target* names *source*'s file afterwards.Nr/   ©r6   ÚsourceÚtargets      r1   Úlinkz
Files.linkV   r8   r0   c                 ó   — y)ziRename *source* over *target* atomically; ``False`` when the platform refused because *target* is in use.Nr/   r?   s      r1   ÚreplacezFiles.replaceY   r8   r0   c                 ó   — y)z”
        Rewrite from offset zero the file ``create`` returned *identity* for.

        ``False`` when *path* no longer leads to that file.
        Nr/   )r6   r7   r<   Úidentitys       r1   Ú	overwritezFiles.overwrite\   r8   r0   c                 ó   — y)z5Remove the file, tolerating one that is already gone.Nr/   r5   s     r1   ÚunlinkzFiles.unlinkc   r8   r0   c                 ó   — y)zDThe names in the directory, or an empty list when it does not exist.Nr/   r5   s     r1   ÚlistdirzFiles.listdirf   r8   r0   ©Úforcec                ó   — y)zÒ
        Create the protocol directories under *root*, refusing anything at those paths that is not a directory.

        Done once per lock; *force* repeats it after a write found a directory missing.
        Nr/   )r6   ÚrootrM   s      r1   ÚpreparezFiles.preparei   r8   r0   N)r7   ÚstrÚreturnúbytes | None)r7   rQ   r<   Úbytesr:   ÚboolrR   útuple[int, int])r@   rQ   rA   rQ   rR   rU   )r7   rQ   r<   rT   rF   rV   rR   rU   )r7   rQ   rR   ÚNone)r7   rQ   rR   z	list[str])rO   rQ   rM   rU   rR   rW   )r+   r,   r-   r.   r   r=   rB   rD   rG   rI   rK   rP   r/   r0   r1   r3   r3   E   s>   „ Ùjókð AFõ 	óyóxóóDóSð 38ö r0   r3   T)Úfrozenc                  óJ   — e Zd ZU dZded<   ded<   ded<   edd„«       Zdd	„Zy
)ÚSnapshotzJThe lock's state at one generation: which token writes, which tokens read.ÚintÚ
generationú
str | NoneÚwriterúfrozenset[str]Úreadersc                óf   — | j                   €| j                  S | j                  | j                   hz  S )z"Every token this generation names.)r^   r`   ©r6   s    r1   ÚmemberszSnapshot.membersy   s+   € ð  $Ÿ{™{Ð2ˆt�|‰|ÐT¸¿¹ÈÏÉÀ}Ñ8TÐTr0   c                ó$  — t         d| j                  › �g}| j                  �|j                  d| j                  › �«       |j	                  d„ t        | j                  «      D «       «       dj                  d„ |D «       «      j                  d«      S )Nzgeneration=zwriter=c              3  ó&   K  — | ]	  }d |› �–— Œ y­w)zreader=Nr/   )Ú.0Útokens     r1   ú	<genexpr>z"Snapshot.encode.<locals>.<genexpr>‚   s   è ø€ ÒI¨5�w˜u˜gÔ&ÑIùó   ‚Ú c              3  ó&   K  — | ]	  }|› d �–— Œ y­w)ú
Nr/   ©rf   Úlines     r1   rh   z"Snapshot.encode.<locals>.<genexpr>ƒ   s   è ø€ Ò5 t˜$˜˜r”{Ñ5ùri   Úascii)	r   r\   r^   ÚappendÚextendÚsortedr`   ÚjoinÚencode)r6   Úliness     r1   rt   zSnapshot.encode~   st   € Ü˜k¨$¯/©/Ð):Ð;Ð<ˆØ�;‰;Ð"Ø�L‰L˜7 4§;¡; -Ð0Ô1Ø�‰ÑI´F¸4¿<¹<Ó4HÔIÔIØ�w‰wÑ5¨uÔ5Ó5×<Ñ<¸WÓEÐEr0   N)rR   r_   ©rR   rT   )r+   r,   r-   r.   Ú__annotations__Úpropertyrc   rt   r/   r0   r1   rZ   rZ   q   s0   … áTàƒOØÓØÓàòUó ðUôFr0   rZ   c                óP  — | rt        | «      t        kD  ry	 | j                  d«      j                  d«      }|d   t
        k7  s|d   ryd}d}t        «       }|dd D ]Ÿ  }|j                  d«      \  }}}|dk(  rG|€Et        |«      t        k  r3|j                  «       r#t        t        |«      «      |k(  rt        |«      }Œd|d	k(  r|€t        |«      r|}Œy|d
k(  r!t        |«      r||vr|j                  |«       ŒŸ y |€dS t        ||t        |«      ¬«      S # t        $ r Y yw xY w)zTThe snapshot a ``gen/<N>`` record encodes, or ``None`` when the record is malformed.Nro   rl   r   éÿÿÿÿé   ú=r\   r^   Úreader©r\   r^   r`   )Úlenr   ÚdecodeÚsplitÚUnicodeDecodeErrorr   ÚsetÚ	partitionr   ÚisdigitrQ   r[   Úis_tokenÚaddrZ   Ú	frozenset)	r<   ru   r\   r^   r`   rn   ÚkeyÚ_Úvalues	            r1   Úparse_snapshotrŒ   †   s0  € á”3�t“9Ô/Ò/ØðØ—‘˜GÓ$×*Ñ*¨4Ó0ˆð ˆQ�x”9Ò  b¢	ØØ!€JØ€FÜ›€GØ�a˜�ò ˆØŸ™ sÓ+‰ˆˆQ�à�<ÒØÐ"Ü�E“
Ô0Ò0Ø—‘”Ü”C˜“J“ 5Ò(ä˜U›‰JØ�HŠ_  ´H¸U´OØ‰FØ�HŠ_¤¨%¤°UÀ'Ñ5IØ�K‰K˜Õáðð  Ð%ˆ4Ðu¬8¸zÐRXÔbkÐlsÓbtÔ+uÐuøô/ ò Ùðús   — D Ä	D%Ä$D%c                óN   — t        | «      t        k(  xr t        d„ | D «       «      S )zBWhether *value* is a claim token: exactly 32 lowercase hex digits.c              3  ó$   K  — | ]  }|d v –— Œ
 y­w)Ú0123456789abcdefNr/   )rf   Ú	characters     r1   rh   zis_token.<locals>.<genexpr>¨   s   è ø€ Ò2jÐW`°9Ð@RÔ3RÑ2jùs   ‚)r   r   Úall)r‹   s    r1   r†   r†   ¦   s#   € äˆu‹:Ô*Ñ*Òj¬sÑ2jÐdiÔ2jÓ/jÐjr0   c                 ó:   — t        j                  t        dz  «      S )zA fresh claim token.é   )r   Ú	token_hexr   r/   r0   r1   Ú	new_tokenr•   «   s   € ä×ÑÔ.°!Ñ3Ó4Ð4r0   c                ó–   — t         › d| › dt        j                  «       › dt        «       › dt	        |«      ›d|› d�j                  d«      S )aC  
    The ``holders/<token>`` record; only the nonce changes between heartbeats, so the length stays constant.

    *lease* is the writer's own ``stale_threshold``: a peer configured tighter must not read this holder's longer
    heartbeat interval as death, so evictors wait the longer of their threshold and this one.
    z
token=z
pid=z
host=z
lease=z
nonce=rl   ro   )r   ÚosÚgetpidr   Úfloatrt   )rg   ÚnonceÚleases      r1   Úencode_holderrœ   °   sN   € ô ˆ+�X˜e˜W F¬2¯9©9«;¨-°w¼y»{¸mÈ8ÔTYÐZ_ÓT`ÐScÐckÐlqÐkrÐrtÐuß�fˆWƒoðr0   c                ó  — 	 t        d„ | xs dj                  d«      j                  d«      D «       «      j                  d«      }t	        |«      }t        |«      r|dkD  rt        |«      |k(  r|S dS # t
        t        f$ r Y yw xY w)zjThe ``lease`` a holder record carries, or ``None`` when it has none (an older release) or it is malformed.c              3  óD   K  — | ]  }|j                  d «      sŒ|–— Œ y­w)úlease=N)Ú
startswithrm   s     r1   rh   zholder_lease.<locals>.<genexpr>¿   s!   è ø€ ò 
ØÈDÏOÉOÐ\dÕLeŒDñ
ùs   ‚ ™ r0   ro   rl   rŸ   Nr   )	Únextr€   r�   Úremoveprefixr™   ÚStopIterationÚ
ValueErrorr
   Úrepr)ÚrecordÚtextr›   s      r1   Úholder_leaser¨   ¼   s�   € ðÜñ 
Ø$šm¨×3Ñ3°GÓ<×BÑBÀ4ÓHô
ó 
ç
‰,�xÓ
 ð 	ô �d“ˆô ˜U”O¨°ª	´d¸5³kÀTÒ6Iˆ5ÐSÈtÐSøô œ:Ð&ò Ùðús   ‚AA2 Á2BÂBc                  ó6   — e Zd ZdZdd„Zddœd	d„Zd
d„Zdd„Zy)ÚLedgera�  
    How long each observed value has stayed the same, measured on this observer's monotonic clock.

    A value that has not changed for ``stale_threshold`` belongs to a participant that stopped refreshing it. The clock
    is the observer's own and only ever measures the gap between two of its own observations, which is what lets two
    hosts agree on liveness without agreeing on the time.
    c                ó    — || _         i | _        y ©N)Ú_clockÚ_seen)r6   Úclocks     r1   Ú__init__zLedger.__init__Ò   s   € ØˆŒØ<>ˆ�
r0   N©Úaskedc               ó¨   — | j                  «       }| j                  j                  |«      x}�|d   |k7  r||f| j                  |<   y|€|n||d   z
  S )a   
        Record *value* for *key* and return for how long it has stayed the same.

        *asked* is the clock reading taken before the caller fetched *value*. An unchanged value counts as unchanged up
        to *asked*, so a pause between the fetch and this call adds no time.
        r   ç        r{   )r­   r®   Úget)r6   r‰   r‹   r²   ÚnowÚseens         r1   ÚobservezLedger.observeÖ   s[   € ð �k‰k‹mˆØ—J‘J—N‘N 3Ó'Ð'ˆDÐ0°D¸±G¸uÒ4DØ$ c˜lˆD�J‰J�s‰OØØ�}‘¨%°4¸±7Ñ:Ð:r0   c                ó<   — | j                   j                  |d «       y r¬   )r®   Úpop)r6   r‰   s     r1   ÚforgetzLedger.forgetã   s   € Ø�
‰
�‰�s˜DÕ!r0   c                ó€   — | j                   j                  «       D ��ci c]  \  }}||v sŒ||“Œ c}}| _         yc c}}w )ziDrop every key not in *keys*: peers that left would otherwise stay in the ledger for the lock's lifetime.N)r®   Úitems)r6   Úkeysr‰   r·   s       r1   ÚretainzLedger.retainæ   s2   € à15·±×1AÑ1AÓ1C×S¡I C¨ÀsÈdÂ{�c˜4‘iÓSˆ�
ùÓSs   ž:«:)r¯   úCallable[[], float]rR   rW   )r‰   rQ   r‹   rS   r²   úfloat | NonerR   r™   )r‰   rQ   rR   rW   )r¾   zset[str]rR   rW   )r+   r,   r-   r.   r°   r¸   r»   r¿   r/   r0   r1   rª   rª   É   s#   „ ñó?ð OSõ ;ó"ôTr0   rª   c                  ó¦   — e Zd ZdZdd„Zdd„Zdd„Zdd„Zdd„Zdd„Z	dd„Z
dd	„Zdd
„Zefdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zd d„Zed d„«       Zy)!ÚGenerationLogzeThe ordered snapshots under ``gen/``, found by listing and probing, advanced by linking the next one.c                óê   — || _         || _        t        |t        «      | _        t        | j                  t        z  «      | _        t        | j                  t        z  «      | _	        d | _
        d | _        y r¬   )Ú_filesÚ
_lock_filer   r!   Ú
_directoryrQ   r#   Ú_epoch_pathr%   Ú
_head_pathÚ_epochÚ_latest)r6   ÚfilesÚ	lock_filerO   s       r1   r°   zGenerationLog.__init__î   sX   € ØˆŒØ#ˆŒÜ˜tÔ%;Ó<ˆŒÜ˜tŸ™´Ñ<Ó=ˆÔÜ˜dŸo™o´
Ñ:Ó;ˆŒØ$(ˆŒØ(,ˆ�r0   c                óŠ   — | j                  «       x}€)| j                  «       x}€t        | j                  dd«      ‚|| _        |S )at  
        The newest snapshot.

        Starts from the newest readable generation among those ``gen/HEAD``, the listing, or memory name, then probes
        forward by name across the retained window. ``HEAD`` only names a generation, and that generation must still
        read back: a committer stalled before its rename can leave ``HEAD`` on a generation compacted since. A
        generation compacted between the listing and the read, and a hole left by a committer that died before it
        compacted, are covered by the probe. Memory and ``HEAD`` are bound to the log's epoch, so a log wiped and
        restarted is never continued from a generation it no longer holds. Only a log that names generations, now or as
        remembered, of which none can be read is refused, because that is a client so far behind the log that nothing
        it reads can be trusted.
        Nz)generation log names no readable snapshot)Ú_findr   rÆ   rË   ©r6   Úlatests     r1   rÑ   zGenerationLog.latest÷   sE   € ð —j‘j“lÐ"ˆFÐ+¸4¿:¹:»<Ð1G°Ð0PÜ+¨D¯O©O¸TÐCnÓoÐoØˆŒØˆr0   c                ó|  — | j                  «       x}| j                  k7  r|d c| _        | _        t        | j	                  «       «      }| j                  �;| j                  j
                  r%|j                  | j                  j
                  «       | j                  «       x}r|j                  |«       t        |d¬«      D ]5  }| j                  |«      x}€Œ| j                  |||k(  rdnt        ¬«      c S  t        |d¬«      }| j                  t        |d t        «       ¬«      «      }|j
                  |kD  s|s|S d S )NT)Úreverser{   )Úpatiencer   )Údefaultr~   )Ú_incarnationrÊ   rË   rƒ   Ú_listr\   r‡   Ú_head_generationrr   Ú_readÚ_prober   ÚmaxrZ   rˆ   )r6   r"   ÚnamedÚheadr\   ÚstartÚnewestÚfounds           r1   rÏ   zGenerationLog._find  s  € Ø×&Ñ&Ó(Ð(ˆE¨T¯[©[Ò8Ø(-¨tÐ%ˆDŒK˜œÜ�D—J‘J“LÓ!ˆà�<‰<Ð#¨¯©×(?Ò(?Ø�I‰I�d—l‘l×-Ñ-Ô.Ø×(Ñ(Ó*Ð*ˆ4Ð*Ø�I‰I�dŒOÜ  °Ô5ò 	gˆJØŸ™ JÓ/Ð/�Ñ<ð —{‘{ 5¸
ÀdÒ8J±1ÔPe�{ÓfÒfð		gô
 �U AÔ&ˆØ—‘œH°¸tÌYË[ÔYÓZˆØ×(Ñ(¨6Ò1¹ˆuÐHÀDÐHr0   c                óZ   — | j                  «       x}�t        |«      x}€y |j                  S r¬   )Ú_head_recordrŒ   r\   )r6   r¦   Úsnapshots      r1   rØ   zGenerationLog._head_generation  s7   € ð ×'Ñ'Ó)Ð)ˆFÐ2Ä>ÐRXÓCYÐ7Y°xÐ6bØØ×"Ñ"Ð"r0   c                ó°   — | j                   j                  | j                  «      x}€y |j                  d«      \  }}}| j	                  «       ||z   k(  r|S d S )Nó   
)rÅ   r   rÉ   r„   Ú_valid_epoch)r6   r<   r"   Únewliner¦   s        r1   râ   zGenerationLog._head_record$  sW   € Ø—K‘K×$Ñ$ T§_¡_Ó5Ð5ˆDÐ>Øà!%§¡°Ó!6Ñˆˆw˜Ø×*Ñ*Ó,°¸±Ò?ˆvÐIÀTÐIr0   c                óz   — | j                   }|�,t        |j                  dd«      j                  d«      «      r|S d S )Nro   rD   rl   )rÊ   r†   r€   Úremovesuffix©r6   r"   s     r1   ræ   zGenerationLog._valid_epoch+  s:   € Ø—‘ˆØÐ)¬h°u·|±|ÀGÈYÓ7W×7dÑ7dÐeiÓ7jÔ.kˆuÐuÐquÐur0   c                óV  — | j                   j                  | j                  «      x}€h	 | j                   j                  | j                  t	        «       › d�j                  d«      d¬«       | j                   j                  | j                  «      }|S # t        $ r Y Œ2t        $ r Y y w xY w)Nrl   ro   Tr9   )rÅ   r   rÈ   r=   r•   rt   ÚFileExistsErrorÚFileNotFoundErrorrê   s     r1   rÖ   zGenerationLog._incarnation/  s›   € Ø—[‘[×%Ñ% d×&6Ñ&6Ó7Ð7ˆEÐ@ðØ—‘×"Ñ" 4×#3Ñ#3¼	»°}ÀBÐ5G×5NÑ5NÈwÓ5WÐaeÐ"Ôfð —K‘K×$Ñ$ T×%5Ñ%5Ó6ˆEØˆøô #ò ÙÜ$ò áðús   ©AB Â	B(ÂB(Â'B(c                ó¨   — | j                  «       }|d t          D ],  }| j                  j                  | j	                  |«      «       Œ. |t         d  S r¬   )Ú_listedr   rÅ   rI   Ú_path)r6   Úlistedr\   s      r1   r×   zGenerationLog._list>  sU   € Ø—‘“ˆØ Ð!8Ô#8Ð"8Ð9ò 	7ˆJØ�K‰K×Ñ˜tŸz™z¨*Ó5Õ6ð	7àÔ,Ð,Ð-Ð.Ð.r0   c                ó~   — t        d„ | j                  j                  t        | j                  «      «      D «       «      S )Nc              3  ó–   K  — | ]A  }t        |«      t        k(  r-|j                  «       r|j                  «       rt	        |«      –— ŒC y ­wr¬   )r   r   Úisasciir…   r[   )rf   Únames     r1   rh   z(GenerationLog._listed.<locals>.<genexpr>F  s9   è ø€ ò 
àÜ�4‹yÔ.Ò.°4·<±<´>ÀdÇlÁlÄnô ��Iñ
ùs   ‚AA	)rr   rÅ   rK   rQ   rÇ   rb   s    r1   rï   zGenerationLog._listedD  s4   € äñ 
àŸ™×+Ñ+¬C°·±Ó,@ÓAô
ó 
ð 	
r0   c                ó€   — |}|j                   }d}||k  r(|dz  }| j                  |«      x}€|dz  }Œ#|}d}||k  rŒ(|S )Nr   r{   )r\   rÙ   )r6   rÞ   rÔ   rÑ   r\   Úgaprã   s          r1   rÚ   zGenerationLog._probeL  sa   € ØˆØ×%Ñ%ˆ
ØˆØ�HŠnØ˜!‰OˆJØ ŸJ™J zÓ2Ð2�Ð;Ø�q‘�ØØˆFØˆCð �H‹nð ˆr0   c                óè   — | j                   j                  | j                  |«      «      x}€y t        |«      x}�|j                  |k7  r(| j                  |«      }t        | j                  |d«      ‚|S )Nzmalformed generation record)rÅ   r   rð   rŒ   r\   Ú_namer   rÆ   )r6   r\   r<   rã   rõ   s        r1   rÙ   zGenerationLog._readY  sm   € Ø—K‘K×$Ñ$ T§Z¡Z°
Ó%;Ó<Ð<ˆDÐEØÜ& tÓ,Ð,ˆHÐ5¸×9LÑ9LÐPZÒ9ZØ—:‘:˜jÓ)ˆDÜ+¨D¯O©O¸TÐC`ÓaÐaØˆr0   c                ób  — | j                   j                  | j                  «      | j                  k7  s| j	                  |j
                  «      sy| j                  | j                  |j
                  «      |j                  «       x}| j                   j                  d¬«      syt        g | j                  «       ¢| j                  «       xs d‘«      |j
                  z
  }|t        k\  s| j	                  |j
                  «      sFd|cxk  r	t        k  s6n | j                   j                  | j                  |j
                  «      «       y|| _        t!        t"        «      5  | j%                  «       x}�| j                   j                  | j                  «      |k(  rW| j                  «       xs d|j
                  k  r6| j                  | j&                  ||z   | j                   j(                  d¬«       ddd«       |j
                  t        z
  dz
  x}dkD  r| j+                  |«       y# 1 sw Y   Œ6xY w)a/  
        Publish *successor* as the next generation; ``False`` when a peer published that generation first.

        The record is complete before it gets its public name, and a no-replace hard link is the compare-and-swap: only
        one link to ``gen/<N+1>`` can ever succeed. The link's return code is not trusted, because an NFS retry can
        report a link that did land as failed; the file's identity after the call is what decides. A log whose epoch
        changed since the snapshot was read is a different log, so the commit is refused as lost and the caller
        re-reads; that narrows a wipe racing this commit to the moment between the epoch check and the link. A slot
        compaction freed is refused the same way, before the link and again after it, since a committer can stall in
        between. After the link a surviving predecessor proves little: it may be a record another stalled committer
        linked into its own freed slot and has yet to remove. A slot comes free once the log is a whole window past it,
        and the head stays, so a record the listing or ``HEAD`` leads by a window is refused as well. A record refused
        after it landed is removed when nothing was built on it. One that peers lead by less than a window stays, or its
        slot would come free early.
        FTr9   r   Nr{   )rÅ   r   rÈ   rÊ   Ú_extends_the_logr\   Ú_publishrð   rt   rB   rÛ   rï   rØ   r   rI   rË   r   ÚOSErrorræ   rÉ   rD   Ú_compact_through)r6   Ú	successorr<   Úleadr"   Úexpireds         r1   ÚcommitzGenerationLog.commita  sÔ  € ð  �;‰;×Ñ˜D×,Ñ,Ó-°·±Ò<ÀD×DYÑDYÐZc×ZnÑZnÔDoØØ�}‰}Ø�J‰J�y×+Ñ+Ó,°i×6FÑ6FÓ6HÐ.H¨dÈ$Ï+É+×JZÑJZÐdhð ô 
ð ÜÐB�T—\‘\“^ÐB T×%:Ñ%:Ó%<Ò%AÀÐBÓCÀi×FZÑFZÑZˆØÔ(Ò(°×0EÑ0EÀi×FZÑFZÔ0[Ø�tÔ3Ô3Ô3Ø—‘×"Ñ" 4§:¡:¨i×.BÑ.BÓ#CÔDØØ ˆŒô ”gÓñ 	aà×+Ñ+Ó-Ð-�Ð:Ø—K‘K×$Ñ$ T×%5Ñ%5Ó6¸%Ò?Ø×*Ñ*Ó,Ò1°°Y×5IÑ5IÒIà—‘˜dŸo™o¨u°t©|¸T¿[¹[×=PÑ=PÐZ_�Ô`÷	að !×+Ñ+Ô.CÑCÀaÑGÐGˆGÈ1ÒLØ×!Ñ! 'Ô*Ø÷	að 	aús   ÅBH%È%H.c                óŽ   — |dkD  r/| j                   j                  | j                  |dz
  «      «      d uS | j                  «       d u S ©Nr{   )rÅ   r   rð   râ   ©r6   r\   s     r1   rû   zGenerationLog._extends_the_logŠ  sF   € ð ˜Š>Ø—;‘;×#Ñ# D§J¡J¨z¸A©~Ó$>Ó?ÀtÐKÐKØ× Ñ Ó" dÐ*Ð*r0   c               ó8  — t        | j                  t        › t        «       › �z  «      }	 | j                  j                  |||¬«       	  |||«      | j                  j                  |«       S # t        $ r Y yw xY w# | j                  j                  |«       w xY w)Nr9   F)rQ   rÇ   r(   r•   rÅ   r=   rí   rI   )r6   rA   r<   Úplacer:   Ú	temporarys         r1   rü   zGenerationLog._publish‘  sŒ   € Ü˜Ÿ™Ô->Ð,?Ä	Ã¸}Ð*MÑMÓNˆ	ð	Ø�K‰K×Ñ˜y¨$¸ÐÔ@ð
	*Ù˜ FÓ+à�K‰K×Ñ˜yÕ)øô !ò 	ñ ð	ûð �K‰K×Ñ˜yÕ)ús   ªA- Á	A< Á-	A9Á8A9Á<Bc                óX  — |}|dkD  re| j                   j                  | j                  |dz
  «      «      �8|dz  }|dkD  r.| j                   j                  | j                  |dz
  «      «      �Œ8t        ||dz   «      D ],  }| j                   j	                  | j                  |«      «       Œ. y r  )rÅ   r   rð   ÚrangerI   )r6   r  Úoldestr\   s       r1   rþ   zGenerationLog._compact_throughž  s—   € àˆØ�qŠj˜TŸ[™[×-Ñ-¨d¯j©j¸À!¹Ó.DÓEÐQØ�a‰KˆFð �qŠj˜TŸ[™[×-Ñ-¨d¯j©j¸À!¹Ó.DÓEÑQä ¨°!©Ó4ò 	7ˆJØ�K‰K×Ñ˜tŸz™z¨*Ó5Õ6ñ	7r0   c                óP   — t        | j                  | j                  |«      z  «      S r¬   )rQ   rÇ   rù   r  s     r1   rð   zGenerationLog._path¦  s   € Ü�4—?‘? T§Z¡Z°
Ó%;Ñ;Ó<Ð<r0   c                ó   — | dt         › d�›S )NÚ0Úd)r   )r\   s    r1   rù   zGenerationLog._name©  s   € à˜QÔ1Ð2°!Ð3Ð4Ð5r0   N)rÌ   r3   rÍ   rQ   rO   rQ   rR   rW   )rR   rZ   )rR   úSnapshot | None)rR   ú
int | None)rR   rS   )rR   z	list[int])rÞ   rZ   rÔ   r[   rR   rZ   )r\   r[   rR   r  )rÿ   rZ   rR   rU   )r\   r[   rR   rU   )
rA   rQ   r<   rT   r  zCallable[[str, str], bool]r:   rU   rR   rU   )r  r[   rR   rW   )r\   r[   rR   rQ   )r+   r,   r-   r.   r°   rÑ   rÏ   rØ   râ   ræ   rÖ   r×   rï   r   rÚ   rÙ   r  rû   rü   rþ   rð   Ústaticmethodrù   r/   r0   r1   rÃ   rÃ   ë   ss   „ Ùoó-óó(Ió$#óJóvóó/ó
ð 7Lô óó'óR+ó*ó7ó=ð ò6ó ñ6r0   rÃ   c                  ó¼   — e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd„Zdd„Zdd„Zdd„Zdd„Zdd„Z	dd„Z
dd	„Z	 	 	 	 	 	 	 	 	 	 dd
„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zy)ÚParticipanta0  
    One acquisition, from publishing a claim through holding the lock to leaving.

    ``advance`` is polled until it reports the lock granted, ``heartbeat`` runs on the holder's schedule, and ``leave``
    commits the participant out. None of them sleep: the caller owns the deadline and the poll interval. The ledger and
    the log outlive one acquisition: how long a peer's record has stayed unchanged is knowledge every attempt against
    the same lock shares, or a caller whose attempts are each shorter than the stale threshold could never evict.
    c               ó  — t        «       | _        || _        d | _        || _        || _        || _        || _        || _        || _	        | j                  | j                  «      | _        d | _        d| _         |«       | _        y ©NF)r•   rg   Úmoder\   rÅ   Ú_rootÚ_stale_thresholdr­   Ú_ledgerÚ_logÚ_holder_pathÚ_holderÚ_holder_identityÚ_enteredÚ_next_sweep)r6   rÌ   rO   r  Ústale_thresholdr¯   ÚledgerÚlogs           r1   r°   zParticipant.__init__¸  su   € ô "+£ˆŒ
Ø!%ˆŒ	Ø&*ˆŒØˆŒØˆŒ
Ø /ˆÔØˆŒØˆŒØˆŒ	Ø×(Ñ(¨¯©Ó4ˆŒØ8<ˆÔØˆŒÙ ›7ˆÕr0   c                ón   — | j                   j                  | j                  «       | j                  «        y)zfCreate the holder record peers watch for liveness; it exists before the token appears in any snapshot.N)rÅ   rP   r  Ú_create_holderrb   s    r1   ÚpublishzParticipant.publishÑ  s$   € à�‰×Ñ˜DŸJ™JÔ'Ø×ÑÕr0   c                óV  — 	 | j                   j                  | j                  | j                  «       «      | _        y # t
        $ rc | j                   j                  | j                  d¬«       | j                   j                  | j                  | j                  «       «      | _        Y y w xY w)NTrL   )rÅ   r=   r  Ú_recordr  rí   rP   r  rb   s    r1   r%  zParticipant._create_holderÖ  sz   € ð	UØ$(§K¡K×$6Ñ$6°t·|±|ÀTÇ\Á\Ã^Ó$TˆDÕ!øÜ ò 	Uà�K‰K×Ñ §
¡
°$ÐÔ7Ø$(§K¡K×$6Ñ$6°t·|±|ÀTÇ\Á\Ã^Ó$TˆDÖ!ð	Uús   ‚9< ¼A)B(Â'B(c                óT   — t        | j                  t        «       | j                  «      S r¬   )rœ   rg   r•   r  rb   s    r1   r(  zParticipant._recordÞ  s   € Ü˜TŸZ™Z¬«°d×6KÑ6KÓLÐLr0   c                ó   ‡ — t        d«      D �]>  }‰ j                  j                  «       }‰ j                  |«       ‰ j	                  |«       t        ˆ fd„|j                  ‰ j                  hz
  D «       «      }|j                  |v rdn|j                  }|j                  |z
  }‰ j                  sL|�|r‰ j                  ||||«        y‰ j                  dk(  r‰ j                  |fnd|‰ j                  hz  f\  }}‰ j                  dk(  xs | }‰ j                  r|s|s y‰ j                  ||||«      x}€�Œ-d‰ _
        |r|‰ _        |c S  y)aö  
        Take the next step toward holding the lock; ``True`` once the lock is granted.

        A reader enters as soon as no live writer is named. A writer enters as soon as no live writer is named, which
        blocks every new reader, then waits for the named readers to leave. Stale members are evicted in the same commit
        that admits this participant, and a writer's final admission is itself a commit, so no admission can rest on a
        snapshot a peer is about to supersede.
        é   c              3  óF   •K  — | ]  }‰j                  |«      sŒ|–— Œ y ­wr¬   )Ú	_is_stale)rf   rg   r6   s     €r1   rh   z&Participant.advance.<locals>.<genexpr>ð  s    øè ø€ Òh¨ÐRV×R`ÑR`ÐafÕRgœeÑhùs   ƒ!š!NFr   r   T)r
  r  rÑ   Ú_keep_claim_freshÚ_sweeprˆ   rc   rg   r^   r`   r  Ú_commitr  r\   )r6   rŠ   rÑ   Ústaler^   r`   Úgrantedr\   s   `       r1   ÚadvancezParticipant.advanceá  s<  ø€ ô �q“ó 	ˆAØ—Y‘Y×%Ñ%Ó'ˆFØ×"Ñ" 6Ô*Ø�K‰K˜ÔÜÓh°·±À4Ç:Á:À,Ñ1NÔhÓhˆEØ#Ÿ]™]¨eÑ3‘T¸¿¹ˆFØ—n‘n uÑ,ˆGØ—=’=ØÐ%áØŸ™ V¨V°W¸eÔDÙ Ø;?¿9¹9ÈÒ;O 4§:¡:¨wÑ"7ÐVZÐ\cÐgk×gqÑgqÐfrÑ\rÐUs‘�˜Ø—i‘i 6Ñ)Ò8°¨[ˆGØ�}Š}¡U±7ÙØ"Ÿl™l¨6°6¸7ÀEÓJÐJ�
ÐSÙØ ˆDŒMÙØ",�”ØŠNð-	ð. r0   c                óÈ   — | j                   |j                  v | _        | j                  «       s)t	        t
        «      5  | j                  «        d d d «       y y # 1 sw Y   y xY wr¬   )rg   rc   r  Ú_refresh_noncer   rì   r%  rÐ   s     r1   r.  zParticipant._keep_claim_fresh  sW   € ð Ÿ
™
 f§n¡nÐ4ˆŒØ×"Ñ"Ô$Üœ/Ó*ñ &Ø×#Ñ#Ô%÷&ð &ð %÷&ð &ús   ½AÁA!c                ó0  — | j                  «       x}| j                  k  ry || j                  dz  z   | _        t        |j                  «      }t        | j                  t        «      }| j                  j                  t        |«      «      D ]a  }|| j                  k7  sŒ||j                  vsŒ"t        |«      sŒ.|j                  d|› �x}«       | j                  |t        ||z  «      «       Œc t        | j                  t        «      }| j                  j                  t        |«      «      D ]L  }|j!                  t"        «      sŒ|j                  d|› �x}«       | j                  |t        ||z  «      «       ŒN | j$                  j'                  |«       y )Nr“   zholder:z
temporary:)r­   r   r  rƒ   rc   r   r  r'   rÅ   rK   rQ   rg   r†   r‡   Ú_collectr!   r    r(   r  r¿   )r6   rÑ   r¶   Úwatchedr&   rõ   r‰   Úgenerationss           r1   r/  zParticipant._sweep  sL  € ð —;‘;“=Ð ˆC D×$4Ñ$4Ò4ØØ ×!6Ñ!6¸Ñ!:Ñ:ˆÔÜ�f—n‘nÓ%ˆÜ�t—z‘zÔ#5Ó6ˆØ—K‘K×'Ñ'¬¨G«Ó5ò 	8ˆDØ�t—z‘zÓ! d°&·.±.Ò&@ÄXÈdÅ^Ø—‘ W¨T¨FÐ#3Ð3˜CÔ4Ø—‘˜c¤3 w°¡~Ó#6Õ7ð	8ô ˜4Ÿ:™:Ô'=Ó>ˆØ—K‘K×'Ñ'¬¨KÓ(8Ó9ò 	<ˆDØ�‰Ô0Õ1Ø—‘ Z°¨vÐ#6Ð6˜CÔ7Ø—‘˜c¤3 {°TÑ'9Ó#:Õ;ð	<ð 	�‰×Ñ˜GÕ$r0   c                ó–   — | j                  ||«      r7| j                  j                  |«       | j                  j	                  |«       y y r¬   )Ú_unchanged_for_its_leaserÅ   rI   r  r»   )r6   r‰   r7   s      r1   r7  zParticipant._collect$  s;   € Ø×(Ñ(¨¨dÔ3Ø�K‰K×Ñ˜tÔ$Ø�L‰L×Ñ Õ$ð 4r0   c                ó   — t        |j                  dz   ||¬«      }| j                  j                  |«      sy |D ]G  }| j                  j                  | j                  |«      «       | j                  j                  |«       ŒI |j                  S )Nr{   r~   )	rZ   r\   r  r  rÅ   rI   r  r  r»   )r6   rÑ   r^   r`   r1  rÿ   rg   s          r1   r0  zParticipant._commit)  s   € ô ¨×(9Ñ(9¸AÑ(=ÀfÐV]Ô^ˆ	Ø�y‰y×Ñ 	Ô*ØØò 	'ˆEØ�K‰K×Ñ˜t×0Ñ0°Ó7Ô8Ø�L‰L×Ñ Õ&ð	'ð ×#Ñ#Ð#r0   c                óD   — | j                  || j                  |«      «      S r¬   )r;  r  ©r6   rg   s     r1   r-  zParticipant._is_stale4  s    € Ø×,Ñ,¨U°D×4EÑ4EÀeÓ4LÓMÐMr0   c                óÜ   — | j                  «       }| j                  j                  |«      }| j                  j	                  |||¬«      t        | j                  t        |«      xs d«      k\  S )Nr±   r´   )r­   rÅ   r   r  r¸   rÛ   r  r¨   )r6   r‰   r7   r²   r¦   s        r1   r;  z$Participant._unchanged_for_its_lease7  s\   € Ø—‘“ˆØ—‘×!Ñ! $Ó'ˆØ�|‰|×#Ñ# C¨°uÐ#Ó=ÄÀT×EZÑEZÔ\hÐioÓ\pÒ\wÐtwÓAxÑxÐxr0   c                óJ   — t        t        | j                  t        |«      «      S r¬   )rQ   r   r  r'   r>  s     r1   r  zParticipant._holder_path<  s   € Ü”4˜Ÿ
™
Ô$6¸Ó>Ó?Ð?r0   c                óŠ   — | j                   x}€y| j                  j                  | j                  | j	                  «       |«      S r  )r  rÅ   rG   r  r(  )r6   rF   s     r1   r5  zParticipant._refresh_nonce?  s9   € Ø×-Ñ-Ð-ˆHÐ6ØØ�{‰{×$Ñ$ T§\¡\°4·<±<³>À8ÓLÐLr0   c                ó2  — 	 | j                  «       sy	 	 | j                  j	                  «       }| j                  |«       | j                  |j                  v rddfS ddfS # t        $ r Y yt        $ r}d|fcY d}~S d}~ww xY w# t        t        f$ r Y yw xY w)aì  
        Refresh the nonce and confirm the latest snapshot still names this participant.

        ``lost`` means a peer evicted this participant or removed its holder record: the lock is no longer held, and the
        holder must stop using what it protects. ``transient`` is a filesystem error refreshing the nonce, worth
        retrying on the next tick. A failure to read the log or to sweep decides nothing about this holder's liveness,
        so it is not counted against it.
        )r   Nr   N)r   Nr   r   )r5  r*   rý   r  rÑ   r/  rg   rc   )r6   ÚerrorrÑ   s      r1   Ú	heartbeatzParticipant.heartbeatD  s¥   € ð	&Ø×&Ñ&Ô(Ø#ð )ð	Ø—Y‘Y×%Ñ%Ó'ˆFØ�K‰K˜Ôð Ÿ
™
 f§n¡nÑ4�À4ÐGÐG¸&À4ÐGÐGøô !ò 	 ÙÜò 	&Ø Ð%Õ%ûð	&ûô
 Ô*Ð+ò 	Ùð	ús4   ‚A  •+B Á 	BÁ+BÁ3A<Á6BÁ<BÂBÂBc                óØ  — t        t        «      5  	 | j                  | j                  j	                  «       x}j
                  v r§t        |j                  dz   |j                  | j                  k(  rdn|j                  |j                  | j                  hz
  ¬«      }| j                  j                  |«      rn3| j                  | j                  j	                  «       x}j
                  v rŒ§d| _        d| _        | j                  j                  | j                  «       	 ddd«       y# d| _        d| _        | j                  j                  | j                  «       w xY w# 1 sw Y   yxY w)zRCommit this participant out of the latest snapshot, then remove its holder record.r{   Nr~   F)r   r*   rg   r  rÑ   rc   rZ   r\   r^   r`   r  r  rÅ   rI   r  )r6   rÑ   rÿ   s      r1   ÚleavezParticipant.leave[  s  € ô
 Ô'Ó(ñ 	1ð1Ø—j‘j¨t¯y©y×/?Ñ/?Ó/AÐ%A V×$JÑ$JÑJÜ (Ø#)×#4Ñ#4°qÑ#8Ø'-§}¡}¸¿
¹
Ò'B™tÈÏÉØ &§¡°$·*±*°Ñ =ô!�Ið
 —y‘y×'Ñ'¨	Ô2Øð —j‘j¨t¯y©y×/?Ñ/?Ó/AÐ%A V×$JÑ$JÒJð !&�”Ø"&�”Ø—‘×"Ñ" 4§<¡<Õ0÷	1ð 	1øð !&�”Ø"&�”Ø—‘×"Ñ" 4§<¡<Õ0ú÷	1ð 	1ús#   �E ’CD(Ã+3E Ä(5EÅE Å E)N)rÌ   r3   rO   rQ   r  ÚModer!  r™   r¯   rÀ   r"  rª   r#  rÃ   rR   rW   )rR   rW   rv   )rR   rU   )rÑ   rZ   rR   rW   )r‰   rQ   r7   rQ   rR   rW   )
rÑ   rZ   r^   r]   r`   r_   r1  r_   rR   r  )rg   rQ   rR   rU   )r‰   rQ   r7   rQ   rR   rU   )rg   rQ   rR   rQ   )rR   z'tuple[HeartbeatOutcome, OSError | None])r+   r,   r-   r.   r°   r&  r%  r(  r3  r.  r/  r7  r0  r-  r;  r  r5  rD  rF  r/   r0   r1   r  r  ®  sÐ   „ ñð#àð#ð ð#ð ð	#ð ð#ð #ð#ð ð#ð ð#ð 
ó#ó2ó
UóMó"óH	&ó%ó(%ð
	$Øð	$Ø(2ð	$Ø=Kð	$ØTbð	$à	ó	$óNóyó
@óMó
Hô.1r0   r  )r3   rÃ   ÚHeartbeatOutcomerª   rG  r  rZ   r*   rœ   r¨   r†   r•   rŒ   )r<   rT   rR   r  )r‹   rQ   rR   rU   )rR   rQ   )rg   rQ   rš   rQ   r›   r™   rR   rT   )r¦   rS   rR   rÁ   )3r.   Ú
__future__r   Ú__lazy_modules__r—   r   r   r   Údataclassesr	   r   r
   r   r   Útypingr   r   r   r   Úfilelock._errorr   Úfilelock._identityr   Úcollections.abcr   rG  rH  r   rw   r   r   r   r   r!   r#   r%   r'   r(   ÚRuntimeErrorr*   r3   rZ   rŒ   r†   r•   rœ   r¨   rª   rÃ   r  Ú__all__r/   r0   r1   ú<module>rR     sE  ðòõ( #âhÐ ã 	Û Ý Ý !Ý Ý ß :Ó :å 5Ý (áÝ(àˆÑ€ØÐ4Ñ5Ð à'€	ˆ:Ó 'Ø!#Ð �JÓ #Ø "Ð �:Ó "à&Ð �*Ó &ð %'Ð �zÓ &Ø%*Ð ˜
Ó *ð "€ˆZÓ !ð  €
ˆJÓ Ø!*Ð �JÓ *Ø *Ð �:Ó *ô˜ô ô)ˆHô )ñX �$Ô÷Fð Fó ðFó(vó@kó
5ó
	ó
T÷Tñ T÷D@6ñ @6÷F1ñ 1òD�r0   