
    he>                       S r SSKJr  SSKJrJrJrJr  SSKrSSK	r	SSK
Jr  SSKJrJrJr  SSKJrJrJrJr  SSKJr  SS	KJr  SS
KJr  SSKJr  \R<                  " SSS9 " S S5      5       r " S S5      r \ " 5       r! " S S\RD                  5      r# " S S\RH                  5      r% " S S\RL                  5      r'g)zA
Support for starting, monitoring, and restarting child process.
    )annotations)AnyDictListOptionalN)service)errorprotocolreactor)IDelayedCallIProcessTransportIReactorProcessIReactorTime)Logger)basic)	deprecate)FailureT)frozenauto_attribsc                      \ rS rSr% SrS\S'   SrS\S'   SrS\S'   \R                  " \R                  " \5      S	9rS
\S'   SrS\S'   \R                  " \R"                  " SSSS5      5      SS j5       rSrg)_Process   a  
The parameters of a process to be restarted.

@ivar args: command-line arguments (including name of command as first one)
@type args: C{list}

@ivar uid: user-id to run process as, or None (which means inherit uid)
@type uid: C{int}

@ivar gid: group-id to run process as, or None (which means inherit gid)
@type gid: C{int}

@ivar env: environment for process
@type env: C{dict}

@ivar cwd: initial working directory for process or None
           (which means inherit cwd)
@type cwd: C{str}
z	List[str]argsNzOptional[int]uidgid)defaultzDict[str, str]envzOptional[str]cwdTwisted      r   c                ^    U R                   U R                  U R                  U R                  4$ )a  
Convert process to tuple.

Convert process to tuple that looks like the legacy structure
of processes, for potential users who inspected processes
directly.

This was only an accidental feature, and will be removed. If
you need to remember what processes were added to a process monitor,
keep track of that when they are added. The process list
inside the process monitor is no longer a public API.

