Ë
    âß²jÓ  ã                  ó´   — d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	m
Z
mZ  ej                  e«      Zdddd	d
œZdZededz   diZdd„Zdd„Zdd„Zdd„Zy)að  Who holds the SQLite write lock on state.db right now (Linux ``/proc/locks``).

The "database is locked for over Ns" failure names the victim but not the holder, and the
open-descriptor scan (``hermes_state_holders``) cannot tell a reader from the one writer: every
Hermes process has the DB open. SQLite's unix VFS takes ``fcntl`` byte-range locks whose offsets
encode the lock kind, and the kernel exports them with the owning pid, so the holder can be named
at the moment the deadline passes.
é    )ÚannotationsN)ÚPath)ÚDictÚListÚTuplez	WAL writezWAL checkpointzWAL recoverzshm dead-man switch)éx   éy   éz   é€   i   @ÚPENDINGé   ÚRESERVEDc                óÔ   — | dk(  r9|t         v r||k(  r	t         |   S d|cxk  rdk  rn n||k(  rd|dz
  › �S d|› d|› �S ||k(  r|t        v r	t        |   S |t        dz   k(  ryd	|› d|› �S )
Nú-shmé{   é   zWAL read slot z
shm bytes Ú-é   zSHARED rangez	db bytes )Ú_SHM_LOCK_NAMESÚ_MAIN_LOCK_NAMESÚ_PENDING_BYTE)ÚsidecarÚstartÚends      ú</home/ubuntu/.hermes/hermes-agent/hermes_state_lockowners.pyÚ_describe_ranger   #   s—   € Ø�&ÒØ”OÑ#¨¨uªÜ" 5Ñ)Ð)Ø�%Ô˜3Õ 3¨%¢<Ø# E¨C¡K =Ð1Ð1Ø˜E˜7 ! C 5Ð)Ð)Ø�‚|˜Ô!1Ñ1Ü Ñ&Ð&Ø” Ñ!Ò!ØØ�u�g˜Q˜s˜eÐ$Ð$ó    c           	     ó  — g }| j                  «       D ]å  }|j                  «       }t        |«      dk  s|d   dk(  rŒ*|dd \  }}}}}	}
}}|dk7  rŒ>	 |
j                  d«      \  }}}t        j                  t        |d«      t        |d«      «      }|t        |«      f}t        |	«      }t        |«      }|dk(  r|n
t        |«      }|j                  |«      }|€ŒÇ|j                  |t        |||«      |f«       Œç |S # t        $ r Y Œõw xY w)	a?  ``(pid, lock kind, sidecar)`` for every WRITE lock on one of ``inodes``.

    ``inodes`` maps ``(st_dev, st_ino)`` to ``""`` (main file), ``"-wal"`` or ``"-shm"``. Read locks
    are dropped: they never block a writer in WAL mode. An OFD lock is reported with pid ``-1``
    (the kernel does not export its owner).
    é   r   z->NÚWRITEú:é   ÚEOF)
