
    &`i              	          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mZm	Z	m
Z
mZmZ d dl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 d dlmZ d d	lmZmZmZmZm Z m!Z!m"Z"m#Z# d d
l$m%Z% d dl&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/ d dl0m1Z1 d dl2m3Z3 d dl4m5Z5 d dl6m7Z7 d dl8m9Z9 d dl:m;Z; d dl<m=Z= d dl>m?Z?m@Z@mAZA d dlBmCZCmDZD d dlEmFZF d dlGmHZH d dlImJZJ d dlKmLZLmMZMmNZNmOZO d dlPmQZQmRZRmSZS d dlTmUZUmVZVmWZWmXZXmYZZm[Z[ d dl\m]Z]m^Z^m_Z_m`Z`maZambZbmcZcmdZdmeZemfZfmgZgmhZhmiZi d dljmkZk  ejl        e-          Zmd ZndZodZp G d d           Zqd!e
ef         d"efd#e
er         d$e
e#         fd%Zsd&efd'efd$etfd(Zud)e
er         d*e
er         d+e
e#         fd,ZvdS )-    N)AnyDictIterableListOptionalTupleUnion)build_address)run_background_task)	GcsClient)ActorHandle)ApplicationStateManagerStatusOverview)AutoscalingStateManager)DeploymentIDHandleMetricReportNodeIdReplicaMetricReportRequestProtocolRequestRoutingInfoRunningReplicaInfoTargetCapacityDirection)DeploymentConfig)	CONTROL_LOOP_INTERVAL_S)RAY_SERVE_CONTROLLER_CALLBACK_IMPORT_PATH*RAY_SERVE_RPC_LATENCY_WARNING_THRESHOLD_MS(RECOVERING_LONG_POLL_BROADCAST_TIMEOUT_SSERVE_CONTROLLER_NAMESERVE_DEFAULT_APP_NAMESERVE_LOGGER_NAMESERVE_NAMESPACESERVE_ROOT_URL_ENV_KEY)create_cluster_node_info_cache)DeploymentInfo)DeploymentStateManager)EndpointState)ExternalScalerDisabledError)set_proxy_default_grpc_options)$configure_http_options_with_defaults)configure_component_logger#configure_component_memory_profilerget_component_logger_file_path)LongPollHostLongPollNamespace)ProxyStateManager)RayInternalKVStore)ServeUsageTag)call_function_from_import_path"get_all_live_placement_group_namesget_head_node_idis_grpc_enabled)HTTPOptionsProxyLocationgRPCOptions)ActorNameListApplicationArgsDeploymentArgsDeploymentRouteEndpointInfoEndpointSet)APITypeApplicationDetailsDeploymentDetailsHTTPOptionsSchemaLoggingConfigProxyDetailsReplicaRankServeActorDetailsServeApplicationSchemaServeDeploySchemaServeInstanceDetailsTargetGroupgRPCOptionsSchema)metricszserve-app-config-checkpointzserve-logging-config-checkpointc            	          e Zd ZdZdddededee         fdZdefdZ	d]d
Z
d	efdZdefdZdefdZdefdZdefdZdefdZd Zdeeef         fdZdefdZd	eeeeef         f         fdZd	efdZd	eeef         fdZ d	efdZ!d Z"d]dZ#de$d e$d!efd"Z%d# Z&d$ Z'd	e(e$ee)         ee*         f         fd%Z+d	eee,e-         f         fd&Z.d	e/fd'Z0d(ed	ee1         fd)Z2d*ed	e$fd+Z3d*ed,ed	e4fd-Z5d	efd.Z6d	efd/Z7d0 Z8d	e9fd1Z:d2 Z;d3eee,e         f         d4eeef         d	dfd5Z<d6ed7e,e         d8ed	dfd9Z=	 d^d;e)d<e$d	dfd=Z>d_d6ed*ed	efd?Z?d	eee(e@ef         f         fd@ZAded	eeB         fdAZCd	e,e         fdBZDdedCed	dfdDZEd`dEeeF         d	efdFZG	 	 dad*ee         dHe9d	e,eH         fdIZIeJfd6ed	efdJZKdKe,e         d	e,e         fdLZLd	e,e         fdMZMd	eeeNf         fdNZOd*ed	e9fdOZPd	e,e         fdPZQ	 d_d6ed*ed	eRdef         fdQZSd6efdRZTd*ed	ee         fdSZUdKeVe         fdTZWdUeXfdVZYded	eeeZf         fdWZ[dbdYe9fdZZ\d	e(fd[Z]d	ee*         fd\Z^dS )cServeControllera  Responsible for managing the state of the serving system.

    The controller implements fault tolerance by persisting its state in
    a new checkpoint each time a state change is made. If the actor crashes,
    the latest checkpoint is loaded and the state is recovered. Checkpoints
    are written/read using a provided KV-store interface.

    All hard state in the system is maintained by this actor and persisted via
    these checkpoints. Soft state required by other components is fetched by
    those actors from this actor on startup and updates are pushed out from
    this actor.

    All other actors started by the controller are named, detached actors
    so they will not fate share with the controller if it crashes.

    The following guarantees are provided for state-changing calls to the
    controller:
        - If the call succeeds, the change was made and will be reflected in
          the system even if the controller or other actors die unexpectedly.
        - If the call fails, the change may have been made but isn't guaranteed
          to have been. The client should retry in this case. Note that this
          requires all implementations here to be idempotent.
    N)grpc_optionshttp_optionsglobal_logging_configrO   c          
        K   t          j                                                    | _        | j        t	                      k    s
