
    +h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y)    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j                         D  cg c]  }t        t        d|z         c}}}} 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% Z0d& Z1d' Z2yc c}}}} w )*Arbiterz
    Arbiter maintain the workers processes alive. It launches or
    kills them if needed. It also manages application reloading
    via SIGHUP/USR2.
          z+HUP QUIT INT TERM TTIN TTOU USR1 USR2 WINCHzSIG%sc              #      K   | ]7  }|d d dk(  r-|d   dk7  r%t        t        |      |dd  j                         f 9 y w)Nr   SIG_)getattrsignallower).0names     C/var/www/html/venv/lib/python3.12/site-packages/gunicorn/arbiter.py	<genexpr>zArbiter.<genexpr>.   sI      6:8uaC 
	QR 01s   =?c                    t         t        j                  d<   d | _        d | _        d | _        | j                  |       d | _        d| _        d| _	        d| _
        d| _        d| _        t        j                         }t        j                   d d  }|j#                  dt        j$                         ||t        j$                  d| _        y )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#kkmxx{As~~& ~~
    c                     | j                   S N)r   r.   s    r   _get_num_workerszArbiter._get_num_workersO   s       r1   c                 d    | j                   }|| _         | j                  j                  | ||       y r3   )r   cfgnworkers_changed)r.   value	old_values      r   _set_num_workerszArbiter._set_num_workersR   s+    %%	!!!$y9r1   c                    || _         |j                  | _        | j                  *| j                  j                  |j                        | _        dt        j
                  v r| j                  j                          | j                  j                  | _        | j                  j                  | _        | j                  j                  | _
        | j                  j                  | _        | j                  j                  | _        | j                  j                  dj                  dj                  d t!        | j                  j"                  j%                         d       D                           | j                  j&                  r?| j                  j&                  j%                         D ]  \  }}|t        j
                  |<    | j                  j(                  r| j                   j+                          y y )NGUNICORN_FDzCurrent configuration:
{0}
c              3   Z   K   | ]#  \  }}d j                  ||j                         % yw)z
  {0}: {1}N)formatr9   )r   configr9   s      r   r   z Arbiter.setup.<locals>.<genexpr>j   s-      ;!FE ##FEKK8;s   )+c                     | d   S N    )settings    r   <lambda>zArbiter.setup.<locals>.<lambda>n   s
    gaj r1   key)r/   r7   r!   logger_classr   r   reopen_filesworker_classaddressworkersnum_workerstimeout	proc_namedebugr@   joinsortedsettingsitemsenvpreload_appwsgi)r.   r/   kvs       r   r"   zArbiter.setupX   sb   7788xx,,SWW5DH BJJ&HH!!# HH11xx''88++xx''++4;;II ; $((++1138:; ;< 	= 88<<**, "1 !

1" 88HHMMO  r1   c                    | j                   j                  dt               dt        j                  v rHt        t        j                  j                  d            | _        | j                  dz   | _        d| _	        t        j                         | _        | j                  j                  _| j                  j                  }| j                  dk7  r|dz  }t        |      | _        | j                  j                  | j                         | j                  j!                  |        | j#                          | j$                  sd}t'        j(                         }|r3d| _        t+        t&        j,                  t&        j,                  |z         }n[| j                  rOg }t        j                  j/                  d      j1                  d	      D ]  }|j3                  t        |              t5        j6                  | j                  | j                   |      | _        d	j9                  | j$                  D cg c]  }t;        |       c}      }| j                   j=                  d
       | j                   j                  d|| j                         | j                   j                  d| j                  j>                         t'        j@                  d| j                          tC        | jD                  d      r0| jD                  jG                  | j                  | j                          | j                  jI                  |        yc c}w )zS        Initialize the arbiter. Start listening and set pidfile if needed.
        zStarting gunicorn %sGUNICORN_PIDz.2zMaster.2Nr   Tr=   ,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&   rQ   r'   getpidpidr7   r#   r   createon_startinginit_signals	LISTENERSr   
