
    F
i                         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  G d d          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e	j
        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eZd Zd Zd Zd Z d Z!d Z"d Z#d Z$d Z%d Z&d Z'd5dZ(d6d Z)d7d"Z*d# Z+d$ Z,d% Z-d& Z.d' Z/d( Z0d) Z1d* Z2d+ Z3d, Z4d- Z5d. Z6d/ Z7d0 Z8d1 Z9d2 Z:d3 Z;d4 Z<dS )8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     C:\Users\Dell Inspiron 16\Desktop\tws\AgrotaPowerBi\back-agrota-powerbi\mcp-client-agrota\venv\Lib\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>0   sk        6:8uaC 
		QRR 0 01!/ r   c                    t           t          j        d<   d | _        d | _        d | _        t          j                    | _        | 	                    |           d | _
        d| _        d| _        d| _        d| _        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)
start_timeworkers_spawnedworkers_killedreloads)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_pidfile_control_server_statsr   getcwdsysargvinsert
executable	START_CTX)selfappr$   r#   s       r   __init__zArbiter.__init__5   s   (7
$% 04- *,,

3# "#!!  $  	
 
 kmmx{As~&&& ~
 
r   c                     | j         S N)r'   r>   s    r   _get_num_workerszArbiter._get_num_workersd   s      r   c                 Z    | j         }|| _         | j                            | ||           d S rB   )r'   cfgnworkers_changed)r>   value	old_values      r   _set_num_workerszArbiter._set_num_workersg   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_PIDzCurrent configuration:
{0}
c              3   R   K   | ]"\  }}d                      ||j                  V  #dS )z
  {0}: {1}N)formatrH   )r   configrH   s      r   r   z Arbiter.setup.<locals>.<genexpr>   sL       ; ;!FE ##FEK88; ; ; ; ; ;r   c                     | d         S N    )settings    r   <lambda>zArbiter.setup.<locals>.<lambda>   s
    gaj r   key)r?   rF   r)   logger_classr%   r&   reopen_filesworker_classaddressworkersnum_workerstimeout	proc_namedebugrO   joinsortedsettingsitemsenvpreload_appwsgi)r>   r?   kvs       r   r-   zArbiter.setupm   s~   78x,,SW55DH RZ''H!!### H1x'8+x'+4;;II ; ; $(+113388: : :; ; ; ; ;< < 	= 	= 	= 8< 	"**,, " "1 !
18 	HMMOOOOO	 	r   c                    | j                             dt                     t          j                    | j        d<   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          |                     %| j        j        rt;          t<          d          s%t?          j         | j        | j         |          | _        d
!                    d | j        D                       }| j         "                    d           | j                             d|| j                   | j                             d| j        j#                   t+          j$        d| j                    t;          | j%        d          r%| j%        &                    | j        | j                    | j        j'        dk    r | j        j(        r| )                                 | *                                 | j        +                    |            dS )zS        Initialize the arbiter. Start listening and set pidfile if needed.
        zStarting gunicorn %sr   rL   z.2zMaster.2Nr   TGUNICORN_FD,SO_REUSEPORTc                 ,    g | ]}t          |          S rT   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	   timer7   r%   r&   intgetr1   r`   r2   getpidpidrF   r.   r   createon_startinginit_signals	LISTENERSr   
listen_fdsrangeSD_LISTEN_FDS_STARTpopsplitappend
reuse_porthasattrsocketr   create_socketsrb   ra   worker_class_str	sd_notifyr[   rt   dirty_workers
dirty_appsspawn_dirty_arbiter_start_control_server
when_ready)r>   pidnamefdsr   fdlisteners_strs         r   startzArbiter.start   s    	,k::: %)IKKL!RZ''!"*.."@"@AADO!^d2DN)D9;;8'h&G!##4"7++DLL)))T"""~ 	NC +--J (#G7#7*DF F  (*..77==cBB ( (BJJs2ww''''H' NGFN,K,K N!%!4TXtx!M!M!E!Edn!E!E!EFF'(((-}dhGGG($(*CDDDCTXNNN 4$n55 	?**48TX>>> 8!A%%$(*=%$$&&& 	""$$$D!!!!!r   c                     | 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)r)   close_on_execSIGNALSr   SIGCHLDsignal_chld)r>   ss     r   r}   zArbiter.init_signals   s_    
 	     	* 	*AM!T[))))fnd&677777r   c                 :    | j                             |           dS )z3Signal handler - NO LOGGING, just queue the signal.Nr,   
put_nowaitr>   sigframes      r   r   zArbiter.signal       !!#&&&&&r   c                 x   |                                   t          j        d| j        z             	 |                                  	 |                                  |                     d          D ]}|| j        vr| j        	                    d|           '| j        
                    |          }t          | d|z  d          }|s| j                            d|           s|t          j        k    r| j        j        n| j        j	        } |d	|            |             |                                  |                                  |                                  # t$          t&          f$ r |                                  Y dS t*          $ r,}|                     |j        |j        
           Y d}~dS d}~wt0          $ r  t2          $ ri | j                            dd           |                     d           | j        | j                                         t;          j        d           Y dS w xY w)zMain master loop.master [%s]T      ?)r_   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   _setproctitler`   manage_workersmaybe_promote_masterwait_for_signals	SIG_NAMESr)   ru   rx   r   errorr   r   ra   murder_workersmanage_dirty_arbiterStopIterationKeyboardInterrupthaltr   r   r   
