
    &`il                        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mZmZmZmZmZmZ d dlZd dlZd dlZd dlmZ d dlmZ d dlZd dlmZ d dlmZ d dlmZm Z m!Z!m"Z"m#Z#m$Z$ d d	l%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4 d d
l5m6Z6 d dl7m8Z8m9Z9m:Z: d dl;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZB d dlCmDZDmEZEmFZFmGZG d dlHmIZImJZJ d dlKmLZLmMZMmNZNmOZOmPZPmQZQmRZR d dlSmTZT d dlUmVZV d dlWmXZX d dlYmZZZm[Z[m\Z\ d dl]m^Z^m_Z_ d dl`maZambZb d dlcmdZd d dlemfZfmgZg d dlhmiZi  ejj        e2          Zkejl        m                    dd          dk    Znejl        m                    d          eko                    d           dZpdZqdZr G d  d!e          Zs G d" d#es          Zt G d$ d%es          Zu G d& d'e          Zv ejw        d (           G d) d*ev                      Zxd+ ZydS ),    N)ABCabstractmethod)AnyCallableDict	GeneratorOptionalSetTuple)version)Receive)CoreContextFilter)get_or_create_event_loop)DeploymentIDEndpointInfoNodeId	ReplicaIDRequestMetadataRequestProtocol)HEALTHY_MESSAGEPROXY_MIN_DRAINING_PERIOD_S'RAY_SERVE_ENABLE_PROXY_GC_OPTIMIZATIONSRAY_SERVE_PROXY_GC_THRESHOLD&RAY_SERVE_REQUEST_PATH_LOG_BUFFER_SIZEREQUEST_LATENCY_BUCKETS_MSSERVE_CONTROLLER_NAMESERVE_HTTP_REQUEST_ID_HEADERSERVE_LOG_COMPONENTSERVE_LOG_COMPONENT_IDSERVE_LOG_REQUEST_IDSERVE_LOG_ROUTESERVE_LOGGER_NAMESERVE_MULTIPLEXED_MODEL_IDSERVE_NAMESPACE)get_proxy_handle)get_grpc_response_statusset_grpc_code_and_detailsstart_grpc_server)MessageQueueconfigure_http_middlewaresconvert_object_to_asgi_messagesget_http_response_statusreceive_http_bodysend_http_response_on_exceptionstart_asgi_http_server)access_log_msgconfigure_component_logger#configure_component_memory_profilerget_component_logger_file_path)LongPollClientLongPollNamespace)ASGIProxyRequestHandlerMetadataProxyRequestResponseGeneratorResponseHandlerInfoResponseStatusgRPCProxyRequest)ProxyResponseGenerator)ProxyRouter)ServeUsageTag)generate_request_idget_head_node_idis_grpc_enabled)HTTPOptionsgRPCOptions)HealthzResponseListApplicationsResponse)DeploymentHandle)EncodingTypeLoggingConfig)metricsSERVE_SOCKET_REUSE_PORT_ENABLED1"SERVE_REQUEST_PROCESSING_TIMEOUT_Sa*  The `SERVE_REQUEST_PROCESSING_TIMEOUT_S` environment variable has been deprecated. Please set `request_timeout_s` in your Serve config's `http_options` or `grpc_options` field instead. `SERVE_REQUEST_PROCESSING_TIMEOUT_S` will be ignored in future versions. See: https://docs.ray.io/en/releases-2.5.1/serve/api/doc/ray.serve.schema.HTTPOptionsSchema.html#ray.serve.schema.HTTPOptionsSchema.request_timeout_s and https://docs.ray.io/en/latest/serve/api/doc/ray.serve.config.gRPCOptions.request_timeout_s.html#ray.serve.config.gRPCOptions.request_timeout_sg?   zThis node is being drained.c                      e Zd ZdZ	 	 d$dededededee	         de
eef         fd	Zeed
efd                        Zd
efdZd ZdefdZeded
efd            Zededed
efd            Zededed
ef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edededededed
e eef         fd            Z!e	 d%d!edededed"ed
efd#            Z"dS )&GenericProxya  This class is served as the base class for different types of proxies.
    It contains all the common setup and methods required for running a proxy.

    The proxy subclass need to implement the following methods:
      - `protocol()`
      - `not_found_response()`
      - `routes_response()`
      - `health_response()`
      - `setup_request_context_and_handle()`
      - `send_request_to_replica()`
    Nnode_idnode_ip_addressis_headproxy_routerrequest_timeout_saccess_log_contextc                 .   || _         | j         | j         dk     rd | _         || _        || _        || _        t	          j        d| j                                         dd| j         dd          | _        t	          j        d| j                                         dd	| j         d
d          | _	        t	          j        d| j                                         dd	| j         dd          | _
        t                              dt                      t	          j        d| j                                         dd| j         d| j         dt          d          | _        t	          j        d| j                                         dd| j         dd                              ||d          | _        d| _        d | _        |pi | _        t-          t.          | j                                         d                              d           d S )Nr   
