Ë
    ¯#ij1  ã                   óŠ   — 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© ó    úM/var/www/html/office/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        «        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_forkr   )Úselfr#   r$   r%   s       r   Ú__init__zControlSocketServer.__init__P   sS   € ð ˆŒØ&ˆÔØ&ˆÔä'¨Ó0ˆŒØˆŒØˆŒ
ØˆŒØˆŒØ(-ˆÔ%ô 	 Õ!r   c                 óÖ   — | j                   ryd| _         t        j                  | j                  d¬«      | _        | j                  j                  «        t        j                  | «       y)z:Start server in background thread with asyncio event loop.NT©ÚtargetÚdaemon)r*   Ú	threadingÚThreadÚ	_run_loopr)   Ústartr   Úadd©r,   s    r   r5   zControlSocketServer.startg   sK   € à�=Š=ØàˆŒÜ ×'Ñ'¨t¯~©~ÀdÔKˆŒØ�‰×ÑÔô 	×Ñ˜DÕ!r   c                 óà  — t         j                  | «       | j                  syd| _        | j                  r1| j                  r%| 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(   r'   Úcall_soon_threadsafeÚ	_shutdownr)   Újoinr   ÚpathÚexistsr$   ÚunlinkÚOSErrorr7   s    r   ÚstopzControlSocketServer.stops   s±   € ô 	×Ñ Ô%à�}Š}ØàˆŒà�:Š:˜$Ÿ,š,à�J‰J×+Ñ+¨D¯N©NÔ;à�<Š<Ø�L‰L×Ñ cÐÔ*ØˆDŒLô �7‰7�>‰>˜$×*Ñ*Ô+ðÜ—	‘	˜$×*Ñ*Õ+ð ,øô ò Ùðús   Ã C! Ã!	C-Ã,C-c                 ó\  — | j                   sd| _        yd| _        d| _         | j                  r2| j                  r&	 | j                  j	                  | j
                  «       | j                  r#| j                  j                  d¬«       d| _        d| _        d| _        y# t        $ r Y ŒIw xY w)z1Stop server before fork (called by fork handler).FNTr9   r:   )	r*   r+   r(   r'   r=   r>   ÚRuntimeErrorr)   r?   r7   s    r   r   z"ControlSocketServer._stop_for_forkŒ   s’   € à�}Š}Ø,1ˆDÔ)Øà(,ˆÔ%ØˆŒà�:Š:˜$Ÿ,š,ðØ—
‘
×/Ñ/°·±Ô?ð
 �<Š<Ø�L‰L×Ñ cÐÔ*ØˆDŒLàˆŒ
Øˆ�øô  ò áðús   ¼%B Â	B+Â*B+c                 óº   — | j                   syd| _         d| _        t        j                  | j                  d¬«      | _        | j
                  j                  «        y)z=Restart server in parent after fork (called by fork handler).NFTr/   )r+   r*   r2   r3   r4   r)   r5   r7   s    r   r   z'ControlSocketServer._restart_after_fork£   sE   € à×,Ò,Øà(-ˆÔ%ØˆŒÜ ×'Ñ'¨t¯~©~ÀdÔKˆŒØ�‰×ÑÕr   c                 óR   — | j                   r| j                   j                  «        yy)z0Shutdown server (called from event loop thread).N)r'   Úcloser7   s    r   r>   zControlSocketServer._shutdown­   s   € à�<Š<Ø�L‰L×ÑÕ ð r   c                 ó  — 	 t        j                  | j                  «       «       y# t        $ r\}| j                  rF| j
                  j                  r+| j
                  j                  j                  d|«       Y d}~yY d}~yY d}~yd}~ww xY w)z0Run the asyncio event loop in background thread.zControl server error: %sN)ÚasyncioÚrunÚ_serveÚ	Exceptionr*   r#   ÚlogÚerror)r,   Úes     r   r4   zControlSocketServer._run_loop²   sd   € ð	FÜ�K‰K˜Ÿ™›Õ&øÜò 	FØ�}Š} §¡×!1Ò!1Ø—‘× Ñ ×&Ñ&Ð'AÀ1×EÑEô "2Œ}ûð	Fús   ‚#& ¦	B¯ABÂBc              ƒ   óL  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                  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)r@   NzControl socket listening at %s)rK   Úget_running_loopr(   r   r@   Údirnamer$   rA   ÚmakedirsrB   Ústart_unix_serverÚ_handle_clientr'   Úchmodr%   r#   rO   ÚinfoÚserve_foreverÚCancelledErrorrC   )r,   Ú