SystemExit	Exceptionstopr.   unlinkr9   exit)r>   r   signamehandler	log_levelinsts         r   runzArbiter.run   sj   

=4>9:::%	!!!,))+++  000==  C$.00&CSIII "n0055G%dK',A4HHG" !'=wGGG 252G2GTX]II3W===GIIII##%%%##%%%))++++,, 01 	 	 	IIKKKKKK 	H 	H 	HIIT[d6FIGGGGGGGGG 	 	 	 	 	 	HNN=$(  * * *IIe|'##%%%HRLLLLLL	s%   D/E! !%H9		H9!F99A<H98H9c                 :    | j                             |           dS )z;SIGCHLD signal handler - NO LOGGING, just queue the signal.Nr   r   s      r   r   zArbiter.signal_chld  r   r   c                 V    |                                   |                                  dS )z6SIGCHLD handling - called from main loop, safe to log.N)reap_workersreap_dirty_arbiterrC   s    r   handle_chldzArbiter.handle_chld	  s,    !!!!!r   c                     | j                             d| j                   |                                  | j        r!|                     t          j                   dS 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)   ru   r2   reloadr3   kill_dirty_arbiterr   SIGHUPrC   s    r   
handle_hupzArbiter.handle_hup  s[     	mT%5666! 	3##FM22222	3 	3r   c                     t           )zSIGTERM handling)r   rC   s    r   handle_termzArbiter.handle_term  s    r   c                 :    |                      d           t          )zSIGINT handlingFr   r   rC   s    r   
handle_intzArbiter.handle_int#      		%r   c                 :    |                      d           t          )zSIGQUIT handlingFr   rC   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.
        rS   Nr^   r   rC   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.
        rS   Nr   rC   s    r   handle_ttouzArbiter.handle_ttou5  sC    
 q  FAr   c                     | j                                          |                     t          j                   | j        r!|                     t          j                   dS dS )zU        SIGUSR1 handling.
        Kill all workers by sending them a SIGUSR1
        N)r)   rZ   kill_workersr   SIGUSR1r3   r   rC   s    r   handle_usr1zArbiter.handle_usr1?  s_    
 	&.)))! 	4##FN33333	4 	4r   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)reexecrC   s    r   handle_usr2zArbiter.handle_usr2J  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)	rF   daemonr)   ru   r^   r   r   SIGTERMra   rC   s    r   handle_winchzArbiter.handle_winchS  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   rL   r   )r1   r%   getppidr)   ru   r2   rF   r`   r&   r.   renamer   r   rC   s    r   r   zArbiter.maybe_promote_master\  s    ?aF?bjll**HMM5666'DDO!X/DN
