
    TfT                         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mZmZ d dlmZmZ  G d de          ZdS )    N)
HaltServerAppImportError)Pidfile)socksystemdutil)__version__SERVER_SOFTWAREc                      e Zd ZdZdZdZi Zg Zi Zg Z	g Z
d d                                D             Z ed  ee          D                       Zd Zd Zd	 Z eee          Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z d Z!d Z"d Z#d Z$d Z%d*dZ&d Z'd+d Z(d! Z)d" Z*d# Z+d$ Z,d% Z-d& Z.d' Z/d( Z0d) Z1dS ),Arbiterz
    Arbiter maintain the workers processes alive. It launches or
    kills them if needed. It also manages application reloading
    via SIGHUP/USR2.
          c                 >    g | ]}t          t          d |z            S )zSIG%s)getattrsignal).0xs     B/var/www/html/env/lib/python3.11/site-packages/gunicorn/arbiter.py
<listcomp>zArbiter.<listcomp>,   s<     O O O vw{++ O O O    z+HUP QUIT INT TERM TTIN TTOU USR1 USR2 WINCHc              #      K   | ]O}|d d         dk    |d         dk    t          t          |          |dd                                          fV  Pd S )Nr   SIG_)r   r   lower)r   names     r   	<genexpr>zArbiter.<genexpr>.   sk        6:8uaC 
		QRR 0 01!/ r   c                    t           t          j        d<   d | _        d | _        d | _        |                     |           d | _        d| _        d| _	        d| _
        d| _        d| _        t          j                    }t          j        d d          }|                    dt          j                   ||t          j        d| _        d S )Nr
   Fr   Master)argscwdr   )r
   osenviron_num_workers _last_logged_active_worker_countlogsetuppidfiler   
worker_age
reexec_pid
master_pidmaster_namer   getcwdsysargvinsert
executable	START_CTX)selfappr    r   s       r   __init__zArbiter.__init__3   s    (7
$% 04-

3#kmmx{As~&&& ~
 
r   c                     | j         S N)r#   r2   s    r   _get_num_workerszArbiter._get_num_workersO   s      r   c                 Z    | j         }|| _         | j                            | ||           d S r6   )r#   cfgnworkers_changed)r2   value	old_values      r   _set_num_workerszArbiter._set_num_workersR   s2    %	!!!$y99999r   c                 2   || _         |j        | _        | j        $| j                            |j                  | _        dt          j        v r| j                                         | j        j        | _        | j        j        | _        | j        j	        | _
        | j        j        | _        | j        j        | _        | j                            d                    d                    d t!          | j        j                                        d           D                                            | j        j        r3| j        j                                        D ]\  }}|t          j        |<   | j        j        r| j                                          d S d S )NGUNICORN_FDzCurrent configuration:
{0}
c              3   R   K   | ]"\  }}d                      ||j                  V  #dS )z
  {0}: {1}N)formatr<   )r   configr<   s      r   r   z Arbiter.setup.<locals>.<genexpr>j   sL       ; ;!FE ##FEK88; ; ; ; ; ;r   c                     | d         S N    )settings    r   <lambda>zArbiter.setup.<locals>.<lambda>n   s
    gaj r   key)r3   r:   r%   logger_classr!   r"   reopen_filesworker_classaddressworkersnum_workerstimeout	proc_namedebugrC   joinsortedsettingsitemsenvpreload_appwsgi)r2   r3   kvs       r   r&   zArbiter.setupX   s~   78x,,SW55DH BJ&&H!!### H1x'8+x'+4;;II ; ; $(+113388: : :; ; ; ; ;< < 	= 	= 	= 8< 	"**,, " "1 !
