Ë
    ×Õ°j6  ã                   óŠ   — d Z ddlZddlZddlZddlZddlmZ ddlmZm	Z	m
Z
  e«       ZddiZd„ Zd„ Zd	„ Zd
„ Z G d„ d«      Zy)aÉ  
Control Socket Server

Runs in the arbiter process and accepts commands via Unix socket.
Uses asyncio in a background thread to handle client connections.

Fork Safety:
    This server uses os.register_at_fork() to properly handle fork() calls.
    Before fork: the asyncio thread is stopped to prevent lock issues.
    After fork in parent: the server is restarted.
    After fork in child: references are cleared (workers don't need the control server).
é    N)ÚCommandHandlers)ÚControlProtocolÚmake_responseÚmake_error_responseÚfork_handlers_registeredFc                  ór   — t         d   rydt         d<   t        j                  t        t        t
        ¬«       y)z,Register fork handlers once at module level.r   NT)ÚbeforeÚafter_in_parentÚafter_in_child)Ú_module_stateÚosÚregister_at_forkÚ_before_forkÚ_after_fork_parentÚ_after_fork_child© ó    úI/var/www/mission/venv/lib/python3.12/site-packages/gunicorn/ctl/server.pyÚ_register_fork_handlersr   %   s0   € äÐ/Ò0ØØ04„MÐ,Ñ-ä×ÑÜÜ*Ü(ör   c                  óL   — t        t        «      D ]  } | j                  «        Œ y)z7Called before fork() - stop all active control servers.N)ÚlistÚ_active_serversÚ_stop_for_fork©Úservers    r   r   r   2   s"   € ä”Ó'ò  ˆØ×ÑÕñ r   c                  óL   — t        t        «      D ]  } | j                  «        Œ y)z<Called in parent after fork() - restart all control servers.N)r   r   Ú_restart_after_forkr   s    r   r   r   8   s"   € ä”Ó'ò %ˆØ×"Ñ"Õ$ñ%r   c                  ó,   — t         j                  «        y)z2Called in child after fork() - cleanup references.N)r   Úclearr   r   r   r   r   >   s   € ô ×ÑÕr   c                   ó˜   — e Zd ZdZdd„Zd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zd
„ Zdedefd„Zdedefd„Zdedefd„Zdedefd„Zdedefd„Zy)ÚControlSocketServeraG  
    Control socket server running in arbiter process.

    The server runs an asyncio event loop in a background thread,
    accepting connections and dispatching commands to handlers.

    Fork safety is handled via os.register_at_fork() - the server
    automatically stops before fork and restarts after in the parent.
    c                 óÚ   — || _         || _        || _        t        |«      | _        d| _        d| _        d| _        d| _        d| _	        t        j                  «       | _        t        «        y)zë
        Initialize control socket server.

        Args:
            arbiter: The Gunicorn arbiter instance
            socket_path: Path for the Unix socket
            socket_mode: Permission mode for socket (default 0o600)
        NF)ÚarbiterÚsocket_pathÚsocket_moder   ÚhandlersÚ_serverÚ_loopÚ_threadÚ_runningÚ_was_running_before_forkÚ	threadingÚEventÚ_readyr   )Úselfr#   r$   r%   s       r   Ú__init__zControlSocketServer.__init__P   sc   € ð ˆŒØ&ˆÔØ&ˆÔä'¨Ó0ˆŒØˆŒØˆŒ
ØˆŒØˆŒØ(-ˆÔ%ô  —o‘oÓ'ˆŒô 	 Õ!r   c                 ó  — | j                   ryd| _         t        j                  «       | _        t        j                  | j
                  d¬«      | _        | j                  j                  «        t        j                  | «       y)z:Start server in background thread with asyncio event loop.NT©ÚtargetÚdaemon)