Ú
splitlinesÚsplitÚlenÚosÚmakedevÚintÚ
ValueErrorÚgetÚappendr   )ÚtextÚinodesÚfoundÚlineÚfieldsÚ_Ú_kindÚ_clsÚaccessÚpid_sÚidentÚstart_sÚend_sÚmajor_sÚminor_sÚino_sÚdevÚkeyÚpidr   r   r   s                         r   Úparse_proc_locksr@   1   s#  € ð )+€EØ—‘Ó!ò KˆØ—‘“ˆäˆv‹;˜Š?˜f Q™i¨4Ò/ØØ?EÀbÀq¸zÑ<ˆˆ5�$˜  u¨g°uØ�WÒØð	Ø&+§k¡k°#Ó&6Ñ#ˆG�W˜eÜ—*‘*œS ¨"Ó-¬s°7¸BÓ/?Ó@ˆCØœ˜E›
Ð#ˆCÜ�e“*ˆCÜ˜“LˆEØ  Eš>‘%¬s°5«zˆCð —*‘*˜S“/ˆØˆ?ØØ�‰�cœ?¨7°E¸3Ó?ÀÐIÕJð)Kð* €Løô ò 	Ùð	ús   ÁA4C=Ã=	D	ÄD	c                ó„  — t         j                  j                  d«      sg S t        j                  j                  t        j                  | «      «      }i }dD ]6  }	 t        j                  ||z   «      }|||j                  |j                  f<   Œ8 	 t        ddd¬«      5 }|j                  «       }ddd«       dd	lm} g }t        |«      D ]D  \  }	}
}|	dkD  r ||	«      nd
}|j!                  |› d|
› dt#        ||z   «      j$                  › �«       ŒF |S # t        $ r Y ŒÉw xY w# 1 sw Y   ŒuxY w# t        $ r g cY S w xY w)z¤Operator-facing lines naming the processes that hold a write-class lock on ``db_path``.

    Empty when nothing is held or the platform has no ``/proc/locks``.
    Úlinux)Ú z-walr   z/proc/locksÚasciiÚreplace)ÚencodingÚerrorsNr   )Údescribe_holder_pidz.OFD lock, owner pid not exported by the kernelz holds z	 lock on )ÚsysÚplatformÚ
startswithr'   ÚpathÚrealpathÚfspathÚstatÚOSErrorÚst_devÚst_inoÚopenÚreadÚhermes_state_holdersrH   r@   r,   r   Úname)Údb_pathÚbaser.   r   ÚstÚhandler-   rH   Úlinesr?   ÚkindÚwhos               r   Ústate_db_write_lock_holdersr^   Q   sG  € ô
 �<‰<×"Ñ" 7Ô+Øˆ	Ü�7‰7×ÑœBŸI™I gÓ.Ó/€DØ)+€FØ'ò 1ˆð	Ü—‘˜ ™Ó(ˆBð *1ˆ�—	‘	˜2Ÿ9™9Ð%Ò&ð1ðÜ�-¨'¸)ÔDð 	!ÈØ—;‘;“=ˆD÷	!õ 9à€EÜ.¨t°VÓ<ò PÑˆˆT�7Ø*-°ª'Ñ! #Ô&Ð7gˆØ�‰˜�u˜G D 6¨´4¸¸w¹Ó3G×3LÑ3LÐ2MÐNÕOðPð €Løô ò 	Ùð	ú÷	!ð 	!ûäò ØŠ	ðús<   ÁDÂD1 Â D%Â1D1 Ä	D"Ä!D"Ä%D.Ä*D1 Ä1D?Ä>D?c                óœ   — t        | «      }|rdj                  |«      }nd}t        j                  d|t	        | «      j
                  |«       y)zQOne WARNING naming the write-lock holders at the moment a writer gave up waiting.z | zMno write-class lock held at the deadline (the holder released just before it)z2state.db write lock unavailable for %.0fs (%s): %sN)r^   ÚjoinÚloggerÚwarningr   rV   )rW   Ú
patience_sÚholdersÚdetails       r   Úlog_write_lock_holdersrf   n   sB   € ä)¨'Ó2€GÙØ—‘˜GÓ$‰à`ˆÜ
‡N�NØ<¸jÌ$ÈwË-×J\ÑJ\Ð^dõr   )r   Ústrr   r)   r   r)   Úreturnrg   )r-   rg   r.   zDict[Tuple[int, int], str]rh   zList[Tuple[int, str, str]])rh   z	List[str])rc   Úfloatrh   ÚNone)Ú__doc__Ú
__future__r   Úloggingr'   rI   Úpathlibr   Útypingr   r   r   Ú	getLoggerÚ__name__ra   r   r   r   r   r@   r^   rf   © r   r   ú<module>rs      s{   ðñõ #ã Û 	Û 
Ý ß $Ñ $à	ˆ×	Ñ	˜8Ó	$€ð 
Ø	Ø	Ø	ñ	€ð €à�9Ø�AÑ�zðÐ ó%óó@ô:	r   