+
    ˆx)j}  ã                   óâ   € R t ^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIHt ^ RIH	t	 ]	! ]
4      P                  4       P                  P                  R,          tR R ltR R	 lt]RR
 R ll4       tR# )u¨  
Garantiza que solo una instancia de un script corra a la vez.

ImplementaciÃ³n basada en fcntl.flock (lock advisory del kernel Linux):
  - Si el proceso que tiene el lock muere por cualquier motivo (crash,
    excepciÃ³n no capturada, kill -9, reboot), el kernel libera el lock
    automÃ¡ticamente al cerrar el file descriptor. NO quedan locks
    huÃ©rfanos que bloqueen ejecuciones futuras.
  - Si una segunda instancia intenta arrancar mientras la primera estÃ¡
    viva, sale inmediatamente sin tocar nada.

Uso tÃ­pico:

    from helpers.singleton import single_instance

    if __name__ == "__main__":
        with single_instance("procesar_output"):
            main()

Para inspeccionar a mano quÃ© scripts estÃ¡n corriendo:

    ls -la .locks/
    cat  .locks/procesar_output.lock     # muestra PID + hora de inicio

Para ver el proceso vivo:

    ps -p $(awk -F= '{print $2}' .locks/procesar_output.lock | awk '{print $1}')
N)Úcontextmanager)Údatetime)ÚPathz.locksc                ó   € V ^8„  d   QhRR/# )é   ÚreturnN© )Úformats   "Ú6/home/tomasb/Code/central_edictos/helpers/singleton.pyÚ__annotate__r   +   s   € ÷ 0ñ 0˜$ñ 0ó    c                  ó4   € \         P                  R R R7       R# )T)ÚparentsÚexist_okN)ÚLOCK_DIRÚmkdirr   r   r
   Ú_ensure_lock_dirr   +   s   € Ü‡N�N˜4¨$€NÖ/r   c                ó0   € V ^8„  d   QhR\         R\        /# )r   Ú	lock_pathr   )r   Ústr)r	   s   "r
   r   r   /   s   € ÷ #ñ #œtð #¬ñ #r   c                 óh   €  V P                  R R7      P                  4       #   \         d     R# i ; i)zutf-8)Úencodingz(no se pudo leer))Ú	read_textÚstripÚ	Exception)r   s   &r
   Ú_read_lock_infor   /   s6   € ð#Ø×"Ñ"¨GÐ"Ó4×:Ñ:Ó<Ð<øÜô #Ú"ð#ús   ‚" ¢1°1c                ó0   € V ^8„  d   QhR\         R\        /# )r   ÚnameÚexit_if_running)r   Úbool)r	   s   "r
   r   r   7   s   € ÷ 3:ñ 3:œ#ð 3:´ñ 3:r   c              #  ó¤  "  € \        4        \        V  R2,          p\        VR4      p \        P                  ! VP                  4       \        P                  \        P                  ,          4       TP!                  ^ 4       TP#                  4        TP%                  R\&        P(                  ! 4        R	\*        P,                  ! 4       P/                  R
R7       R\1        \        P2                  ^ ,          4      P4                   R24       TP7                  4        \8        P8                  ! 4       p Rx € \8        P8                  ! 4       T,
          p \        P                  ! TP                  4       \        P:                  4       TP                  4         TP=                  4        \        RT  RTR R24       R#   \         dm    \        T4      pRT  RT RT R2pTP                  4        T'       d2   \        T\        P                  R7       \        P                  ! ^ 4       \        T4      hi ; i  \>         d     Lœi ; i  TP                  4         TP=                  4        i   \>         d     i i ; i; i  \8        P8                  ! 4       T,
          p \        P                  ! TP                  4       \        P:                  4       TP                  4         TP=                  4        MH  \>         d     M;i ; i  TP                  4         TP=                  4        i   \>         d     i i ; i; i\        RT  RTR R24       i ; i5i)zÏ
Adquiere un lock exclusivo identificado por `name`.

Si ya hay otra instancia corriendo:
  - exit_if_running=True (default): imprime mensaje y hace sys.exit(0)
  - exit_if_running=False: lanza RuntimeError
z.lockza+Ú[z(] Ya hay una instancia corriendo. Lock: z	 | Info: z. Saliendo.)Úfilezpid=z	 started=Úseconds)Útimespecz script=Ú
Nz] lock liberado (z.1fzs)) r   r   ÚopenÚfcntlÚflockÚfilenoÚLOCK_EXÚLOCK_NBÚBlockingIOErrorr   ÚcloseÚprintÚsysÚstderrÚexitÚRuntimeErrorÚseekÚtruncateÚwriteÚosÚgetpidr   ÚnowÚ	isoformatr   Úargvr   ÚflushÚtimeÚLOCK_UNÚunlinkÚFileNotFoundError)r   r   r   ÚfpÚinfoÚmsgÚstartedÚelapseds   &&      r
   Úsingle_instancerE   6   sœ  é € ô ÔÜ˜d˜V 5˜>Õ)€Iô 
ˆi˜Ó	€Bð Ü�Š�B—I‘I“K¤§¡´·±Õ!>Ô?ð ‡G�GˆA„JØ‡K�K„MØ‡H�HØ
Œr�yŠy‹{ˆmð Ü—<’<“>×+Ñ+°YÐ+Ó?Ð@ð AÜ”s—x‘x •{Ó#×(Ñ(Ð)¨ð	-ôð
 ‡H�H„Jä�iŠi‹k€Gð:Ûä—)’)“+ Õ'ˆð	Ü�KŠK˜Ÿ	™	›¤U§]¡]Ô3à�H‰HŒJðØ× Ñ Ô"ô 	��$�Ð(¨°¨°RÐ8Ö9øôG ô 
 Ü˜yÓ)ˆà�ˆvð Ø�K˜y¨¨¨kð;ð 	ð 	�‰Œ
ßÜ�#œCŸJ™JÕ'Ü�HŠH�QŒKÜ˜3ÓÐð
 ûôB %ô Ùðûð �H‰HŒJðØ× Ñ Õ"øÜ$ô Ùðþô —)’)“+ Õ'ˆð	Ü�KŠK˜Ÿ	™	›¤U§]¡]Ô3à�H‰HŒJðØ× Ñ Õ"øÜ$ô Ùðûð �H‰HŒJðØ× Ñ Õ"øÜ$ô Ùðýä��$�Ð(¨°¨°RÐ8Õ9üs÷   ‚'MªAF< Á2B?MÄ2I> Ä6MÅ3I ÆMÆH6 Æ'MÆ<A7H3È3MÈ6IÉMÉIÉMÉI;ÉI*É)I;É*I8É5I;É7I8É8I;É;MÉ>MÊ3LËMË K1Ë0MË1K?Ë<MË>K?Ë?MÌL6ÌL%Ì$L6Ì%L3Ì0L6Ì2L3Ì3L6Ì6MÍM)T)Ú__doc__r'   r6   r/   r<   Ú
contextlibr   r   Úpathlibr   Ú__file__ÚresolveÚparentr   r   r   rE   r   r   r
   Ú<module>rL      sd   ðñó: Û 	Û 
Û Ý %Ý Ý ñ �‹>×!Ñ!Ó#×*Ñ*×1Ñ1°HÕ<€õ0õ#ð ö3:ó ò3:r   