
    \eiv                         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mZmZ d dlmZmZ d dlmZmZ  G d d      Zy)	    N)
HaltServerAppImportError)Pidfile)socksystemdutil)__version__SERVER_SOFTWARE)DirtyArbiterset_dirty_socket_pathc                      e Zd ZdZdZdZi Zg Zi Ze	j                  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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/dZ)d0dZ*d1dZ+d  Z,d! Z-d" Z.d# Z/d$ Z0d% Z1d& Z2d' Z3d( Z4d) Z5d* Z6d+ Z7d, Z8d- Z9d. Z:yc c}}}} w )2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     F/var/www/ceduoda/envi/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 | _        t        j                         | _        | j                  |       d | _
        d| _        d| _        d| _        d| _        d| _        d| _        d | _        d | _        t'        j(                         }t*        j,                  d d  }|j/                  dt*        j0                         ||t*        j0                  d| _        y )Nr
   Fr   Master)argscwdr   )r
   osenviron_num_workers _last_logged_active_worker_countlogqueueSimpleQueue	SIG_QUEUEsetuppidfiler   
worker_age
reexec_pid
master_pidmaster_namedirty_arbiter_piddirty_arbiterdirty_pidfiler   getcwdsysargvinsert
executable	START_CTX)selfappr   r   s       r   __init__zArbiter.__init__4   s    (7

$% 04- **,

3# "#!!kkmxx{As~~& ~~
    c                     | j                   S N)r!   r6   s    r   _get_num_workerszArbiter._get_num_workersX   s       r9   c                 d    | j                   }|| _         | j                  j                  | ||       y r;   )r!   cfgnworkers_changed)r6   value	old_values      r   _set_num_workerszArbiter._set_num_workers[   s+    %%	!!!$y9r9   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_PIDzCurrent configuration:
{0}
c              3   Z   K   | ]#  \  }}d j                  ||j                         % yw)z
  {0}: {1}N)formatrA   )r   configrA   s      r   r   z Arbiter.setup.<locals>.<genexpr>s   s-      ;!FE ##FEKK8;s   )+c                     | d   S N    )settings    r   <lambda>zArbiter.setup.<locals>.<lambda>w   s
    gaj r9   key)r7   r?   r#   logger_classr   r    reopen_filesworker_classaddressworkersnum_workerstimeout	proc_namedebugrH   joinsortedsettingsitemsenvpreload_appwsgi)r6   r7   kvs       r   r'   zArbiter.setupa   sb   7788xx,,SWW5DH RZZ'HH!!# HH11xx''88++xx''++4;;II ; $((++1138:; ;< 	= 88<<**, "1 !

1" 88HHMMO  r9   c                 L   | 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        |              | j                  j4                  rt7        t8        d
      s0t;        j<                  | j                  | j                   |      | _        d	j?                  | j$                  D cg c]  }tA        |       c}      }| j                   jC                  d       | j                   j                  d|| j                         | j                   j                  d| j                  jD                         t'        jF                  d| j                          t7        | jH                  d      r0| jH                  jK                  | j                  | j                          | j                  jL                  dkD  r&| j                  jN                  r| jQ                          | j                  jS                  |        yc c}w )zS        Initialize the arbiter. Start listening and set pidfile if needed.
        zStarting gunicorn %srE   z.2zMaster.2Nr   TGUNICORN_FD,SO_REUSEPORTzArbiter bootedzListening at: %s (%s)zUsing worker: %sz&READY=1
