
    ia                        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	 ddl
mZ  G d de      Z G d	 d
      Zeddd       Zg dZy)uC  auto_merge_lock.py — FileLock helper for the auto-merge controller.

Goal: serialize concurrent runs of the auto-merge controller so the bot only
ever processes one PR at a time. Two layers exist:

1. Process-local advisory lock via ``fcntl.flock`` on a file under
   ``memory/cache/auto_merge_controller.lock``.
2. GitHub Actions ``concurrency`` group (defined in the workflow file).

The lock is intentionally narrow: it protects the merge "critical section"
inside ``auto_merge_controller.process_open_prs`` and is released on context
exit (success, exception, or timeout).
    )annotationsN)contextmanager)Path)Iteratorc                      e Zd ZdZy)LockTimeoutz;Raised when the lock cannot be acquired within the timeout.N)__name__
__module____qualname____doc__     H/home/jay/workspace/.worktrees/task-2444-dev2/scripts/auto_merge_lock.pyr   r      s    Er   r   c                  :    e Zd ZdZdd	dZd
dZd
dZddZd
dZy)FileLockzCross-process advisory lock backed by ``fcntl.flock``.

    Usage::

        with FileLock(Path("memory/cache/auto_merge_controller.lock"), timeout=10):
            critical_section()
    c                r    t        |      | _        t        |      | _        t        |      | _        d | _        y N)r   pathfloattimeoutpoll_interval_fd)selfr   r   r   s       r   __init__zFileLock.__init__'   s,    J	W~"=1#r   c                   | j                   j                  j                  dd       t        j                  t        | j                         t        j                  t        j                  z  d      | _        t        j                         | j                  z   }	 	 t        j                  | j                  t        j                  t        j                  z         t        j                   | j                  d       t        j"                          dt        j                          dj%                  d      }t        j&                  | j                  |       y # t(        $ r t        j                         |k\  rLt        j*                  | j                         d | _        t-        d| j                    d| j                   d	      t        j.                  | j0                         Y nw xY wO)
NT)parentsexist_oki  r   
zutf-8zcould not acquire z within s)r   parentmkdirosopenstrO_RDWRO_CREATr   time	monotonicr   fcntlflockLOCK_EXLOCK_NB	ftruncategetpidencodewriteBlockingIOErrorcloser   sleepr   )r   deadlinepayloads      r   acquirezFileLock.acquire-   sI   		td;773tyy>299rzz+A5I>>#dll2/DHHemmemm&CDTXXq)YY[MDIIK=;BB7K7+" />>#x/HHTXX&#DH%,TYYKx~QO  

4--./ s   B:E BG"!G"c                   | j                   y 	 t        j                  | j                   t        j                         t	        j
                  | j                          d | _         y # t	        j
                  | j                          d | _         w xY wr   )r   r)   r*   LOCK_UNr"   r2   r   s    r   releasezFileLock.releaseA   s\    88	KK%--0HHTXXDH HHTXXDHs   .A$ $(Bc                &    | j                          | S r   )r6   r9   s    r   	__enter__zFileLock.__enter__J   s    r   c                $    | j                          y r   )r:   )r   exc_typeexc_valexc_tbs       r   __exit__zFileLock.__exit__N   s    r   N)      $@g?)r   r   r   r   r   r   )returnNone)rC   z
'FileLock')	r	   r
   r   r   r   r6   r:   r<   rA   r   r   r   r   r      s     $/(r   r   c              #     K   t        | |      }|j                          	 | |j                          y# |j                          w xY ww)z8Convenience context manager: ``with lock_path(p): ...``.)r   N)r   r6   r:   )r   r   locks      r   	lock_pathrG   R   s9      D'*DLLN
s   A6 AAA)r   r   rG   )rB   )r   r   r   r   rC   zIterator[FileLock])r   
__future__r   r)   r"   r'   
contextlibr   pathlibr   typingr   RuntimeErrorr   r   rG   __all__r   r   r   <module>rN      sU    #  	  %  F, F1 1h   3r   