serve_num_	_requestszThe number of z requests processed.routemethodapplicationstatus_code)descriptiontag_keys_error_requestszThe number of errored z responses.)r[   
error_coder\   r]   serve_num_deployment_z' responses returned by each deployment.)
deploymentrb   r\   r[   r]   zREQUEST_LATENCY_BUCKET_MS: serve__request_latency_mszThe end-to-end latency of z# requests (measured from the Serve z proxy).)r\   r[   r]   r^   )r_   
boundariesr`   serve_num_ongoing_z'The number of ongoing requests in this z proxy.)rQ   rR   )namer_   r`   _PROXY_USEDrL   )rU   _node_id_is_headrT   rJ   Counterprotocollowerrequest_counterrequest_error_counter deployment_request_error_counterloggerdebugr   	Histogramprocessing_latency_trackerGaugeset_default_tagsnum_ongoing_requests_gauge_ongoing_requests_draining_start_time_access_log_contextgetattrr?   upperrecord)selfrQ   rR   rS   rT   rU   rV   s          l/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/ray/serve/_private/proxy.py__init__zGenericProxy.__init__   s    "3!-$2H12L2L%)D"(&9,,..999LLLLF 
  
  
 &-_?,,..???KKKK	&
 	&
 	&
" 18JDM$7$7$9$9JJJ9 9 9 91
 1
 1
-  	O3MOOPPP*1*;?T]((**???DT] D D,0MD D D 2+
 +
 +
' +2-Fdm&9&9&;&;FFF$-   3	+
 +
 +

 
"#2 
 
 	' "# 6:!#5#; $-"5"5"7"7DDDEELLSQQQQQ    returnc                     t           )zvProtocol used in the proxy.

        Each proxy needs to implement its own logic for setting up the protocol.
        NotImplementedErrorr   s    r   rn   zGenericProxy.protocol   s
     "!r   c                     | j         duS )z8Whether is proxy actor is in the draining status or not.N)r{   r   s    r   _is_drainingzGenericProxy._is_draining   s    (44r   c                     |                                  sdS | j         o#t          j                    | j        z
  t          k    S )zCheck whether the proxy actor is drained or not.

        A proxy actor is drained if it has no ongoing requests
        AND it has been draining for more than
        `PROXY_MIN_DRAINING_PERIOD_S` seconds.
        F)r   rz   timer{   r   r   s    r   
is_drainedzGenericProxy.is_drained   sG       "" 	5** 
Y[[4448SS	
r   drainingc                 @   |rS|                                  s?t                              d| j         dddi           t	          j                    | _        |sD|                                  r2t                              d| j         dddi           d| _        dS dS dS )zUpdate the draining status of the proxy.

        This is called by the proxy state manager
        to drain or un-drain the proxy actor.
        z'Start to drain the proxy actor on node .log_to_stderrFextraz&Stop draining the proxy actor on node N)r   rs   infork   r   r{   )r   r   s     r   update_drainingzGenericProxy.update_draining   s      	4T..00 	4KKJ$-JJJ&.     )-	D% 	-d//11 	-KKIIII&.     )-D%%%	- 	- 	- 	-r   proxy_requestc                    K   t           Nr   )r   r   s     r   not_found_responsezGenericProxy.not_found_response         "!r   healthymessagec                   K   t           r   r   r   r   r   s      r   routes_responsezGenericProxy.routes_response  r   r   c                   K   t           r   r   r   s      r   health_responsezGenericProxy.health_response  r   r   c                 d    | xj         dz  c_         | j                            | j                    dS )aq  Ongoing requests start.

        The current autoscale logic can downscale nodes with ongoing requests if the
        node doesn't have replicas and has no primary copies of objects in the object
        store. The counter and the dummy object reference will help to keep the node
        alive while draining requests, so they are not dropped unintentionally.
           Nrz   ry   setr   s    r   _ongoing_requests_startz$GenericProxy._ongoing_requests_start  s8     	!#'++D,BCCCCCr   c                 d    | xj         dz  c_         | j                            | j                    dS )zOngoing requests end.

        Decrement the ongoing request counter and drop the dummy object reference
        signaling that the node can be downscaled safely.
        r   Nr   r   s    r   _ongoing_requests_endz"GenericProxy._ongoing_requests_end$  s8     	!#'++D,BCCCCCr   c                 l   | j                             | j                  \  }}|                                 r
d}t          }n|sd}|}n	d}t
          }|j        r|                     ||          }n |j        sJ | 	                    ||          }t          |t          |j                  dd          S )zGet the response handler for system health and route endpoints.

        If the proxy is draining or has not yet received a route table update from the
        controller, both will return a non-OK status.
        FT)r   r   r[   response_generatormetadatashould_record_access_log!should_increment_ongoing_requests)rT   ready_for_trafficrl   r   DRAINING_MESSAGEr   is_health_requestr   is_route_requestr   r:   r7   
route_path)r   r   router_ready_for_traffic
router_msgr   r   r   s          r   _get_health_or_routes_reponsez*GenericProxy._get_health_or_routes_reponse-  s     04/@/R/RM0
 0
, *  	&G&GG) 	&G GGG%G* 	X!%!5!5gw!5!W!W 1111!%!5!5gw!5!W!W"1$#.   &+.3
 
 
 	
r   c                    |j         s|j        r|                     |          S d }| j        t          j        k    r | j                            |j                  }n4| j        t          j	        k    r| j        
                    |j                  }|4t          |                     |          t          d          dd          S |\  }}}|j        }|dk    r| j        t          j        k    r|                    d          rJ |                    |j        |z              t#          j        t&          j                  t#          j        d          k     r*|                    |                    |dd                     | j        t          j        k    r!| j                            ||j                  }n|j        j        }t7                      }|                     |j        j        ||||	          \  }}	|                     |	||||
          }
