
    AҐi)                     j    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  G d dej                        Z
y)zy
ASGI worker for gunicorn.

Provides native asyncio-based ASGI support using gunicorn's own
HTTP parsing infrastructure.
    N)baseASGIProtocolc                        e Zd ZdZ fdZed        Z fdZd Zd Z	d Z
d Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Z xZS )
ASGIWorkerzASGI worker using asyncio event loop.

    Supports:
    - HTTP/1.1 with keepalive
    - WebSocket connections
    - Lifespan protocol (startup/shutdown hooks)
    - Optional uvloop for improved performance
    c                     t        |   |i | | j                  j                  | _        d | _        g | _        d| _        d | _        i | _        d| _	        y )Nr   F)
super__init__cfgworker_connectionsloopserversnr_connslifespanstate_quick_shutdown)selfargskwargs	__class__s      O/var/www/descvideos/venv/lib/python3.12/site-packages/gunicorn/workers/gasgi.pyr
   zASGIWorker.__init__   sR    $)&)"&(("="=	
$    c                 F    |j                   dkD  r|j                  d       yy)z'Validate configuration for ASGI worker.   zOASGI worker does not use threads configuration. Use worker_connections instead.N)threadswarning)clsr   logs      r   check_configzASGIWorker.check_config)   s%     ;;?KK : ; r   c                 B    | j                          t        | 	          y)zInitialize the worker process.N)_setup_event_loopr	   init_process)r   r   s    r   r"   zASGIWorker.init_process0   s     	 r   c                    t        | j                  dd      }|dk(  r	 ddl}d}|dk(  r6	 ddl}|j	                         | _        | j                  j                  d       n4t        j                         | _        | j                  j                  d	       t        j                  | j
                         y# t        $ r d}Y w xY w# t        $ r7 | j                  j                  d       t        j                         | _        Y pw xY w)
zSetup the asyncio event loop.	asgi_loopautor   NuvloopasynciozUsing uvloop event loopz-uvloop not available, falling back to asynciozUsing asyncio event loop)getattrr   r&   ImportErrornew_event_loopr   r   debugr   r'   set_event_loop)r   	loop_typer&   s      r   r!   zASGIWorker._setup_event_loop6   s    DHHk6:	&$	  5"113	89
  ..0DIHHNN56tyy)  &%	&  5  !PQ#224	5s"   B3 4C 3C C=DDc                    	 | j                   j                         | _        y# t        $ r[}| j                  j
                  s | j                  j                  |       | j                  t        |            | _        Y d}~yd}~ww xY w)zLoad the ASGI application.N)
appwsgiasgiSyntaxErrorr   reloadr   	exception_make_error_appstrr   es     r   	load_wsgizASGIWorker.load_wsgiO   s`    	5DI 	588??HHq!,,SV4DII		5s   " 	BABBc                     fd}|S )z9Create an error ASGI app for syntax errors during reload.c                 b  K   | d   dk(  r: |dddgd       d {     |dd j                         d	       d {    y | d   d
k(  rT |        d {   }|d   dk(  r |ddi       d {     |        d {   }|d   dk(  r |ddi       d {    y y y 7 7 d7 N7 67 )7 w)Ntypehttpzhttp.response.starti  )s   content-types
   text/plain)r<   statusheaderszhttp.response.bodyzApplication error: )r<   bodyr   zlifespan.startupzlifespan.startup.completezlifespan.shutdownzlifespan.shutdown.complete)encode)scopereceivesendmessage	error_msgs       r   	error_appz-ASGIWorker._make_error_app.<locals>.error_app[   s     V}&1! @A   
 01)=DDF    v*, '	/6?&88(CDEEE '	/6?&99(DEFFF : -

 *E)Fsi   B/B##B/ B%B/B'B/2B)3B/B+B/B-B/%B/'B/)B/+B/-B/ )r   rF   rG   s    ` r   r5   zASGIWorker._make_error_appY   s    	G$ r   c                    | j                   D ]&  }t        j                  |t        j                         ( | j                  j	                  t        j
                  | j                         | j                  j	                  t        j                  | j                         | j                  j	                  t        j                  | j                         | j                  j	                  t        j                  | j                         | j                  j	                  t        j                  | j                         | j                  j	                  t        j                  | j                         y)z'Initialize signal handlers for asyncio.N)SIGNALSsignalSIG_DFLr   add_signal_handlerSIGQUIThandle_quit_signalSIGTERMhandle_exit_signalSIGINTSIGUSR1handle_usr1_signalSIGWINCHhandle_winch_signalSIGABRThandle_abort_signal)r   ss     r   init_signalszASGIWorker.init_signalso   s      	-AMM!V^^,	- 			$$V^^T5L5LM		$$V^^T5L5LM		$$V]]D4K4KL		$$V^^T5L5LM		$$V__d6N6NO		$$V^^T5M5MNr   c                 p    d| _         | j                  syd| _        | j                  j                  |        y)z+Handle SIGQUIT/SIGINT - immediate shutdown.TNF)r   aliver   