listen_fdsrangeSD_LISTEN_FDS_STARTpopsplitappendr   create_socketsrS   strrR   worker_class_str	sd_notifyhasattrrL   r_   
when_ready)r.   pidnamefdsri   fdlnrlisteners_strs          r   startzArbiter.startx   sD    	,k:RZZ'!"**.."@ADO!^^d2DN)D99;88'hh&&G!#4"7+DLLL)T"~~C ++-J#G77#77*DF **..7==cB (BJJs2w'( "00488SIDNdnn!Es#c(!EF'(-}dhhG($((*C*CDCTXXN 4$$n5**488TXX>D! "Fs   /L<c                    | j                   D ]  }t        j                  |        t        j                         x| _         }|D ],  }t	        j
                  |       t	        j                  |       . | j                  j                          | j                  D ]"  }t        j                  || j                         $ t        j                  t        j                  | j                         y)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)r.   ppairss       r   rg   zArbiter.init_signals   s      	AHHQK	 779$	D 	"A!!!$q!	" 	   	*AMM!T[[)	*fnnd&6&67r1   c                     t        | j                        dk  r,| j                  j                  |       | j                          y y )N   )len	SIG_QUEUErn   wakeupr.   sigframes      r   r   zArbiter.signal   s3    t~~"NN!!#&KKM #r1   c                 h   | j                          t        j                  d| j                  z         	 | j	                          	 | j                          | j                  r| j                  j                  d      nd}|1| j                          | j                          | j	                          m|| j                  vr| j                  j                  d|       | j                  j                  |      }t        | d|z  d      }|s| j                  j                  d|       | j                  j                  d|        |        | j!                          # t"        t$        f$ r | j'                          Y yt(        $ r1}| j'                  |j*                  |j,                  	       Y d}~yd}~wt.        $ r  t0        $ rl | j                  j                  d
d       | j3                  d       | j4                  | j4                  j7                          t9        j:                  d       Y y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)rz   r   _setproctitlerQ   manage_workersmaybe_promote_masterr   rl   sleepmurder_workers	SIG_NAMESr!   r`   rb   r   errorr   StopIterationKeyboardInterrupthaltr   r   r   
SystemExit	Exceptionstopr#   unlinkr)   exit)r.   r   signamehandlerinsts        r   runzArbiter.run   s   

=4>>9:%	!))+/3~~dnn((+4;JJL'')'')dnn,HHMM"?E..,,S1!$g(=tDHHNN#97C3W=	+ , 01 	IIK 	HIIT[[d6F6FIGG 	 	HHNN=$(  *IIe||'##%HHRL	s%   D'E H1<H1'F00A>H10H1c                 D    | j                          | j                          y)zSIGCHLD handlingN)reap_workersr   r   s      r   r   zArbiter.handle_chld   s    r1   c                 p    | j                   j                  d| j                         | j                          y)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!   r`   r'   reloadr4   s    r   
handle_hupzArbiter.handle_hup   s%     	mT%5%56r1   c                     t         )zSIGTERM handling)r   r4   s    r   handle_termzArbiter.handle_term   s    r1   c                 0    | j                  d       t        )zSIGINT handlingFr   r   r4   s    r   
handle_intzArbiter.handle_int      		%r1   c                 0    | j                  d       t        )zSIGQUIT handlingFr   r4   s    r   handle_quitzArbiter.handle_quit  r   r1   c                 N    | xj                   dz  c_         | j                          y)zR        SIGTTIN handling.
        Increases the number of workers by one.
        rD   NrO   r   r4   s    r   handle_ttinzArbiter.handle_ttin  s!    
 	Ar1   c                 n    | j                   dk  ry| xj                   dz  c_         | j                          y)zR        SIGTTOU handling.
        Decreases the number of workers by one.
        rD   Nr   r4   s    r   handle_ttouzArbiter.handle_ttou  s2    
 q Ar1   c                 v    | j                   j                          | j                  t        j                         y)zU        SIGUSR1 handling.
        Kill all workers by sending them a SIGUSR1
        N)r!   rK   kill_workersr   SIGUSR1r4   s    r   handle_usr1zArbiter.handle_usr1  s&    
 	&..)r1   c                 $    | j                          y)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)reexecr4   s    r   handle_usr2zArbiter.handle_usr2'  s     	r1   c                     | j                   j                  rB| j                  j                  d       d| _        | j                  t        j                         y| j                  j                  d       y)zSIGWINCH handlingzgraceful stop of workersr   z SIGWINCH ignored. Not daemonizedN)	r7   daemonr!   r`   rO   r   r   SIGTERMrR   r4   s    r   handle_winchzArbiter.handle_winch0  sI    88??HHMM45 Dfnn-HHNN=>r1   c                    | j                   dk(  ry | j                   t        j                         k7  r| j                  j	                  d       d| _        d| _         | j                  j                  | _        t        j                  d= | j                  /| j                  j                  | j                  j                         t        j                  d| j                  z         y y )Nr   zMaster has been promoted.r   r]   r   )r&   r   getppidr!   r`   r'   r7   rQ   r   r#   renamer   r   r4   s    r   r   zArbiter.maybe_promote_master9  s    ??a??bjjl*HHMM56'DDO!XX//DN