This allows changing the internal structure of the process list,
when warranted by bug fixes or additional features.
)r   r   r   r   selfs    ]/root/1688_scrapy/alibaba-scraper/venv/lib/python3.13/site-packages/twisted/runner/procmon.pytoTuple_Process.toTuple9   s#    " 		488TXXtxx88     )returnz8tuple[list[str], int | None, int | None, dict[str, str]])__name__
__module____qualname____firstlineno____doc____annotations__r   r   attribFactorydictr   r   r   
deprecatedincrementalVersionr&   __static_attributes__r)   r(   r%   r   r      sw    ( OCC''$,,t*<=C=C+--iQBC9 D9r(   r   c                      \ rS rSrSrSrg)DummyTransportM   r   r)   N)r+   r,   r-   r.   disconnectingr8   r)   r(   r%   r:   r:   M   s    Mr(   r:   c                  X    \ rS rSr% S\S'   S\S'   S\S'   S\S'   S	rS	rS
rS	rSS jr	Sr
g	)
LineLoggerT   strtagstreamProcessMonitorr   bytes	delimiterN   
c                     UR                  S5      nU R                  R                  R                  SU R                  X R                  S9  g ! [         a    [        U5      n NQf = f)Nzutf-8z[{tag}] {line})rA   linerB   )decodeUnicodeDecodeErrorreprr   loginforA   rB   )r$   rH   slines      r%   lineReceivedLineLogger.lineReceiveda   s]    	KK(E 	$(({{ 	 	
 " 	JE	s   A A%$A%r)   )rH   rD   r*   None)r+   r,   r-   r.   r0   rA   rB   rE   r   rO   r8   r)   r(   r%   r>   r>   T   s3    	HK CFIG
r(   r>   c                      \ rS rSr% S\S'   S\S'   SrSrSS jrSS jrSS	 jr	SS
 jr
\SS j5       r\SS j5       rSrg)LoggingProtocoll   rC   r   r@   nameNc                   [        5       U l        U R                  U R                  l        SU R                  l        U R
                  U R                  l        SU l        [        5       U l        U R                  U R                  l        SU R                  l        U R
                  U R                  l        SU l        U R                  R                  [        5        U R                  R                  [        5        g )NstdoutTstderr)r>   _outputrU   rA   rB   r   _outputEmpty_error_errorEmptymakeConnection	transportr#   s    r%   connectionMadeLoggingProtocol.connectionMadeu   s    !|99&#||  l))%"ll##I.""9-r(   c                T    U R                   R                  U5        US   S:H  U l        g NrF   )rY   dataReceivedrZ   r$   datas     r%   outReceivedLoggingProtocol.outReceived   s%    !!$' H-r(   c                T    U R                   R                  U5        US   S:H  U l        g rb   )r[   rd   r\   re   s     r%   errReceivedLoggingProtocol.errReceived   s%      &8u,r(   c                    U R                   (       d  U R                  R                  S5        U R                  (       d  U R                  R                  S5        U R
                  R                  U R                  U5        g )NrF   )rZ   rY   rd   r\   r[   r   _monitoredProcessExitedrU   )r$   reasons     r%   processEndedLoggingProtocol.processEnded   sP      LL%%e,KK$$U+,,TYY?r(   c                    U R                   $ N)rY   r#   s    r%   outputLoggingProtocol.output   s    ||r(   c                    U R                   $ rr   )rZ   r#   s    r%   emptyLoggingProtocol.empty   s       r(   )r[   r\   rY   rZ   r*   rQ   )rf   rD   r*   rQ   )rn   r   r*   rQ   )r*   r>   )r*   bool)r+   r,   r-   r.   r0   r   rU   r_   rg   rj   ro   propertyrs   rv   r8   r)   r(   r%   rS   rS   l   sV    
I GD. .-@   ! !r(   rS   c                     \ rS rSrSrSrSrSrSr\	" 5       r
\4   SS jjr\R                  " \R                   " SSS	S
5      5        SS j5       r\R$                  " \R                   " SSS	S
5      5      SS j5       rSS0 S4             SS jjrSS jrS S jrS S jr\R                  " \R                   " SSSS
5      5      SS j5       rS!S"S jjrSS jrS#S jrSS jrS S jrS$S jrSrg)%rC      a  
ProcessMonitor runs processes, monitors their progress, and restarts them
when they die.

The ProcessMonitor will not attempt to restart a process that appears to
die instantly -- with each "instant" death (less than 1 second, by
default), it will delay approximately twice as long before restarting it.
A successful run will reset the counter.

The primary interface is L{addProcess} and L{removeProcess}.  When the
service is running (that is, when the application it is attached to is
running), adding a process automatically starts it.

Each process has a name.  This name string must uniquely identify the
process.  In particular, attempting to add two processes with the same name
will result in a C{KeyError}.

@type threshold: C{float}
@ivar threshold: How long a process has to live before the death is
    considered instant, in seconds.  The default value is 1 second.

@type killTime: C{float}
@ivar killTime: How long a process being killed has to get its affairs in
    order before it gets killed with an unmaskable signal.  The default
    value is 5 seconds.

@type minRestartDelay: C{float}
@ivar minRestartDelay: The minimum time (in seconds) to wait before
    attempting to restart a process.  Default 1s.

@type maxRestartDelay: C{float}
@ivar maxRestartDelay: The maximum time (in seconds) to wait before
    attempting to restart a process.  Default 3600s (1h).

@type _reactor: L{IReactorProcess} provider
@ivar _reactor: A provider of L{IReactorProcess} and L{IReactorTime} which
    will be used to spawn processes and register delayed calls.

@type log: L{Logger}
@ivar log: The logger used to propagate log messages from spawned
    processes.
      i  c                    Xl         [        U5      U l        0 U l        0 U l        0 U l        0 U l        0 U l        0 U l        g rr   )	_reactorr   _clock
_processes	protocolsdelaytimeStartedmurderrestart)r$   r   s     r%   __init__ProcessMonitor.__init__   s@      "7+/157')
-//102r(   r   r    r!   r   c                    U R                   R                  5        VVs0 s H  u  pXR                  5       _M     snn$ s  snnf )z]
Processes as dict of tuples

@return: Dict of process name to monitored processes as tuples
)r   itemsr&   )r$   rU   processs      r%   	processesProcessMonitor.processes   s8     >B__=R=R=TU=TMDoo''=TUUUs   >c                    [         R                  R                  U 5      nUS	 0 US'   0 US'   0 US'   0 US'   0 US'   US	 U R                  US'   U$ )	Nr   r   r   r   r   r   r   r   )r   Service__getstate__r   )r$   dcts     r%   r   ProcessMonitor.__getstate__   sg    oo**40
OKGMHI>>K
r(   Nc                    XR                   ;   a  [        SU S35      e[        X#XEU5      U R                   U'   U R                  U R                  U'   U R
                  (       a  U R                  U5        gg)a  
Add a new monitored process and start it immediately if the
L{ProcessMonitor} service is running.

Note that args are passed to the system call, not to the shell.  If
running the shell is desired, the common idiom is to use
C{ProcessMonitor.addProcess("name", ['/bin/sh', '-c', shell_script])}

@param name: A name for this process.  This value must be unique across
    all processes added to this monitor.

@param args: The argv sequence for the process to launch.

@param uid: The user ID to use to run the process.  If L{None}, the
    current UID is used.

@param gid: The group ID to use to run the process.  If L{None}, the
    current GID is used.

@param env: The environment to give to the launched process.  See
    L{IReactorProcess.spawnProcess}'s C{env} parameter.

@param cwd: The initial working directory of the launched process.  The
    default of C{None} means inheriting the laucnhing process's working
    directory.

@raise KeyError: If a process with the given name already exists.
zremove z firstN)r   KeyErrorr   minRestartDelayr   runningstartProcess)r$   rU   r   r   r   r   r   s          r%   
addProcessProcessMonitor.addProcess   sh    J ??"WTF&122 (Cc B//

4<<d# r(   c                @    U R                  U5        U R                  U	 g)z
Stop the named process and remove it from the list of monitored
processes.

@param name: A string that uniquely identifies the process.
N)stopProcessr   r$   rU   s     r%   removeProcessProcessMonitor.removeProcess!  s     	OOD!r(   c                    [         R                  R                  U 5        [        U R                  5       H  nU R                  U5        M     g)z 
Start all monitored processes.
N)r   r   startServicelistr   r   r   s     r%   r   ProcessMonitor.startService+  s7     	$$T*)Dd# *r(   c                B   [         R                  R                  U 5        [        U R                  R                  5       5       H,  u  pUR                  5       (       d  M  UR                  5         M.     [        U R                  5       H  nU R                  U5        M     g)zI
Stop all monitored processes and cancel all scheduled process restarts.
N)
r   r   stopServicer   r   r   activecancelr   r   )r$   rU   delayedCalls      r%   r   ProcessMonitor.stopService3  su     	##D) "&dll&8&8&:!;D!!##""$ "< )DT" *r(      c                $    U R                  U5      $ )aV  
Called when a monitored processes exits.  If
L{service.IService.running} is L{True} (ie the service is started), the
process will be restarted.  If the process had been running for more
than L{ProcessMonitor.threshold} seconds it will be restarted
immediately.  If the process had been running for less than
L{ProcessMonitor.threshold} seconds, the restart will be delayed and
each time the process dies before the configured threshold, the restart
delay will be doubled - up to a maximum delay of maxRestartDelay sec.