>*|'##DH$4555}t~=>>>>> +*r   c                 D    | j                             | j                   dS )z Wake up the arbiter's main loop.N)r,   r   WAKEUP_REQUESTrC   s    r   wakeupzArbiter.wakeupm  s!    !!$"566666r   Nr   c                 l   |                                   |                                  |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)_stop_control_serverr   r)   ru   r   r2   r.   r   rF   on_exitr9   r   )r>   r   r   log_funcs       r   r   zArbiter.haltq  s     	!!###		$/1$4$448==$(.$d&6777H\6***<#L!!!r   r   c                    g }	 | j                             d|          }|| j        k    r|                    |           	 	 | j                                         }|| j        k    r|                    |           n# t
          j        $ r Y nw xY wQn3# t
          j        $ r Y n"t          $ r t          j	                     Y nw xY w|S )ze        Wait for signals with timeout.
        Returns a list of signals that were received.
        T)blockr_   )
r,   rx   r   r   
get_nowaitr*   Emptyr   r9   r   )r>   r_   signalsr   s       r   r   zArbiter.wait_for_signals  s    
 	.$$4$AACd)))s###.3355Cd111s+++{   E { 	 	 	D  	 	 	HJJJJJ	s;   =B 9A< ;B <BB BB C$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        r|                     |           |                     |           | }| j        s| j        r8t          j                    |k     r |s	 | j                                        }|t          j        t          j
        fv rw| j                            d           d}|                     t          j
                   | j        r|                     t          j
                   t          j                    dz   }n# t,          $ r Y nw xY w|                                  |                                  t          j        d           | j        s| j        rt          j                    |k      |                     t          j                   | j        r|                     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   zQuick shutdown requestedT       @皙?N)r0   r1   r   rF   r   r   close_socketsr~   r   r   SIGQUITrv   graceful_timeoutr3   r   r   WORKERSr,   r   SIGINTr)   ru   r   r   r   sleepSIGKILL)r>   gracefulr   r   limitquick_shutdownpending_sigs          r   r   zArbiter.stop  se    Ot3333!3333 (L (H'' 	
 	4>6222n 	!.C	dh77 ! 	)##C((( 	#%| 	t5 	49;;;N;N! "&.";";"="=K"v}fn&EEE&@AAA)-))&.9991 D 33FNCCC $	c 1    D##%%%JsOOO# | 	t5 	49;;;N;N& 	&.)))! 	4##FN333!!!!!s   )B*F 