>*||'##DHH$4$45}t~~=> +r1   c                     	 t        j                  | j                  d   d       y# t        $ r7}|j                  t        j
                  t        j                  fvr Y d}~yd}~ww xY w)z;        Wake up the arbiter by writing to the PIPE
        rD      .N)r   writer|   IOErrorerrnoEAGAINEINTR)r.   es     r   r   zArbiter.wakeupJ  sN    	HHTYYq\4( 	wwu||U[[99 :	s   #& 	A&-A!!A&Nc                 n   | j                          |dk(  r| j                  j                  n| j                  j                  } |d| j                         |	 |d|       | j
                  | j
                  j                          | j                  j                  |        t        j                  |       y)z halt arbiter r   zShutting down: %sNz
Reason: %s)r   r!   r`   r   r'   r#   r   r7   on_exitr)   r   )r.   r   r   log_funcs       r   r   zArbiter.haltT  s    		$/1$4488==$((..$d&6&67\6*<<#LL!r1   c                    	 t        j                   | j                  d   gg g d      }|d   syt        j                  | j                  d   d      r&	 t        j                  | j                  d   d      r%yy# t         j                  t
        f$ rG}t        |d|j                  d         }|t        j                  t        j                  fvr Y d}~yd}~wt        $ r t        j                          Y yw xY w)zm        Sleep until PIPE is readable or we timeout.
        A readable PIPE means a signal occurred.
        r   g      ?NrD   r   )selectr|   r   readr   OSErrorr   r   r   r   r   r   r)   r   )r.   readyr   error_numbers       r   r   zArbiter.sleepb  s    
	MM499Q<."b#>E8''$))A,* ''$))A,*g& 	"1gqvvay9LELL%++#>> ?  	HHJ	s#   +A8 AA8 8C6=C C65C6c                    | j                   | j                  cxk(  xr dk(  nc xr& | j                   xr | j                  j                   }t        j                  | j                  |       g | _        t        j                  }|st        j                  }t        j                         | j                  j                  z   }| j                  |       | j                  rPt        j                         |k  r9t        j                  d       | j                  rt        j                         |k  r9| j                  t        j                          y)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   r7   
reuse_portr   close_socketsrh   r   r   SIGQUITtimegraceful_timeoutr   WORKERSr   SIGKILL)r.   gracefulr   r   limits        r   r   zArbiter.stopu  s     OOt3!3 (LL (HH''' 	
 	4>>62nn..C		dhh777#lltyy{U2JJsO lltyy{U2 	&..)r1   c                 P   | j                   dk7  r| j                  j                  d       y| j                  dk7  r| j                  j                  d       yt	        j
                         }t	        j                         | _         | j                   dk7  ry| j                  j                  |        | j                  j                  j                         }t        |      |d<   | j                  rBt        t	        j
                               |d<   t        t        | j                              |d<   n%dj                  d	 | j                  D              |d
<   t	        j                   | j"                  d          t	        j$                  | j"                  d   | j"                  d   |       y)z1        Relaunch the master and workers.
        r   z"USR2 signal ignored. Child exists.Nz#USR2 signal ignored. Parent exists.r]   
LISTEN_PID
LISTEN_FDSr^   c              3   N   K   | ]  }t        |j                                 y wr3   )rp   fileno)r   rx   s     r   r   z!Arbiter.reexec.<locals>.<genexpr>  s       .=&)CJJL!.=s   #%r=   r   r   )r%   r!   warningr&   r   rc   forkr7   pre_execenv_origcopyrp   r   r   rh   rS   chdirr-   execvpe)r.   r&   r   s      r   r   zArbiter.reexec  s:    ??aHHAB??aHHBCYY[
'')??a$((##((*"%j/<<$'		$4GL!$'DNN(;$<GL!%(XX .=-1^^.= &=GM" 	&' 	

4>>!$dnnV&<gFr1   c                 R   | j                   j                  }| j                   j                  D ]W  }|| j                   j                  v r+| j                   j                  |   t        j
                  |<   F	 t        j
                  |= Y | j                  j                          | j                  | j                         | j                  j                          || j                   j                  k7  r| j                  D ]  }|j                           t        j                  | j                   | j                        | _        dj!                  | j                  D cg c]  }t#        |       c}      }| j                  j%                  d|       | j                   j'                  |        | j(                  | j(                  j+                          | j                   j(                  It-        | j                   j(                        | _        | j(                  j/                  | j0                         t3        j4                  d| j6                  z         t9        | j                   j:                        D ]  }| j=                           | j?                          y # t        $ r Y sw xY wc c}w )Nr^   zListening at: %sr   ) r7   rM   rW   r   r   r   KeyErrorr/   r   r"   r!   rK   rh   r}   r   ro   rS   rp   r`   	on_reloadr#   r   r   re   rd   r   r   rQ   rj   rN   spawn_workerr   )r.   old_addressrZ   rx   ry   r   s         r   r   zArbiter.reload  s   hh&&  
	ADHH%%% !% 1 1! 4

1

1
	 	

488 	 $((***~~ 		 "00488DDNHH$..%I3c#h%IJMHHMM,m< 	4  <<#LL! 88'"488#3#34DLLL) 	=4>>9: txx''( 	 A	  	Q   " &Js   4JJ$	J! J!c                     | j                   syt        | j                  j                               }|D ]  \  }}	 t	        j                         |j
                  j                         z
  | j                   k  rD	 |j                  sD| j                  j                  d|       d|_	        | j                  |t        j                         | j                  |t        j                          y# t        t        f$ r Y w xY w)z)        Kill unused/idle workers
        NzWORKER TIMEOUT (pid:%s)T)rP   listr   rV   r   tmplast_updater   
ValueErrorabortedr!   criticalkill_workerr   SIGABRTr   )r.   rN   rd   workers       r   r   zArbiter.murder_workers  s     ||t||))+,$ 	6MS&99;!7!7!99T\\I J
 >>!!";SA!%  fnn5  fnn5	6 Z( s   <C++C=<C=c                    	 	 t        j                  dt         j                        \  }}|sy| j                  |k(  r	d| _        nX|dz	  }|dk7  r| j                  j                  d||       || j                  k(  rd}t        || j                        || j                  k(  rd}t        || j                        |dkD  r| j                  j                  d||       nj|dkD  re	 t        j                  |      j                  }d	j                  ||      }|t        j                  k(  r|d