socket_dirs     r   rM   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 Ã4A9J$Å.H Å>HÅ?H ÆH	Æ HÆ!H	Æ%H Æ0HÆ1H Æ5)J$ÇH7 Ç>J$ÈH ÈH	ÈH È	HÈHÈHÈH ÈH4È1I È3H4È4I È7	IÉ J$ÉIÉJ$É*J!É1JÊJ!Ê	JÊJ!ÊJÊ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*   rK   Úwait_forr   Úread_message_asyncÚTimeoutErrorÚIncompleteReadErrorrN   Ú	_dispatchÚwrite_message_asyncr#   rO   ÚdebugrI   Úwait_closed)r,   ÚreaderÚwriterÚmessageÚresponserQ   s         r   rX   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ri   Ú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>  s   è ø€ Ò2¨œS ŸVÑ2ùs   ‚zInvalid argument: NzCommand errorzCommand failed: )ÚgetÚstripr   ÚshlexÚsplitÚextendÚ_execute_commandr   Ú
ValueErrorrN   r#   rO   Ú	exception)r,   ri   Ú
request_idrn   rp   ÚpartsÚresultrQ   s           r   rc   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
        rq   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ÚrestrS   s        r   r|   z$ControlSocketServer._execute_command.  s  € ñ Ü˜_Ó-Ð-à�A‰h�n‰nÓˆØ�Q�Rˆyˆð �&Š=Ø×$Ñ$ TÓ*Ð*Ø�HŠ_Ø×&Ñ& tÓ,Ð,Ø�GŠ^Ø×%Ñ% dÓ+Ð+Ø�HŠ_Ø—=‘=×'Ñ'Ó)Ð)Ø�HŠ_Ø—=‘=×'Ñ'Ó)Ð)Ø�JÒÙ"�4˜’7¨
ˆDØ—=‘=×)Ñ)¨$Ó/Ð/Ø�FŠ]Ø—=‘=×%Ñ%Ó'Ð'äÐ0°°Ð6Ó7Ð7r   rp   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,   rp   r0   s      r   r�   z ControlSocketServer._handle_showQ  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ƒ   Nr6   ÚremoveÚkillzMissing PID for worker killzUnknown worker action: )r}   rŒ   Úintr&   Ú
worker_addÚworker_removeÚworker_kill)r,   rp   ÚactionÚaction_argsÚcountÚpids         r   rŽ   z"ControlSocketServer._handle_workerg  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ƒ   Nr6   rŸ   zUnknown dirty action: )r}   rŒ   r¡   r&   Ú	dirty_addÚdirty_remove)r,   rp   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__r-   r5   rD   r   r   r>   r4   rM   rX   Údictrc   r   r|   r�   rŽ   r�   r   r   r   r!   r!   E   s¡   „ ñó"ò.
"òò2ò.ò!ò
Fò$òL'ðR#K tð #K°ó #KðJ!8 dð !8¨tó !8ðF? ð ?¨$ó ?ð,A 4ð A¨Dó Að,@ $ð @¨4ô @r   r!   )r¯   rK   r   ry   r2   Úgunicorn.ctl.handlersr   Úgunicorn.ctl.protocolr   r   r   Úsetr   r   r   r   r   r   r!   r   r   r   ú<module>r´      sZ   ðñ
ó Û 	Û Û å 1÷ñ ñ “%€Ø+¨UÐ3€ò
ò ò%ò÷G@ò G@r   