
    AҐiG                     <    d Z ddlZddlZddlZddlZ G d d      Zy)zn
Control Interface Command Handlers

Provides handlers for all control commands with access to arbiter state.
    Nc                      e Zd ZdZd ZdefdZdefdZdefdZdefdZ	defdZ
dd	edefd
Zdd	edefdZdedefdZdd	edefdZdd	edefdZded	edefdZdefdZdefdZddedefdZdefdZdefdZdefdZy)CommandHandlersz
    Command handlers with access to arbiter state.

    All handler methods return dictionaries that will be sent
    as the response data.
    c                     || _         y)z
        Initialize handlers with arbiter reference.

        Args:
            arbiter: The Gunicorn arbiter instance
        N)arbiter)selfr   s     N/var/www/descvideos/venv/lib/python3.12/site-packages/gunicorn/ctl/handlers.py__init__zCommandHandlers.__init__   s         returnc           	         g }t        j                         }| j                  j                  j	                         D ]d  \  }}	 |j
                  j                         }t        ||z
  d      }|j                  ||j                  |j                  |j                  |d       f |j                  d        |t        |      dS # t        t        f$ r d}Y kw xY w)a}  
        Return list of HTTP workers.

        Returns:
            Dictionary with workers list containing:
            - pid: Worker process ID
            - age: Worker age (spawn order)
            - requests: Number of requests handled (if available)
            - booted: Whether worker has finished booting
            - last_heartbeat: Seconds since last heartbeat
           N)pidagebootedabortedlast_heartbeatc                     | d   S Nr    ws    r   <lambda>z.CommandHandlers.show_workers.<locals>.<lambda>A   s
    1U8 r
   key)workerscount)time	monotonicr   WORKERSitemstmplast_updateroundOSError
ValueErrorappendr   r   r   sortlen)r   r   nowr   workerr"   r   s          r   show_workerszCommandHandlers.show_workers"   s     nn<<//557 	KC&$jj446!&s['8!!< NNzz --!>>"0 	  	+,"S\:: Z( &!%&s   )CCCc                 0   | j                   j                  sddg g dS t        | j                   dd      }g }g }|r%t        |d      rt	        j
                         }|j                  j                         D ]f  \  }}	 |j                  j                         }t        ||z
  d      }|j                  ||j                  t        |dg       t        |dd      |d	       h t        |d
      ru|j                   j                         D ]X  \  }	}
t#        |j$                  j'                  |	g             }|j                  |	|
j'                  d      t)        |      |d       Z d| j                   j                  ||dS # t        t        t        f$ r d}Y w xY w)a%  
        Return dirty workers and apps information.

        Returns:
            Dictionary with:
            - enabled: Whether dirty arbiter is running
            - pid: Dirty arbiter PID
            - workers: List of dirty worker info
            - apps: List of dirty app specs
        FN)enabledr   r   appsdirty_arbiterr   r   	app_pathsr   )r   r   r.   r   r   	app_specsworker_count)import_pathr2   current_workersworker_pidsT)r   dirty_arbiter_pidgetattrhasattrr   r   r   r    r!   r"   r#   r$   r%   AttributeErrorr&   r   r1   listapp_worker_mapgetr(   )r   r/   r   r.   r)   r   r*   r"   r   pathspecr5   s               r   
show_dirtyzCommandHandlers.show_dirtyE   s    ||-- 	   otDW]I>.."C,44::< V*"(**"8"8":K%*3+<a%@N !::#FK<%fh>&4    }k2"/"9"9"?"?"A JD$"&}'C'C'G'Gb'Q"RKKK'+(,(@+.{+;'2	!  <<11	
 	
-  ^< *%)N*s   >)E<<FFc                 R   | j                   j                  }i }g d}|D ]v  }	 t        ||      }t        |      rt	        |      }nKt        |d      r?t        |t        t        t        t        t        t        t        d      f      st	        |      }|||<   x |S # t        $ r Y w xY w)zz
        Return current effective configuration.

        Returns:
            Dictionary of configuration values
        )bindr   worker_classthreadstimeoutgraceful_timeout	keepalivemax_requestsmax_requests_jitterworker_connectionspreload_appdaemonpidfile	proc_namereloaddirty_workers