STATUS=Gunicorn arbiter bootedcheck_config)*r#   infor	   r   r    intgetr+   rY   r,   getpidpidr?   r(   r   createon_startinginit_signals	LISTENERSr   
listen_fdsrangeSD_LISTEN_FDS_STARTpopsplitappend
reuse_porthasattrsocketr   create_socketsr[   strrZ   worker_class_str	sd_notifyrT   rh   dirty_workers
dirty_appsspawn_dirty_arbiter
when_ready)r6   pidnamefdsrr   fdlnrlisteners_strs          r   startzArbiter.start   s    	,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'( HH''GFN,K!%!4!4TXXtxx!Mdnn!Es#c(!EF'(-}dhhG($((*C*CDCTXXN 4$$n5**488TXX> 88!!A%$((*=*=$$&D! "Fs   N!c                     | 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)r#   close_on_execSIGNALSr   SIGCHLDsignal_chld)r6   ss     r   rp   zArbiter.init_signals   sS    
 	   	*AMM!T[[)	*fnnd&6&67r9   c                 :    | j                   j                  |       y)z3Signal handler - NO LOGGING, just queue the signal.Nr&   
put_nowaitr6   sigframes      r   r   zArbiter.signal       !!#&r9   c                 v   | j                          t        j                  d| j                  z         	 | j	                          	 | j                          | j                  d      D ]  }|| j                  vr| j                  j                  d|       .| j                  j                  |      }t        | d|z  d      }|s| j                  j                  d|       x|t        j                  k(  r| j                  j                  n| j                  j                  } |d	|        |         | j!                          | j	                          | j#                          # t$        t&        f$ r | j)                          Y yt*        $ r1}| j)                  |j,                  |j.                  
       Y d}~yd}~wt0        $ r  t2        $ rl | j                  j                  dd       | j5                  d       | j6                  | j6                  j9                          t;        j<                  d       Y yw xY w)zMain master loop.master [%s]T      ?)rX   zIgnoring unknown signal: %sz	handle_%sNzUnhandled signal: %szHandling signal: %s)reasonexit_statusz Unhandled exception in main loopexc_infoF)r   r   _setproctitlerY   manage_workersmaybe_promote_masterwait_for_signals	SIG_NAMESr#   ri   rk   r   errorr   r   rZ   murder_workersmanage_dirty_arbiterStopIterationKeyboardInterrupthaltr   r   r   
SystemExit	Exceptionstopr(   unlinkr1   exit)r6   r   signamehandler	log_levelinsts         r   runzArbiter.run   s   

=4>>9:%	!))+  000= C$..0&CSI "nn005G%dK',A4HG"'=wG 252GTXX]]I3W=I ##%##%))++ , 01 	IIK 	HIIT[[d6F6FIGG 	 	HHNN=$(  *IIe||'##%HHRL	s%   D.E" "H8H8'F77A>H87H8c                 :    | j                   j                  |       y)z;SIGCHLD signal handler - NO LOGGING, just queue the signal.Nr   r   s      r   r   zArbiter.signal_chld   r   r9   c                 D    | j                          | j                          y)z6SIGCHLD handling - called from main loop, safe to log.N)reap_workersreap_dirty_arbiterr<   s    r   handle_chldzArbiter.handle_chld   s    !r9   c                     | j                   j                  d| j                         | j                          | j                  r | j                  t        j                         y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#   ri   r,   reloadr-   kill_dirty_arbiterr   SIGHUPr<   s    r   
handle_hupzArbiter.handle_hup   sE     	mT%5%56!!##FMM2 "r9   c                     t         )zSIGTERM handling)r   r<   s    r   handle_termzArbiter.handle_term  s    r9   c                 0    | j                  d       t        )zSIGINT handlingFr   r   r<   s    r   
handle_intzArbiter.handle_int      		%r9   c                 0    | j                  d       t        )zSIGQUIT handlingFr   r<   s    r   handle_quitzArbiter.handle_quit  r   r9   c                 N    | xj                   dz  c_         | j                          y)zR        SIGTTIN handling.
        Increases the number of workers by one.
        rL   NrW   r   r<   s    r   handle_ttinzArbiter.handle_ttin  s!    
 	Ar9   c                 n    | j                   dk  ry| xj                   dz  c_         | j                          y)zR        SIGTTOU handling.
        Decreases the number of workers by one.
        rL   Nr   r<   s    r   handle_ttouzArbiter.handle_ttou#  s2    
 q Ar9   c                     | j                   j                          | j                  t        j                         | j
                  r | j                  t        j                         yy)zU        SIGUSR1 handling.
        Kill all workers by sending them a SIGUSR1
        N)r#   rS   kill_workersr   SIGUSR1r-   r   r<   s    r   handle_usr1zArbiter.handle_usr1-  sF    
 	&..)!!##FNN3 "r9   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)reexecr<   s    r   handle_usr2zArbiter.handle_usr28  s     	r9   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)	r?   daemonr#   ri   rW   r   r   SIGTERMrZ   r<   s    r   handle_winchzArbiter.handle_winchA  sI    88??HHMM45 Dfnn-HHNN=>r9   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   rE   r   )r+   r   getppidr#   ri   r,   r?   rY   r    r(   renamer   r   r<   s    r   r   zArbiter.maybe_promote_masterJ  s    ??a??bjjl*HHMM56'DDO!XX//DN