r*   r,   r-   r.   ÚThreadÚ	_run_loopr)   Ústartr   Úadd©r/   s    r   r7   zControlSocketServer.startk   sY   € à�=Š=ØàˆŒÜ—o‘oÓ'ˆŒÜ ×'Ñ'¨t¯~©~ÀdÔKˆŒØ�‰×ÑÔô 	×Ñ˜DÕ!r   c                 ó   — t         j                  | «       | j                  syd| _        | j                  j	                  d¬«       | j
                  �%| j
                  j                  | j                  «       | j                  r#| j                  j                  d¬«       d| _        t        j                  j                  | j                  «      r!	 t        j                  | j                  «       yy# t        $ r Y yw xY w)zStop server and cleanup socket.NFç       @©Útimeout)r   Údiscardr*   r.   Úwaitr(   Úcall_soon_threadsafeÚ	_shutdownr)   Újoinr   ÚpathÚexistsr$   ÚunlinkÚOSErrorr9   s    r   ÚstopzControlSocketServer.stopx   sÅ   € ô 	×Ñ Ô%à�}Š}ØàˆŒð 	�‰×Ñ ÐÔ%Ø�:‰:Ð!à�J‰J×+Ñ+¨D¯N©NÔ;à�<Š<Ø�L‰L×Ñ cÐÔ*ØˆDŒLô �7‰7�>‰>˜$×*Ñ*Ô+ðÜ—	‘	˜$×*Ñ*Õ+ð ,øô ò Ùðús   ÃC1 Ã1	C=Ã<C=c                 ó&  — | j                   sd| _        yd| _        d| _         | j                  j                  d¬«       | j                  �&	 | j                  j                  | j                  «       | j                  rx| j                  j                  d¬«       | j                  j                  «       r;| j                  j                  r%| j                  j                  j                  d«       d| _        d| _        d| _        y# t        $ r Y Œžw xY w)z1Stop server before fork (called by fork handler).FNTr;   r<   z.control socket thread did not stop before fork)r*   r+   r.   r?   r(   r@   rA   ÚRuntimeErrorr)   rB   Úis_aliver#   ÚlogÚwarningr'   r9   s    r   r   z"ControlSocketServer._stop_for_fork“   sÞ   € à�}Š}Ø,1ˆDÔ)Øà(,ˆÔ%ØˆŒð 	�‰×Ñ ÐÔ%Ø�:‰:Ð!ðØ—
‘
×/Ñ/°·±Ô?ð
 �<Š<Ø�L‰L×Ñ cÐÔ*Ø�|‰|×$Ñ$Ô&¨4¯<©<×+;Ò+;Ø—‘× Ñ ×(Ñ(ØDôFàˆDŒLàˆŒ
Øˆ�øô  ò áðús   Á%D Ä	DÄDc                 óì   — | j                   syd| _         d| _        t        j                  «       | _        t        j
                  | j                  d¬«      | _        | j                  j                  «        y)z=Restart server in parent after fork (called by fork handler).NFTr2   )	r+   r*   r,   r-   r.   r5   r6   r)   r7   r9   s    r   r   z'ControlSocketServer._restart_after_fork²   sS   € à×,Ò,Øà(-ˆÔ%ØˆŒÜ—o‘oÓ'ˆŒÜ ×'Ñ'¨t¯~©~ÀdÔKˆŒØ�‰×ÑÕr   c                 óR   — | j                   r| j                   j                  «        yy)z0Shutdown server (called from event loop thread).N)r'   Úcloser9   s    r   rA   zControlSocketServer._shutdown½   s   € à�<Š<Ø�L‰L×ÑÕ ð r   c                 óz  — 	 t        j                  | j                  «       «       | j                  j                  «        y# t        $ rR}| j                  r<| j
                  j                  r&| j
                  j                  j                  d|«       Y d}~Œqd}~ww xY w# | j                  j                  «        w xY w)z0Run the asyncio event loop in background thread.zControl server error: %sN)