z  }| j                  j                  |       | j                  j!                  |d      }|se|j"                  j%                          | j&                  j)                  | |       # t        $ r dj                  |      }Y w xY w# t*        $ r(}|j,                  t,        j.                  k7  r Y d}~yd}~ww xY w)z7        Reap workers to avoid zombie processes
        r   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   r@   r   r   rl   r   r}   r7   
child_exitr   r   ECHILD)	r.   wpidstatusexitcoder   sig_namemsgr   r   s	            r   r   zArbiter.reap_workers  s   1	!zz"bjj9f??d*&'DO
  &{H1}'LdT\]4#9#99!9(1G1GHH4#6#66!6(1D1DEE!| 'M'+X7!@'-~~f'='B'BH =CC (, "V^^3#<<Cs+!\\--dD9F! JJ$$&HH''f5[ >  * @'0'7'7'?H@  	ww%,,& '	sB   *F? B5F? #F BF? F<9F? ;F<<F? ?	G0G++G0c                 &   t        | j                        | j                  k  r| j                          | j                  j	                         }t        |d       }t        |      | j                  kD  rM|j                  d      \  }}| j                  |t        j                         t        |      | j                  kD  rMt        |      }| j                  |k7  r8|| _
        | j                  j                  dj                  |      d|dd       y	y	)