dirty_appsdirty_timeoutcontrol_socketcontrol_socket_disable	__class__N)r   cfgr7   callablestrr8   
isinstanceintfloatboolr:   dicttyper9   )r   rU   configconfig_keysr   values         r   show_configzCommandHandlers.show_config   s     ll
  	C
S)E?JEUK0S%tT4:N:PJE#s	  " s   A3B	B&%B&c           
         t        | j                  di       }|j                  d      }d}|r!t        t	        j                         |z
  d      }|| j                  j
                  t        | j                  j                        | j                  j                  |j                  dd      |j                  dd      |j                  dd      | j                  j                  xs dd	S )
a  
        Return server statistics.

        Returns:
            Dictionary with:
            - uptime: Seconds since arbiter started
            - pid: Arbiter PID
            - workers_current: Current number of workers
            - workers_spawned: Total workers spawned
            - workers_killed: Total workers killed (if tracked)
            - reloads: Number of reloads (if tracked)
        _stats
start_timeNr   workers_spawnedr   workers_killedreloads)uptimer   workers_currentworkers_targetre   rf   rg   r6   )
r7   r   r<   r#   r   r   r(   r   num_workersr6   )r   statsrd   rh   s       r   
show_statszCommandHandlers.show_stats   s     h3YY|,
499;3Q7F <<##"4<<#7#78"ll66$yy):A>#ii(8!<yyA.!%!?!?!G4	
 		
r
   c                    g }| j                   j                  D ]  }t        |      }||j                         d}	 |j                  }|j
                  t        j                  k(  rd|d<   nE|j
                  t        j                  k(  rd|d<   n"|j
                  t        j                  k(  rd|d<   |j                  |        |t        |      dS # t        $ r d|d<   Y 1w xY w)zo
        Return bound socket information.

        Returns:
            Dictionary with listeners list
        )addressfdunixr]   tcptcp6unknown)	listenersr   )r   	LISTENERSrW   filenosockfamilysocketAF_UNIXAF_INETAF_INET6	Exceptionr&   r(   )r   ru   lnraddrlistener_inforx   s         r   show_listenerszCommandHandlers.show_listeners   s     	<<)) 	,Cs8DjjlM	2xx;;&..0,2M&)[[FNN2,1M&)[[FOO3,2M&) ]+'	,* 'Y@@  2(1f%2s   A4CC! C!r   c                     t        dt        |            }| j                  j                  }| j                  xj                  |z  c_        | j                  j	                          ||| j                  j                  dS )z
        Increase worker count.

        Args:
            count: Number of workers to add (default 1)

        Returns:
            Dictionary with added count and new total
           )addedprevioustotalmaxrY   r   rk   wakeup)r   r   	old_counts      r   
worker_addzCommandHandlers.worker_add   si     As5z"LL,,	  E)  	 !\\--
 	
r
   c                     t        dt        |            }| j                  j                  }t        d||z
        }||z
  }|| j                  _        | j                  j	                          |||dS )z
        Decrease worker count.

        Args:
            count: Number of workers to remove (default 1)

        Returns:
            Dictionary with removed count and new total
        r   )removedr   r   r   )r   r   r   	new_countactual_removeds        r   worker_removezCommandHandlers.worker_remove   ss     As5z"LL,,	 9u,-	"Y.#,  	 &!
 	