>*||'##DHH$4$45}t~~=> +r9   c                 N    | j                   j                  | j                         y)z Wake up the arbiter's main loop.N)r&   r   WAKEUP_REQUESTr<   s    r   wakeupzArbiter.wakeup[  s    !!$"5"56r9   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#   ri   r   r,   r(   r   r?   on_exitr1   r   )r6   r   r   log_funcs       r   r   zArbiter.halt_  s    		$/1$4488==$((..$d&6&67\6*<<#LL!r9   c                    g }	 | j                   j                  d|      }|| j                  k7  r|j                  |       	 	 | j                   j	                         }|| j                  k7  r|j                  |       <# t
        j                  $ r Y |S w xY w# t
        j                  $ r Y |S t        $ r t        j                          Y |S w xY w)ze        Wait for signals with timeout.
        Returns a list of signals that were received.
        T)blockrX   )
r&   rk   r   rw   
get_nowaitr$   Emptyr   r1   r   )r6   rX   signalsr   s       r   r   zArbiter.wait_for_signalsm  s    
 	..$$4$ACd)))s#..335Cd111s+	 
 {{ 
 {{ 	  ! 	HHJ	s;   >B :A> =B >BB BB C.CC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                  r| j                  |       | j                  |       | }| j                   s| j                  r;t        j                         |k  r#|s	 | j"                  j%                         }|t        j&                  t        j                  fv r~| j(                  j+                  d       d}| j                  t        j                         | j                  r| j                  t        j                         t        j                         dz   }| j/                          | j1                          t        j2                  d       | j                   s| j                  rt        j                         |k  r#| j                  t        j4                         | j                  r| j                  t        j4                         | j/                          | j1                          y# t,        $ r Y w xY w)z        Stop workers

        :attr graceful: boolean, If True (the default) workers will be
        killed gracefully  (ie. trying to wait for the current connection)
        r   zQuick shutdown requestedT       @皙?N)r*   r+   r   r?   rx   r   close_socketsrq   r   r   SIGQUITtimegraceful_timeoutr-   r   r   WORKERSr&   r   SIGINTr#   ri   r   r   r   sleepSIGKILL)r6   gracefulr   r   limitquick_shutdownpending_sigs          r   r   zArbiter.stop  s    OOt3!3 (LL (HH''' 	
 	4>>62nn..C		dhh777 !!##C( 	#%||t55499;;N!"&..";";"=K"v}}fnn&EE&@A)-))&..911 33FNNC $		c 1 ##%JJsO# ||t55499;;N& 	&..)!!##FNN3! ! s   &B:J1 1	J=<J=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.rE   
LISTEN_PID
LISTEN_FDSrf   c              3   N   K   | ]  }t        |j                                 y wr;   )r|   fileno)r   r   s     r   r   z!Arbiter.reexec.<locals>.<genexpr>  s       .=&)CJJL!.=s   #%re   r   r   )r*   r#   warningr+   r   rl   forkr?   pre_execenv_origcopyr|   r   lenrq   r[   chdirr5   execvpe)r6   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Fr9   c                    | 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         | j8                  }t;        | j                   j<                        D ]  }| j?                           | jA                          tC        jD                         | j                   jF                  z   }tC        jD                         |k  r{| jH                  sy tK        d | jH                  jM                         D              }||kD  ry | jO                          tC        jP                  d       tC        jD                         |k  rzy y # t        $ r Y <w xY wc c}w )Nrf   zListening at: %sr   c              3   4   K   | ]  }|j                     y wr;   age)r   ws     r   r   z!Arbiter.reload.<locals>.<genexpr>  s     >1>s   r   ))r?   rU   r_   r   r   r    KeyErrorr7   r   r'   r#   rS   rq   closer   r{   r[   r|   ri   	on_reloadr(   r   r   rn   rm   r   r   rY   r)   rs   rV   spawn_workerr   r   	monotonicr   r   minvaluesr   r   )	r6   old_addressrb   r   r   last_worker_ager   deadlineoldests	            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	  	 >>#dhh&?&??nn)<<>(;(;(=>>F'JJsO nn)_   " &Js   4MM-	M*)M*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)rX   listr   r^   r   r  tmplast_updateOSError
ValueErrorabortedr#   criticalkill_workerr   SIGABRTr   )r6   rV   rm   workers       r   r   zArbiter.murder_workers$  s     ||t||))+,$ 	6MS&>>#fjj&<&<&>>$,,N O
 >>!!";SA!%  fnn5  fnn5	6 Z( s   <C++C=<C=c                    	 	 t        j                  dt         j                        \  }}|sy| j                  |k(  r	d| _        nd}t        j                  |      rt        j
                  |      }nt        j                  |      rt        j                  |      }	 t        j                  |      j                  }dj                  ||      }|t        j                  k(  r!|dz  }| j                  j                  |       nJ|t        j                   k(  r| j                  j#                  |       n| j                  j%                  |       |"|dk7  r| j                  j                  d||       || j&                  k(  rd}t)        || j&                        || j*                  k(  rd	}t)        || j*                        | j,                  j/                  |d      }|s|j0                  j3                          | j4                  j7                  | |       # t        $ r dj                  |      }Y ww xY w# t8        $ r(}	|	j:                  t:        j<                  k7  r Y d}	~	yd}	~	ww xY w)
z7        Reap workers to avoid zombie processes
        r   r   Nz	signal {}zWorker (pid:{}) was sent {}!z Perhaps out of memory?z$Worker (pid:%s) exited with code %s.zWorker failed to boot.zApp failed to load.)r   waitpidWNOHANGr*   	WIFEXITEDWEXITSTATUSWIFSIGNALEDWTERMSIGr   Signalsr   r  rH   r   r#   r   r   ri   r   WORKER_BOOT_ERRORr   APP_LOAD_ERRORr   ru   r  r  r?   