@param name: A string that uniquely identifies the process which
    exited.
)rm   r   s     r%   connectionLostProcessMonitor.connectionLostA  s     ++D11r(   c                L   UbN  UR                  [        R                  [        R                  5      (       d  U R                  R                  SUUS9  XR                  ;   aL  U R                  U   R                  5       (       a  U R                  U   R                  5         U R                  U	 U R                  U	 U R                  R                  5       U R                  U   -
  U R                  :  aC  U R                  U   n[        U R                  U   S-  U R                   5      U R                  U'   OSnU R"                  U R                  U'   U R$                  (       aD  XR&                  ;   a4  U R                  R)                  X0R*                  U5      U R,                  U'   ggg)a  
Called when a monitored processes exits.  If
L{service.IService.running} is L{True} (ie the service is started), the
process will be restarted.  If the process had been running for more
than L{ProcessMonitor.threshold} seconds it will be restarted
immediately.  If the process had been running for less than
L{ProcessMonitor.threshold} seconds, the restart will be delayed and
each time the process dies before the configured threshold, the restart
delay will be doubled - up to a maximum delay of maxRestartDelay sec.

@param name: A string that uniquely identifies the process which
    exited.

@param reason: The reason why the connection was lost.
Nz(Process '{name}' has exited: {failure!r})failurerU      r   )checkr	   ProcessDoneProcessTerminatedrL   r   r   r   r   r   r   secondsr   	thresholdr   minmaxRestartDelayr   r   r   	callLaterr   r   )r$   rU   rn   	nextDelays       r%   rm   &ProcessMonitor._monitoredProcessExitedR  s[   " fll##'
 '
 HH:   ;;{{4 ''))D!((*D!NN4 ;; 4#3#3D#99DNNJ

4(I"4::d#3a#79M9MNDJJt
 I#33DJJt <<DOO3!%!6!6,,d"DLL 4<r(   c           
        XR                   ;   a  gU R                  U   n[        5       nXl        Xl        X0R                   U'   U R
                  R                  5       U R                  U'    U R                  R                  UUR                  S   UR                  UR                  UR                  UR                  UR                  S9  g! [         a    U R!                  U[#        5       5         gf = f)z4
@param name: The name of the process to be started
Nr   )r   r   r   path)r   r   rS   r   rU   r   r   r   r   spawnProcessr   r   r   r   r   OSErrorrm   r   )r$   rU   r   protos       r%   r   ProcessMonitor.startProcess  s     >>!//$'!
$t!%!4!4!6	:MM&&QKKKKKK[[ '   	:((wy9	:s   ,AC $C21C2c                \     UR                  S5        g ! [        R                   a     g f = f)NKILL)signalProcessr	   ProcessExitedAlready)r$   procs     r%   _forceStopProcess ProcessMonitor._forceStopProcess  s-    	v&)) 		s    ++c                t   XR                   ;  a  [        SU 35      eU R                  R                  US5      nUbb  UR                  nUc   e UR                  S5        U R                  R                  U R                  U R                  U5      U R                  U'   gg! [        R                   a     gf = f)z4
@param name: The name of the process to be stopped
zUnrecognized process name: NTERM)r   r   r   getr^   r   r   r   killTimer   r   r	   r   )r$   rU   r   r   s       r%   r   ProcessMonitor.stopProcess  s     &8?@@""4.??D###""6* %)KK$9$9MM4#9#94%D! 
 -- s   B   B76B7c                L    U R                    H  nU R                  U5        M     g)z
Restart all processes. This is useful for third party management
services to allow a user to restart servers because of an outside change
in circumstances -- for example, a new version of a library is
installed.
N)r   r   r   s     r%   
restartAllProcessMonitor.restartAll  s      OODT" $r(   c                   / nU R                   R                  5        H  u  p#SnUR                  b  [        UR                  5      nUR                  b  US[        UR                  5      -   -  nU(       a  SU-   S-   nUR                  U< U SUR                  < 35        M     SU R                  R                  -   S-   SR                  U5      -   S-   $ )	N :()z: < >)
r   r   r   r@   r   appendr   	__class__r+   join)r$   lstrU   r   uidgids        r%   __repr__ProcessMonitor.__repr__  s    ////1JDFxx#TXXxx##DHH--v+JJ$&DII=9: 2 T^^,,,s2SXXc]BSHHr(   )r   r   r   r   r   r   r   r   )r   r   r*   rQ   )r*   zCdict[str, tuple[list[str], int | None, int | None, dict[str, str]]])r*   r   )rU   r@   r   z	list[str]r   
int | Noner   r   r   zdict[str, str]r   z
str | Noner*   rQ   )rU   r@   r*   rQ   rx   rr   )rU   r@   rn   zFailure | Noner*   rQ   )r   r   r*   rQ   )r*   r@   ) r+   r,   r-   r.   r/   r   r   r   r   r   rL   r   r   r   deprecatedPropertyr6   r7   r   r5   r   r   r   r   r   r   rm   r   r   r   r   r   r8   r)   r(   r%   rC   rC      sf   )V IHOO
(C $,3 3 
3 !!+"5"5iQ"JKV	LV LV +--iQBC
 D
   *$*$ *$ 	*$
 *$ *$ *$ 
*$X"$# !!+"5"5iQ"JK2 L2 2h::(#Ir(   rC   )(r/   
__future__r   typingr   r   r   r   r1   r6   twisted.applicationr   twisted.internetr	   r
   r   r   twisted.internet.interfacesr   r   r   r   twisted.loggerr   twisted.protocolsr   twisted.pythonr   twisted.python.failurer   sr   r:   r^   LineReceiverr>   ProcessProtocolrS   r   rC   r)   r(   r%   <module>r      s   
 # , ,   ' A A  " # $ * t$',9 ,9 (,9^  	
## 
0.!h.. .!bvIW__ vIr(   