worker_intr   s    r   rO   zASGIWorker.handle_quit_signal}   s-    #zz
D!r   c                     d| _         y)z#Handle SIGTERM - graceful shutdown.FN)r\   r^   s    r   rQ   zASGIWorker.handle_exit_signal   s	    
r   c                 8    | j                   j                          y)z"Handle SIGUSR1 - reopen log files.N)r   reopen_filesr^   s    r   rT   zASGIWorker.handle_usr1_signal   s    r   c                 :    | j                   j                  d       y)z$Handle SIGWINCH - ignored in worker.zworker: SIGWINCH ignored.N)r   r+   r^   s    r   rV   zASGIWorker.handle_winch_signal   s    23r   c                 r    d| _         | j                  j                  |        t        j                  d       y)zHandle SIGABRT - abort.Fr   N)r\   r   worker_abortsysexitr^   s    r   rX   zASGIWorker.handle_abort_signal   s&    
d#r   c                    	 | j                   j                  | j                                | j                          y# t        $ r&}| j                  j                  d|       Y d}~;d}~ww xY w# | j                          w xY w)z Main entry point for the worker.zWorker exception: %sN)r   run_until_complete_serve	Exceptionr   r4   _cleanupr7   s     r   runzASGIWorker.run   s`    	II((7 MMO  	:HH5q99	: MMOs'   )< 	A+A&!A. &A++A. .B c                    K   t         j                  dd      }|dk7  rVddlm}  | j                   j
                   j                         _        	  j                  j                          d{     j                         } j                  D ]o  }	  j                  j                   fd
|j                   |dd       d{   } j"                  j%                  |        j
                  j'                  d|       q  j"                  s j
                  j                  d       y	  j(                  rx j+                           j,                  t/        j0                         k7  r j
                  j'                  d        n*t3        j4                  d       d{     j(                  rx j9                          d{    y7 Y# t        $ rT}|dk(  r! j
                  j                  d|       Y d}~y j
                  j                  d	|       d _        Y d}~d}~ww xY w7 g# t        $ r(} j
                  j                  d||       Y d}~d}~ww xY w7 # t2        j6                  $ r Y w xY w7 w)zMain async serving loop.asgi_lifespanr%   offr   )LifespanManagerNonz ASGI lifespan startup failed: %sz&ASGI lifespan not supported by app: %sc                      t               S )Nr   r^   s   r   <lambda>z#ASGIWorker._serve.<locals>.<lambda>   s    L. r   T)socksslreuse_addressstart_servingzASGI server listening on %sz!Failed to create server on %s: %szNo servers could be startedz!Parent changed, shutting down: %s      ?)r(   r   gunicorn.asgi.lifespanrp   r1   r   r   r   startuprj   errorr+   _get_ssl_contextsocketsr   create_serverrt   r   appendinfor\   notifyppidosgetppidr'   sleepCancelledError	_shutdown)r   lifespan_moderp   r8   ssl_contextrt   servers   `      r   ri   zASGIWorker._serve   s      /6BE!>+DIItxxLDM	)mm++--- ++-LL 	MDM#yy66.#"&"&  7    ##F+;TB	M ||HHNN89	** 99