18 	HMMOOOOO	 	r   c                    | j                             dt                     dt          j        v rGt          t          j                            d                    | _        | j        dz   | _        d| _	        t          j
                    | _        | j        j        O| j        j        }| j        dk    r|dz  }t          |          | _        | j                            | j                   | j                            |            |                                  | j        sd}t'          j                    }|r/d| _        t+          t&          j        t&          j        |z             }n`| j        rYg }t          j                            d                              d	          D ]$}|                    t          |                     %t5          j        | j        | j         |          | _        d	                    d
 | j        D                       }| j                             d           | j                             d|| j                   | j                             d| j        j                   t'          j        d| j                    tA          | j!        d          r%| j!        "                    | j        | j                    | j        #                    |            dS )zS        Initialize the arbiter. Start listening and set pidfile if needed.
        zStarting gunicorn %sGUNICORN_PIDz.2zMaster.2Nr   Tr@   ,c                 ,    g | ]}t          |          S rH   strr   lnrs     r   r   z!Arbiter.start.<locals>.<listcomp>   s    !E!E!Es#c((!E!E!Er   zArbiter bootedzListening at: %s (%s)zUsing worker: %sz&READY=1
STATUS=Gunicorn arbiter bootedcheck_config)$r%   infor	   r!   r"   intgetr*   rT   r+   getpidpidr:   r'   r   createon_startinginit_signals	LISTENERSr   
listen_fdsrangeSD_LISTEN_FDS_STARTpopsplitappendr   create_socketsrV   rU   worker_class_str	sd_notifyhasattrrO   rg   
when_ready)r2   pidnamefdsrq   fdlisteners_strs         r   startzArbiter.startx   sw    	,k:::RZ''!"*.."@"@AADO!^d2DN)D9;;8'h&G!##4"7++DLL)))T"""~ 	JC +--J (#G7#7*DF F  (*..77==cBB ( (BJJs2ww''''!048SIIDN!E!Edn!E!E!EFF'(((-}dhGGG($(*CDDDCTXNNN 4$n55 	?**48TX>>>D!!!!!r   c                    | j         D ]}t          j        |           t          j                    x| _         }|D ]*}t	          j        |           t	          j        |           +| j                                         | j        D ]}t          j	        || j	                   t          j	        t          j
        | j                   dS )z        Initialize master signal handling. Most of the signals
        are queued. Child signals only wake up the master.
        N)PIPEr!   closepiper   set_non_blockingclose_on_execr%   SIGNALSr   SIGCHLDhandle_chld)r2   ppairss       r   ro   zArbiter.init_signals   s      	 	AHQKKKK 799$	D 	" 	"A!!$$$q!!!!     	* 	*AM!T[))))fnd&677777r   c                     t          | j                  dk     r0| j                            |           |                                  d S d S )N   )len	SIG_QUEUErv   wakeupr2   sigframes      r   r   zArbiter.signal   sF    t~""N!!#&&&KKMMMMM #"r   c                    |                                   t          j        d| j        z             	 |                                  	 |                                  | j        r| j                            d          nd}|=|                                  | 	                                 |                                  w|| j
        vr| j                            d|           | j
                            |          }t          | d|z  d          }|s| j                            d|           | j                            d|            |             |                                  "# t"          t$          f$ r |                                  Y dS t(          $ r,}|                     |j        |j        	           Y d}~dS d}~wt.          $ r  t0          $ ri | j                            d
d           |                     d           | j        | j                                         t9          j        d           Y dS w xY w)zMain master loop.master [%s]Tr   NzIgnoring unknown signal: %sz	handle_%szUnhandled signal: %szHandling signal: %s)reasonexit_statusz Unhandled exception in main loopexc_infoF)r   r   _setproctitlerT   manage_workersmaybe_promote_masterr   rt   sleepmurder_workers	SIG_NAMESr%   rh   rj   r   errorr   StopIterationKeyboardInterrupthaltr   r   r   
SystemExit	Exceptionstopr'   unlinkr-   exit)r2   r   signamehandlerinsts        r   runzArbiter.run   s^   

=4>9:::%	!!!))+++/3~Gdn((+++4;JJLLL'')))'')))dn,,HMM"?EEE.,,S11!$g(=tDD HNN#97CCC3W===			+, 01 	 	 	IIKKKKKK 	H 	H 	HIIT[d6FIGGGGGGGGG 	 	 	 	 	 	HNN=$(  * * *IIe|'##%%%HRLLLLLL	s%   D7E) )%I	I!GA<I Ic                 V    |                                   |                                  dS )zSIGCHLD handlingN)reap_workersr   r   s      r   r   zArbiter.handle_chld   s%    r   c                 n    | j                             d| j                   |                                  dS )z        HUP handling.
        - Reload configuration
        - Start the new worker processes with a new configuration
        - Gracefully shutdown the old worker processes
        zHang up: %sN)r%   rh   r+   reloadr7   s    r   
handle_hupzArbiter.handle_hup   s.     	mT%5666r   c                     t           )zSIGTERM handling)r   r7   s    r   handle_termzArbiter.handle_term   s    r   c                 :    |                      d           t          )zSIGINT handlingFr   r   r7   s    r   
handle_intzArbiter.handle_int      		%r   c                 :    |                      d           t          )zSIGQUIT handlingFr   r7   s    r   handle_quitzArbiter.handle_quit  r   r   c                 N    | xj         dz  c_         |                                  dS )zR        SIGTTIN handling.
        Increases the number of workers by one.
        rG   NrR   r   r7   s    r   handle_ttinzArbiter.handle_ttin  s0    
 	Ar   c                 h    | j         dk    rdS | xj         dz  c_         |                                  dS )zR        SIGTTOU handling.
        Decreases the number of workers by one.
        rG   Nr   r7   s    r   handle_ttouzArbiter.handle_ttou  sC    
 q  FAr   c                 v    | j                                          |                     t          j                   dS )zU        SIGUSR1 handling.
        Kill all workers by sending them a SIGUSR1
        N)r%   rN   kill_workersr   SIGUSR1r7   s    r   handle_usr1zArbiter.handle_usr1  s4    
 	&.)))))r   c                 .    |                                   dS )z        SIGUSR2 handling.
        Creates a new arbiter/worker set as a fork of the current
        arbiter without affecting old workers. Use this to do live
        deployment with the ability to backout a change.
        N)reexecr7   s    r   handle_usr2zArbiter.handle_usr2'  s     	r   c                     | j         j        rB| j                            d           d| _        |                     t          j                   dS | j                            d           dS )zSIGWINCH handlingzgraceful stop of workersr   z SIGWINCH ignored. Not daemonizedN)	r:   daemonr%   rh   rR   r   r   SIGTERMrU   r7   s    r   handle_winchzArbiter.handle_winch0  sb    8? 	?HMM4555 Dfn-----HNN=>>>>>r   c                 v   | j         dk    rd S | j         t          j                    k    r| j                            d           d| _        d| _         | j        j        | _        t          j        d= | j	        $| j	        
                    | j        j	                   t          j        d| j        z             d S d S )Nr   zMaster has been promoted.r   r`   r   )r*   r!   getppidr%   rh   r+   r:   rT   r"   r'   renamer   r   r7   s    r   r   zArbiter.maybe_promote_master9  s    ?aF?bjll**HMM5666'DDO!X/DN
>*|'##DH$4555}t~=>>>>> +*r   c                     	 t          j        | j        d         d           dS # t          $ r+}|j        t          j        t          j        fvr Y d}~dS d}~ww xY w)z;        Wake up the arbiter by writing to the PIPE
        rG      .N)r!   writer   IOErrorerrnoEAGAINEINTR)r2   es     r   r   zArbiter.wakeupJ  sq    	HTYq\4((((( 	 	 	wu|U[999 :99999	s    $ 
A AANr   c                 D   |                                   |dk    r| j        j        n| j        j        } |d| j                   | |d|           | j        | j                                         | j                            |            t          j
        |           dS )z halt arbiter r   zShutting down: %sNz
Reason: %s)r   r%   rh   r   r+   r'   r   r:   on_exitr-   r   )r2   r   r   log_funcs       r   r   zArbiter.haltT  s    		$/1$4$448==$(.$d&6777H\6***<#L!!!r   c                    	 t          j         | j        d         gg g d          }|d         sdS t          j        | j        d         d          r#	 t          j        | j        d         d          !dS dS # t           j        t
          f$ rB}t          |d|j        d                   }|t          j	        t          j
        fvr Y d}~dS d}~wt          $ r t          j                     Y dS w xY w)zm        Sleep until PIPE is readable or we timeout.
        A readable PIPE means a signal occurred.
        r   g      ?NrG   r   )selectr   r!   readr   OSErrorr   r   r   r   r   r   r-   r   )r2   readyr   error_numbers       r   r   zArbiter.sleepb  s   
	M49Q<."b#>>E8 '$)A,**  '$)A,**     g& 	 	 	"1gqvay99LEL%+#>>> ?>>>>>  	 	 	HJJJJJJ	s#   +A4 AA4 4C+
7C C+*C+Tc                 "   | j         | j        cxk    odk    nc o| j         o| j        j         }t          j        | j        |           g | _        t          j	        }|st          j
        }t          j                    | j        j        z   }|                     |           | j        rIt          j                    |k     r2t          j        d           | j        rt          j                    |k     2|                     t          j                   dS )z        Stop workers

        :attr graceful: boolean, If True (the default) workers will be
        killed gracefully  (ie. trying to wait for the current connection)
        r   皙?N)r)   r*   r   r:   
reuse_portr   close_socketsrp   r   r   SIGQUITtimegraceful_timeoutr   WORKERSr   SIGKILL)r2   gracefulr   r   limits        r   r   zArbiter.stopu  s    Ot3333!3333 (L (H'' 	
 	4>6222n 	!.C	dh77#l 	ty{{U22JsOOO l 	ty{{U22 	&.)))))r   c                 (   | j         dk    r| j                            d           dS | j        dk    r| j                            d           dS t	          j                    }t	          j                    | _         | j         dk    rdS | j                            |            | j        j	        
                                }t          |          |d<   | j        rHt          t	          j                              |d<   t          t          | j                            |d<   n'd                    d	 | j        D                       |d
<   t	          j        | j        d                    t	          j        | j        d         | j        d         |           dS )z1        Relaunch the master and workers.
        r   z"USR2 signal ignored. Child exists.Nz#USR2 signal ignored. Parent exists.r`   
LISTEN_PID
LISTEN_FDSra   c              3   X   K   | ]%}t          |                                          V  &d S r6   )rd   filenore   s     r   r   z!Arbiter.reexec.<locals>.<genexpr>  sC       .= .=&)CJJLL!!.= .= .= .= .= .=r   r@   r    r   )r)   r%   warningr*   r!   rk   forkr:   pre_execenv_origcopyrd   r   r   rp   rV   chdirr1   execvpe)r2   r*   r"   s      r   r   zArbiter.reexec  sv    ?aHABBBF?aHBCCCFY[[
'))?aF$(#((**"%j//< 	=$'	$4$4GL!$'DN(;(;$<$<GL!!%(XX .= .=-1^.= .= .= &= &=GM" 	&''' 	
4>!$dnV&<gFFFFFr   c                 T   | j         j        }| j         j        D ]N}|| j         j        v r | j         j        |         t          j        |<   0	 t          j        |= ?# t          $ r Y Kw xY w| j                                         | 	                    | j                   | j
                                         || j         j        k    r| j        D ]}|                                 t          j        | j         | j
                  | _        d                    d | j        D                       }| j
                            d|           | j                             |            | j        | j                                         | j         j        =t+          | j         j                  | _        | j                            | j                   t1          j        d| j        z             t7          | j         j                  D ]}|                                  |                                  d S )Nra   c                 ,    g | ]}t          |          S rH   rc   re   s     r   r   z"Arbiter.reload.<locals>.<listcomp>  s    %I%I%I3c#hh%I%I%Ir   zListening at: %sr   )r:   rP   rZ   r   r!   r"   KeyErrorr3   r   r&   r%   rN   rp   r   r   rw   rV   rh   	on_reloadr'   r   r   rm   rl   r   r   rT   rr   rQ   spawn_workerr   )r2   old_addressr]   rf   r   r   s         r   r   zArbiter.reload  s   h&  
	 
	ADH%%% !% 1! 4
1
1   D 	

48 	 $(***~  		!048DDDNHH%I%I$.%I%I%IJJMHMM,m<<< 	4    <#L!!! 8'"48#344DLL))) 	=4>9::: tx'(( 	  	 A 	s   
A
A%$A%c                    | j         sdS t          | j                                                  }|D ]\  }}	 t	          j                    |j                                        z
  | j         k    r=n# t          t          f$ r Y Qw xY w|j
        sC| j                            d|           d|_
        |                     |t          j                   |                     |t          j                   dS )z)        Kill unused/idle workers
        NzWORKER TIMEOUT (pid:%s)T)rS   listr   rY   r   	monotonictmplast_updater   
ValueErrorabortedr%   criticalkill_workerr   SIGABRTr   )r2   rQ   rl   workers       r   r   zArbiter.murder_workers  s    | 	Ft|))++,,$ 	6 	6MS&>##fj&<&<&>&>>$,NN OZ(    > 6!!";SAAA!%  fn5555  fn5555	6 	6s   6A00BBc                    	 	 t          j        dt           j                  \  }}|sdS | j        |k    r	d| _        nl|dz	  }|dk    r| j                            d||           || j        k    rd}t          || j                  || j        k    rd}t          || j                  |dk    r| j                            d||           n|dk    r	 t          j
        |          j        }n%# t          $ r d	                    |          }Y nw xY wd
                    ||          }|t          j        k    r|dz  }| j                            |           | j                            |d          }|ss|j                                         | j                            | |           # t*          $ r!}|j        t,          j        k    r Y d}~dS d}~ww xY w)z7        Reap workers to avoid zombie processes
        Tr   r      z#Worker (pid:%s) exited with code %szWorker failed to boot.zApp failed to load.z$Worker (pid:%s) exited with code %s.zcode {}zWorker (pid:{}) was sent {}!z Perhaps out of memory?N)r!   waitpidWNOHANGr)   r%   r   WORKER_BOOT_ERRORr   APP_LOAD_ERRORr   Signalsr   r  rC   r   r   rt   r   r   r:   
child_exitr   r   ECHILD)	r2   wpidstatusexitcoder   sig_namemsgr  r   s	            r   r   zArbiter.reap_workers  s-   1	-6!z"bj99f E?d**&'DOO
  &{H1}}'LdT\]]]4#999!9(1GHHH4#666!6(1DEEE!|| 'M'+X7 7 7 7!@'-~f'='='BHH) @ @ @'0'7'7'?'?HHH@<CC (, , "V^33#<<Cs+++!\--dD99F! ! J$$&&&H''f555[-6\  	 	 	w%,&& '&&&&&	sB   %F+ B(F+ C, +F+ ,DF+ DBF+ +
G5GGc                 :   t          | j                  | j        k     r|                                  | j                                        }t          |d           }t          |          | j        k    rP|                    d          \  }}|                     |t          j	                   t          |          | j        k    Pt          |          }| j
        |k    r<|| _
        | j                            d                    |          d|dd           d	S d	S )
z[        Maintain the number of workers by spawning or killing
        as required.
        c                     | d         j         S rF   )age)ws    r   rJ   z(Arbiter.manage_workers.<locals>.<lambda>>  s    ! r   rK   r   z{0} workerszgunicorn.workersgauge)metricr<   mtype)extraN)r   r   rR   spawn_workersrY   rW   rt   r  r   r   r$   r%   rU   rC   )r2   rQ   rl   r   active_worker_counts        r   r   zArbiter.manage_workers5  s%   
 t|t///   ,$$&&&8&8999'llT---{{1~~HS!S&.111 'llT--- "'ll04GGG4GD1HNN=//0CDD,>+>+2"4 "4  5 5 5 5 5 HGr   c           	         | xj         dz  c_         |                     | j         | j        | j        | j        | j        dz  | j        | j                  }| j                            | |           t          j
                    }|dk    r||_        || j        |<   |S | j                                        D ]}|j                                         t          j                    |_        	 t!          j        d| j        z             | j                            d|j                   | j                            | |           |                                 t-          j        d           n# t0          $ r  t2          $ r{}| j                            dd           t7          d	|z  t,          j        
           t,          j                                         t-          j        | j                   Y d }~nad }~wt>          $ rQ | j                             d           |j!        st-          j        | j"                   t-          j        d           Y nw xY w| j                            d|j                   	 |j                                         | j        #                    | |           d S # t>          $ r0 | j        $                    dtK          j&                               Y d S w xY w# | j                            d|j                   	 |j                                         | j        #                    | |           w # t>          $ r/ | j        $                    dtK          j&                               Y w w xY wxY w)NrG   g       @r   zworker [%s]zBooting worker with pid: %sz'Exception while loading the applicationTr   z%s)filezException in worker processr   zWorker exiting (pid: %s)z Exception during worker exit:
%s)'r(   rO   rl   rp   r3   rS   r:   r%   pre_forkr!   r   r   valuesr   r   rk   r   r   rT   rh   	post_forkinit_processr-   r   r   r   rU   printstderrflushr  r   	exceptionbootedr  worker_exitr   	traceback
format_exc)r2   r  rl   siblingr   s        r   r   zArbiter.spawn_workerK  s   1""4?DHdn#'8T\C-?#'8TX7 7 	$'''gii!88FJ &DLJ |**,, 	  	 GK Y[[
	9}t~=>>>HMM7DDDHtV,,,!!!HQKKKK 	 	 	 	* 	* 	*HNND$(  * * *$(,,,,JHT()))))))) 	 	 	H<==== 1/000HRLLLLL		 HMM4fjAAA9
  """$$T622222 9 9 9  !D!*!5!7!79 9 9 9 9 99	 HMM4fjAAA9
  """$$T62222 9 9 9  !D!*!5!7!79 9 9 9 99su   'A?E' &K& 'I;A1G1,K& 1AIK& IK& 34J) )6K#"K#&!M94L=<M9=6M63M95M66M9c                     t          | j        t          | j                  z
            D ]>}|                                  t          j        dt          j                    z             ?dS )z        Spawn new workers as needed.

        This is where a worker process leaves the main loop
        of the master process.
        r   N)rr   rR   r   r   r   r   r   random)r2   r   s     r   r  zArbiter.spawn_workersy  sg     t'#dl*;*;;<< 	. 	.AJsV]__,----	. 	.r   c                     t          | j                                                  }|D ]}|                     ||           dS )z^        Kill all workers with the signal `sig`
        :attr sig: `signal.SIG*` value
        N)r   r   keysr  )r2   r   worker_pidsrl   s       r   r   zArbiter.kill_workers  sQ    
 4<,,..// 	' 	'CS#&&&&	' 	'r   c                 d   	 t          j        ||           dS # t          $ r}|j        t          j        k    rq	 | j                            |          }|j                                         | j	        
                    | |           Y d}~dS # t          t          f$ r Y Y d}~dS w xY w d}~ww xY w)zj        Kill a worker

        :attr pid: int, worker pid
        :attr sig: `signal.SIG*` value
         N)r!   killr   r   ESRCHr   rt   r   r   r:   r+  r   )r2   rl   r   r   r  s        r   r  zArbiter.kill_worker  s    	GC 		 		 		w%+%%!\--c22FJ$$&&&H((v666FFFFF '*   FFFFFF		s2    
B/B*ABB&B*%B&&B**B/)Nr   )T)2__name__
__module____qualname____doc__r  r  r1   rp   r   r   r   ru   r   dictdirr   r   r4   r8   r>   propertyrR   r&   r   ro   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r  rH   r   r   r   r      s          NIIGD IO OEKKMMO O OG  >Ac&kk    I

 
 
8! ! !: : : (+-=>>K  @/" /" /"b8 8 8,  
* * *X  
      
  
    * * *  ? ? ?? ? ?"       &* * * *6 G  G  GD5 5 5n6 6 6*5 5 5n5 5 5,,9 ,9 ,9\
. 
. 
.' ' '    r   r   )r   r!   r0  r   r   r-   r   r,  gunicorn.errorsr   r   gunicorn.pidfiler   gunicornr   r   r   r	   r
   objectr   rH   r   r   <module>rB     s   
  				    



      6 6 6 6 6 6 6 6 $ $ $ $ $ $ ( ( ( ( ( ( ( ( ( ( 1 1 1 1 1 1 1 1K
 K
 K
 K
 K
f K
 K
 K
 K
 K
r   