J d            t          j                    j        | _        t          t          j                    j                  | _	        d| j         }t          || j	                  | _        t                      | _        t          j                    | _        d | _        | j                            t&                    }|t)          j        |          }|                     |           t/          dt1          t3          j                                         t6          r7t8                              dt6           d           t=          t6                     t?          | j	                  | _         | j         !                                 tE          tG          |          | j        | j         | j        tI          |                    | _%        ~~tM          | j        | j                  | _'        t           j(        )                    d	
          }d |D             }tU                      | _+        tY          | j        | j        |t[                      | j         | j+                  | _.        t_          | j.        | j+        | j'        | j        | j                  | _0        tc          t          j                                                    t           j(        2                                t           j(        3                                t          j                    4                                tj          t          j                    6                                to                                | _8        d| _9        t          j                    | _:        d | _;        | <                                 t{          | >                                           d | _?        d | _@        | A                                 t                      | _C        | D                                 d S )Nz$Controller must be on the head node.)addressz
ray-serve-
controller)component_namecomponent_idz0Calling user-provided callback from import path .)rP   head_node_idcluster_node_info_cachelogging_configrO   T)all_namespacesc                 @    g | ]}|d          t           k    |d         S )	namespacename)r!   ).0actors     q/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/ray/serve/_private/controller.py
<listcomp>z,ServeController.__init__.<locals>.<listcomp>   s6     !
 !
 !
[!_44 &M444    )node_idnode_ipnode_instance_idactor_id
actor_name	worker_idlog_file_pathF)Erayget_runtime_contextget_node_id_controller_node_idr4   r]   ray_worker_namespacer   gcs_address
gcs_clientr0   kv_storer-   long_poll_hostasyncioEventdone_recovering_eventrQ   getLOGGING_CONFIG_CHECKPOINT_KEYpickleloads!reconfigure_global_logging_configr+   strosgetpidr   loggerinfor2   r#   rY   updater/   r)   r(   proxy_state_managerr&   endpoint_stateutillist_named_actorsr   autoscaling_state_managerr%   r3   deployment_state_managerr   application_state_managerrF   get_node_ip_addressget_node_instance_idget_actor_idr   get_worker_idr,   _actor_details_shutting_down_shutdown_event_shutdown_start_time_create_control_loop_metricsr   run_control_loop_target_capacity_target_capacity_direction_recover_state_from_checkpointset_proxy_nodes_update_proxy_nodes)selfrP   rQ   rO   kv_store_namespacelog_config_checkpointall_current_actorsall_serve_actor_namess           ra   __init__zServeController.__init__   s      $'#:#<#<#H#H#J#J $(8(:(::::1 ;:: %($;$=$=$G!#C,C,E,E,QRRRE$*CEE*+=tOO*nn%,]__"
 &*" $ 1 12O P P ,$*L1F$G$G!../DEEE+'c")++6F6F	
 	
 	
 	
 5 	VKK@<@ @ @   ++TUUU (Fdo'V'V$$++--- $5=lKK1$($@57EE$
 $
 $
  ,+DM4;NOO !X77t7LL!
 !
+!
 !
 !
 *A)B)B&(>M!.00(*)
 )
% *A)*M&*
 *
& 0+--99;;H0022 X::<<,..;;==,-//==??8::
 
 
 $&}$(!))+++D1133444 26MQ'++---  EE  """""rc   c                    | j         r| j         |k    rd S | j                            t          t	          j        |                     || _         | j                            t          j	        |i           t          dt          t          j                              |           t                              dt           j         dddi           t                              d| j                     d S )	NrT   )rU   rV   rZ   zController starting (version='z').log_to_stderrFextraz;Configure the serve controller logger with logging config: )rQ   rr   putrx   ry   dumpsrs   notify_changedr.   GLOBAL_LOGGING_CONFIGr*   r|   r}   r~   r   r   rk   __version__debug)r   rQ   s     ra   r{   z1ServeController.reconfigure_global_logging_config   s   &	*.CCCF)6<8M+N+N	
 	
 	
 &;"**46KL	
 	
 	
 	#'RY[[))0	
 	
 	
 	
 	AS_AAA"E* 	 	
 	
 	
 	A$($>A A	
 	
 	
 	
 	
rc   returnc                     dS )z+No-op to check if this controller is alive.N r   s    ra   check_alivezServeController.check_alive  s    rc   c                 (    t          j                    S N)r}   r~   r   s    ra   get_pidzServeController.get_pid  s    y{{rc   replica_metric_reportc                    t          j                     |j        z
  }|dz  }| j                            ||j        j        j        |j        j        j        |j        j        d           |t          k    r6t                              d|j         d|j         d| dt           d	           | j                            |           d S )	N  
deploymentapplicationreplicatagsz*Received autoscaling metrics from replica  with timestamp 
 which is Bms ago. This is greater than the warning threshold RPC latency of ms. This may indicate a performance issue with the controller try increasing the RAY_SERVE_RPC_LATENCY_WARNING_THRESHOLD_MS environment variable.)time	timestampreplica_metrics_delay_gauger   
replica_iddeployment_idr^   app_name	unique_idr   r   warningr   "record_request_metrics_for_replica)r   r   latency
latency_mss       ra   'record_autoscaling_metrics_from_replicaz7ServeController.record_autoscaling_metrics_from_replica  s    )++ 5 ??t^
(,,3>LQ4?MV0;E  	- 	
 	
 	
 BBBNN`=R=] ` `  pE  pO ` `&` `Mw` ` `   	&II!	
 	
 	
 	
 	
rc   handle_metric_reportc                 ~   t          j                     |j        z
  }|dz  }| j                            ||j        j        |j        j        |j        d           |t          k    r>t          
                    d|j         d|j         d|j         d| dt           d	           | j                            |           d S )
Nr   r   r   handler   z)Received autoscaling metrics from handle z for deployment r   r   r   r   )r   r   handle_metrics_delay_gauger   r   r^   r   	handle_idr   r   r   r   !record_request_metrics_for_handle)r   r   r   r   s       ra   &record_autoscaling_metrics_from_handlez6ServeController.record_autoscaling_metrics_from_handle.  s$    )++ 4 >>t^
'++2@E3AJ.8  	, 	
 	
 	
 BBBNN`<P<Z ` `  mA  mO ` `  au  a ` `&` `Mw` ` `   	&HH 	
 	
 	
 	
 	