ÚasyncioÚrunÚ_serveÚ	Exceptionr*   r#   rK   Úerrorr.   Úset)r/   Úes     r   r6   zControlSocketServer._run_loopÂ   s}   € ð	Ü�K‰K˜Ÿ™›Ô&ð �K‰K�O‰OÕøô ò 	FØ�}Š} §¡×!1Ò!1Ø—‘× Ñ ×&Ñ&Ð'AÀ1ÔEÿøð	Fûð �K‰K�O‰OÕús*   ‚#A  Á 	BÁ	ABÂB ÂBÂB ÂB:c              ƒ   ó€  K  — t        j                  «       | _        t        j                  j                  | j                  «      }|r6t        j                  j                  |«      st        j                  |d¬«       t        j                  j                  | j                  «      rt        j                  | j                  «       t        j                  | j                  | j                  ¬«      ƒ d{  –—† | _        t        j                  | j                  | j                  «       | j                  j                   r0| j                  j                   j#                  d| j                  «       | j$                  j'                  «        	 | j                  4 ƒd{  –—†  | j                  j)                  «       ƒ d{  –—†  ddd«      ƒd{  –—†  t        j                  j                  | j                  «      r!	 t        j                  | j                  «       yy7 �Œ'7 Œ„7 Œd7 ŒV# 1 ƒd{  –—†7  sw Y   ŒfxY w# t         j*                  $ r Y Œ~w xY w# t,        $ r Y yw xY w# t        j                  j                  | j                  «      r0	 t        j                  | j                  «       w # t,        $ r Y w w xY ww xY w­w)zMain async server loop.iÀ  )Úmode)rC   NzControl socket listening at %s)rQ   Úget_running_loopr(   r   rC   Údirnamer$   rD   ÚmakedirsrE   Ústart_unix_serverÚ_handle_clientr'   Úchmodr%   r#   rK   Úinfor.   rV   Úserve_foreverÚCancelledErrorrF   )r/   Ú
socket_dirs     r   rS   zControlSocketServer._serveÎ   s  è ø€ ä×-Ñ-Ó/ˆŒ
ô —W‘W—_‘_ T×%5Ñ%5Ó6ˆ
ÙœbŸg™gŸn™n¨ZÔ8Ü�K‰K˜
¨Õ/ô �7‰7�>‰>˜$×*Ñ*Ô+Ü�I‰I�d×&Ñ&Ô'ô %×6Ñ6Ø×ÑØ×!Ñ!ô
÷ 
ˆŒô 	�‰�×!Ñ! 4×#3Ñ#3Ô4à�<‰<×ÒØ�L‰L×Ñ×!Ñ!Ð"BØ"&×"2Ñ"2ô4ð 	�‰�‰Ôð
	Ø—|‘|÷ 3ñ 3Ø—l‘l×0Ñ0Ó2×2Ð2÷3÷ 3ô
 �w‰w�~‰~˜d×.Ñ.Ô/ðÜ—I‘I˜d×.Ñ.Õ/ð 0ð+
ùð 3øØ2øð3ø÷ 3÷ 3ñ 3ûä×%Ñ%ò 	Ùð	ûô ò Ùðûô �w‰w�~‰~˜d×.Ñ.Ô/ðÜ—I‘I˜d×.Ñ.Õ/øÜò Ùðúð 0üså   ‚C1J>Ã3HÃ4BJ>ÆH8 ÆHÆH8 ÆH#Æ:HÆ;H#Æ?H8 Ç
H!ÇH8 Ç)J>Ç9I ÈJ>ÈH8 ÈH#È!H8 È#H5È)H,È*H5È1H8 È8IÉI  ÉIÉI  É	IÉJ>ÉIÉJ>É *J;ÊJ+Ê*J;Ê+	J7Ê4J;Ê6J7Ê7J;Ê;J>c              ƒ   ó"  K  — 	 | j                   rw	 t        j                  t        j                  |«      d¬«      ƒ d{  –—† }| j                  |«      ƒ d{  –—† }t        j                  ||«      ƒ d{  –—†  | j                   rŒw|j                  «        	 |j                  «       ƒ d{  –—†  y7 Œr# t        j
                  $ r Y ŒAt        j                  $ r Y ŒUt        $ r Y Œ_w xY w7 Œ’7 Œv# t        $ rF}| j                  j                  r&| j                  j                  j                  d|«       Y d}~Œ±d}~ww xY w7 Œ”# t        $ r Y yw xY w# |j                  «        	 |j                  «       ƒ d{  –—†7   w # t        $ r Y w w xY wxY w­w)zŒ
        Handle client connection.

        Args:
            reader: asyncio StreamReader
            writer: asyncio StreamWriter
        g     Àr@r<   NzControl client error: %s)r*   rQ   Úwait_forr   Úread_message_asyncÚTimeoutErrorÚIncompleteReadErrorrT   Ú	_dispatchÚwrite_message_asyncr#   rK   ÚdebugrO   Úwait_closed)r/   ÚreaderÚwriterÚmessageÚresponserW   s         r   r^   z"ControlSocketServer._handle_client÷   s_  è ø€ ð	Ø—-’-ðÜ$+×$4Ñ$4Ü'×:Ñ:¸6ÓBØ %ô%÷ �Gð "&§¡°Ó!8×8�ô &×9Ñ9¸&À(ÓK×KÐKð) —-“-ð4 �L‰LŒNðØ×(Ñ(Ó*×*Ñ*ð5ùô ×+Ñ+ò áÜ×2Ñ2ò áÜ ò áðúð
 9øð Lùäò 	FØ�|‰|×ÒØ—‘× Ñ ×&Ñ&Ð'AÀ1ÔEÿøð	Fúð +ùÜò Ùðûð �L‰LŒNðØ×(Ñ(Ó*×*Ò*øÜò Ùðÿs	  ‚F„C. ‘-B3 ¾B1¿B3 ÁC. ÁC*ÁC. Á5C,Á6C. ÂFÂE Â+E Â,E Â0FÂ1B3 Â3C'ÃC. ÃC'ÃC. ÃC'Ã$C. Ã&C'Ã'C. Ã,C. Ã.	D=Ã7<D8Ä3E Ä8D=Ä=E Å E Å	EÅFÅEÅFÅFÅ#E=Å6E9Å7E=Å<FÅ=	F	ÆFÆF	Æ	FÆFro   Úreturnc              ƒ   ód  K  — |j                  dd«      }|j                  dd«      j                  «       }|j                  dg «      }|st        |d«      S 	 t        j                  |«      }|r|j                  d„ |D «       «       |st        |d«      S | j                  |«      }t        ||«      S # t        $ r}t        |d|› �«      cY d	}~S d	}~wt        $ rT}| j                  j                  r%| j                  j                  j                  d