t          |
t          |j        j        |j        j        |          dd          S )N r   TFr   /z0.33.0r   )app_namehandler[   r   internal_request_id)
request_idr   r   r   app_is_cross_language)application_namedeployment_namer[   )r   r   r   rn   r   HTTPrT   match_router   GRPCget_handle_for_endpointr:   r   r7   endswithset_root_path	root_pathr   parse	starlette__version__set_pathreplacematch_route_patternscopedeployment_idr   r@    setup_request_context_and_handlesend_request_to_replicari   )r   r   matched_routeroute_prefixr   r   r   logs_and_metrics_router   r   r   s              r   _get_response_handler_infoz'GenericProxy._get_response_handler_infoQ  s    * 	Em.L 	E55mDDD=O000 -99-:RSSMM]o222 -EE( M  &#'#:#:=#I#I( 	   *.27
 
 
 
 ;H7L&"7 '1Js""t}8L'L'L'0055555++M,Cl,RSSS =!677'-:Q:QQQ!**:+=+=lBPQ+R+RSSS } 444)-):)N)N -"5* *&& *0)=)F&"5"7"7!%!F!F-6,+$7 "G " "FJ "&!=!=%$7+&; "> " " '#5(%+%9%B$*$8$=0  
 *.26	 	 	 	r   c           	       K   |j         dv sJ |                     |          }t          j                    }|j        r|                                  	 d}|j        2 3 d{V }t          |t                    r|}|W V  $6 |t          |t                    sJ 	 |j        r|                                  n!# |j        r|                                  w w xY wt          j                    |z
  dz  }|j	        rt          j        j                                        }|j        | j        t           <   |j        | j        t$          <   t&                              t+          |j        |j        t/          |j                  |          | j                   | j                            |j        j        |j        |j        j        t/          |j                  d           | j                            ||j        j        |j        |j        j        t/          |j                  d           |j        r| j                             |j        j        |j        |j        j        t/          |j                  d           | j!                            |j        j        |j        |j        j        t/          |j                  |j        j"        d	           dS dS )
