+
    jHàjÏ  ã                  ón   € R t ^ RIHt ^ RIt^ RIt^ RIHt ^ RIHtH	t	H
t
 RtRt ! R R4      tR	 R
 ltR# )a  Wake the restart-safe cron delivery drain when a worker writes the queue (#117307).

A restart-safe worker runs its job outside the gateway, queues the final send in
``cron/deliveries.db`` and polls that row once a second; the gateway drained the
queue only on its housekeeping tick, so a turn that ended in 8 s reached the user
a minute later. Between ticks the housekeeping thread now stats the queue file
(and its WAL) and drains as soon as either changed. The tick's own drain stays
as the fallback for anything the stat cannot see.
)ÚannotationsN)ÚPath)ÚCallableÚIterableÚOptionalg      ð?z!Cron durable delivery queue drainc                  óJ   € ] tR t^tRtR R ltR R ltR R ltR R	 ltR
t	R# )ÚDeliveryQueueWatcha3  Stamp-compare every served profile's queue file; ``drain`` when a stamp moved.

The watch never resets itself after draining: the drain's own status writes
move the stamp once more and cost one empty pass, after which the stamp is
stable, while a worker that enqueued during the drain still moves it again.
c               ó$   € V ^8„  d   QhRRRRRR/# )é   Úhomesz&Callable[[], Iterable[Optional[Path]]]ÚdrainzCallable[[], None]ÚreturnÚNone© )Úformats   "ÚE/home/ubuntu/.hermes/hermes-agent/gateway/run_delivery_queue_watch.pyÚ__annotate__ÚDeliveryQueueWatch.__annotate__   s$   € ÷ #ñ #ÐDð #ÐM_ð #Ðdhñ #ó    c                	ór   € Wn         W n        \        V! 4       4      V n        V P	                  4       V n        R # )N)Ú_homesr   ÚlistÚ_servedÚ_stampÚ_seen)Úselfr   r   s   &&&r   Ú__init__ÚDeliveryQueueWatch.__init__   s&   € ØŒØŒ
Ü!¡%£'›]ˆŒØ—[‘[“]ˆŽ
r   c               ó   € V ^8„  d   QhRR/# )r
   r   r   r   )r   s   "r   r   r   %   s   € ÷ +ñ +˜tñ +r   c                óB   € \        V P                  4       4      V n        R# )z¦Re-resolve the served profiles once per tick (a directory read under multiplex),
not on every poll; a profile that appears mid-interval is drained by the tick itself.N)r   r   r   )r   s   &r   Úrefresh_homesÚ DeliveryQueueWatch.refresh_homes%   s   € ô ˜DŸK™K›MÓ*ˆŽr   c               ó   € V ^8„  d   QhRR/# )r
   r   Útupler   )r   s   "r   r   r   *   s   € ÷ ñ ˜ñ r   c                	óf  € ^ RI Hp . pV P                   F}  pV! V4      pWDP                  VP                  R,           4      3 FK  p \
        P                  ! V4      pTP                  \        T4      TP                  TP                  34       KM  	  K  	  \        V4      #   \         d     Kl  i ; i)é    )Ú
queue_pathz-wal)Úcron.delivery_queuer&   r   Ú	with_nameÚnameÚosÚstatÚOSErrorÚappendÚstrÚst_mtime_nsÚst_sizer#   )r   r&   ÚstampsÚhomeÚpathÚ	candidateÚinfos   &      r   r   ÚDeliveryQueueWatch._stamp*   s˜   € Ý2àˆØ—L”LˆDÙ˜dÓ#ˆDØ"§N¡N°4·9±9¸vÕ3EÓ$FÓG�	ðÜŸ7š7 9Ó-�Dð —‘œs 9›~¨t×/?Ñ/?ÀÇÁÐNÖOó Hñ !ô �V‹}Ðøô ô Úðús   ÁB!Â!B0Â/B0c               ó   € V ^8„  d   QhRR/# )r
   r   Úboolr   )r   s   "r   r   r   8   s   € ÷ ñ ˜ñ r   c                	óV   € V P                  4       pWP                  8X  d   R # Wn        R# )FT)r   r   )r   Úcurrents   & r   ÚchangedÚDeliveryQueueWatch.changed8   s"   € Ø—+‘+“-ˆØ—j‘jÔ ÙØŒ
Ùr   )r   r   r   r   N)
Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   r    r   r;   Ú__static_attributes__r   r   r   r   r      s    † ñõ#õ+õ
÷ñ r   r   c               ó$   € V ^8„  d   QhRRRRRR/# )r
   ÚintervalÚfloatÚwatchzOptional[DeliveryQueueWatch]r   r   r   )r   s   "r   r   r   @   s#   € ÷ ñ ¨Uð Ð;Wð Ðcgñ r   c                ó¾  € Vf   V P                  VR7       R# VP                  4        \        P                  ! 4       V,           p \	        RV\        P                  ! 4       ,
          4      pV P                  \        V\        4      R7      '       d   R# VP                  4       '       d   V! \        VP                  4       \        P                  ! 4       V8¼  g   K˜  R# )zQSleep one housekeeping interval, draining the worker queue the moment it changes.N)Útimeoutg        )
Úwaitr    ÚtimeÚ	monotonicÚmaxÚminÚDELIVERY_QUEUE_WATCH_SECONDSr;   ÚDRAIN_LABELr   )Ú
stop_eventrD   rF   ÚchoreÚdeadlineÚ	remainings   &&&&  r   Úwait_for_next_tickrT   @   s—   € à‚}Ø�‰ ˆÔ)ÙØ	×ÑÔÜ�~Š~Ó (Õ*€HØ
Ü˜˜X¬¯ªÓ(8Õ8Ó9ˆ	Ø�?‰?¤3 yÔ2NÓ#Oˆ?×PÒPÙØ�=‰=�?Š?Ù”+˜uŸ{™{Ô+Ü�>Š>Ó˜xÖ'Ùr   )rA   Ú
__future__r   r*   rJ   Úpathlibr   Útypingr   r   r   rN   rO   r   rT   r   r   r   Ú<module>rX      s;   ðñõ #ã 	Û Ý ß /Ñ /ð  #Ð Ø1€÷&ñ &÷Rr   