z[        Maintain the number of workers by spawning or killing
        as required.
        c                      | d   j                   S rC   )age)ws    r   rG   z(Arbiter.manage_workers.<locals>.<lambda>>  s    ! r1   rH   r   z{0} workerszgunicorn.workersgauge)metricr9   mtype)extraN)r   r   rO   spawn_workersrV   rT   rl   r   r   r   r    r!   rR   r@   )r.   rN   rd   r   active_worker_counts        r   r   zArbiter.manage_workers5  s    
 t||t/// ,,$$&&89'lT---{{1~HS!S&..1 'lT--- "'l004GG4GD1HHNN=//0CD,>+>+2"4  5 Hr1   c           	         | xj                   dz  c_         | j                  | j                   | j                  | j                  | j                  | j
                  dz  | j                  | j                        }| j                  j                  | |       t        j                         }|dk7  r||_        || j                  |<   |S | j                  j                         D ]  }|j                  j                           t        j                         |_        	 t!        j"                  d| j$                  z         | j                  j'                  d|j                         | j                  j)                  | |       |j+                          t-        j.                  d       | j                  j'                  d|j                         	 |j                  j                          | j                  jG                  | |       y # t0        $ r  t2        $ r}| j                  j5                  dd       t7        d	|z  t,        j8                  
       t,        j8                  j;                          t-        j.                  | j<                         Y d }~d }~wt>        $ r_ | j                  jA                  d       |jB                  st-        j.                  | jD                         t-        j.                  d       Y Ww xY w# t>        $ r1 | j                  jI                  dtK        jL                                Y y w xY w# | j                  j'                  d|j                         	 |j                  j                          | j                  jG                  | |       w # t>        $ r1 | j                  jI                  dtK        jL                                Y w w xY wxY w)NrD   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$   rL   rd   rh   r/   rP   r7   r!   pre_forkr   r   r   valuesr   r}   rc   r   r   rQ   r`   	post_forkinit_processr)   r   r   r   rR   printstderrflushr  r   	exceptionbootedr  worker_exitr   	traceback
format_exc)r.   r   rd   siblingr   s        r   r   zArbiter.spawn_workerK  s   1""4??DHHdnn#'88T\\C-?#'88TXX7 	$'ggi!8FJ &DLLJ ||**, 	 GKK	  YY[
	9}t~~=>HHMM7DHHtV,!HHQK HHMM4fjjA9

  "$$T62#  	 	*HHNND$(  *$(,JJHHT(()) 	HH<===//0HHRL		  9  !D!*!5!5!799	 HHMM4fjjA9

  "$$T62 9  !D!*!5!5!799so   B	G= 6K: =K7A8JL7 A'K73L7 6K77L7 :7L43L47'O6NO7OOOOc                     t        | j                  t        | j                        z
        D ]<  }| j	                          t        j                  dt        j                         z         > y)z        Spawn new workers as needed.

        This is where a worker process leaves the main loop
        of the master process.
        r   N)rj   rO   r   r   r   r   r   random)r.   r   s     r   r  zArbiter.spawn_workersy  sO     t''#dll*;;< 	.AJJsV]]_,-	.r1   c                 |    t        | j                  j                               }|D ]  }| j                  ||        y)z^        Kill all workers with the signal `sig`
        :attr sig: `signal.SIG*` value
        N)r   r   keysr   )r.   r   worker_pidsrd   s       r   r   zArbiter.kill_workers  s:    
 4<<,,./ 	'CS#&	'r1   c                 p   	 t        j                  ||       y# t        $ r}|j                  t        j                  k(  rp	 | j
                  j                  |      }|j                  j                          | j                  j                  | |       Y d}~y# t        t        f$ r Y Y d}~y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   rl   r   r}   r7   r#  r   )r.   rd   r   r   r   s        r   r   zArbiter.kill_worker  s    	GGC 		ww%++%!\\--c2FJJ$$&HH((v6 '* 		s3    	B5B0 ABB,%B0+B,,B00B5)Nr   )T)3__name__
__module____qualname____doc__r  r  r-   rh   r   r|   r   rm   r   r   r   dictdirr   r0   r5   r;   propertyrO   r"   rz   rg   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   )r   xr   r   s   0000r   r   r      s?     NIIGD IEKKMO O vw{+ OG >A&k I

8!: +-=>K@/"b8,
*X


*??"&*6 GD5n6*5n5,,9\
.'EOs   C
r   )r   r   r(  r   r   r)   r   r$  gunicorn.errorsr   r   gunicorn.pidfiler   gunicornr   r   r   r	   r
   objectr   rE   r1   r   <module>r;     s<   
  	    
   6 $ ( ( 1K
f K
r1   