
    &`i(                         d dl Z d dlmZmZmZmZmZmZ d dlm	Z	 d dl
mZ d dlmZ d dlmZ d dlmZmZmZ d dlmZ d d	lmZmZ d d
lmZ  e j        e          ZdZdZ G d d          ZdS )    N)AnyCallableDictListOptionalTuple)	Starlette)Request)Route)Scope)ApplicationNameDeploymentIDEndpointInfo)SERVE_LOGGER_NAME)RoutePatternget_asgi_route_name)DeploymentHandlez!Route table is not populated yet.zNo replicas are available yet.c                       e Zd ZdZdeeegef         fdZdede	eef         fdZ
deeef         fdZd	edee	eeef                  fd
Zdedee	eeef                  fdZdededefdZdS )ProxyRouterz&Router interface for the proxy to use.
get_handlec                 ,   || _         t                      | _        d| _        t	                      | _        t                      | _        t                      | _        t                      | _        t                      | _	        t                      | _
        d S )NF)_get_handledicthandles_route_table_populatedlistsorted_routes
route_infoapp_to_is_cross_language	endpointsroute_patterns_route_pattern_apps)selfr   s     s/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/ray/serve/_private/proxy_router.py__init__zProxyRouter.__init__   sw    
 &=AVV ',# )-3766EIVV% <@66
 >BVV 4866       is_headreturnc                     | j         s	dt          fS |rdS | j                                        D ]}|                                r dS dt
          fS )a  Whether the proxy router is ready to serve traffic.

        The first return value will be false if any of the following hold:
        - The route table has not been populated yet with a non-empty set of routes
        - The route table has been populated, but none of the handles
          have received running replicas yet AND it lives on a worker node.

        Otherwise, the first return value will be true.
        F)T )r   NO_ROUTES_MESSAGEr   valuesrunning_replicas_populatedNO_REPLICAS_MESSAGE)r#   r'   handles      r$   ready_for_trafficzProxyRouter.ready_for_traffic:   su     * 	,+++  	8l))++ 	  	 F0022  xx  )))r&   r    c                 0   t                               d| dddi           |rd| _        || _        t	          | j                                                  }g }i }i }i }|                                D ]\  }}|                    |j	                   |||j	        <   |j
        ||j        <   |j        r|j        ||j	        <   || j        v r|                    |           m|                     ||          | j        |<   t          |          dk    r/t                               dt          |           ddd	i           |D ]
}| j        |= t!          |d
 d          | _        || _        || _        || _        | j                                         d S )NzGot updated endpoints: .log_to_stderrT)extrar   z	Deleting z unused handles.Fc                      t          |           S N)len)xs    r$   <lambda>z+ProxyRouter.update_routes.<locals>.<lambda>{   s    #a&& r&   )keyreverse)loggerinfor   r    setr   keysitemsappendrouteapp_is_cross_languageapp_namer!   remover   r7   sortedr   r   r   r"   clear)	r#   r    existing_handlesroutesr   r   r!   endpointr=   s	            r$   update_routeszProxyRouter.update_routesW   s   2i222?D:Q 	 	
 	
 	
  	/*.D'"t|002233
#% 'oo// 		J 		JNHdMM$*%%%%-Jtz":>:T$X%67" A-1-@tz*4<'' ''1111)-)9)9(D)I)IX&&   1$$KKCC 011CCC&.     ) 	' 	'HX&& $F0@0@$OOO$(@%, &&(((((r&   target_routec                 P   | j         D ]}|                    |          rd}|                    d          rd}n;t          |          t          |          k    s|t          |                   dk    rd}|r/| j        |         }|| j        |         | j        |j                 fc S dS )zReturn the longest prefix match among existing routes for the route.
        Args:
            target_route: route to match against.
        Returns:
            (route, handle, is_cross_language) if found, else None.
        F/TN)r   
startswithendswithr7   r   r   r   rD   )r#   rL   rB   matchedrJ   s        r$   match_routezProxyRouter.match_route   s     ' 	 	E&&u--  >>#&& 	#"GG &&#e**44SZZ8PTW8W8W"G #u5HX.5h6GH    tr&   target_app_namec                     | j                                         D ]F\  }}||j        k    st          | j                   dk    r| j        |         }|j        ||j        fc S GdS )a2  Return the handle that matches with endpoint.

        Args:
            target_app_name: app_name to match against.
        Returns:
            (route, handle, is_cross_language) for the single app if there
            is only one, else find the app and handle for exact match. Else return None.
           N)r   r@   rD   r7   r    rB   rC   )r#   rS   endpoint_tagr/   endpoint_infos        r$   get_handle_for_endpointz#ProxyRouter.get_handle_for_endpoint   s     %)L$6$6$8$8 		 		 L& ,"7773t|;L;LPQ;Q;Q $| <!'!7    <R tr&   route_prefix
asgi_scopec                    || j         vr|S | j         |         }|s|S | j                            |          }|f	 dt          fdfd|D             }t	          |          }|| j        |<   n1# t
          $ r$ t                              d| d           |cY S w xY w	 t          ||          }|r|S n/# t
          $ r" t                              d	| d           Y nw xY w|S )
a  Match an incoming request to a specific route pattern.

        This attempts to match the request path to a route pattern (e.g., /api/{user_id})
        rather than just the route prefix. This provides more granular metrics.

        The mock Starlette app is cached per route_prefix for performance, avoiding
        the overhead of recreating the app and routes on every request.

        Args:
            route_prefix: The matched route prefix from match_route()
            asgi_scope: The ASGI scope containing the request path and method

        Returns:
            The matched route pattern if available, otherwise the route_prefix
        Nrequestc                 
   K   d S r6    )r\   s    r$   dummy_endpointz7ProxyRouter.match_route_pattern.<locals>.dummy_endpoint   s      Dr&   c                 H    g | ]}t          |j        |j                   S ))methods)r   pathra   ).0patternr_   s     r$   
<listcomp>z3ProxyRouter.match_route_pattern.<locals>.<listcomp>   s<        ',PPP  r&   )rI   z6Failed to create mock app for route pattern matching: T)exc_infoz"Failed to match route pattern for )	r!   r"   getr
   r	   	Exceptionr<   debugr   )r#   rY   rZ   patternsmock_apprI   rQ   r_   s          @r$   match_route_patternzProxyRouter.match_route_pattern   s   " t222&|4 	  +//==$'       #+   %F333 :B(66 $ $ $[\[[!     $###$		)(J??G  	 	 	LLC\CC      	 s#   3A/ /+BB!B6 6)C"!C"N)__name__
__module____qualname____doc__r   strr   r%   boolr   r0   r   r   r   rK   r   rR   rX   r   rl   r^   r&   r$   r   r      s-       00:c3Z)99:: : : :@* *%c	2B * * * *:))tL,,F'G )) )) )) ))V""	%-t34	5" " " "H"	%-t34	5   0> > >3 > > > > > >r&   r   ) loggingtypingr   r   r   r   r   r   starlette.applicationsr	   starlette.requestsr
   starlette.routingr   starlette.typesr   ray.serve._private.commonr   r   r   ray.serve._private.constantsr   1ray.serve._private.thirdparty.get_asgi_route_namer   r   ray.serve.handler   	getLoggerr<   r+   r.   r   r^   r&   r$   <module>r~      sM    = = = = = = = = = = = = = = = = , , , , , , & & & & & & # # # # # # ! ! ! ! ! ! Q Q Q Q Q Q Q Q Q Q : : : : : :        . - - - - -		,	-	-7 6 e e e e e e e e e er&   