o
    ikE                     @  sB  U d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZd dlZd dlmZmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlZdd	lmZ dd
lmZ ddlmZmZm Z  ddl!m"Z" ddl#m$Z$m%Z% ddl&m'Z' d a(ej)a*de+d< ej,dddZ-eG dd dZ.G dd deZ/dS )    )annotationsN)ABCabstractmethod)	Generator)	dataclass)BaseContext)Any   logger)metrics)aiolog_exceptionstime_ms)duplex_unix   )channelproto)LogQueueListenerzsignal.Handlers_mask_ctrl_c_originalreturnGenerator[None, None, None]c                
   c  s    t  t  urdV  dS tdkrttjtjatd7 azdV  W td8 atdkr4ttjt dS dS td8 atdkrFttjt w w )u1  Temporarily ignore SIGINT so forked/spawned children inherit SIG_IGN.

    Unlike pthread_sigmask (per-thread), signal.signal is process-wide and
    SIG_IGN is preserved across exec() per POSIX — so children start with
    SIGINT ignored regardless of which thread performs the fork.

    Uses refcounting so concurrent async callers (e.g. proc pool warming
    multiple processes) don't clobber each other's saved handler.

    signal.signal() can only be called from the main thread.
    Keep the critical section *tiny* (just around Process.start()).
    Nr   r   )	threadingcurrent_threadmain_thread_mask_ctrl_c_refcountsignalSIGINTSIG_IGNr    r   r   d/var/www/html/livekit_bhavya/venv/lib/python3.10/site-packages/livekit/agents/ipc/supervised_proc.py_mask_ctrl_c    s"   r!   c                   @  sN   e Zd ZU ded< ded< ded< ded< ded< ded< ded< d	ed
< dS )	_ProcOptsfloatinitialize_timeoutclose_timeoutmemory_warn_mbmemory_limit_mbping_intervalping_timeouthigh_ping_threshold
str | None
http_proxyN)__name__
__module____qualname____annotations__r   r   r   r    r"   ?   s   
 r"   c                   @  s"  e Zd ZdIddZedJddZedKddZedLddZedMd!d"Z	edLd#d$Z
edMd%d&ZedLd'd(ZdNd)d*ZdNd+d,ZdNd-d.ZdNd/d0ZdNd1d2ZdNd3d4ZdNd5d6ZdNd7d8Zeed9dNd:d;Zeed9dOd?d@Zeed9dPdAdBZeed9dNdCdDZdQdFdGZdHS )RSupervisedProcr$   r#   r%   r&   r'   r(   r)   r*   r,   r+   mp_ctxr   loopasyncio.AbstractEventLoopr   Nonec       
      
   C  s`   |
| _ |	| _t||||||||d| _d | _d | _d | _d| _d| _t	j
d   | _t	 | _d S )N)r$   r%   r&   r'   r(   r)   r*   r,   F)_loop_mp_ctxr"   _opts	_exitcode_pid_supervise_atask_closing
_kill_sentasyncioFuture_initialize_futLock_lock)selfr$   r%   r&   r'   r(   r)   r*   r,   r2   r3   r   r   r    __init__L   s&   zSupervisedProc.__init__cchsocket.socketlog_cch
mp.Processc                 C  s   d S Nr   )rC   rE   rG   r   r   r    _create_processp   s   zSupervisedProc._create_processipc_ch!aio.ChanReceiver[channel.Message]c                   s   d S rI   r   )rC   rK   r   r   r    
_main_tasks   s   zSupervisedProc._main_taskboolc                 C  s   t dd dvS )NLK_DUMP_STACK_TRACES0)rP   falseno)osgetenvlowerrC   r   r   r    enabled_stack_trace_dumpv   s   z'SupervisedProc.enabled_stack_trace_dump
int | Nonec                 C     | j S rI   )r9   rV   r   r   r    exitcodez      zSupervisedProc.exitcodec                 C  rY   rI   )r=   rV   r   r   r    killed~   r[   zSupervisedProc.killedc                 C  rY   rI   )r:   rV   r   r   r    pid   r[   zSupervisedProc.pidc                 C  s
   | j d uS rI   )r;   rV   r   r   r    started   s   
zSupervisedProc.startedc                   s6   | j rtd| jrtdt|  I dH  dS )zstart the supervised processzprocess already startedzprocess is closedN)r^   RuntimeErrorr<   r>   shield_startrV   r   r   r    start   s   zSupervisedProc.startc                   s  dfdd}j 4 I d H  t \}}t \}}||||f}zAtj|I d H _tj|}t||  	  
||_t  jd jj	I d H  W d    n1 s]w   Y  W n& ty   |D ]}tt |  W d    n1 sw   Y  ql w |  |  jj_tjd   _d fdd}	tj|	d	d
}
|
	  t _W d   I d H  d S 1 I d H sw   Y  d S )Nrecordlogging.LogRecordr   r5   c                   s*      }| D ]
\}}t| || qd S rI   )logging_extraitemssetattr)rc   extrakeyvaluerV   r   r    _add_proc_ctx_log   s   z0SupervisedProc._start.<locals>._add_proc_ctx_logc                     s@   j      zjjjd  W d S  ty   Y d S w rI   )_procjoinstopr6   call_soon_threadsafe	_join_fut
set_resultr_   r   log_listenerrC   r   r    	_sync_run   s   
z(SupervisedProc._start.<locals>._sync_runproc_join_thread)targetname)rc   rd   r   r5   r   r5   )rB   socket
socketpairr   _AsyncDuplexopen_pch_Duplexr   rb   rJ   rl   r!   r6   run_in_executor	Exception
contextlibsuppressOSErrorcloser]   r:   r>   r?   rp   r   Threadcreate_task_supervise_taskr;   )rC   rk   mp_pchmp_cch
mp_log_pch
mp_log_cchsocketslog_pchsrt   threadr   rr   r    ra      sB   


.zSupervisedProc._startc                   s0   | j std| jrt| jI dH  dS dS )zwait for the process to finishprocess not startedN)r^   r_   r;   r>   r`   rV   r   r   r    rm      s   zSupervisedProc.joinc              
     s\  t | jtj| j | jj| jj	| jj