,HHMM"EtL
 mmC((( **" nne . ) D(HHNN#EqI HHNN#KQO$(DMM)  MBD!LLM( )%% 		 	s   AJG 1G
2G 6J0H0H-;H0*J-A2I& I$ I& 1JI?J
G 	H*!H%7J<#H%J%H**J-H00	I!9IJI!!J$I& &I<9J;I<<Jc                   K   | j                   j                  d       | j                  D ]  }|j                           | j                  sM| j                  D ]>  }| j                  r n0	 t        j                  |j                         d       d{    @ | j                  dkD  r9| j                  s,| j                  j                  }| j                   j                  d| j                         | j                  j                         |z   }| j                  dkD  r| j                  j                         |k  rr| j                  r| j                   j                  d       nJt        j                  d       d{    | j                  dkD  r| j                  j                         |k  rr| j                  dkD  r&| j                   j                  d	| j                         | j                   r1| j                  s$	 | j                   j#                          d{    yyy7 # t
        j                  $ r Y w xY w7 7 &# t$        $ r&}| j                   j'                  d
|       Y d}~yd}~ww xY ww)zPerform graceful shutdown.zWorker shutting down...g      ?timeoutNr   z'Waiting for %d connections to finish...zQuick shutdown requestedg?zForcing close of %d connectionsz ASGI lifespan shutdown error: %s)r   r   r   closer   r'   wait_forwait_closedTimeoutErrorr   r   graceful_timeoutr   timer   r   r   shutdownrj   r{   )r   r   r   deadliner8   s        r   r   zASGIWorker._shutdown   s    /0 ll 	FLLN	 ##,, ''!**6+=+=+?MMM	 ==1T%9%9#xx88HHMMCT]]Syy~~'*::H--!#		(88(C''HHMM"<=mmC(((	 --!#		(88(C }}q   !BDMMR ==!5!5Fmm,,... "6=' N++  ) / FA1EEFs   A&I2)(H"HH"C$I2:H<;0I2,AI2:I  H>I  I2H""H95I28H99I2>I   	I/	I*%I2*I//I2c                     | j                   j                  sy	 ddlm} |j	                  | j                         S # t
        $ r&}| j                  j                  d|       Y d}~yd}~ww xY w)zGet SSL context if configured.Nr   )rt   z Failed to create SSL context: %s)r   is_sslgunicornrt   r   rj   r   r{   )r   rt   r8   s      r   r|   zASGIWorker._get_ssl_context  sS    xx	%##DHH-- 	HHNN=qA	s    : 	A)A$$A)c                    	 t        j                  | j                        }|D ]  }|j                           |rnt        j                  |ddi}| j
                  r2	 | j                  j                  t        j                  |d             n| j                  j                  |       | j                  j                          | j                  D ]  }	 |j                           y# t         j                  $ r | j                  j                  d       Y mw xY w# t        $ r&}| j                  j                  d|       Y d}~d}~ww xY w# t        $ r Y w xY w)zClean up resources on exit.return_exceptionsTrx   r   z#Timeout waiting for tasks to cancelzCleanup error: %sN)r'   	all_tasksr   cancelgatherr   rh   r   r   r   r+   r   rj   r}   )r   pendingtaskr   r8   rY   s         r   rk   zASGIWorker._cleanup  s%   	3''		2G   IDI''N		44#,,VSA II008IIOO
  	A		 #// N'LMN  	3HHNN.22	3  sN   AD 0C% 6D E%.DD DD 	E"EE	EE)__name__
__module____qualname____doc__r
   classmethodr   r"   r!   r9   r5   rZ   rO   rQ   rT   rV   rX   rl   ri   r   r|   rk   __classcell__)r   s   @r   r   r      sp    % ; ;*25,O" 4:x%FN
r   r   )r   r'   r   rK   re   gunicorn.workersr   gunicorn.asgi.protocolr   Workerr   rH   r   r   <module>r      s0   
  	  
 ! /Z Zr   