rc   r   c                 6    | j                             |          S r   )r   %get_total_num_requests_for_deploymentr   r   s     ra   2_get_total_num_requests_for_deployment_for_testingzBServeController._get_total_num_requests_for_deployment_for_testingG  s"     -SS
 
 	
rc   c                 6    | j                             |          S r   )r   get_metrics_for_deploymentr   s     ra   '_get_metrics_for_deployment_for_testingz7ServeController._get_metrics_for_deployment_for_testingN  s    -HHWWWrc   c                 0    | j         j        |         j        S r   )r   _deployment_states	_replicasr   s     ra    _dump_replica_states_for_testingz0ServeController._dump_replica_states_for_testingQ  s    ,?NXXrc   c                 N    | j         j        |                                          d S r   )r   r   %_stop_one_running_replica_for_testingr   s     ra   r   z5ServeController._stop_one_running_replica_for_testingT  s(    %8	

/
/
1
1
1
1
1rc   keys_to_snapshot_idsc                    K   | j                                         s| j                                          d{V  | j                            |           d{V S )a  Proxy long pull client's listen request.

        Args:
            keys_to_snapshot_ids (Dict[str, int]): Snapshot IDs are used to
              determine whether or not the host should immediately return the
              data or wait for the value to be changed.
        N)rv   is_setwaitrs   listen_for_change)r   r   s     ra   r   z!ServeController.listen_for_changeY  sp       )0022 	4,11333333333(::;OPPPPPPPPPrc   keys_to_snapshot_ids_bytesc                    K   | j                                         s| j                                          d{V  | j                            |           d{V S )zProxy long pull client's listen request.

        Args:
            keys_to_snapshot_ids_bytes (Dict[str, int]): the protobuf bytes of
              keys_to_snapshot_ids (Dict[str, int]).
        N)rv   r   r   rs   listen_for_change_java)r   r   s     ra   r   z&ServeController.listen_for_change_javaf  s       )0022 	4,11333333333(??&
 
 
 
 
 
 
 
 	
rc   c                 4    | j                                         S )2Returns a dictionary of deployment name to config.)r   get_endpointsr   s    ra   get_all_endpointsz!ServeController.get_all_endpointst  s    "00222rc   c                     |                                  }d |                                D             }t          |                                          S )r   c                 L    i | ]!\  }}|j         t          |d                    "S )route)r   )r^   EndpointInfoProto)r_   endpoint_tagendpoint_dicts      ra   
<dictcomp>z:ServeController.get_all_endpoints_java.<locals>.<dictcomp>}  sB     
 
 
+m 0}W7MNNN
 
 
rc   )	endpoints)r   itemsr>   SerializeToString)r   r   datas      ra   get_all_endpoints_javaz&ServeController.get_all_endpoints_javax  sZ    **,,	
 
/8/@/@
 
 
 T***<<>>>rc   c                 F    | j         i S | j                                         S )z7Returns a dictionary of node ID to proxy actor handles.)r   get_proxy_handlesr   s    ra   get_proxieszServeController.get_proxies  s%    #+I'99;;;rc   c                     | j         dS t          | j                                                                                   }|                                S )z9Returns the proxy actor name list serialized by protobuf.N)names)r   r9   get_proxy_namesvaluesr   )r   actor_name_lists     ra   r   zServeController.get_proxy_names  sV    #+4'*::<<CCEE
 
 
 00222rc   c                     | j                                         }|t          | j                                                  z
  }|                    | j                   || _        dS )zUpdate the nodes set where proxy actors should run.

        Controller decides where proxy actors should run
        (head node and nodes with deployment replicas).
        N)r   get_active_node_idsr   rY   get_draining_nodesaddrn   r   )r   new_proxy_nodess     ra   r   z#ServeController._update_proxy_nodes  sg     7KKMM)C(;;==-
 -
 
 	D4555+rc   c                   K   t           }d}t          j                    }	 t          j                    }	 |                     |||           d {V  nN# t          $ rA}t                              d|            t          j        d           d {V  Y d }~nd }~ww xY wt          j                    |z
  }|dk    r"t                              d| ddd	i
           | j	        
                    |           |dz  }| j        
                    |           t          j                    }t          j        t                     d {V  | j        
                    t          j                    |z
             Y)Nr   Tz,There was an exception in the control loop:    
   z%The last control loop was slow (took z~s). This is likely caused by running a large number of replicas in a single Ray cluster. Consider using multiple Ray clusters.r   Fr   )r   r   run_control_loop_step	Exceptionr   	exceptionrt   sleepr   control_loop_duration_gauge_sr   num_control_loops_gauger   sleep_duration_gauge_s)r   recovering_timeout	num_loops
start_timeloop_start_timeeloop_durationsleep_start_times           ra   r   z ServeController.run_control_loop  s      F	Y[[
	L"ikkO'00 2I           ' ' '  !SPQ!S!STTTmA&&&&&&&&&&&&&&'
 !IKK/9Mr!!-M - - - +E2     .22=AAANI(,,Y777#y{{- 7888888888'++DIKK:J,JKKK7	Ls   A 
B7BBr  r  r  c                   K   	 | j                                          n*# t          $ r t                              d           Y nw xY w| j        r@	 |                                  n*# t          $ r t                              d           Y nw xY w| j                                        sQt          j	                    |z
  |k    r7t          
                    d| d           | j                                         d }	 t          j	                    }| j                                        }| j                            t          j	                    |z
             | j                                        sX|sV| j                                         |dk    r7t                              dt          j	                    |z
  ddd	d
i           n*# t          $ r t                              d           Y nw xY w	 t          j	                    }| j                                         | j                            t          j	                    |z
             n*# t          $ r t                              d           Y nw xY wt          j	                    }|                                  | j                            t          j	                    |z
             | j        r| j                                        r	 t          j	                    }| j                            | j                   | j                            t          j	                    |z
             n*# t          $ r t                              d           Y nw xY w|d