child_exitr  errnoECHILD)
r6   wpidstatusexitcoder   sig_namemsgr   r  es
             r   r   zArbiter.reap_workers9  s   4	!zz"bjj9f??d*&'DO
  $H||F+#%>>&#9/ kk&1?'-~~c':'?'?H =CC (, &..0#<<C HHNN3/ FNN2 HHMM#. !HH,,S1+A'M'+X7  4#9#99!9(1G1GHH4#6#66!6(1D1DEE!\\--dD9F! JJ$$&HH''f5a "  * ?'2'9'9#'>H?@  	ww%,,& '	sB   *H7 A/H7 H <EH7 H40H7 3H44H7 7	I( I##I(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  r7|| _
        | j                  j                  dj                  |      d|dd       | j                  j                  rSt!        d	 | j"                  D              }|dk\  r1| j                  j                  d
j                  |      d|dd       yyy)z[        Maintain the number of workers by spawning or killing
        as required.
        c                      | d   j                   S rK   r  )r  s    r   rO   z(Arbiter.manage_workers.<locals>.<lambda>|  s    ! r9   rP   r   z{0} workerszgunicorn.workersgauge)metricrA   mtype)extrac              3   F   K   | ]  } |j                          xs d   yw)r   N)get_backlog)r   r   s     r   r   z)Arbiter.manage_workers.<locals>.<genexpr>  s+      6" +$**,11 6s   !zsocket backlog: {0}zgunicorn.backlog	histogramN)r   r   rW   spawn_workersr^   r\   ru   r  r   r   r"   r#   rZ   rH   r?   enable_backlog_metricsumrq   )r6   rV   rm   r   active_worker_countbacklogs         r   r   zArbiter.manage_workerss  sS   
 t||t/// ,,$$&&89'lT---{{1~HS!S&..1 'lT--- "'l004GG4GD1HHNN=//0CD,>+>+2"4  5
 88)) 6&*nn6 6G !|4;;GD0B/6/:&<  = 	 *r9   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(                  r/t+        j,                  | j                  | j                        |_        | j                  j1                  | |       |j3                          t5        j6                  d       | j                  j'                  d|j                         	 |j                  j                          | j                  jO                  | |       y # t8        $ r  t:        $ r}| j                  j=                  dd       t?        d	|z  t4        j@                  
       t4        j@                  jC                          t5        j6                  | jD                         Y d }~d }~wtF        $ r}| j                  jI                  d       t?        d	|z  t4        j@                  
       t4        j@                  jC                          |jJ                  st5        j6                  | jL                         t5        j6                  d       Y d }~d }~ww xY w# tF        $ r1 | j                  jQ                  dtS        jT                                Y y w xY w# | j                  j'                  d|j                         	 |j                  j                          | j                  jO                  | |       w # tF        $ r1 | j                  jQ                  dtS        jT                                Y w w xY wxY w)NrL   r   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)   rT   rm   rq   r7   rX   r?   r#   pre_forkr   r   r   r
  r  r  rl   r   r   rY   ri   rx   r   r{   sockets	post_forkinit_processr1   r   r   r   rZ   printstderrflushr#  r   	exceptionbootedr"  worker_exitr   	traceback
format_exc)r6   r  rm   siblingr,  s        r   r  zArbiter.spawn_worker  s   1""4??DHHdnn#'88T\\C-?#'88TXX7 	$'ggi!8FJ &DLLJ ||**, 	 GKK	  YY[
	9}t~~=>HHMM7Dxx""!%!4!4TXXtxx!HHHtV,!HHQK" HHMM4fjjA9

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

  "$$T62 9  !D!*!5!5!799su   CI 6N M?A8KN? M?BM:4N? :M??N? 7N<;N<?'Q'6PQ7QQQQ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)rs   rW   r   r   r  r   r   random)r6   r   s     r   r6  zArbiter.spawn_workers  sO     t''#dll*;;< 	.AJJsV]]_,-	.r9   c                 |    t        | j                  j                               }|D ]  }| j                  ||        y)z^        Kill all workers with the signal `sig`
        :attr sig: `signal.SIG*` value
        N)r  r   keysr  )r6   r   worker_pidsrm   s       r   r   zArbiter.kill_workers  s:    
 4<<,,./ 	'CS#&	'r9   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   ru   r  r  r?   rF  r  )r6   rm   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c                     ddl }| j                  j                  dd      j                  dd      }t        j                  j                  |j                         d| d      S )a)  Get the well-known PID file path for orphan detection.

        Uses self.proc_name (not self.cfg.proc_name) so that during USR2
        the new master gets a different PID file path ("myapp.2" vs "myapp").
        This prevents the old dirty arbiter from removing the new one's PID file.
        r   N/r    zgunicorn-dirty-z.pid)tempfilerY   replacer   pathr[   
gettempdir)r6   rU  	safe_names      r   _get_dirty_pidfile_pathzArbiter._get_dirty_pidfile_path  sQ     	NN**34<<S#F	ww||H//1_YKt3TUUr9   c                    | j                   dk7  ry| j                         }t        j                  j	                  |      sy	 t        |      5 }t        |j                         j                               }ddd       t        j                  d       | j                  j                  d|       t        j                  |t        j                         t        d      D ].  }t        j                   d       	 t        j                  |d       0 t        j                  |t        j$                         	 t        j*                  |       y# 1 sw Y   xY w# t"        $ r Y  /w xY w# t&        t(        t"        f$ r Y Iw xY w# t"        $ r Y yw xY w)zKill any orphaned dirty arbiter from a previous crash.

        Only runs on fresh start (master_pid == 0), not during USR2.
        r   Nz(Killing orphaned dirty arbiter (pid: %s)
   r   )r+   rZ  r   rW  existsopenrj   readstriprP  r#   r   r   r   rs   r   r   r  r   r  IOErrorr   )r6   r(   fold_pidr   s        r   _cleanup_orphaned_dirty_arbiterz'Arbiter._cleanup_orphaned_dirty_arbiter  s;    ??a..0ww~~g&	g 0!affhnn./0 GGGQHHGQGGGV^^,2Y 1