r
   r   c                     t        |      }|| j                  j                  vr	dd| ddS 	 t        j                  |t
        j                         d|dS # t        $ r}dt        |      dcY d}~S d}~ww xY w)z
        Gracefully terminate a specific worker.

        Args:
            pid: Worker process ID

        Returns:
            Dictionary with killed PID or error
        FzWorker z
 not foundsuccesserrorT)r   killedN)	rY   r   r   oskillsignalSIGTERMr$   rW   )r   r   es      r   worker_killzCommandHandlers.worker_kill  s     #hdll*** "3%z2 

	GGC(   	 Q 	s   (A 	A8 A3-A83A8c                     | j                   j                  sdddS t        dt        |            }| j	                  d|      S )a  
        Spawn additional dirty workers.

        Sends a MANAGE message to the dirty arbiter to spawn workers.

        Args:
            count: Number of dirty workers to add (default 1)

        Returns:
            Dictionary with added count or error
        FDirty arbiter not runningr   r   addr   r6   r   rY   _send_manage_messager   r   s     r   	dirty_addzCommandHandlers.dirty_add4  sF     ||-- 4 
 As5z"((66r
   c                     | j                   j                  sdddS t        dt        |            }| j	                  d|      S )a  
        Remove dirty workers.

        Sends a MANAGE message to the dirty arbiter to remove workers.

        Args:
            count: Number of dirty workers to remove (default 1)

        Returns:
            Dictionary with removed count or error
        Fr   r   r   remover   r   s     r   dirty_removezCommandHandlers.dirty_removeI  sF     ||-- 4 
 As5z"((599r
   	operationc                    d}t        | j                  d      r7| j                  j                  r!t        | j                  j                  dd      }|st        j
                  j                  d      }|sdddS 	 dd	lm}m	}m
} |d
k(  r|n|}t        j                  t        j                  t        j                        }|j                  d       |j                  |       |j                   d||d}	|j#                  ||	       |j%                  |      }
|j'                          |
j                  d      |j(                  k(  r|
j                  dddi      S |
j                  d      |j*                  k(  r0|
j                  di       }d|j                  dt-        |            dS dd|
j                  d       dS # t.        $ r}dt-        |      dcY d}~S d}~ww xY w)z
        Send a worker management message to the dirty arbiter.

        Args:
            operation: "add" or "remove"
            count: Number of workers to add/remove

        Returns:
            Dictionary with result or error
        Nr/   socket_pathGUNICORN_DIRTY_SOCKETFz%Cannot find dirty arbiter socket pathr   r   )DirtyProtocolMANAGE_OP_ADDMANAGE_OP_REMOVEr   g      $@r   )r]   idopr   r]   resultr   Tr   messagezUnexpected response type: )r8   r   r/   r7   r   environr<   gunicorn.dirty.protocolr   r   r   rz   r{   SOCK_STREAM
settimeoutconnectMSG_TYPE_MANAGEwrite_messageread_messagecloseMSG_TYPE_RESPONSEMSG_TYPE_ERRORrW   r~   )r   r   r   dirty_socket_pathr   r   r   r   rx   requestresponser   r   s                r   r   z$CommandHandlers._send_manage_message^  s    !4<<1dll6P6P '**M4! ! "

/F G  @ 
*	  #,u"4:JB==1C1CDDOOD!LL*+ &55	G ''g6 %11$7HJJL||F#}'F'FF||Hy$.?@@f%)E)EE Wb1$"YYy#e*=   %9(,,v:N9OP 
  	 Q 	s,   9CF; AF; $F; ;	GGGGc                 z    t        j                  | j                  j                  t        j
                         ddiS )zv
        Trigger graceful reload (equivalent to SIGHUP).

        Returns:
            Dictionary with status
        status	reloading)r   r   r   r   r   SIGHUPr   s    r   rN   zCommandHandlers.reload  s+     	  &--0+&&r
   c                 z    t        j                  | j                  j                  t        j
                         ddiS )zp
        Reopen log files (equivalent to SIGUSR1).

        Returns:
            Dictionary with status
        r   	reopening)r   r   r   r   r   SIGUSR1r   s    r   reopenzCommandHandlers.reopen  s+     	  &..1+&&r
   modec                     |dk(  r9t        j                  | j                  j                  t        j
                         n8t        j                  | j                  j                  t        j                         d|dS )z
        Initiate shutdown.

        Args:
            mode: "graceful" (SIGTERM) or "quick" (SIGINT)

        Returns:
            Dictionary with status
        quickshutting_down)r   r   )r   r   r   r   r   SIGINTr   )r   r   s     r   shutdownzCommandHandlers.shutdown  sN     7?GGDLL$$fmm4GGDLL$$fnn5)488r
   c           	      v   t        j                         }| j                  j                  ddd}g }| j                  j                  j                         D ]Z  \  }}	 |j                  j                         }t        ||z
  d      }|j                  |d|j                  |j                  |d       \ |j                  d 	       d}g }	| j                  j                  r*| j                  j                  d