u rM| j                            | j                                        | j                                        z             d S d S )Nz+Exception updating cluster node info cache.zException during shutdown.z Replicas still recovering after z@s, setting done recovering event to broadcast long poll updates.r   z&Finished recovering deployments after z.2fzs.r   Fr   z$Exception updating deployment state.z%Exception updating application state.)proxy_nodeszException updating proxy state.)rY   r   r  r   r	  r   shutdownrv   r   r   r   r   r   dsm_update_duration_gauge_sr   r   asm_update_duration_gauge_sr   node_update_duration_gauge_sr   r   proxy_update_duration_gauge_sr   drop_stale_handle_metricsget_alive_replica_actor_idsget_alive_proxy_actor_ids)	r   r  r  r  any_recoveringdsm_update_start_timeasm_update_start_timenode_update_start_timeproxy_update_start_times	            ra   r  z%ServeController.run_control_loop_step  s+     	L(//1111 	L 	L 	LJKKKKK	L  	?? ? ? ?  !=>>>>>? *1133	-	j(+===NNP3E P P P   &**,,, *.	E$(IKK!!:AACCN,00?T1TUUU-4466 ~ *..000q==KK> IKK*4=> > >.6     
  	E 	E 	ECDDDDD	E	F$(IKK!*11333,00?T1TUUUU 	F 	F 	FDEEEEE	F
 "&  """)--dikk<R.RSSS
 # 	D(B(I(I(K(K 	DD*.)++'(//D<M/NNN266IKK"99     D D D  !BCCCCCD
 U""*DD-IIKK*DDFFG     #"sZ    $AAA% %$BB<CG $G/.G/3AI $I54I5.A!M $M76M7c                 p   t          j        dd          | _        t          j        dd          | _        t          j        dd          | _        t          j        dd	          | _        t          j        d
d          | _        t          j        dd          | _        t          j        ddd          | _        | j        	                    dt          j                                                    i           t          j        ddd          | _        t          j        ddd          | _        d S )N'serve_controller_node_update_duration_sz:The control loop time spent on collecting proxy node info.)description.serve_controller_proxy_state_update_duration_sz4The control loop time spent on updating proxy state.3serve_controller_deployment_state_update_duration_sz9The control loop time spent on updating deployment state.4serve_controller_application_state_update_duration_sz:The control loop time spent on updating application state.!serve_controller_sleep_duration_sz.The duration of the last control loop's sleep.(serve_controller_control_loop_duration_sz&The duration of the last control loop."serve_controller_num_control_loopszpThe number of control loops performed by the controller. Increases monotonically over the controller's lifetime.)rg   )r&  tag_keysrg   *serve_autoscaling_replica_metrics_delay_mszpTime taken for the replica metrics to be reported to the controller. High values may indicate a busy controller.r   )serve_autoscaling_handle_metrics_delay_mszoTime taken for the handle metrics to be reported to the controller. High values may indicate a busy controller.r   )rL   Gauger  r  r  r  r  r  r  set_default_tagsrk   rl   r   r   r   r   s    ra   r   z,ServeController._create_control_loop_metrics  s   ,3M5T-
 -
 -
) .5]<N.
 .
 .
* ,3=AS,
 ,
 ,