«       t        |d|› �«      cY d	}~S d	}~ww xY w­w)z¥
        Dispatch command to appropriate handler.

        Args:
            message: Request message dict

        Returns:
            Response dictionary
        Úidr   ÚcommandÚ ÚargsúEmpty commandc              3   ó2   K  — | ]  }t        |«      –— Œ y ­w)N)Ústr)Ú.0Úas     r   ú	<genexpr>z0ControlSocketServer._dispatch.<locals>.<genexpr>5  s   è ø€ Ò2¨œS ŸVÑ2ùs   ‚zInvalid argument: NzCommand errorzCommand failed: )ÚgetÚstripr   ÚshlexÚsplitÚextendÚ_execute_commandr   Ú
ValueErrorrT   r#   rK   Ú	exception)r/   ro   Ú
request_idrt   rv   ÚpartsÚresultrW   s           r   ri   zControlSocketServer._dispatch   s  è ø€ ð —[‘[  qÓ)ˆ
Ø—+‘+˜i¨Ó,×2Ñ2Ó4ˆØ�{‰{˜6 2Ó&ˆáÜ& z°?ÓCÐCð	Kä—K‘K Ó(ˆEÙØ—‘Ñ2¨TÔ2Ô2áÜ*¨:°ÓGÐGð ×*Ñ*¨5Ó1ˆFÜ  ¨VÓ4Ð4øäò 	MÜ& zÐ5GÈÀsÐ3KÓLÕLûÜò 	KØ�|‰|×ÒØ—‘× Ñ ×*Ñ*¨?Ô;Ü& zÐ5EÀaÀSÐ3IÓJÕJûð	Küs[   ‚AD0Á<B0 ÂD0ÂB0 Â/D0Â0	D-Â9CÃD-ÃD0ÃD-ÃA	D(Ä"D-Ä#D0Ä(D-Ä-D0r†   c                 óø  — |st        d«      ‚|d   j                  «       }|dd }|dk(  r| j                  |«      S |dk(  r| j                  |«      S |dk(  r| j	                  |«      S |dk(  r| j
                  j                  «       S |d	k(  r| j
                  j                  «       S |d
k(  r$|r|d   nd}| j
                  j                  |«      S |dk(  r| j
                  j                  «       S t        d|› �«      ‚)z¯
        Execute a parsed command.

        Args:
            parts: Command parts (e.g., ["show", "workers"])

        Returns:
            Handler result dictionary
        rw   r   é   NÚshowÚworkerÚdirtyÚreloadÚreopenÚshutdownÚgracefulÚhelpzUnknown command: )
rƒ   ÚlowerÚ_handle_showÚ_handle_workerÚ_handle_dirtyr&   r�   rŽ   r�   r‘   )r/   r†   ÚcmdÚrestrY   s        r   r‚   z$ControlSocketServer._execute_commandE  s  € ñ Ü˜_Ó-Ð-à�A‰h�n‰nÓˆØ�Q�Rˆyˆð �&Š=Ø×$Ñ$ TÓ*Ð*Ø�HŠ_Ø×&Ñ& tÓ,Ð,Ø�GŠ^Ø×%Ñ% dÓ+Ð+Ø�HŠ_Ø—=‘=×'Ñ'Ó)Ð)Ø�HŠ_Ø—=‘=×'Ñ'Ó)Ð)Ø�JÒÙ"�4˜’7¨
ˆDØ—=‘=×)Ñ)¨$Ó/Ð/Ø�FŠ]Ø—=‘=×%Ñ%Ó'Ð'äÐ0°°Ð6Ó7Ð7r   rv   c                 óÒ  — |st        d«      ‚|d   j                  «       }|dk(  r| j                  j                  «       S |dk(  r| j                  j	                  «       S |dk(  r| j                  j                  «       S |dk(  r| j                  j                  «       S |dk(  r| j                  j                  «       S |dk(  r| j                  j                  «       S t        d	|› �«      ‚)
zHandle 'show' commands.z>Missing show target (all|workers|dirty|config|stats|listeners)r   ÚallÚworkersrŒ   ÚconfigÚstatsÚ	listenerszUnknown show target: )	rƒ   r’   r&   Úshow_allÚshow_workersÚ
show_dirtyÚshow_configÚ
show_statsÚshow_listeners)r/   rv   r3   s      r   r“   z ControlSocketServer._handle_showh  sÔ   € áÜÐ]Ó^Ð^à�a‘—‘“ˆà�UŠ?Ø—=‘=×)Ñ)Ó+Ð+Ø�yÒ Ø—=‘=×-Ñ-Ó/Ð/Ø�wÒØ—=‘=×+Ñ+Ó-Ð-Ø�xÒØ—=‘=×,Ñ,Ó.Ð.Ø�wÒØ—=‘=×+Ñ+Ó-Ð-Ø�{Ò"Ø—=‘=×/Ñ/Ó1Ð1äÐ4°V°HÐ=Ó>Ð>r   c                 ó¦  — |st        d«      ‚|d   j                  «       }|dd }|dk(  r-|rt        |d   «      nd}| j                  j	                  |«      S |dk(  r-|rt        |d   «      nd}| j                  j                  |«      S |dk(  r6|st        d«      ‚t        |d   «      }| j                  j                  |«      S t        d	|› �«      ‚)
zHandle 'worker' commands.z'Missing worker action (add|remove|kill)r   r‰   Nr8   ÚremoveÚkillzMissing PID for worker killzUnknown worker action: )rƒ   r’   Úintr&   Ú
worker_addÚworker_removeÚworker_kill)r/   rv   ÚactionÚaction_argsÚcountÚpids         r   r”   z"ControlSocketServer._handle_worker~  sÕ   € áÜÐFÓGÐGà�a‘—‘“ˆØ˜1˜2�hˆà�UŠ?Ù+6”C˜ A™Ô'¸AˆEØ—=‘=×+Ñ+¨EÓ2Ð2Ø�xÒÙ+6”C˜ A™Ô'¸AˆEØ—=‘=×.Ñ.¨uÓ5Ð5Ø�vÒÙÜ Ð!>Ó?Ð?Ü�k !‘nÓ%ˆCØ—=‘=×,Ñ,¨SÓ1Ð1äÐ6°v°hÐ?Ó@Ð@r   c                 ó0  — |st        d«      ‚|d   j                  «       }|dd }|dk(  r-|rt        |d   «      nd}| j                  j	                  |«      S |dk(  r-|rt        |d   «      nd}| j                  j                  |«      S t        d|› �«      ‚)zHandle 'dirty' commands.z!Missing dirty action (add|remove)r   r‰   Nr8   r¥   zUnknown dirty action: )rƒ   r’   r§   r&   Ú	dirty_addÚdirty_remove)r/   rv   r«   r¬   r­   s        r   r•   z!ControlSocketServer._handle_dirty”  s›   € áÜÐ@ÓAÐAà�a‘—‘“ˆØ˜1˜2�hˆà�UŠ?Ù+6”C˜ A™Ô'¸AˆEØ—=‘=×*Ñ*¨5Ó1Ð1Ø�xÒÙ+6”C˜ A™Ô'¸AˆEØ—=‘=×-Ñ-¨eÓ4Ð4äÐ5°f°XÐ>Ó?Ð?r   N)i€  )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r0   r7   rG   r   r   rA   r6   rS   r^   Údictri   r   r‚   r“   r”   r•   r   r   r   r!   r!   E   s    „ ñó"ò6"òò6ò>	ò!ò

ò'òR'ðR#K tð #K°ó #KðJ!8 dð !8¨tó !8ðF? ð ?¨$ó ?ð,A 4ð A¨Dó Að,@ $ð @¨4ô @r   r!   )rµ   rQ   r   r   r,   Úgunicorn.ctl.handlersr   Úgunicorn.ctl.protocolr   r   r   rV   r   r   r   r   r   r   r!   r   r   r   ú<module>r¹      sZ   ðñ
ó Û 	Û Û å 1÷ñ ñ “%€Ø+¨UÐ3€ò
ò ò%ò÷^@ò ^@r   