F! F!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.rL   
LISTEN_PID
LISTEN_FDSrm   c              3   X   K   | ]%}t          |                                          V  &d S rB   )rq   filenorr   s     r   r   z!Arbiter.reexec.<locals>.<genexpr>  sC       .= .=&)CJJLL!!.= .= .= .= .= .=r   rl   r$   r#   )r0   r)   warningr1   r%   ry   forkrF   pre_execenv_origcopyrq   r   lenr~   rb   chdirr=   execvpe)r>   r1   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                    | j         dxx         dz  cc<   | 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                   t3          j        d| j        z             | j        }t;          | j        j                  D ]}|                                  |                                   tC          j"                    | j        j#        z   }tC          j"                    |k     r| j$        sd S tK          d | j$        &                                D                       }||k    rd S | '                                 tC          j(        d           tC          j"                    |k     d S d S )	Nr"   rS   rm   c                 ,    g | ]}t          |          S rT   rp   rr   s     r   r   z"Arbiter.reload.<locals>.<listcomp>  s    %I%I%I3c#hh%I%I%Ir   zListening at: %sr   c              3   $   K   | ]}|j         V  d S rB   age)r   ws     r   r   z!Arbiter.reload.<locals>.<genexpr>6  s$      >>1>>>>>>r   r   ))r7   rF   r\   rf   r  r%   r&   KeyErrorr?   r   r-   r)   rZ   r~   closer   r   rb   ru   	on_reloadr.   r   r   r{   rz   r   r   r`   r/   r   r]   spawn_workerr   rv   	monotonicr   r   minvaluesr   r   )	r>   old_addressri   rs   r   last_worker_ager   deadlineoldests	            r   r   zArbiter.reload  s   I!#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 	 >##dh&??n))< >>(;(;(=(=>>>>>F''JsOOO n))))))s   A--
A:9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)r_   listr   re   rv   r  tmplast_updateOSError
ValueErrorabortedr)   criticalkill_workerr   SIGABRTr   )r>   r]   rz   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| _        nd}t          j        |          rt          j        |          }nt          j        |          rt          j        |          }	 t          j	        |          j
        }n%# t          $ r d                    |          }Y nw xY wd                    ||          }|t          j        k    r |dz  }| j                            |           nE|t          j        k    r| j                            |           n| j                            |           |"|dk    r| j                            d||           || j        k    rd	}t)          || j                  || j        k    rd
}t)          || j                  | j                            |d          }|s|j                                         | j                            | |           # t8          $ 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   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WNOHANGr0   	WIFEXITEDWEXITSTATUSWIFSIGNALEDWTERMSIGr   Signalsr   r!  rO   r   r)   r   r   ru   r  WORKER_BOOT_ERRORr   APP_LOAD_ERRORr   r   r  r  rF   
child_exitr   errnoECHILD)
r>   wpidstatusexitcoder   sig_namemsgr   r&  es
             r   r   zArbiter.reap_workersQ  s{   4	06!z"bj99f E?d**&'DOO
  $H|F++ 2#%>&#9#9// 2 k&11?'-~c':':'?HH) ? ? ?'2'9'9#'>'>HHH?<CC (, , &.00#<<C HNN3//// FN22 HMM#.... !H,,S111+A'M'+X7 7 7  4#999!9(1GHHH4#666!6(1DEEE!\--dD99F! ! J$$&&&H''f555a06b  	 	 	w%,&& '&&&&&	sB   %H A'H B+ *H +C
H CEH 
I"H>>I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           | j        j        rYt!          d	 | j        D                       }|dk    r7| j                            d
                    |          d|dd           dS dS dS )z[        Maintain the number of workers by spawning or killing
        as required.
        c                     | d         j         S rR   r  )r  s    r   rV   z(Arbiter.manage_workers.<locals>.<lambda>  s    ! r   rW   r   z{0} workerszgunicorn.workersgauge)metricrH   mtype)extrac              3   8   K   | ]} |j                     pd V  dS )r   N)get_backlog)r   r   s     r   r   z)Arbiter.manage_workers.<locals>.<genexpr>  sF       6 6" +$*,,1 6 6 6 6 6 6r   zsocket backlog: {0}zgunicorn.backlog	histogramN)r  r   r^   spawn_workersre   rc   r   r$  r   r   r(   r)   ra   rO   rF   enable_backlog_metricsumr~   )r>   r]   rz   r   active_worker_countbacklogs         r   r   zArbiter.manage_workers  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
 8) 	= 6 6&*n6 6 6 6 6G !||4;;GDD0B/6/:&< &<  = = = = =	= 	= |r   c           	      
   | xj         dz  c_         |                     | j         | j        | j        | j        | j        dz  | j        | j                  }| j                            | |           t          j
                    }|dk    r(||_        || j        |<   | j        dxx         dz  cc<   |S | j                                        D ]}|j                                         t          j                    |_        	 t#          j        d| j        z             | j                            d|j                   | j        j        r$t-          j        | j        | j                  |_        | j                            | |           |                                 t7          j        d           n.# t:          $ r  t<          $ r{}| j                            dd	           tA          d
|z  t6          j!                   t6          j!        "                                 t7          j        | j#                   Y d }~nd }~wtH          $ r}| j        %                    d           tA          d
|z  t6          j!                   t6          j!        "                                 |j&        st7          j        | j'                   t7          j        d           Y d }~nd }~ww xY w| j                            d|j                   	 |j                                         | j        (                    | |           d S # tH          $ r0 | j        )                    dtU          j+                               Y d S w xY w# | j                            d|j                   	 |j                                         | j        (                    | |           w # tH          $ r/ | j        )                    dtU          j+                               Y w w xY wxY w)NrS   r   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/   r[   rz   r~   r?   r_   rF   r)   pre_forkr%   r  r   r7   r  r  r  ry   r   r   r`   ru   r   r   r   sockets	post_forkinit_processr9   r   r   r   ra   printstderrflushr0  r   	exceptionbootedr/  worker_exitr  	traceback
format_exc)r>   r&  rz   siblingr9  s        r   r  zArbiter.spawn_worker  s   1""4?DHdn#'8T\C-?#'8TX7 7 	$'''gii!88FJ &DLK)***a/***J |**,, 	  	 GK Y[[
	9}t~=>>>HMM7DDDx" I!%!4TXtx!H!HHtV,,,!!!HQKKKK 	 	 	 	* 	* 	*HNND$(  * * *$(,,,,JHT()))))))) 	 	 	H<===$(,,,,J= 1/000HRLLLLLLLL	 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9s{   <B/F- +M/ -KA1H72M/ 7KB