zWrapper for proxy request.

        This method is served as common entry point by the proxy. It handles the
        routing, including routes and health checks, ongoing request counter,
        and metrics.
        >   grpchttp	websocketNg     @@)r\   r[   status
latency_msr   rZ   )tags)r[   r\   r]   rb   )r[   r\   r]   rb   rd   )#request_typer   r   r   r   r   
isinstancer;   r   r   rayservecontext_get_serve_request_contextr[   r|   r!   r   r    rs   r   r0   r\   strcoderp   incr   r   rv   observeis_errorrq   rr   r   )r   r   response_handler_info
start_timer   r   r   request_contexts           r   r   zGenericProxy.proxy_request  s;      )-JJJJJ $ ? ? N NY[[
 B 	+((***	-/3F!6!I       gg~66 %$F	 "J %*V^*L*L%%L% %F -**,,, %F -**,,,,- ikkJ.&8
 9 	!i/JJLLO8G8MD$_5=L=WD$%9:KK(/)/v{++)	   .     	  .7='.4=N"6;//	  	! 	
 	
 	
 	'//.7='.4=N"6;//	  	0 	
 	
 	
 ? 	&**2;A+2#8#A#R"%fk"2"2	  +    1552;A+2#8#A#R"%fk"2"2"7"@"P  6     	 	s   	B6 A?!8B6 6Cr   r   r[   r   c                     t           )zSetup the request context and handle for the request.

        Each proxy needs to implement its own logic for setting up the request context
        and handle.
        r   )r   r   r   r[   r   r   s         r   r   z-GenericProxy.setup_request_context_and_handle  s
     "!r   Fr   r   c                    K   t           )zSend the request to the replica and handle streaming response.

        Each proxy needs to implement its own logic for sending the request and
        handling the streaming response.
        r   )r   r   r   r   r   r   s         r   r   z$GenericProxy.send_request_to_replica  s       "!r   NNF)#__name__
__module____qualname____doc__r   r   boolr>   r	   floatr   r   r   propertyr   r   rn   r   r   r   r8   r9   r   r   r   r   r   r:   r   r   r   rG   r   r   r    r   r   rP   rP   s   s       
 
$ .2-1VR VRVR VR 	VR
 "VR $E?VR !cNVR VR VR VRp "/ " " " ^ X"5d 5 5 5 5
 
 
- - - - -( ")"	" " " ^"
 ""),"	" " " ^"
 ""),"	" " " ^"
	D 	D 	DD D D"
)"
	"
 "
 "
 "
HN)N	N N N N`Q QBS Q Q Q Qf "" !" 	"
 $" !" 
$	%" " " ^"  '," "" !" !	"
 $"  $" 
" " " ^" " "r   rP   c                       e Zd ZdZedefd            ZdedefdZ	de
dedefdZde
defd	Zd
ede
defdZdedededededeeef         fdZ	 ddedededede
defdZdS )	gRPCProxya  This class is meant to be instantiated and run by an gRPC server.

    This is the servicer class for the gRPC server. It implements `unary_unary`
    as the entry point for unary gRPC request and `unary_stream` as the entry
    point for streaming gRPC request.
    r   c                     t           j        S r   )r   r   r   s    r   rn   zgRPCProxy.protocol      ##r   r   c                   K   |j         sd}nd|j          d}| d}t          t          j        j        |d          W V  d S )NzApplication metadata not set.zApplication 'z' not found.zP Ping /ray.serve.RayServeAPIService/ListApplications for available applications.Tr   r   r   )r   r;   r   
StatusCode	NOT_FOUND)r   r   application_messagenot_found_messages       r   r   zgRPCProxy.not_found_response!  s       % 	W"A"V-2H"V"V"V" Y Y Y 	
 *%
 
 
 	
 	
 	
 	
 	
 	
r   r   r   c                  K   t          d | j        j        D                                                       W V  t	          |rt
          j        j        nt
          j        j        ||           W V  d S )Nc                     g | ]	}|j         
S r   )r   ).0endpoints     r   
<listcomp>z-gRPCProxy.routes_response.<locals>.<listcomp>7  s(       &.!  r   )application_namesr   )	rF   rT   	endpointsSerializeToStringr;   r   r   OKUNAVAILABLEr   s      r   r   zgRPCProxy.routes_response3  s       ' 262C2M  
 
 
 


		 	 	 	 '.O##DO4O [
 
 
 	
 	
 	
 	
 	
 	
r   c                  K   t          |                                          W V  t          |rt          j        j        nt          j        j        ||           W V  d S )Nr   r   )rE   r	  r;   r   r   r
  r  r   s      r   r   zgRPCProxy.health_responseB  s{      g...@@BBBBBB'.O##DO4O [
 
 
 	
 	
 	
 	
 	
 	
r   service_methodstreamc           	           dt           dt          j        j        j        dt
          f fd}dt           dt          j        j        j        dt          t
          d d f         f fd}|r|n|S )Nrequest_protor   r   c                    K   t          | |d          }d}d}                    |          2 3 d{V }t          |t                    r|}|}"6 t	          ||           |S )a,  Entry point of the gRPC proxy unary request.

            This method is called by the gRPC server when a unary request is received.
            It wraps the request in a ProxyRequest object and calls proxy_request.
            The return value is serialized user defined protobuf bytes.
            Fr  r   r  r  Nr   r<   r   r   r;   r'   )r  r   r   r   responser   r   r  s         r   unary_unaryz6gRPCProxy.service_handler_factory.<locals>.unary_unaryK  s       -+-	  M FH!%!3!3-!3!P!P ' ' ' ' ' ' 'gg~66 '$FF&HH	 "Q &gv666Os   Ac                   K   t          | |d          }d}                    |          2 3 d{V }t          |t                    r|}|W V  %6 t	          ||           dS )aO  Entry point of the gRPC proxy streaming request.

            This method is called by the gRPC server when a streaming request is
            received. It wraps the request in a ProxyRequest object and calls
            proxy_request. The return value is a generator of serialized user defined
            protobuf bytes.
            Tr  Nr  r  )r  r   r   r   r   r   r  s        r   unary_streamz7gRPCProxy.service_handler_factory.<locals>.unary_streamg  s       -+-	  M F!%!3!3-!3!P!P " " " " " " "gg~66 "$FF!MMMMM	 "Q &gv66666s   A)r   r   _cythoncygrpc_ServicerContextbytesr   )r   r  r  r  r  s   ``   r   service_handler_factoryz!gRPCProxy.service_handler_factoryJ  s    		)-)<)M		 	 	 	 	 	 	8	7	7)-)<)M	7udD()	7 	7 	7 	7 	7 	7 	74  &6||;6r   r   r   r[   r   c                 d   |j         }|j        }|st                      }||_        |                    |j        ||j                  }||||||j        d}t          j        j	        j
                            t          j        j	        j        di |           |                    |           ||fS )zSetup request context and handle for the request.

        Unpack gRPC request metadata and extract info to set up request context and
        handle.
        )r  multiplexed_model_idmethod_name)r[   r   _internal_request_idr   r   grpc_context)r   r   )r   r   r@   optionsr  r!  ray_serve_grpc_contextr   r   r   _serve_request_contextr   _RequestContextsend_request_id)	r   r   r   r[   r   r   r   r   request_context_infos	            r   r   z*gRPCProxy.setup_request_context_and_handle  s      -A"-
 	2,..J'1M$ '!5%1   
 
 $$7 $8)@ 
  
 		044I-EE0DEE	
 	
 	
 	%%%<<<z!!r   Fr   r   c                  K   t          |                    |                                          | j                  }	 |2 3 d {V \  }}|                    |j                   |W V  *6 t          t          j        j	                  }	n-# t          $ r }
t          |
| j        |          }	Y d }
~
nd }
~
ww xY w|	J |	W V  d S )N)	timeout_s)r   )r=   remoteserialized_replica_argrU   _set_on_grpc_contextr   r;   r   r   r
  BaseExceptionr&   )r   r   r   r   r   r   r   r   resultr   es              r   r   z!gRPCProxy.send_request_to_replica  s      4MM->>@@AA,
 
 

	U);       ogv,,]-BCCC *< $);<<<FF 	U 	U 	U-a1GTTFFFFFF	U !!!s$   B A+AB 
B6B11B6Nr   )r   r   r   r   r   r   rn   r8   r9   r   r   r   r   r   r   r  rG   r   r   r   r   r   r   r   r     s         $/ $ $ $ X$
)
	
 
 
 
$

),
	
 
 
 

 
BS 
 
 
 
77c 774 77H 77 77 77 77r%"%" !%" 	%"
 $%" !%" 
$	%%" %" %" %"Z ',  ! !	
 $  $ 
     r   r   c                   V    e Zd ZdZ	 	 d%dedededededee	         d	e
eef         f fd
Zedefd            ZdedefdZdededefdZdddededefdZdedefdZd Zdededee         fdZdedededededeeef         fdZdedefd Z 	 d&d"edededed#edefd$Z! xZ"S )'	HTTPProxyzFThis class is meant to be instantiated and run by an ASGI HTTP server.NrQ   rR   rS   rT   self_actor_namerU   rV   c                     t                                          ||||||           || _        t                      | _        d S )N)rU   rV   )superr   r4  dictasgi_receive_queues)	r   rQ   rR   rS   rT   r4  rU   rV   	__class__s	           r   r   zHTTPProxy.__init__  sT     	/1 	 	
 	
 	
  /<@FF   r   r   c                     t           j        S r   )r   r   r   s    r   rn   zHTTPProxy.protocol  r   r   r   c                z   K   d}t          d|j         d|          D ]}|W V  t          |d          W V  d S )Ni  zPath 'z;' not found. Ping http://.../-/routes for available routes.r^   Tr   r   )r+   pathr;   )r   r   r^   r   s       r   r   zHTTPProxy.not_found_response  sx       6=]' = = =#
 
 
 	 	G
 MMMMM+=========r   r   r   c               .  K   |rdnd}|rYt                      }| j        j                                        D ]+\  }}|j        r|j        ||j        <   |j        ||j        <   ,n|}t          ||          D ]}|W V  t          |||           W V  d S )N     r<  r   )	r7  rT   r  itemsr   r[   ri   r+   r;   )r   r   r   r^   r  r  r   asgi_messages           r   r   zHTTPProxy.routes_response  s       %-cc# 
	vvH"&"3"="C"C"E"E 9 9$$ 9+3+<HTZ(( ,4=HTZ((9 H;#
 
 
 	 	L  [
 
 
 	
 	
 	
 	
 	
 	
r   r   r  c               t   K   |rdnd}t          ||          D ]}|W V  t          || |          W V  d S )Nr@  rA  r<  )r   r   r   )r+   r;   )r   r   r   r^   rC  s        r   r   zHTTPProxy.health_response
  s       %-cc#;#
 
 
 	 	L  [
 
 
 	
 	
 	
 	
 	
 	
r   request_metadatac                    K   | j                             |j        d           }|t          d|j         d          |                                 d {V  |                                S )NzRequest ID z not found.)r8  getr   KeyErrorr   wait_for_messageget_messages_nowait)r   rE  queues      r   receive_asgi_messageszHTTPProxy.receive_asgi_messages  s~       (,,-=-QSWXX=Q)9)DQQQRRR$$&&&&&&&&&((***r   c                    K   t          |||          }|                     |          2 3 d{V }t          |t                    s ||           d{V  .6 dS )zImplements the ASGI protocol.

        See details at:
            https://asgi.readthedocs.io/en/latest/specs/index.html.
        )r   receivesendN)r6   r   r   r;   )r   r   rN  rO  r   r   s         r   __call__zHTTPProxy.__call__$  s       )ugDQQQ!//>> 	$ 	$ 	$ 	$ 	$ 	$ 	$'g~66 $d7mm####### ?>>s   ArN  rK  c                   K   	 	  |             d{V } ||           d{V  |d         dk    r	 |                                  dS |d         dk    r|d         |                                  S m# |                                  w xY w)aY  Proxies the `receive` interface, placing its messages into the queue.

        Once a disconnect message is received, the call exits and `receive` is no longer
        called.

        For HTTP messages, `None` is always returned.
        For websocket messages, the disconnect code is returned if a disconnect code is
        received.
        TNtypezhttp.disconnectwebsocket.disconnectr   )close)r   rN  rK  msgs       r   proxy_asgi_receivezHTTPProxy.proxy_asgi_receive/  s      	'#GIIooooooeCjj       v;"333 KKMMMMM v;"888v; KKMMMM' KKMMMMs   .A2 	A2 1A2 2Br   r   r[   r   c                    |||dd}|j         D ]\  }}|                                t          k    r/|                                }	|                    |	          }|	|d<   |                                t          k    r|                                |d<   t
          j        j        j        	                    t          j        j        j
        di |           ||d         fS )zSetup request context and handle for the request.

        Unpack HTTP request headers and extract info to set up request context and
        handle.
        T)r[   r   r"  is_http_request)r   r   r   r   )headersdecoder#   r$  r   r   r   r   r&  r   r'  )
r   r   r   r[   r   r   r)  keyvaluer   s
             r   r   z*HTTPProxy.setup_request_context_and_handleJ  s      $7#	 
  
 (/ 	D 	DJCzz||999',||~~$=QRR?S$%;<zz||;;;5:\\^^$\2	044I-EE0DEE	
 	
 	
 +L999r   c                   K   |j                             d          }t          |j         |j        |j                   d{V }|r/|                                                    dd          d         }n|                                }|S )zIConvert an HTTP request to the Java-accepted format (single byte string).query_stringN=r   )r   rG  r-   rN  rO  rZ  split)r   r   r^  http_body_bytesargs        r   _format_handle_arg_for_javaz%HTTPProxy._format_handle_arg_for_javai  s      
 %*..~>> 1!68J!
 !
 
 
 
 
 
 
  	+%%''--c155a8CC!((**C
r   Fr   r   c                  K   |r#|                      |           d{V }t          }n'|                    | j                  }t          j        }t                      }|| j        |<   t                      	                    | 
                    |j        |                    }	t          |                    |          | j        |	|          }
d}d}d}	 |
2 3 d{V }|D ]=}|d         dk    rPt          |d                   }t!          ||                    d          	          }|                    d
d          }n|d         dk    r|
                                 n|d         dk    r-|                    dd          s|s|
                                 n}|d         dk    r+|                    dd          s|
                                 nF|d         dv r<t          |d                   }t!          ||dv	          }|
                                 |W V  d}?J6 nE# t(          $ r8}t+          || j        |          }t-          ||          D ]}|W V  Y d}~nd}~ww xY wd}|	                                s|	                                 nd}|O|j        dk    rD|r1t!          t          |	                                          d	          }nt!          dd	          }| j        |= n# d}|	                                s|	                                 nd}|O|j        dk    rD|r1t!          t          |	                                          d	          }nt!          dd	          }| j        |= w xY w|J |W V  dS )zSend the request to the replica and yield its response messages.

        The yielded values will be ASGI messages until the final one, which will be
        the status code.
        N)proxy_actor_name)r+  disconnected_taskresult_callbackFrR  zhttp.response.startr   )45r=  trailerszwebsocket.acceptzhttp.response.body	more_bodyzhttp.response.trailersmore_trailers)zwebsocket.closerS  r   )10001001Tr   rm  )rc  r+   r-  r4  pickleloadsr)   r8  r   create_taskrV  rN  r=   r,  rU   r   r;   
startswithrG  stop_checking_for_disconnectr/  r,   r.   donecancelr   r0  )r   r   r   r   r   r   handle_arg_bytesrg  receive_queueproxy_asgi_receive_taskr   r   response_startedexpecting_trailersasgi_message_batchrC  r^   r1  receive_client_disconnect_msgs                      r   r   z!HTTPProxy.send_request_to_replicay  s      ! 		+%)%E%Em%T%TTTTTTT=OO,CC!%!5  D     %lO
 %8E !45":"<"<"H"H##M$9=II#
 #
 4MM*++,5+	
 
 
 ,0 "S	>,> ., ., ., ., ., ., .,( %7 +, +,L#F+/DDD '*,x*@&A&A!/!,%0%;%;J%G%G" " " .:-=-=j%-P-P**%f-1CCC +GGIIII$V,0DDD , 0 0e D D E 2 E +GGIIII%f-1III  ,//GG N.KKMMM%f- 2   '*,v*>&?&?!/!, &18H%H	" " " +GGIII&&&&&'+$$W+, -?,>^  	# 	# 	#-a1GTTF ?(! ! # # #"""""# # # # #	# -2)*//11 5'..000004- ~-"<"K"K0 + !8!?!?!A!ABB!%  FF ,#!%  F
 ()<==3 -2)*//11 5'..000004- ~-"<"K"K0 + !8!?!?!A!ABB!%  FF ,#!%  F
 ()<===== !!!s>   H! HEH!  K- !
I#+.IK- I##K- -BM5r   r   )#r   r   r   r   r   r   r   r>   r	   r   r   r   r   r   r   rn   r8   r9   r   r   r   r   rL  rP  r   r)   intrV  rG   r   r   r  rc  r   __classcell__r9  s   @r   r3  r3    s       PP .2-1C CC C 	C
 "C C $E?C !cNC C C C C C* $/ $ $ $ X$>)>	> > > >

),
	
 
 
 
: 02
 
 

),
	
 
 
 
 + /+	+ + + +	$ 	$ 	$'3	#   6:: !: 	:
 $: !: 
$	%: : : :># 
   , ',B BB !B !	B
 $B  $B 
B B B B B B B Br   r3  c            	          e Zd ZdZeddedededefdZ	e
defd	            Ze
ddeddfd            Ze
	 ddedee         ddfd            Ze
ddee         defd            Ze
defd            Ze
defd            Ze
dedefd            Ze
defd            Ze
dee         fd            Ze
dedefd            ZdefdZdS )ProxyActorInterfacezAbstract interface for proxy actors in Ray Serve.

    This interface defines the contract that all proxy actor implementations must follow,
    allowing for different proxy backends (Ray HTTP/gRPC proxies, HAProxy, etc.).
    )log_buffer_sizerQ   rR   logging_configr  c                h    || _         || _        || _        || _        |                     |           dS )a
  Initialize the proxy actor.

        Args:
            node_id: ID of the node this proxy is running on
            node_ip_address: IP address of the node
            logging_config: Logging configuration
            log_buffer_size: Size of the log buffer
        N)rk   _node_ip_address_logging_config_log_buffer_size_update_logging_config)r   rQ   rR   r  r  s        r   r   zProxyActorInterface.__init__  s=        /- /##N33333r   r   c                 
   K   dS )zBlocks until the proxy is ready to serve requests.

        Returns:
            JSON-serialized metadata containing proxy information (worker ID, log file path, etc.)
        Nr   r   s    r   readyzProxyActorInterface.ready         	r   Twait_for_applications_runningNc                 
   K   dS )zWait for the proxy to be ready to serve requests.

        Args:
            wait_for_applications_running: Whether to wait for the applications to be running

        Returns:
            None
        Nr   r   r  s     r   servingzProxyActorInterface.serving%         	r   r   _afterc                 
   K   dS )zUpdate the draining status of the proxy.

        Args:
            draining: Whether the proxy should be draining
            _after: Optional ObjectRef for scheduling dependency
        Nr   r   r   r  s      r   r   z#ProxyActorInterface.update_draining1  r  r   c                 
   K   dS )zCheck whether the proxy is drained.

        Args:
            _after: Optional ObjectRef for scheduling dependency

        Returns:
            True if the proxy is drained, False otherwise
        Nr   r   r  s     r   r   zProxyActorInterface.is_drained=  r  r   c                 
   K   dS )zsCheck the health of the proxy.

        Returns:
            True if the proxy is healthy, False otherwise
        Nr   r   s    r   check_healthz ProxyActorInterface.check_healthI  r  r   c                     dS )zWRespond to ping from replicas.

        Returns:
            A response string
        Nr   r   s    r   pongzProxyActorInterface.pongR  s	     	r   rE  c                 
   K   dS )zHandle ASGI messages for HTTP requests.

        Args:
            request_metadata: Metadata about the request

        Returns:
            Serialized ASGI messages
        Nr   r   rE  s     r   rL  z)ProxyActorInterface.receive_asgi_messages[  r  r   c                     dS )z#Get HTTP options used by the proxy.Nr   r   s    r   _get_http_optionsz%ProxyActorInterface._get_http_optionsh  	     	r   c                     dS )z8Get the file path for the logger (for testing purposes).Nr   r   s    r   _get_logging_configz'ProxyActorInterface._get_logging_configm  r  r   r[   c                     dS )z'Get replicas for a route (for testing).Nr   )r   r[   s     r   "_dump_ingress_replicas_for_testingz6ProxyActorInterface._dump_ingress_replicas_for_testingr  r  r   c                 @    t          d| j        || j                   d S )Nproxy)component_namecomponent_idr  buffer_size)r1   r  r  )r   r  s     r   r  z*ProxyActorInterface._update_logging_configw  s5    "".)-		
 	
 	
 	
 	
 	
r   Tr   )r   r   r   r   r   r   r   rI   r}  r   r   r  r   r  r	   r   r   r   r  r  r   r  rL  rC   r  r  r
   r  r  r   r   r   r  r    sW          F4 4 4 4 	4
 &4 4 4 4 4. S    ^ 	 	4 	4 	 	 	 ^	 6:	 		&.sm			 	 	 ^	 	 	x} 	 	 	 	 ^	 D    ^ c    ^ 	O 	PU 	 	 	 ^	 ;    ^ Xc]    ^      ^
] 
 
 
 
 
 
r   r  )num_cpusc                       e Zd Zdddedededededee	         f fd	Z
d
eeef         fdZdefdZdedee         fdZdefdZddeddfdZddedee         fdZddee         fdZdefdZd ZdedefdZdefdZ xZ S )
ProxyActorN)long_poll_clienthttp_optionsgrpc_optionsrQ   rR   r  r  c                Z   t                                          |||           || _        t          |          | _        t          | j                  }t                      }|pQt          t          j	        t          t                    t          j        | j        t          j        | j        i|          | _        d| j         d| j        j         }	|r|	d| j        j         dz  }	n|	dz  }	t(                              |	           t(                              dt          j                                                     d	|            t3          d
|           |j        t6          j        k    rXt;          j                    }
t:          j        D ]}|
                     |d            i |
tB          d
tD          | j#        ddddddi}ndddd}| j        tI                      k    }tK          tL                    | _'        tQ          | j        | j#        |t          j                    )                                | j'        | j        j*        |          | _+        |r.tY          | j        | j#        || j'        | j        j*        |          nd | _-        |.                    t_          | j+        | j        |t`                              | _1        d | _2        d | _3        |r?|.                    ti          | j-        j5        | j        |t`                              | _3        d | _6        to                       d S )N)rQ   rR   r  )	namespace)call_in_event_loopzProxy starting on node z (HTTP port: z, gRPC port: z).zConfigure Proxy actor z logger with logging config: r  )r  r  r   Fskip_context_filterTserve_access_log)r   r  r  )rQ   rR   rS   r4  rT   rU   rV   )rQ   rR   rS   rT   rU   rV   )
event_loopenable_so_reuseport)8r6  r   _grpc_optionsr*   _http_optionsrB   r   r4   r   	get_actorr   r$   r5   GLOBAL_LOGGING_CONFIGr  ROUTE_TABLE_update_routes_in_proxiesr  rk   portrs   r   rt   get_runtime_contextget_actor_idr2   encodingrH   JSONr   get_ray_core_logging_contextTASK_LEVEL_LOG_KEYSpopr   r   r  rA   r>   r%   rT   r3  get_actor_namerU   
http_proxyr   
grpc_proxyrq  r/   SOCKET_REUSE_PORT_ENABLED_start_http_server_task_running_http_server_task_start_grpc_server_taskr(   r  _running_grpc_server_task_configure_gc_options)r   r  r  rQ   rR   r  r  grpc_enabledr  startup_msgray_core_logging_contextr[  rV   rS   r9  s                 r   r   zProxyActor.__init__  s    	+) 	 	
 	
 	
 *7EE&t'9::-//
 0 !
NM/?KKK!79T!-t/M  *5
 5
 5
 feeDL^Lcee 	 F4+=+BFFFFKK4KK   <S%<%>%>%K%K%M%M < <+9< <	
 	
 	

 	,"	
 	
 	
 	
 "l&777
 (9'U'W'W$
 )< 8 8(,,S$7777"*"#W&(=%t"D" " "''+$(" " -#3#5#55'(899#M 1355DDFF*"0B1
 
 
$ 	I $ 5!."&"4"F#5     	 (2'='=""%$=	  (
 (
$ BF& @D$ 	+5+A+A!O;&)(A	  , ,D( BF&r   r  c                 :    | j                             |           d S r   )rT   update_routes)r   r  s     r   r  z$ProxyActor._update_routes_in_proxies   s    ''	22222r   r   c                 ~    d}t           j        D ]-}t          |t          j        j                  r|j        j        }.|S )z5Get the logging configuration (for testing purposes).N)rs   handlersr   loggingMemoryHandlertargetbaseFilename)r   log_file_pathhandlers      r   r  zProxyActor._get_logging_config  sA     	< 	<G'7#3#ABB < ' ;r   r[   c                 t    | j         j                            |          \  }}}|j        j        j        j        S r   )r  rT   r   _router_asyncio_router_request_router_replica_id_set)r   r[   _r   s       r   r  z-ProxyActor._dump_ingress_replicas_for_testing  s1    3??FF61~-=MMr   c                   K   	 | j          d{V | _        n/# t          $ r"}t                              d           |dd}~ww xY w	 | j        | j         d{V | _        n/# t          $ r"}t                              d           |dd}~ww xY wt          j        t          j
                                                    t                      g          S )a  Blocks until the proxy HTTP (and optionally gRPC) servers are running.

        Returns JSON-serialized metadata containing the proxy's worker ID and log
        file path.

        Raises any exceptions that occur setting up the HTTP or gRPC server.
        Nz"Failed to start proxy HTTP server.z"Failed to start proxy gRPC server.)r  r  	Exceptionrs   	exceptionr  r  jsondumpsr   r  get_worker_idr3   )r   r1  s     r   r  zProxyActor.ready  s     	373O-O-O-O-O-O-OD** 	 	 	ABBB		+77;7S1S1S1S1S1S1S. 	 	 	ABBB	 z'))7799.00
 
 	
s*    
A>AA! !
B+BBTr  c                 
   K   dS )z1Wait for the proxy to be ready to serve requests.Nr   r  s     r   r  zProxyActor.serving.  s      r   r   r  c                    K   | j                             |           | j        r| j                            |           dS dS )zUpdate the draining status of the HTTP and gRPC proxies.

        Unused `_after` argument is for scheduling: passing an ObjectRef
        allows delaying this call until after the `_after` call has returned.
        N)r  r   r  r  s      r   r   zProxyActor.update_draining2  sN       	''111? 	6O++H55555	6 	6r   c                 |   K   | j                                         o!| j        du p| j                                        S )zCheck whether both HTTP and gRPC proxies are drained or not.

        Unused `_after` argument is for scheduling: passing an ObjectRef
        allows delaying this call until after the `_after` call has returned.
        N)r  r   r  r  s     r   r   zProxyActor.is_drained=  s@       ))++ 
Ot#Ct'A'A'C'C	
r   c                 F   K   t                               dddi           dS )zwNo-op method to check on the health of the HTTP Proxy.

        Make sure the async event loop is not blocked.
        zReceived health check.r   Fr   T)rs   rt   r   s    r   r  zProxyActor.check_healthH  s)      
 	-ou5MNNNtr   c                     dS )z<Called by the replica to initialize its handle to the proxy.Nr   r   s    r   r  zProxyActor.pongP  s    r   rE  c                 j   K   t          j        | j                            |           d{V           S )a`  Get ASGI messages for the provided `request_metadata`.

        After the proxy has stopped receiving messages for this `request_metadata`,
        this will always return immediately.

        Raises `KeyError` if this request ID is not found. This will happen when the
        request is no longer being handled (e.g., the user disconnects).
        N)ro  r  r  rL  r  s     r   rL  z ProxyActor.receive_asgi_messagesT  sB       |/778HIIIIIIII
 
 	