( ,3=BT,
 ,
 ,
( '.m/H'
 '
 '
# .5]6@.
 .
 .
* (/}0J #(
 (
 (
$ 	$55022??AAB	
 	
 	

 ,3=8> >,
 ,
 ,
( +2-7> =+
 +
 +
'''rc   c                     |                                  \  }}}|| _        |7t                              dddi           |                     ||           d S d S )Nz!Recovered config from checkpoint.r   Fr   )deployment_time)_read_config_checkpointr   r   r   apply_config)r   r3  serve_configtarget_capacity_directions       ra   r   z.ServeController._recover_state_from_checkpointJ  s}    
 ((**		
%*C'#KK3OU;S     lOLLLLL	 $#rc   c                     | j                             t                    }|Lt          j        |          \  }}}}|t          t          |                                          |          |fS dS )a  Reads the current Serve config checkpoint.

        The Serve config checkpoint stores active application configs and
        other metadata.

        Returns:

        If the GCS contains a checkpoint, tuple of:
            1. A deployment timestamp.
            2. A Serve config. This Serve config is reconstructed from the
                active application states. It may not exactly match the
                submitted config (e.g. the top-level http options may be
                different).
            3. The target_capacity direction calculated after the Serve
               was submitted.

        If the GCS doesn't contain a checkpoint, returns (0, None, None).
        N)applicationstarget_capacity)        NN)rr   rw   CONFIG_CHECKPOINT_KEYry   rz   rH   listr   )r   
checkpointr3  r:  r7  config_checkpoints_dicts         ra   r4  z'ServeController._read_config_checkpointW  s    , ]&&'<==
! Z(()'  !!%&=&D&D&F&F!G!G$3   *  %$rc   c                 4    | j                                         S )z_Used for testing.

        Returned dictionary maps deployment names to replica infos.
        )r   get_running_replica_infosr   s    ra   _all_running_replicasz%ServeController._all_running_replicas  s     ,FFHHHrc   c                     | j         S )z^Returns the actor details for this controller.

        Currently used for test only.
        )r   r   s    ra   get_actor_detailsz!ServeController.get_actor_details  s    
 ""rc   rd   c                 l    | j         dS | j                                                             |          S )zReturns the proxy details for the proxy on the given node.

        Currently used for test only. Will return None if the proxy doesn't exist on
        the given node.
        N)r   get_proxy_detailsrw   )r   rd   s     ra   rF  z!ServeController.get_proxy_details  s5     #+4'99;;??HHHrc   r   c                     | j                                                                         D ]\  }}||k    r	|j        c S dS )zcReturns the deployment timestamp for the given app.

        Currently used for test only.
        N)r   list_app_statusesr   deployment_timestamp)r   r   	_app_nameapp_status_infos       ra   get_deployment_timestampsz)ServeController.get_deployment_timestamps  s`     +==??EEGG	< 	< 
9$$&;;;; %		< 	<rc   deployment_namec                 B    | j                             |          |         S )zjReturns the deployment details for the app and deployment.

        Currently used for test only.
        )r   list_deployment_details)r   r   rM  s      ra   get_deployment_detailsz&ServeController.get_deployment_details  s%     -EEhOO
 	
rc   c                 ^    | j         t                      S | j                                         S )z$Return the HTTP proxy configuration.)r   r6   
get_configr   s    ra   get_http_configzServeController.get_http_config  s*    #+== '22444rc   c                 ^    | j         t                      S | j                                         S )z$Return the gRPC proxy configuration.)r   r8   get_grpc_configr   s    ra   rU  zServeController.get_grpc_config  s*    #+== '77999rc   c                    | j         dS |                                 }|j        dk    rWt          t          j        v rt          j        t                   S |j        dS dt          |j        |j                   |j	         S |j        S )z+Return the root url for the serve instance.N zhttp://)
r   rS  root_urlr"   r}   environhostr
   port	root_path)r   http_configs     ra   get_root_urlzServeController.get_root_url  s    #+4**,,2%%%33z"899 #+2/mK,<k>NOO /",/ / ##rc   c                 D    | j                             t                    du S )zReturns whether the config checkpoint has been deleted.

        Get the config checkpoint from the kv store. If it is None, then it has been
        deleted.
        N)rr   rw   r<  r   s    ra   config_checkpoint_deletedz)ServeController.config_checkpoint_deleted  s      }  !6774??rc   c                 ,   | j         sdS | j        6t          j                    | _        t                              dddi           | j                            t                     | j                            t                     | j	        
                                 | j        
                                 | j        
                                 | j        r| j        
                                 |                                 }| j	                                        }| j                                        }| j                                        }| j        du p| j                                        }|rV|rT|rR|rP|rNt                              dddi           t#          j                    j        }t#          j        |d           dS t          j                    | j        z
  d	k    r|s&t                              t           d
ddi           |st                              dddi           |st                              dddi           |st                              dddi           |s"t                              dddi           dS dS dS )am  Shuts down the serve instance completely.

        This method will only be triggered when `self._shutting_down` is true. It
        deletes the kv store for config checkpoints, sets application state to deleting,
        delete all deployments, and shuts down all proxies. Once all these
        resources are released, it then kills the controller actor.
        NzController shutdown started.r   Fr   z1All resources have shut down, controller exiting.T)
no_restartr  z not yet deletedzapplication not yet shutdownzdeployment not yet shutdownzendpoint not yet shutdownzproxy_state not yet shutdown)r   r   r   r   r   rr   deleter<  rx   r   r  r   r   r   r`  is_ready_for_shutdownr   rk   rl   current_actorkill)r   r`  application_is_shutdowndeployment_is_shutdownendpoint_is_shutdownproxy_state_is_shutdown_controller_actors          ra   r  zServeController.shutdown  s    " 	F$,(,	D%KK6PU>VKWWW2333:;;;&//111%..000$$&&&# 	0$--///$($B$B$D$D!"&"@"V"V"X"X!%!>!T!T!V!V#2HHJJ$, @'==?? 	 
 &&	'&	 '&	 %	&	
 (&	 NNC&.     !$ 7 9 9 GH&4888888Y[[444r99, ,>>>*E2     + 2*E2     * 1*E2     ( /*E2     + 2*E2      - :9* rc   name_to_deployment_args_listname_to_application_argsc                    i }|                                 D ]v\  }}g }|D ]g}t          j        |          }|                    |j        |j        |j        |j        |j        |	                    d          r|j
        ndd           h|||<   wi }	|                                 D ]\  }}
t          j        |
          |	|<   | j                            ||	           | j                                         dS )a0  
        Takes in a list of dictionaries that contain deployment arguments.
        If same app name deployed, old application will be overwritten.

        Args:
            name: Application name.
            deployment_args_list: List of serialized deployment information,
                where each item in the list is bytes representing the serialized
                protobuf `DeploymentArgs` object. `DeploymentArgs` contains all the
                information for the single deployment.
            name_to_application_args: Dictionary mapping application names to serialized
                application arguments, where each item is bytes representing the serialized
                protobuf `ApplicationArgs` object. `ApplicationArgs` contains the information
                for the application.
        route_prefixN)rM  deployment_config_proto_bytesreplica_config_proto_bytesdeployer_job_idingressro  )r   r;   
FromStringappendrM  deployment_configreplica_configrr  rs  HasFieldro  r:   r   deploy_appssave_checkpoint)r   rl  rm  name_to_deployment_argsr^   deployment_args_listdeployment_args_deserializeddeployment_args_bytesargs%name_to_application_args_deserializedapplication_args_bytess              ra   deploy_applicationsz#ServeController.deploy_applications  sK   ( #%*F*L*L*N*N 	I 	I&D&+-()=  %%01FGG,33+/+?9=9O6:6I+/+?#'<15~1N1NXD--TX	 	    -I#D))02-,D,J,J,L,L 	 	(D(:I:T&; ;1$77 	&22#%J	
 	
 	
 	&6688888rc   r^   r|  application_argsc                 :    |                      ||i||i           dS )av  
        Deploy a single application
        (as deploy_applications(), but it only takes a single name and deployment args).
        This primarily exists as a shim to avoid
        changing Java code in https://github.com/ray-project/ray/pull/49168,
        and could be removed if the Java code was refactored
        to use the new bulk deploy_applications API.
        N)r  )r   r^   r|  r  s       ra   deploy_applicationz"ServeController.deploy_applicationR  s8     	  '(#$	
 	
 	
 	
 	
rc   r;  configr3  c           	         t           j                            d           |st          j                    }i }|                                 \  }}}t          ||| j                  | _        t          | j        |j	        | j                   |j	        | _        |j
        D ]<}|j        |j        r|j        |_        |                    d          }|||j        <   =| j                            t           t#          j        || j        | j        |f                     | j                            |j
        || j        | j                   | j                                         dS )zApply the config described in `ServeDeploySchema`.

        This will upgrade the applications to the goal state specified in the
        config.

        If `deployment_time` is not provided, `time.time()` is used.
        v2)curr_config
new_configcurr_target_capacity_directionNTexclude_unset)r3  r:  r7  )r1   API_VERSIONrecordr   r4  #calculate_target_capacity_directionr   log_target_capacity_changer   r:  r9  rZ   dictr^   rr   r   r<  ry   r   r   apply_app_configsrz  )r   r  r3  new_config_checkpoint_r  
app_configapp_config_dicts           ra   r5  zServeController.apply_confige  s    	!((... 	*"ikkO " 88::;*M#+/+J+
 +
 +
'
 	#!"+	
 	
 	

 !' 6 - 	E 	EJ (0V5J0,2,A
)(ooDoAAO5D!*/22!L#)3)	 
	
 
	
 
	
 	&88+ 1&*&E	 	9 	
 	
 	
 	&6688888rc   rW  c                 >   t          ||          }| j                            |          }| |rd| dnd}t          d| d| d          | j                            |          }t          |                                |	          }|                                S )
a  Get the current information about a deployment.

        Args:
            name: the name of the deployment.

        Returns:
            DeploymentRoute's protobuf serialized bytes

        Raises:
            KeyError: If the deployment doesn't exist.
        r^   r   Nz in application ''rW  zDeployment 'z' does not existrW   )deployment_infor   )	r   r   get_deploymentKeyErrorr   get_endpoint_router<   to_protor   )r   r^   r   idr  app_msgr   deployment_routes           ra   get_deployment_infoz#ServeController.get_deployment_info  s     th7777FFrJJ"9AI5(5555rGJ$JJJJJKKK#66r::*+4466e
 
 
  11333rc   c                 r      fd j                                                                         D             S )zGets the current information about all deployments.

        Returns:
            Dict(deployment_id, (DeploymentInfo, route))
        c                 P    i | ]"\  }}||j                             |          f#S r   )r   r  )r_   r  r   r   s      ra   r   z=ServeController.list_deployments_internal.<locals>.<dictcomp>  sE     
 
 
D t*==bAAB
 
 
rc   )r   get_deployment_infosr   r   s   `ra   list_deployments_internalz)ServeController.list_deployments_internal  sI    
 
 
 
 9NNPPVVXX
 
 
 	
rc   c                 p    | j                                                             |          }|r|j        ndS )a  Get the deployment config for the given deployment id.

        Args:
            deployment_id: The deployment id to get the config for.

        Returns:
            A deployment config object if the deployment id exist,
            None otherwise.
        N)r   r  rw   rv  )r   r   r  s      ra   get_deployment_configz%ServeController.get_deployment_config  sA     7LLNNRR
 
 5DM00Mrc   c                 >    | j         j                                        S )z6Gets the current list of all deployments' identifiers.)r   r   keysr   s    ra   list_deployment_idsz#ServeController.list_deployment_ids  s    ,?DDFFFrc   target_num_replicasc                    |j         }| j                            |          st          d| d          | j                            |          st          d|j         d| d          | j                            ||           dS )aA  Update the target number of replicas for a deployment.

        Args:
            deployment_id: The deployment to update.
            target_num_replicas: The new target number of replicas.

        Raises:
            ExternalScalerDisabledError: If external_scaler_enabled is set to False for the application.
        zApplication 'z' not foundz'Cannot update replicas for deployment 'z' in application 'a	  '. The external scaling API can only be used when 'external_scaler_enabled' is set to true in the application configuration. Current value: external_scaler_enabled=false. To use this API, redeploy your application with 'external_scaler_enabled: true' in the config.N)	r   r   does_app_exist
ValueErrorget_external_scaler_enabledr'   r^   r   set_target_num_replicas)r   r   r  r   s       ra   update_deployment_replicasz*ServeController.update_deployment_replicas  s     !)-<<XFF 	DBXBBBCCC-II(SS 	-B-:L B B (B B B   	%==.	
 	
 	
 	
 	
rc   sourcec                     |                                  }|                                 }i }| j                            |          }|r|                                 ni }|                                D ]\  }}t          || j                            |          |                     |          |j	        |j
        |j        |                    |          | j                            |          | j                            |          | j                            |          | j                            |                    ||<   t#          j        |                    d                    }	t)          j        |                    d                    }
t+          | j        | j        t1          j        |j                  |	|
| j        r| j                                        nd||                                                               d          S )a  Gets details on all applications on the cluster and system-level info.

        The information includes application and deployment statuses, config options,
        error messages, etc.

        Args:
            source: If provided, returns application
                statuses for applications matching this API type.
                Defaults to None, which means all applications are returned.

        Returns:
            Dict that follows the format of the schema ServeInstanceDetails.
        )r  )r^   ro  	docs_pathstatusmessagelast_deployed_time_sdeployed_app_configr  deploymentsexternal_scaler_enableddeployment_topologyTr  N)r:  controller_infoproxy_locationrP   rO   proxiesr9  target_groups)rS  rU  r   rH  get_app_configsr   r@   get_route_prefixget_docs_pathr  r  rI  rw   get_app_sourcerO  r  get_deployment_topologyrB   	parse_objr  rK   rI   r   r   r7   _from_deployment_modelocationr   rF  get_target_groups'_get_user_facing_json_serializable_dict)r   r  r]  grpc_configr9  app_statusesapp_configsr   rK  rP   rO   s              ra   get_serve_instance_detailsz*ServeController.get_serve_instance_details  s    **,,**,,5GGvGVV 1=Dd**,,,"
 !!	 	 
%7!;LLXVV,,X66&-'/%4%I %0OOH$=$=5DDXNN :RR  )-(F(b(b) ) %)$B$Z$Z% %%& & &L""2 )2;3C3CRV3C3W3WXX(2;3C3CRV3C3W3WXX# 1 /(>{?STT%% +(::<<<%0022
 
 
 2
1
1
E
E	Frc   Ffrom_proxy_managerc           	         g }| j                                         r|                    t          t          j        d| j                             t          j                                       t          |                                           rQ|                    t          t          j	        d| j                             t          j	                                       |S )zTarget groups contains information about IP
        addresses and ports of all proxies in the cluster.

        This information is used to setup the load balancer.
        /)protocolro  targets)
r   rF  ru  rJ   r   HTTPget_targetsr5   rU  GRPC)r   r   r  r  s       ra   r  z!ServeController.get_target_groupsK  s     ,.#5577 	   ,1!$ 4@@AUVV     t335566 	$$!0!5%( $ 8 D D+0! !     rc   c                     | j                             |          }| j                             |          }t          |||          }|                                                                S )zReturn application status
        Args:
            name: application name. If application name doesn't exist, app_status
                  is NOT_STARTED.
        )r^   
app_statusdeployment_statuses)r   get_app_status_infoget_deployments_statusesr   r  r   )r   r^   r  r  status_infos        ra   get_serve_statusz ServeController.get_serve_statusn  su     3GGMM
"<UU
 
 %! 3
 
 

 ##%%77999rc   r   c                 d    g }|D ]*}|                     |                     |                     +|S r   )ru  r  )r   r   statusesr^   s       ra   get_serve_statusesz"ServeController.get_serve_statuses  s>     	9 	9DOOD11$778888rc   c                     g }| j                                         D ]*}|                    |                     |                     +|S r   )r   rH  ru  r  )r   r  r^   s      ra   list_serve_statusesz#ServeController.list_serve_statuses  sM    2DDFF 	9 	9DOOD11$778888rc   c                     | j                             t                    }|i S t          j        |          \  }}}}d |                                D             S )Nc                 >    i | ]\  }}|t          j        |          S r   )rG   r  )r_   appr  s      ra   r   z3ServeController.get_app_configs.<locals>.<dictcomp>  s:     
 
 
V '1&99
 
 
rc   )rr   rw   r<  ry   rz   r   )r   r>  r  r?  s       ra   r  zServeController.get_app_configs  si    ]&&'<==
I+1<
+C+C(1a(
 
6<<>>
 
 
 	
rc   c                 6    | j                             |          S )a  Get the external_scaler_enabled flag value for an application.

        This is a helper method specifically for Java tests to verify the flag
        is correctly set, since Java cannot deserialize Python Pydantic objects.

        Args:
            app_name: Name of the application.

        Returns:
            True if external_scaler_enabled is set for the application, False otherwise.
        )r   r  r   r   s     ra   r  z+ServeController.get_external_scaler_enabled  s     -II(SSSrc   c                 L    | j                                         }d |D             S )z6Gets deployment status bytes for all live deployments.c                 Z    g | ](}|                                                                 )S r   )r  r   )r_   r  s     ra   rb   z?ServeController.get_all_deployment_statuses.<locals>.<listcomp>  s.    MMM&!!3355MMMrc   )r   get_deployment_statuses)r   r  s     ra   get_all_deployment_statusesz+ServeController.get_all_deployment_statuses  s*    0HHJJMMHMMMMrc   c                     t          ||          }| j                            |g          }|sdS |d                                                                         S )zGet deployment status by deployment name.

        Args:
            name: Deployment name.
            app_name: Application name. Default is "" because 1.x
                deployments go through this API.
        r  Nr   )r   r   r  r  r   )r   r^   r   r  r  s        ra   get_deployment_statusz%ServeController.get_deployment_status  s]     th777.FFtLL 	4ay!!##55777rc   c                 6    | j                             |          S )zqDocs path for application.

        Currently, this is the OpenAPI docs path for FastAPI-integrated applications.)r   r  )r   r^   s     ra   r  zServeController.get_docs_path  s     -;;DAAArc   c                 6    | j                             |          S )zName of the ingress deployment in an application.

        Returns:
            Ingress deployment name (str): if the application exists.
            None: if the application does not exist.
        )r   get_ingress_deployment_namer  s     ra   r  z+ServeController.get_ingress_deployment_name  s     -II(SSSrc   c                 v    |D ]}| j                             |           | j                                          dS )zhDelete applications based on names

        During deletion, the application status is DELETING
        N)r   
delete_apprz  )r   r   r^   s      ra   delete_appszServeController.delete_apps  sH    
  	< 	<D*55d;;;;&6688888rc   r   c                 :    | j                             |           dS )zRecord replica routing information for a replica.

        Args:
            info: RequestRoutingInfo including deployment name, replica tag,
                multiplex model ids, and routing stats.
        N)r   record_request_routing_info)r   r   s     ra   r  z+ServeController.record_request_routing_info  s!     	%AA$GGGGGrc   c                 6    | j                             |          S )a	  Get the current rank mapping for all replicas in a deployment.
        Args:
            deployment_id: The deployment ID to get ranks for.
        Returns:
            Dictionary mapping replica_id to ReplicaRank object (with rank, node_rank, local_rank).
        )r   _get_replica_ranks_mappingr   s     ra   r  z*ServeController._get_replica_ranks_mapping  s     ,GGVVVrc   Tr   c                 ^   K   d| _         |sdS | j                                         d{V  dS )a  Set the shutting down flag on controller to signal shutdown in
        run_control_loop().

        This is used to signal to the controller that it should proceed with shutdown
        process, so it can shut down gracefully. It also waits until the shutdown
        event is triggered if wait is true.

        Raises:
            RayActorError: if wait is True, the caller waits until the controller
                is killed, which raises a RayActorError.
        TN)r   r   r   )r   r   s     ra   graceful_shutdownz!ServeController.graceful_shutdown  sL       # 	F "'')))))))))))rc   c                     d}t           j        D ]-}t          |t          j        j                  r|j        j        }.| j        |fS )z5Get the logging configuration (for testing purposes).N)r   handlers
isinstanceloggingMemoryHandlertargetbaseFilenamerQ   )r   rj   handlers      ra   _get_logging_configz#ServeController._get_logging_config  sI     	< 	<G'7#3#ABB < ' ;)=88rc   c                     | j         S )z=Gets the controller's scale direction (for testing purposes).)r   r   s    ra   _get_target_capacity_directionz.ServeController._get_target_capacity_direction  s     ..rc   )r   N)r;  )rW  r   )NF)T)___name__
__module____qualname____doc__r6   rC   r   r8   r   r{   r   intr   r   r   r   r   r   r   r   r   r   r   r|   r   bytesr   r   r   r   r   r   r   r   r   r   floatr  r   r   r   rH   r   r4  r   r   rB  rF   rD  rD   rF  rL  rA   rP  rS  rU  r^  boolr`  r  r  r  r5  r  r$   r  r   r  r  r  r?   r  rJ   r  r   r  r  r  rG   r  r  r  r	   r  r  r  r   r  r   r  rE   r  r  r  r  r   rc   ra   rN   rN   i   s~        : /3m# m# m# "m#  -	m#
 {+m# m# m# m#^
} 
 
 
 
:       
%8
 
 
 
2
$6
 
 
 
2
)
 
 
 
X\ X X X XYl Y Y Y Y2 2 2
QDcN Q Q Q Q
u 
 
 
 
34d38n(D#E 3 3 3 3	? 	? 	? 	? 	?<T&+"56 < < < <3 3 3 3 3, , ,"L "L "L "LHMM5:MGJM M M M^5
 5
 5
nM M M(%	uh018<S3TT	U(% (% (% (%TItL$?Q:R,R'S I I I I##4 # # # #	I 	I,1G 	I 	I 	I 	I
<# 
<% 
< 
< 
< 
<	
	
.1	
		
 	
 	
 	
5 5 5 5 5: : : : :$ $ $$@4 @ @ @ @E E EN19&*3U+;&<19 #'sEz"219 
	19 19 19 19f

 #5k
  	

 

 
 
 
, "%?9 ?9!?9 ?9 
	?9 ?9 ?9 ?9B4 4 4s 4E 4 4 4 42
	lE.#"566	7
 
 
 
N)N	"	#N N N N"GT,%7 G G G G
)
@C
	
 
 
 
@HF HF'1B HFd HF HF HF HFX #'#(! !3-! !! 
k		! ! ! !F ,B : :S :e : : : :$S	 d5k    T%[    	
c+A&A!B 	
 	
 	
 	
TC TD T T T TNT%[ N N N N *,8 88#&8	tU{	8 8 8 8"B# B B B BTC THSM T T T T9# 9 9 9 9H0B H H H H	W)	W	c;		W 	W 	W 	W* *D * * * *(9U 9 9 9 9/9P0Q / / / / / /rc   rN   r  r  r  r   c                     d}d}| ]t          | |          rM| j        }|j        }||k    r|}nL||t          j        }n;|d}n6||k     rt          j        }n#t          j        }n|j        t          j        }nd}|S )zCCompares two Serve configs to calculate the next scaling direction.N)applications_matchr:  r   DOWNUP)r  r  r  curr_target_capacitynext_target_capacity_directionnext_target_capacitys         ra   r  r  
  s      %)"#5k:#N#N*:)9#777-K**!).B.N-D-I**!)-1**!$888-D-G**-D-I**		#	/ *A)C&&)-&))rc   config1config2c                 R    d | j         D             }d |j         D             }||k    S )zzChecks whether the applications in config1 and config2 match.

    Two applications match if they have the same name.
    c                     h | ]	}|j         
S r   r^   r_   r  s     ra   	<setcomp>z%applications_match.<locals>.<setcomp>3      BBBcBBBrc   c                     h | ]	}|j         
S r   r  r  s     ra   r  z%applications_match.<locals>.<setcomp>4  r  rc   )r9  )r  r  config1_app_namesconfig2_app_namess       ra   r  r  -  s?     CBW-ABBBBBW-ABBB 111rc   r  r  r  c           	          | |k    rnt          |t                    r=t                              d|j                                         d|  d| d           dS t                              d           dS dS )z$Logs changes in the target_capacity.zTarget capacity scaling z from z to rW   z.Target capacity entering 100% at steady state.N)r  r   r   r   valuelower)r  r  r  s      ra   r  r  9  s     33346MNN 	JKKJ17==??J J,J J2FJ J J     KKHIIIII 43rc   )wrt   r  r}   ry   r   typingr   r   r   r   r   r   r	   rk   ray._common.network_utilsr
   ray._common.utilsr   ray._rayletr   	ray.actorr   $ray.serve._private.application_stater   r   $ray.serve._private.autoscaling_stater   ray.serve._private.commonr   r   r   r   r   r   r   r   ray.serve._private.configr   ray.serve._private.constantsr   r   r   r   r   r   r    r!   r"   ray.serve._private.default_implr#   "ray.serve._private.deployment_infor$   #ray.serve._private.deployment_stater%   !ray.serve._private.endpoint_stater&   ray.serve._private.exceptionsr'   ray.serve._private.grpc_utilr(   ray.serve._private.http_utilr)    ray.serve._private.logging_utilsr*   r+   r,   ray.serve._private.long_pollr-   r.   ray.serve._private.proxy_stater/   #ray.serve._private.storage.kv_storer0   ray.serve._private.usager1   ray.serve._private.utilsr2   r3   r4   r5   ray.serve.configr6   r7   r8   ray.serve.generated.serve_pb2r9   r:   r;   r<   r=   r   r>   ray.serve.schemar?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   ray.utilrL   	getLoggerr   #_CRASH_AFTER_CHECKPOINT_PROBABILITYr<  rx   rN   r  r  r  r  r  r   rc   ra   <module>r@     sr     				                    


 3 3 3 3 3 3 1 1 1 1 1 1 ! ! ! ! ! ! ! ! ! ! ! ! X X X X X X X X H H H H H H	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 7 6 6 6 6 6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 K J J J J J = = = = = = F F F F F F ; ; ; ; ; ; E E E E E E G G G G G G              
 I H H H H H H H < < < < < < B B B B B B 2 2 2 2 2 2            E D D D D D D D D D                                                  		,	-	- '( #5  A ^/ ^/ ^/ ^/ ^/ ^/ ^/ ^/B% *+, *! * %-UO * %&	 *  *  *  *F	2 1 	2<M 	2RV 	2 	2 	2 	2J"5/J"5/J %--D$EJ J J J J Jrc   