KM/ KM/ <4L2 26M,+M,/!P4OP6O?<P>O??P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)r   r^   r  r   r  rv   r   random)r>   r   s     r   rC  zArbiter.spawn_workers  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$  )r>   r   worker_pidsrz   s       r   r   zArbiter.kill_workers  sQ    
 4<,,..// 	' 	'CS#&&&&	' 	'r   c                    	 t          j        ||           |t          j        t          j        fv r| j        dxx         dz  cc<   dS 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
         r!   rS   N)r%   killr   r   r   r7   r   r2  ESRCHr   r   r  r  rF   rS  r  )r>   rz   r   r9  r&  s        r   r$  zArbiter.kill_worker  s   	GCv~v~666,---2----- 76 		 		 		w%+%%!\--c22FJ$$&&&H((v666FFFFF '*   FFFFFF		s7   AA
 

C C*AB>>CCCCC c                     ddl }| j                            dd                              dd          }t          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)tempfiler`   replacer%   pathrb   
gettempdir)r>   rb  	safe_names      r   _get_dirty_pidfile_pathzArbiter._get_dirty_pidfile_path  sb     	N**344<<S#FF	w||H//113TY3T3T3TUUUr   c                 >   | j         dk    rdS |                                 }t          j                            |          sdS 	 t          |          5 }t          |                                                                          }ddd           n# 1 swxY w Y   t          j	        |d           | j
                            d|           t          j	        |t          j                   t          d          D ]=}t          j        d           	 t          j	        |d           -# t"          $ r Y  n#w xY wt          j	        |t          j                   n# t&          t(          t"          f$ r Y nw xY w	 t          j        |           dS # t"          $ r Y dS 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   )r1   rg  r%   rd  existsopenrw   readstripr]  r)   r  r   r   r   rv   r   r   r   r!  IOErrorr   )r>   r.   fold_pidr   s        r   _cleanup_orphaned_dirty_arbiterz'Arbiter._cleanup_orphaned_dirty_arbiter  s    ?aF..00w~~g&& 	F	g 0!affhhnn..//0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 GGQHGQQQGGV^,,,2YY 1 1
3GGQ''''   EE 000GW- 	 	 	D		Ig 	 	 	DD	sm   E 4BE BE BA7E D)(E )
D73E 6D77"E E43E48F 
FFc                 |   ddl m}m} | j        rdS |                                  |                                 | _         || j        | j        | j                  | _	        | j	        j
        }t          j                    }|dk    r?|| _         ||           |t          j        d<   | j                            d||           |S 	 | j	                                         t!          j        d           dS # t$          $ r  t&          $ r2 | j                            d           t!          j        d           Y dS w xY w)	z        Spawn the dirty arbiter process.

        The dirty arbiter manages a separate pool of workers for
        long-running, blocking operations.
        r   )DirtyArbiterset_dirty_socket_pathN)r.   GUNICORN_DIRTY_SOCKETz%Spawned dirty arbiter (pid: %s) at %sz"Exception in dirty arbiter processr   )gunicorn.dirtyrs  rt  r3   rq  rg  r5   rF   r)   r4   socket_pathr%   r  r&   ru   r   r9   r   r   r   rQ  )r>   rs  rt  rw  rz   s        r   r   zArbiter.spawn_dirty_arbiterA  sp    	GFFFFFFF! 	F 	,,... "99;;)\Hdh&
 
 
 (4gii!88%(D"!!+...2=BJ./HMMA{, , ,J	""$$$HQKKKKK 	 	 	 	 	 	HCDDDHRLLLLLL	s   -C5 5AD;:D;c                     | j         sdS 	 t          j        | j         |           dS # t          $ r4}|j        t          j        k    rd| _         d| _        Y d}~dS Y d}~dS d}~ww xY w)z\        Send a signal to the dirty arbiter.

        :attr sig: `signal.SIG*` value
        Nr   )r3   r%   r]  r   r2  r^  r4   )r>   r   r9  s      r   r   zArbiter.kill_dirty_arbitero  s     % 	F	*GD*C00000 	* 	* 	*w%+%%)*&%)""""""" &%%%%%	*s   ' 
A%#A  A%c                 d   | j         sdS 	 t          j        | j         t          j                  \  }}|sdS t          j        |          rSt          j        |          }|dk    r| j                            d||           n`| j                            d|           nDt          j	        |          r0t          j
        |          }| j                            d||           d| _         d| _        dS # t          $ r4}|j        t          j        k    rd| _         d| _        Y d}~dS Y d}~dS 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)r3   r%   r(  r)  r*  r+  r)   r   ru   r,  r-  r  r4   r   r2  r3  )r>   r4  r5  r6  r   r9  s         r   r   zArbiter.reap_dirty_arbiter  sj    % 	F	*:d&<bjIILD& |F## 