r   c                     | j         S )z6Internal method to get HTTP options used by the proxy.)r  r   s    r   r  zProxyActor._get_http_optionsa  s    !!r   r  r   )!r   r   r   rC   rD   r   r   rI   r	   r4   r   r   r   r   r  r   r  r
   r   r  r  r   r  r   r   r   r  r  r   r  rL  r  r~  r  s   @r   r  r    s        6:|  |  | !|  "| 
 |  |  &|  #>2|  |  |  |  |  | |34l8R3S 3 3 3 3U    N NI N N N N
S 
 
 
 
> 4 4    	6 	6d 	6HSM 	6 	6 	6 	6	
 	
x} 	
 	
 	
 	
D      
O 
PU 
 
 
 
"; " " " " " " " "r   r  c                      t           sd S t          j        d           t          j                     t          j        t
                     d S )N   )r   gccollectfreezeset_thresholdr   r   r   r   r  r  f  sC    2  JqMMMIKKK 122222r   )zasyncior  r  r  osro  r   abcr   r   typingr   r   r   r   r	   r
   r   r   r   starlette.routing	packagingr   starlette.typesr   r   ray._common.filtersr   ray._common.utilsr   ray.serve._private.commonr   r   r   r   r   r   ray.serve._private.constantsr   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   ray.serve._private.default_implr%   ray.serve._private.grpc_utilr&   r'   r(   ray.serve._private.http_utilr)   r*   r+   r,   r-   r.   r/    ray.serve._private.logging_utilsr0   r1   r2   r3   ray.serve._private.long_pollr4   r5   )ray.serve._private.proxy_request_responser6   r7   r8   r9   r:   r;   r<   +ray.serve._private.proxy_response_generatorr=   ray.serve._private.proxy_routerr>   ray.serve._private.usager?   ray.serve._private.utilsr@   rA   rB   ray.serve.configrC   rD   ray.serve.generated.serve_pb2rE   rF   ray.serve.handlerG   ray.serve.schemarH   rI   ray.utilrJ   	getLoggerrs   environrG  r  warningINITIAL_BACKOFF_PERIOD_SECMAX_BACKOFF_PERIOD_SECr   rP   r   r3  r  r,  r  r  r   r   r   <module>r     s    				   				   # # # # # # # # G G G G G G G G G G G G G G G G G G                # # # # # # 



 1 1 1 1 1 1 6 6 6 6 6 6                                                " = < < < < <         
                             K J J J J J J J                  O N N N N N 7 7 7 7 7 7 2 2 2 2 2 2         
 6 5 5 5 5 5 5 5 S S S S S S S S - - - - - - 8 8 8 8 8 8 8 8      		,	-	- JNN4c::cA  :>>677C
NN	9	 	 	 "  0 _" _" _" _" _"3 _" _" _"Dm m m m m m m m`v v v v v v v vr	
 
 
 
 
# 
 
 
D Qb" b" b" b" b"$ b" b" b"J	3 	3 	3 	3 	3r   