3GGGQ'1 0
	IIg-0 0   GW- 		  		sa   E& (E
5BE& 7E&E& 4F  
EE& 	E#E& "E##E& &E=<E= 	FFc                    | j                   ry| j                          | j                         | _        t	        | j
                  | j                  | j                        | _        | j                  j                  }t        j                         }|dk7  rD|| _         t        |       |t        j                  d<   | j                  j                  d||       |S 	 | j                  j                          t        j                   d       y# t"        $ r  t$        $ r3 | j                  j'                  d       t        j                   d       Y yw xY w)z        Spawn the dirty arbiter process.

        The dirty arbiter manages a separate pool of workers for
        long-running, blocking operations.
        N)r(   r   GUNICORN_DIRTY_SOCKETz%Spawned dirty arbiter (pid: %s) at %sz"Exception in dirty arbiter processr   )r-   rd  rZ  r/   r   r?   r#   r.   socket_pathr   r   r   r    ri   r   r1   r   r   r   rD  )r6   rg  rm   s      r   r   zArbiter.spawn_dirty_arbiter%  s    !! 	,,. "99;)HHdhh&&
 ((44ggi!8%(D"!+.2=BJJ./HHMMA{,J	""$HHQK 	 	HHCDHHRL	s   /D AEEc                     | j                   sy	 t        j                  | j                   |       y# t        $ r:}|j                  t        j
                  k(  rd| _         d| _        Y d}~yY d}~yd}~ww xY w)z\        Send a signal to the dirty arbiter.

        :attr sig: `signal.SIG*` value
        Nr   )r-   r   rP  r  r%  rQ  r.   )r6   r   r,  s      r   r   zArbiter.kill_dirty_arbiterP  sa     %%	*GGD**C0 	*ww%++%)*&%)"" &	*s    0 	A3+A..A3c                    | j                   sy	 t        j                  | j                   t        j                        \  }}|syt        j                  |      rUt        j
                  |      }|dk7  r| j                  j                  d||       nd| j                  j                  d|       nGt        j                  |      r2t        j                  |      }| j                  j                  d||       d| _         d| _        y# t        $ r:}|j                  t        j                  k(  rd| _         d| _        Y d}~yY d}~yd}~ww xY w)zA        Reap the dirty arbiter process if it has exited.
        Nr   z*Dirty arbiter (pid:%s) exited with code %szDirty arbiter (pid:%s) exitedz*Dirty arbiter (pid:%s) killed by signal %s)r-   r   r  r  r  r  r#   r   ri   r  r   r   r.   r  r%  r&  )r6   r'  r(  r)  r   r,  s         r   r   zArbiter.reap_dirty_arbiter`  s    %%	*::d&<&<bjjILD&||F#>>&1q=HHNN#O#'3 HHMM"A4H'kk&)  !M!%s, &'D"!%D 	*ww%,,&)*&%)"" '	*s   3D B?D 	E+EEc                     | j                   ry| j                  j                  dkD  rC| j                  j                  r,| j                  j                  d       | j                          yyy)zL        Maintain the dirty arbiter process by respawning if needed.
        Nr   zSpawning dirty arbiter...)r-   r?   r   r   r#   ri   r   r<   s    r   r   zArbiter.manage_dirty_arbiter  sS     !!88!!A%$((*=*=HHMM56$$& +>%r9   )Nr   )r   )T);__name__
__module____qualname____doc__r"  r#  r5   rq   r   r   NSIGr   rv   r   r   dictdirr   r8   r=   rC   propertyrW   r'   r   rp   r   r   r   
handle_cldr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r6  r   r  rZ  rd  r   r   r   r   )r   xr   r   s   0000r   r   r      sr     NIIG [[N FKKMO O vw{+ OG >A&k I
"
H!: +-=>K@4"l
8'*X'" J3

	4??"724"l GDDL6*8t=@09d
.'0	V&P)V* *>	'eOs   C+
r   )r%  r   r$   rK  r   r1   r   rG  rz   gunicorn.errorsr   r   gunicorn.pidfiler   gunicornr   r   r   r	   r
   gunicorn.dirtyr   r   r   rM   r9   r   <module>ry     s@     	    
    6 $ ( ( 1 >r' r'r9   