o
    ci                     @   st   d dl Z d dlmZmZmZmZmZ d dlmZm	Z	m
Z
 d dlmZ d dlmZ e eZdZdZG dd	 d	ZdS )
    N)CallableDictListOptionalTuple)ApplicationNameDeploymentIDEndpointInfo)SERVE_LOGGER_NAME)DeploymentHandlez!Route table is not populated yet.zNo replicas are available yet.c                   @   s   e Zd ZdZdeeegef fddZdede	eef fddZ
d	eeef fd
dZdedee	eeef  fddZdedee	eeef  fddZdS )ProxyRouterz&Router interface for the proxy to use.
get_handlec                 C   s8   || _ t | _d| _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)selfr    r   S/home/ubuntu/.local/lib/python3.10/site-packages/ray/serve/_private/proxy_router.py__init__   s   zProxyRouter.__init__is_headreturnc                 C   s<   | j sdtfS |rdS | j D ]	}| r dS q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   handler   r   r   ready_for_traffic)   s   zProxyRouter.ready_for_trafficr   c                 C   s   t jd| dddid |rd| _|| _t| j }g }i }i }| D ])\}}||j	 |||j	< |j
||j< || jv rF|| q&| ||| j|< q&t|dkret jdt| ddd	id |D ]}| j|= qgt|d
d dd| _|| _|| _d S )NzGot updated endpoints: .log_to_stderrT)extrar   z	Deleting z unused handles.Fc                 S   s   t | S )N)len)xr   r   r   <lambda>g   s    z+ProxyRouter.update_routes.<locals>.<lambda>)keyreverse)loggerinfor   r   setr   keysitemsappendrouteapp_is_cross_languageapp_nameremover   r'   sortedr   r   r   )r   r   existing_handlesroutesr   r   endpointr-   r   r   r   update_routesF   s6   



zProxyRouter.update_routestarget_routec                 C   s|   | j D ]8}||r;d}|drd}nt|t|ks$|t| dkr&d}|r;| j| }|| j| | j|j f  S q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endswithr'   r   r   r   r4   )r   r;   r2   matchedr9   r   r   r   match_routek   s   



 

zProxyRouter.match_routetarget_app_namec                 C   sL   | j  D ]\}}||jkst| j dkr#| j| }|j||jf  S qd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   r0   r4   r'   r   r2   r3   )r   rA   endpoint_tagr"   endpoint_infor   r   r   get_handle_for_endpoint   s   
z#ProxyRouter.get_handle_for_endpointN)__name__
__module____qualname____doc__r   strr   r   boolr   r#   r   r   r	   r:   r   r@   rE   r   r   r   r   r      s"    
%
$r   )loggingtypingr   r   r   r   r   ray.serve._private.commonr   r   r	   ray.serve._private.constantsr
   ray.serve.handler   	getLoggerr,   r   r!   r   r   r   r   r   <module>   s    