dd}| j!                         }	||t#        |      ||	t#        |	      dS # t        t        f$ r d}Y w xY w)z
        Return overview of all processes (arbiter, web workers, dirty arbiter, dirty workers).

        Returns:
            Dictionary with complete process hierarchy
        r   master)r   r]   roler   Nweb)r   r]   r   r   r   c                     | d   S r   r   r   s    r   r   z*CommandHandlers.show_all.<locals>.<lambda>  s
    qx r
   r   r/   zdirty master)r   web_workersweb_worker_countr/   rO   dirty_worker_count)r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r   r   r'   r6   _query_dirty_workersr(   )
r   r)   arbiter_infor   r   r*   r"   r   dirty_arbiter_inforO   s
             r   show_allzCommandHandlers.show_all  sI    nn <<##
 <<//557 	KC&$jj446!&s['8!!< zz --"0  	  	/0 "<<))||55'&" !557M $& #K 0/*"%m"4
 	
9 Z( &!%&s   )D$$D87D8c                    d}t        | j                  d      r7| j                  j                  r!t        | j                  j                  dd      }|st        j
                  j                  d      }|sg S 	 ddlm} t        j                  t        j                  t        j                        }|j                  d       |j                  |       |j                  dd	}|j                  ||       |j!                  |      }|j#                          |j                  d
      |j$                  k(  r$|j                  di       }|j                  dg       S 	 g S # t&        $ r Y g S w xY w)z
        Query the dirty arbiter for worker information.

        Connects to the dirty arbiter socket and sends a status request.

        Returns:
            List of dirty worker info dicts, or empty list on error
        Nr/   r   r   r   )r   g       @zctl-status-1)r]   r   r]   r   r   )r8   r   r/   r7   r   r   r<   r   r   rz   r{   r   r   r   MSG_TYPE_STATUSr   r   r   r   r~   )r   r   r   rx   r   r   r   s          r   r   z$CommandHandlers._query_dirty_workers  s8    !4<<1dll6P6P '(B(BMSW X  "

/F G I	===1C1CDDOOC LL*+ &55$G ''g6 %11$7HJJL||F#}'F'FF!h3zz)R00 G 	  			s   6CE 	E$#E$c                 .    ddddddddd	d
dddddd}d|iS )z|
        Return list of available commands.

        Returns:
            Dictionary with commands and descriptions
        z8Show all processes (arbiter, web workers, dirty workers)z#List HTTP workers with their statuszList dirty workers and appsz$Show current effective configurationzShow server statisticszShow bound socketszSpawn N workers (default 1)zRemove N workers (default 1)z$Gracefully terminate specific workerz!Spawn N dirty workers (default 1)z"Remove N dirty workers (default 1)zGraceful reload (HUP)zReopen log files (USR1)zShutdown server (TERM/INT)zShow this help message)zshow allzshow workersz
show dirtyzshow configz
show statszshow listenerszworker add [N]zworker remove [N]zworker kill <PID>zdirty add [N]zdirty remove [N]rN   r   zshutdown [graceful|quick]helpcommandsr   )r   r   s     r   r   zCommandHandlers.help1  sF     SA7A22;!?!G@ D-/)E,
" H%%r
   N)r   )graceful)__name__
__module____qualname____doc__r	   r\   r+   r?   ra   rm   r   rY   r   r   r   r   r   rW   r   rN   r   r   r   r:   r   r   r   r
   r   r   r      s   !;d !;F:
D :
x!T !F
D 
>A A@
 
D 
.
3 
t 
8s t <7s 74 7*:# :d :*Cc C# C$ CJ	' 	'' '9S 9$ 9"9
$ 9
v+d +Z&d &r
   r   )r   r   r   rz   r   r   r   r
   r   <module>r      s$   
 
   x& x&r
   