,>&11q==HNN#O#'3 3 3 3 HMM"A4HHHH'' ,k&))  !M!%s, , , &'D"!%D 	* 	* 	*w%,&&)*&%)""""""" '&&&&&	*s   )C1 B9C1 1
D/;#D**D/c                     | j         rdS | j        j        dk    r<| j        j        r2| j                            d           |                                  dS dS dS )zL        Maintain the dirty arbiter process by respawning if needed.
        Nr   zSpawning dirty arbiter...)r3   rF   r   r   r)   ru   r   rC   s    r   r   zArbiter.manage_dirty_arbiter  si     ! 	F8!A%%$(*=%HMM5666$$&&&&& &%%%r   c                     | j         j        }t          j                            |          s1t          j                            t          j                    |          }|S )z<Get the control socket path, making relative paths absolute.)rF   control_socketr%   rd  isabsrb   r   r8   )r>   rw  s     r   _get_control_socket_pathz Arbiter._get_control_socket_path  sD    h-w}}[)) 	C',,t{}}kBBKr   c                 n   | j         j        r| j                            d           dS ddlm} |                                 }| j         j        }	  || ||          | _        | j        	                                 dS # t          $ r-}| j                            d|           d| _        Y d}~dS d}~ww xY w)z        Start the control socket server.

        The server runs in a background thread and accepts commands
        via Unix socket.
        zControl socket disabledNr   )ControlSocketServerz"Failed to start control socket: %s)rF   control_socket_disabler)   ra   gunicorn.ctl.serverr  r~  control_socket_moder6   r   r   r  )r>   r  rw  socket_moder9  s        r   r   zArbiter._start_control_server  s     8* 	HNN4555F 	<;;;;;3355h2	(#6#6k;$ $D   &&((((( 	( 	( 	(HA1EEE#'D       	(s   +A= =
B4"B//B4c                     | j         rV	 | j                                          n2# t          $ r%}| j                            d|           Y d}~nd}~ww xY wd| _         dS dS )z0        Stop the control socket server.
        z!Error stopping control server: %sN)r6   r   r   r)   ra   )r>   r9  s     r   r   zArbiter._stop_control_server  s      	(G$))++++ G G GBAFFFFFFFFG#'D   	( 	(s   # 
AAA)Nr   )r   )T)=__name__
__module____qualname____doc__r/  r0  r=   r~   r   r   NSIGr   r   r   dictdirr   r@   rD   rJ   propertyr^   r-   r   r}   r   r   r   
handle_cldr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  rC  r   r$  rg  rq  r   r   r   r   r~  r   r   rT   r   r   r   r      s_          NIIG [NO OEKKMMO O OG  >Ac&kk    I
-
 -
 -
^! ! !: : : (+-=>>K  @:" :" :"x
8 
8 
8' ' '* * *X' ' '" " " J3 3 3    
  
    	4 	4 	4  ? ? ?? ? ?"7 7 7   "   24" 4" 4" 4"l G  G  GDG G GR6 6 6*8 8 8t= = =@19 19 19f
. 
. 
.' ' '  6	V 	V 	V& & &P, , ,\* * * * * *>	' 	' 	'  ( ( (4	( 	( 	( 	( 	(r   r   )r2  r%   r*   rX  r   r9   rv   rT  r   gunicorn.errorsr   r   gunicorn.pidfiler   gunicornr   r   r   r	   r
   r   rT   r   r   <module>r     s     				    



       6 6 6 6 6 6 6 6 $ $ $ $ $ $ ( ( ( ( ( ( ( ( ( ( 1 1 1 1 1 1 1 1
@( @( @( @( @( @( @( @( @( @(r   