| jjpddI dH  z[tjd|  d t }tjt | jtj| jjdI dH }t|tjsJJ d|jrUtd|j | jd t | }tj|d	 tjd
i |  dt|did W dS  tjy   | j td | ! I dH  | " I dH    t#y } z| j |  d}~ww )zinitialize the process, this is sending a InitializeRequest message and waiting for a
        InitializeResponse with a timeout )asyncio_debugr(   r)   r*   r,   Nzinitializing processrh   timeoutz(first message must be InitializeResponsezprocess initialization failed: )time_elapsedzprocess initializedelapsed_timer	   z process initialization timed out)$r   asend_messager}   r   InitializeRequestr6   	get_debugr8   r(   r)   r*   r,   r   infore   timeperf_counterr>   wait_forarecv_messageIPC_MESSAGESr$   
isinstanceInitializeResponseerrorr_   r@   rq   r   proc_initializedroundTimeoutErrorset_exception_send_dump_signal_send_kill_signalr   )rC   
start_timeinit_resr   er   r   r    
initialize   sT   

zSupervisedProc.initializec              	     s2  | j sdS d| _ttj t| jt	
 I dH  W d   n1 s&w   Y  z| jr?tjt| j| jjdI dH  W n! tjya   tjd|  d |  I dH  |  I dH  Y nw | j4 I dH # | jrt| jI dH  W d  I dH  dS W d  I dH  dS 1 I dH sw   Y  dS )z2attempt to gracefully close the supervised processNTr   z-process did not exit in time, killing processr   )r^   r<   r   r   r   DuplexClosedr   r   r}   r   ShutdownRequestr;   r>   r   r`   r8   r%   r   r   r   re   r   r   rB   rV   r   r   r    aclose   s6   .zSupervisedProc.aclosec              	     s   | j stdd| _|  I dH  |  I dH  | j4 I dH # | jr8t| jI dH  W d  I dH  dS W d  I dH  dS 1 I dH sIw   Y  dS )z&forcefully kill the supervised processr   TN)	r^   r_   r<   r   r   rB   r;   r>   r`   rV   r   r   r    kill  s   .zSupervisedProc.killc                   sp   | j sd S ttdrd S z tjd|  d t| jt	
 I d H  tdI d H  W d S  ty7   Y d S w )NSIGUSR1z0sending DumpStackTraceRequest message to processr         ?)rW   hasattrr   r   r   re   r   r   r}   r   DumpStackTraceRequestr>   sleepr   rV   r   r   r    r   &  s   
z SupervisedProc._send_dump_signalc                   s   z
| j  s
W dS W n
 ty   Y dS w tjd|  d tjdkr:z| j  r/| j   W nJ ty9   Y nBw t	t
dreztjd|  d t| j jt
j tdI dH  W n	 tyd   Y nw z| j  rp| j   W n	 tyz   Y nw d| _dS )	zforcefully kill the processNzkilling processr   win32r   z!sending SIGUSR1 signal to processr   T)rl   is_alive
ValueErrorr   r   re   sysplatform	terminater   r   rS   r   r]   r   r>   r   r   r=   rV   r   r   r    r   8  sB   







z SupervisedProc._send_kill_signalr
   c                   s  z| j I d H  W n tjy   Y n	 ty   Y nw t| jj}tjt	j
   t|  }t|  |}t| |}| fdd d }| jjdksZ| jjdkrat|  }| jI d H  | jj| _| j  t|||I d H  |d urt|I d H  ttj | j I d H  W d    n1 sw   Y  | jdkr| jst j!d| j | " d d S d S d S )Nc                   s      S rI   )r   )_rK   r   r    <lambda>h  s    z0SupervisedProc._supervise_task.<locals>.<lambda>r   z'process exited with non-zero exit code r   )#r@   r>   r   r   r   r   r8   r)   Chanr   Messager   rM   _read_ipc_task_ping_pong_taskadd_done_callbackr'   r&   _memory_monitor_taskrp   rl   rZ   r9   r   cancel_and_waitr   r   r   r   r}   r   r=   r   r   re   )rC   pong_timeout	main_taskread_ipc_task	ping_taskmemory_monitor_taskr   r   r    r   W  s@   



zSupervisedProc._supervise_taskaio.Chan[channel.Message]r   	aio.Sleepc                   s   	 zt | jtjI d H }W n tjy   Y d S w t|tjrVt	 |j
 }|| jjd kr<tjdd|i|  d ttj |  W d    n1 sQw   Y  t|tjrjtjdd|ji|  d || q)NTi  zprocess is unresponsivedelayr   zprocess exitingreason)r   r   r}   r   r   r   r   r   PongResponser   	timestampr8   r*   r   warningre   r   r   r   SleepFinishedresetExitingr   r   send_nowait)rC   rK   r   msgr   r   r   r    r     s0   

zSupervisedProc._read_ipc_taskc                   s   t jj ttdd fdd}ttddfdd}t| t| g}ztj| I d H  W t j	| I d H  d S t j	| I d H  w )	Nr
   r   r5   c                     sN   	    I d H  ztjtjt dI d H  W n tjy%   Y d S w q)NT)r   )	tickr   r   r}   r   PingRequestr   r   r   r   )r(   rC   r   r    _send_ping_co  s   "z5SupervisedProc._ping_pong_task.<locals>._send_ping_coc                     s>    I d H  t jd d  I d H   I d H  d S )Nz(process is unresponsive, killing processr   )r   r   re   r   r   r   )r   rC   r   r    _pong_timeout_co  s
   
z8SupervisedProc._ping_pong_task.<locals>._pong_timeout_corx   )
r   intervalr8   r(   r   r   r>   r   gatherr   )rC   r   r   r   tasksr   )r(   r   rC   r    r     s   &zSupervisedProc._ping_pong_taskc              
     s  | j s| jszh| jstdI dH  W qt| j}| }|jd }| j	j
dkrO|| j	j
krOtjd|| j	j
d|  d |  I dH  |  I dH  n| j	jdkrn|| j	jkrntjd|| j	j| j	j
d	|  d W nH tjtjfy } z| j s| jrW Y d}~dS tjd
|  |d W Y d}~dS d}~w ty   | j s| jrY dS tjd|  d Y nw tdI dH  | j s| jrdS dS dS dS )zBMonitor memory usage and kill the process if it exceeds the limit.   Ni   r   z.process exceeded memory limit, killing process)memory_usage_mbr'   r   zprocess memory usage is high)r   r&   r'   z%Failed to get memory info for process)rh   exc_infozError in memory monitoring task)r<   r=   r:   r>   r   psutilProcessmemory_inforssr8   r'   r   r   re   r   r   r&   r   NoSuchProcessAccessDeniedr   	exception)rC   processr   	memory_mbr   r   r   r    r     sf   


	z#SupervisedProc._memory_monitor_taskdict[str, Any]c                 C  s   d| j i}|S )Nr]   )r]   )rC   rh   r   r   r    re     s   zSupervisedProc.logging_extraN)r$   r#   r%   r#   r&   r#   r'   r#   r(   r#   r)   r#   r*   r#   r,   r+   r2   r   r3   r4   r   r5   )rE   rF   rG   rF   r   rH   )rK   rL   r   r5   )r   rN   )r   rX   rx   )rK   r   r   r   r   r5   )r   r   r   r5   )r   r   )r-   r.   r/   rD   r   rJ   rM   propertyrW   rZ   r\   r]   r^   rb   ra   rm   r   r   r   r   r   r   r   r   r   r   r   re   r   r   r   r    r1   K   sB    
$



2

1


'9r1   )r   r   )0
__future__r   r>   r   loggingmultiprocessingmprS   r   ry   r   r   r   abcr   r   collections.abcr   dataclassesr   multiprocessing.contextr   typingr   r   logr   	telemetryr   utilsr   r   r   	utils.aior   r   r   r   	log_queuer   r   SIG_DFLr   r0   contextmanagerr!   r"   r1   r   r   r   r    <module>   s<    