o
    $ij                     @   s   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 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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  d dl!m"Z" d dl#m$Z$m%Z%m&Z&m'Z' d dl(m)Z)m*Z* d dl+m,Z,m-Z- d dl.m/Z/ d dl0m1Z1 d dl2m3Z3 d dl4m5Z5m6Z6 d dl7m8Z8m9Z9 d dl:m;Z; dZ<dZ=G dd deZ>G dd dZ?G dd dZ@G dd dZAG dd  d ZBG d!d" d"ZCG d#d$ d$ZDG d%d& d&ZEG d'd( d(ZFejGG d)d* d*ZHeHI ZJd+d, ZKd-d. ZLe)fd/eMd0e&d1eNfd2d3ZOe)fd4eMd5eMd1ePfd6d7ZQe)fd/eMd8ePd5eMd1ePfd9d:ZRe)d;fd/eMd8ePd5eMd<eNd1ePf
d=d>ZSe)fd/eMd8ePd5eMd1ePfd?d@ZTdAefdBdCZU		ddDe dEe%dFeeP dGeeee-ePef   fdHdIZVejWe=e*d dJG dKdL dLZXejGdMd idNG dOdP dPZYeYI ZZdQdR Z[e=fdSe1dTedUeMfdVdWZ\ddXdYZ]ddZd[Z^dd\d]Z_d^d_ Z`d`da Zadbdc Zbddde Zcedfe fdgdhZdG didj djZeG dkdl dlZfG dmdn dnZgejWdodp Zhd8ePfdqdrZie)dfd4eMd5eMdse"fdtduZjejWG dvdw dwZkddyeMdzeMfd{d|Zle'jmfd}e"d5eMd~eeMe'f fddZne'jme)dd;d;d;fd~eeMe'f d5eMdeNdeNdeNdeNd1eeM fddZoe'jme)dd;d;d;fd~eeMe'f d5eMdeNdeNdeNdeNd1eMfddZpe)fd5eMfddZqde)fddZrdS )    N)asynccontextmanager)copydeepcopy)AnyCallableDictListOptionalTupleUnion)Request)serve)build_address)wait_for_condition)	TimerBase)ActorHandle)ServeControllerClient)CreatePlacementGroupRequestDeploymentIDDeploymentStatusRequestProtocol)SERVE_DEFAULT_APP_NAMESERVE_NAMESPACE)ALL_REPLICA_STATESReplicaState)DRAINING_MESSAGE)ServeUsageTag)_get_global_client)	serve_pb2serve_pb2_grpc)ApplicationStatusTargetGroup)list_actorsz
/telemetrystoragec                   @   s^   e Zd Zddee fddZddee fddZdefdd	Zd
efddZdefddZ	dS )	MockTimerN
start_timec                 C   s   t  | _| j|d d S )Nr%   )	threadingLock_lockresetselfr%    r-   Z/home/ubuntu/veenaModal/venv/lib/python3.10/site-packages/ray/serve/_private/test_utils.py__init__.   s   
zMockTimer.__init__c                 C   s   |d u rt   }|| _d S N)time_currr+   r-   r-   r.   r*   2   s   
zMockTimer.resetreturnc                 C      | j S r0   r2   r,   r-   r-   r.   r1   7      zMockTimer.timebyc                 C   s:   | j  |  j|7  _W d    d S 1 sw   Y  d S r0   r)   r2   )r,   r8   r-   r-   r.   advance:   s   "zMockTimer.advanceamtc                 C   s>   | j  |  j|d 7  _W d    d S 1 sw   Y  d S )NgMbP?r9   r,   r;   r-   r-   r.   realistic_sleep>   s   "zMockTimer.realistic_sleepr0   )
__name__
__module____qualname__r	   floatr/   r*   r1   r:   r=   r-   r-   r-   r.   r$   -   s    r$   c                   @   s\   e Zd Zddee fddZdddZdefdd	Zd
efddZd
efddZ	dd Z
dS )MockAsyncTimerr   r%   c                 C   s   | j |d d| _d S )Nr&   r   )r*   _num_sleepersr+   r-   r-   r.   r/   D   s   
zMockAsyncTimer.__init__c                 C   
   || _ d S r0   r5   r+   r-   r-   r.   r*   H      
zMockAsyncTimer.resetr3   c                 C   r4   r0   r5   r6   r-   r-   r.   r1   K   r7   zMockAsyncTimer.timer;   c                    sP   |  j d7  _ | j| }| j|k rtdI d H  | j|k s|  j d8  _ d S )N   r   )rC   r2   asynciosleep)r,   r;   endr-   r-   r.   rH   N   s   


zMockAsyncTimer.sleepc                 C   s   |  j |7  _ d S r0   r5   r<   r-   r-   r.   r:   X      zMockAsyncTimer.advancec                 C   r4   r0   )rC   r6   r-   r-   r.   num_sleepers[   r7   zMockAsyncTimer.num_sleepersN)r   )r%   r   )r>   r?   r@   r	   rA   r/   r*   r1   rH   r:   rK   r-   r-   r-   r.   rB   C   s    

rB   c                   @   sN   e Zd Zdd ZdededefddZdedefdd	Zdedefd
dZ	dS )MockKVStorec                 C   s   t  | _d S r0   )dictstorer6   r-   r-   r.   r/   `   s   zMockKVStore.__init__keyvalr3   c                 C   s*   t |tstdt||| j|< dS )Nkey must be a string, got: {}.T
isinstancestr	TypeErrorformattyperN   )r,   rO   rP   r-   r-   r.   putc   s   

zMockKVStore.putc                 C   s*   t |tstdt|| j|d S )NrQ   )rS   rT   rU   rV   rW   rN   getr,   rO   r-   r-   r.   rY   i   s   
zMockKVStore.getc                 C   s6   t |tstdt||| jv r| j|= dS dS )NrQ   TFrR   rZ   r-   r-   r.   deleten   s   

zMockKVStore.deleteN)
r>   r?   r@   r/   rT   r   boolrX   rY   r[   r-   r-   r-   r.   rL   _   s
    rL   c                   @   sn   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dde
dedefddZde
defddZdS )MockClusterNodeInfoCachec                 C   s,   t  | _t | _t | _t | _t | _d S r0   )setalive_node_idsrM   total_resources_per_nodeavailable_resources_per_nodedraining_nodesnode_labelsr6   r-   r-   r.   r/   z   s
   z!MockClusterNodeInfoCache.__init__c                 C   r4   r0   )r_   r6   r-   r-   r.   get_alive_node_ids   r7   z+MockClusterNodeInfoCache.get_alive_node_idsc                 C   r4   r0   )rb   r6   r-   r-   r.   get_draining_nodes   r7   z+MockClusterNodeInfoCache.get_draining_nodesc                 C   s   | j t| j S r0   )r_   r^   rb   r6   r-   r-   r.   get_active_node_ids      z,MockClusterNodeInfoCache.get_active_node_idsc                 C      d S r0   r-   )r,   node_idr-   r-   r.   get_node_az      z$MockClusterNodeInfoCache.get_node_azc                 C   r4   r0   )ra   r6   r-   r-   r.    get_available_resources_per_node   r7   z9MockClusterNodeInfoCache.get_available_resources_per_nodec                 C   r4   r0   )r`   r6   r-   r-   r.   get_total_resources_per_node   r7   z5MockClusterNodeInfoCache.get_total_resources_per_nodeNri   	resourceslabelsc                 C   sB   | j | t|pi | j|< t|pi | j|< |pi | j|< d S r0   )r_   addr   r`   ra   rc   )r,   ri   rn   ro   r-   r-   r.   add_node   s   z!MockClusterNodeInfoCache.add_nodec                 C   s   t || j|< d S r0   )r   ra   )r,   ri   rn   r-   r-   r.    set_available_resources_per_node   rJ   z9MockClusterNodeInfoCache.set_available_resources_per_nodeNN)r>   r?   r@   r/   rd   re   rf   rj   rl   rm   rT   r   rq   rr   r-   r-   r-   r.   r]   y   s    r]   c                   @      e Zd Zdd ZdS )FakeRemoteFunctionc                 C   rh   r0   r-   r6   r-   r-   r.   remote   rk   zFakeRemoteFunction.remoteN)r>   r?   r@   rv   r-   r-   r-   r.   ru      s    ru   c                   @   s,   e Zd Zdd Zedd Zedd ZdS )MockActorHandlec                 K   s   || _ d| _d| _d| _d S )Nfake_idF)_options	_actor_id"initialize_and_get_metadata_calledis_allocated_called)r,   kwargsr-   r-   r.   r/      s   
zMockActorHandle.__init__c                 C      d| _ t S NT)r{   ru   r6   r-   r-   r.   initialize_and_get_metadata   s   z+MockActorHandle.initialize_and_get_metadatac                 C   r~   r   )r|   ru   r6   r-   r-   r.   is_allocated   s   zMockActorHandle.is_allocatedN)r>   r?   r@   r/   propertyr   r   r-   r-   r-   r.   rw      s    
rw   c                   @   s*   e Zd Zdd Zdd ZdefddZdS )	MockActorClassc                 C      d| _ t | _d S Nr-   )
_init_argsrM   ry   r6   r-   r-   r.   r/         zMockActorClass.__init__c                 K   s(   t | }| D ]	\}}||j|< q|S r0   )r   itemsry   )r,   r}   reskvr-   r-   r.   options   s   zMockActorClass.optionsr3   c                 G   s   t dd|i| jS )N	init_argsr-   )rw   ry   )r,   argsr-   r-   r.   rv         zMockActorClass.remoteN)r>   r?   r@   r/   r   rw   rv   r-   r-   r-   r.   r      s    r   c                   @   s   e Zd ZdefddZdS )MockPlacementGrouprequestc                 C   s*   |j | _|j| _|j| _|j| _d| _d S )Ndetached)	bundles_bundlesstrategy	_strategytarget_node_id_soft_target_node_idname_name	_lifetime)r,   r   r-   r-   r.   r/      s
   
zMockPlacementGroup.__init__N)r>   r?   r@   r   r/   r-   r-   r-   r.   r      s    r   c                   @   s~   e Zd ZefdedefddZdd Zdd Zd	d
 Zde	e fddZ
defddZdd ZdefddZdefddZdS )MockDeploymentHandledeployment_nameapp_namec                 C   s$   || _ || _tj| _d| _d| _d S )NF)_deployment_name	_app_namer   	UNDEFINED	_protocol_running_replicas_populated_initialized)r,   r   r   r-   r-   r.   r/      s
   
zMockDeploymentHandle.__init__c                 C   r4   r0   )r   r6   r-   r-   r.   is_initialized   r7   z#MockDeploymentHandle.is_initializedc                 C   s   | j rtdd| _ d S )Nzalready initializedT)r   RuntimeErrorr6   r-   r-   r.   _init   s   
zMockDeploymentHandle._initc                 O   s   | S r0   r-   )r,   r   r}   r-   r-   r.   r      rk   zMockDeploymentHandle.optionsdepc                 C   s   |\}}| j |ko| j|kS r0   )r   r   )r,   r   other_deployment_nameother_app_namer-   r-   r.   __eq__   s   
zMockDeploymentHandle.__eq__protocolc                 C   rD   r0   )r   )r,   r   r-   r-   r.   _set_request_protocol   rE   z*MockDeploymentHandle._set_request_protocolc                 C   rh   r0   r-   r6   r-   r-   r.   _get_or_create_router   rk   z*MockDeploymentHandle._get_or_create_routerr3   c                 C   r4   r0   r   r6   r-   r-   r.   running_replicas_populated   r7   z/MockDeploymentHandle.running_replicas_populatedrP   c                 C   rD   r0   r   )r,   rP   r-   r-   r.   set_running_replicas_populated   rE   z3MockDeploymentHandle.set_running_replicas_populatedN)r>   r?   r@   r   rT   r/   r   r   r   r
   r   r   r   r   r\   r   r   r-   r-   r-   r.   r      s    r   c                   @   rt   )GetPIDc                 C   s   t  S r0   )osgetpidr6   r-   r-   r.   __call__   s   zGetPID.__call__N)r>   r?   r@   r   r-   r-   r-   r.   r      s    r   c                   C   s&   zt d W dS  ty   Y dS w )N%http://localhost:8265/api/ray/versionFT)requestsrY   	Exceptionr-   r-   r-   r.   check_ray_stopped   s   
r   c                   C   s   t djdkS )Nr      )r   rY   status_coder-   r-   r-   r.   check_ray_started  rg   r   r   expected_statusr3   c                 C   s&   t  j| }|j|  j|ksJ dS r   )r   statusapplicationsdeployments)r   r   r   
app_statusr-   r-   r.   check_deployment_status  s   r   r   r   c                 C   s,   t | |d}tdd| fdgd}t|S )z<Get the replicas currently running for the given deployment.)r   r   
class_name=)stater   ALIVE)filters)r   r"   to_replica_actor_class_namelen)r   r   dep_idactorsr-   r-   r.   get_num_alive_replicas  s   r   targetc                 C   s   t | ||ks	J dS )z#Check if num replicas is >= target.Tr   r   r   r   r-   r-   r.   check_num_replicas_gte#     r   Fuse_controllerc                 C   sN   |rt  j| j|  }|jtjd}||ksJ dS t| ||ks%J dS )z#Check if num replicas is == target.r   T)	r   r   r   r   replica_statesrY   r   RUNNINGr   )r   r   r   r   r   num_running_replicasr-   r-   r.   check_num_replicas_eq,  s   r   c                 C   s   t | ||ks	J dS )z#Check if num replicas is <= target.Tr   r   r-   r-   r.   check_num_replicas_lte>  r   r   appsc                 C   s,   t  }| D ]}|j| jtjksJ qdS r   r   r   r   r    r   )r   r   r   r-   r-   r.   check_apps_runningG  s   r   
controllerdeployment_idtotalby_statec           
         s   t | j||dur fddtD } |ks J ||durn|D ]G\}} t|ts2J t|tr;|dks=J  rR fddj|gdD }t	|}nj|gd}d| d	| d
| d}	||ksmJ |	q&dS )a  Uses _dump_replica_states_for_testing to check replica counts.

    Args:
        controller: A handle to the Serve controller.
        deployment_id: The deployment to check replica counts for.
        total: The total number of expected replicas for the deployment.
        by_state: A list of tuples of the form
            (replica state, number of replicas, filter function).
            Used for more fine grained checks.
    Nc                    s*   i | ]}  |gr|t  |gqS r-   )rY   r   ).0r   )replicasr-   r.   
<dictcomp>e  s    
z(check_replica_counts.<locals>.<dictcomp>r   c                    s   h | ]} |r|qS r-   r-   )r   r)checkr-   r.   	<setcomp>q      z'check_replica_counts.<locals>.<setcomp>)statesz	Expected z for state z	 but got .T)
rayrY    _dump_replica_states_for_testingrv   r   countrS   r   intr   )
r   r   r   r   replica_countsr   r   filtered
curr_countmsgr-   )r   r   r.   check_replica_countsP  s&   


r   )r   	namespacenum_cpusc                   @   sB   e Zd Zdd ZdeddfddZdefdd	Zdefd
dZdS )TelemetryStoragec                 C   r   Nr   )reports_receivedrM   current_reportr6   r-   r-   r.   r/   }  r   zTelemetryStorage.__init__reportr3   Nc                 C   s   |  j d7  _ || _d S NrF   )r   r   )r,   r   r-   r-   r.   store_report  s   
zTelemetryStorage.store_reportc                 C   r4   r0   )r   r6   r-   r-   r.   
get_report  r7   zTelemetryStorage.get_reportc                 C   r4   r0   )r   r6   r-   r-   r.   get_reports_received  r7   z%TelemetryStorage.get_reports_received)	r>   r?   r@   r/   r   r   r   r   r   r-   r-   r-   r.   r   {  s
    r   r   )ray_actor_optionsc                   @   s&   e Zd Zdd ZdedefddZdS )TelemetryReceiverc                 C   s   t jttd| _d S )N)r   r   )r   	get_actorSTORAGE_ACTOR_NAMEr   r#   r6   r-   r-   r.   r/     r   zTelemetryReceiver.__init__r   r3   c                    s(   |  I d H }t| jj| dS r   )jsonr   rY   r#   r   rv   )r,   r   r   r-   r-   r.   r     s   zTelemetryReceiver.__call__N)r>   r?   r@   r/   r   r\   r   r-   r-   r-   r.   r     s    r   c                  C   s   t  } tjtdtd | S )u  Start a telemetry Serve app.

    Ray should be initialized before calling this method.

    NOTE: If you're running the TelemetryReceiver Serve app to check telemetry,
    remember that the receiver itself is counted in the telemetry. E.g. if you
    deploy a Serve app other than the receiver, the number of apps in the
    cluster is 2- not 1– since the receiver is also running.

    Returns a handle to a TelemetryStorage actor. You can use this actor
    to access the latest telemetry reports.
    	telemetry)r   route_prefix)r   rv   r   runreceiver_appTELEMETRY_ROUTE_PREFIX)r#   r-   r-   r.   start_telemetry_app  s   r  tagexpectedstorage_actor_namec                 C   s@   t j|td}t |j }t|d  | ||ksJ dS )N)r   extra_usage_tagsT)r   r   r   rY   r   rv   printget_value_from_report)r  r  r	  storage_handler   r-   r-   r.   check_telemetry  s
   r  c                 C   s   dd l }t| }t }|rE|tj}|jj	|d\}}W d    n1 s)w   Y  |j
}| tjjks;J | tksCJ dS |jj	|d\}	}
|
 tjjksXJ |	j|ks_J dS )Nr   r   T)pytestr   RayServeAPIServiceStubr   ListApplicationsRequestraisesgrpcRpcErrorListApplications	with_callvaluecode
StatusCodeUNAVAILABLEdetailsr   OKapplication_names)channel	app_namestest_drainingr  stubr   exception_info_	rpc_errorresponsecallr-   r-   r.   ping_grpc_list_applications  s   
r(  c           
      C   s   dd l }t| }t }|rE|tj}|jj	|d\}}W d    n1 s)w   Y  |j
}| tjjks;J | tksCJ d S |jj	|d\}}	|	 tjjksXJ |jdks_J d S )Nr   r  success)r  r   r  r   HealthzRequestr  r  r  Healthzr  r  r  r  r  r  r   r  message)
r  r!  r  r"  r   r#  r$  r%  r&  r'  r-   r-   r.   ping_grpc_healthz  s   
r-  c                 C   s   dd l }t| }tjdddd}d|ff}|rW|tj}|jj	||d\}}W d    n1 s3w   Y  |j
}	|	 tjjksIJ |	 d| d	|	 v sUJ d S |jj	||d\}
}| tjjksoJ | |
jd
ksyJ |
jd S )Nr   foo   barr   numr.  applicationr   metadatazApplication 'z' not found.zHello foo from bar)r  r   UserDefinedServiceStubr   UserDefinedMessager  r  r  r   r  r  r  r  	NOT_FOUNDr  r  greeting)r  r   test_not_foundr  r"  r   r5  r#  r$  r%  r&  r'  r-   r-   r.   ping_grpc_call_method  s   

r;  c                 C   sD   t | }tjdddd}d|ff}|j||d}|jdks J d S )Nr.  r/  r0  r1  r3  r4  zHello foo from method1)r   r6  r   r7  Method1r9  r  r   r"  r   r5  r&  r-   r-   r.   ping_grpc_another_method  s
   

r>  c                 C   sT   t | }tjdddd}d}d|fd|ff}|j||d}|jd	| ks(J d S )
Nr.  r/  r0  r1  999r3  multiplexed_model_idr4  z%Method2 called model, loading model: )r   r6  r   r7  Method2r9  )r  r   r"  r   r@  r5  r&  r-   r-   r.   ping_grpc_model_multiplexing  s   
rB  c                 C   s\   t | }tjdddd}d|ff}|j||d}t|D ]\}}|j| dks+J qd S )Nr.  r/  r0  r1  r3  r4  z: Hello foo from bar)r   r6  r   r7  	Streaming	enumerater9  )r  r   r"  r   r5  	responsesidxr&  r-   r-   r.   ping_grpc_streaming  s   

rG  c                 C   sB   t | }tjddd}d|ff}|j||d}|jdksJ d S )N      )orangeappler3  r4      )r   FruitServiceStubr   FruitAmounts
FruitStandcostsr=  r-   r-   r.   ping_fruit_stand  s
   

rQ  signal_actorc                 C  sh   d}zd V  t dI d H  W n t jy+   d}tjjd  | j I d H  Y nw |s2t	dd S )NFd   TzGCancelledError wasn't raised during `send_signal_on_cancellation` block)
rG   rH   CancelledErrorr   _rayletasync_task_idr^   sendrv   r   )rR  	cancelledr-   r-   r.   send_signal_on_cancellation  s   rY  c                   @   sl   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd ZdS )FakeGrpcContextc                 C   s@   ddi| _ dg| _d| _d| _d| _d | _d | _g | _g | _d S )NrO   r  )rO   r  peers   peer_identitiespeer_identity_key)_auth_context_invocation_metadata_peer_peer_identities_peer_identity_key_code_details_trailing_metadatar6   r-   r-   r.   r/   '  s   

zFakeGrpcContext.__init__c                 C   r4   r0   )r]  r6   r-   r-   r.   auth_context2  r7   zFakeGrpcContext.auth_contextc                 C   r4   r0   rb  r6   r-   r-   r.   r  5  r7   zFakeGrpcContext.codec                 C   r4   r0   rc  r6   r-   r-   r.   r  8  r7   zFakeGrpcContext.detailsc                 C   r4   r0   )r_  r6   r-   r-   r.   r[  ;  r7   zFakeGrpcContext.peerc                 C   r4   r0   )r`  r6   r-   r-   r.   peer_identities>  r7   zFakeGrpcContext.peer_identitiesc                 C   r4   r0   )ra  r6   r-   r-   r.   r\  A  r7   z!FakeGrpcContext.peer_identity_keyc                 C   r4   r0   rd  r6   r-   r-   r.   trailing_metadataD  r7   z!FakeGrpcContext.trailing_metadatac                 C   rD   r0   rf  )r,   r  r-   r-   r.   set_codeG  rE   zFakeGrpcContext.set_codec                 C   rD   r0   rg  )r,   r  r-   r-   r.   set_detailsJ  rE   zFakeGrpcContext.set_detailsc                 C   rD   r0   ri  )r,   rj  r-   r-   r.   set_trailing_metadataM  rE   z%FakeGrpcContext.set_trailing_metadatac                 C   r4   r0   )r^  r6   r-   r-   r.   invocation_metadataP  r7   z#FakeGrpcContext.invocation_metadataN)r>   r?   r@   r/   re  r  r  r[  rh  r\  rj  rk  rl  rm  rn  r-   r-   r-   r.   rZ  &  s    rZ  c                   @   st   e Zd Zddedee fddZdeeef fddZdd	ee	e
f deeef fd
dZdeeef fddZdS )	FakeGaugeNr   tag_keysc                 C   $   || _ t | _|p
d| _t | _d S r   )r   rM   valuestagsdefault_tagsr,   r   rp  r-   r-   r.   r/   U     
zFakeGauge.__init__rs  c                 C   .   |  D ]\}}|| jv sJ || j|< qd S r0   r   rs  rt  r,   rs  rO   r  r-   r-   r.   set_default_tags\     zFakeGauge.set_default_tagsr  c                 C   s   | j  }||p
i  t| t| jksJ | j}| jd d D ]}|| }||vr2t ||< || }q#|||| jd  < d S )N)rt  r   updater^   keysrs  rr  rM   )r,   r  rs  merged_tagsdr  	tag_valuer-   r-   r.   r^   a  s   


zFakeGauge.setc                 C   6   | j }| jD ]}|| }||}|d u r d S q|S r0   )rr  rs  rY   r,   rs  r  r  r  r-   r-   r.   	get_valueo     

zFakeGauge.get_valuers   r0   )r>   r?   r@   rT   r
   r/   r   rz  r   r   rA   r^   r  r-   r-   r-   r.   ro  T  s
    $ro  c                   @   s   e Zd Zddedee fddZdeeef fddZdd
ee	e
f deeef fddZdeeef de	fddZdd ZdS )FakeCounterNr   rp  c                 C   rq  r   )r   rM   countsrs  rt  ru  r-   r-   r.   r/   {  rv  zFakeCounter.__init__rs  c                 C   rw  r0   rx  ry  r-   r-   r.   rz    r{  zFakeCounter.set_default_tags      ?r  c                 C   s   | j  }||p
i  t| t| jksJ | j}| jd d D ]}|| }||vr2t ||< || }q#|| jd  }||d| ||< d S )Nr|  r   )	rt  r   r}  r^   r~  rs  r  rM   rY   )r,   r  rs  r  r  r  r  rO   r-   r-   r.   inc  s   


zFakeCounter.incr3   c                 C   r  r0   )r  rs  rY   r  r-   r-   r.   	get_count  r  zFakeCounter.get_countc                 C   r4   r0   )rs  r6   r-   r-   r.   get_tags  r7   zFakeCounter.get_tagsrs   )r  N)r>   r?   r@   rT   r
   r/   r   rz  r   r   rA   r  r  r  r-   r-   r-   r.   r  z  s    $
r  c                   C   s   t   S r0   )r   get_runtime_contextget_node_idr-   r-   r-   r.   r    s   r  c                 C   s&   dd t  D }t|| ksJ dS )Nc                 S   s   g | ]}|d  r|qS )Aliver-   )r   noder-   r-   r.   
<listcomp>  r   z)check_num_alive_nodes.<locals>.<listcomp>T)r   nodesr   )r   alive_nodesr-   r-   r.   check_num_alive_nodes  s   r  _clientc                 C   s&   |pt  }| }|d | d |  S )Nr   r   )r   get_serve_details)r   r   r  clientr  r-   r-   r.   get_deployment_details  s   
r  c                   @   s*   e Zd ZdefddZdd Zdd ZdS )	Counterr   c                 C   s   d| _ || _t | _d S r   )r   r   rG   Eventready_event)r,   r   r-   r-   r.   r/     s   zCounter.__init__c                 C   s,   |  j d7  _ | j | jkr| j  d S d S r   )r   r   r  r^   r6   r-   r-   r.   r    s   zCounter.incc                    s   | j  I d H  d S r0   )r  waitr6   r-   r-   r.   r    s   zCounter.waitN)r>   r?   r@   r   r/   r  r  r-   r-   r-   r.   r    s    r  INFOslevelc                 C   s6   t j  ddd }td| d| d|   dS )z&Convenient logging method for testing.z%H:%M:%S.%fN[z]  )datetimenowstrftimer  )r  r  r  r-   r-   r.   tlog  s   r  r  r   c                    s@   t | jj|} fdd|D }dd |D }t|dkS )a%  Wait for target groups to be ready for the given app and protocol.

    Target groups are ready when there are at least one target for the given protocol. And it's
    possible that target groups are not ready immediately. An example is when the controller
    is recovering from a crash.
    c                       g | ]	}|j  kr|qS r-   r   r   target_groupr  r-   r.   r    
    
z-check_target_groups_ready.<locals>.<listcomp>c                 S   s   g | ]
}|j D ]}|qqS r-   )targets)r   r  r   r-   r-   r.   r    s
    r   )r   rY   _controllerget_target_groupsrv   r   )r  r   r   target_groupsall_targetsr-   r  r.   check_target_groups_ready  s   
r  Tuse_localhostis_websocketexclude_route_prefixfrom_proxy_managerc                    sR  t dd}| }||d v sJ d| d|d | d }|s%|du r'd}t tr0t  t|jj	||}	 fd	d
|	D }	t
|	dkrWtd| d  d| g }
|	D ]K}|jD ]E}|rfdn|j} tjkr|rrdnd}| dt||j | }n tjkr|rtdt||j}ntd  |d}|
| q`q[|
S )ac  Get the URL of the application.

    Args:
        protocol: The protocol to use for the application.
        app_name: The name of the application.
        use_localhost: Whether to use localhost instead of the IP address.
            Set to True if Serve deployments are not exposed publicly or
            for low latency benchmarking.
        is_websocket: Whether the url should be served as a websocket.
        exclude_route_prefix: The route prefix to exclude from the application.
        from_proxy_manager: Whether the caller is a proxy manager.
    Returns:
        The URLs of the application.
    T)_health_check_controllerr   zApp zV not found in serve details. Use this method only when the app is known to be running.r  N c                    r  r-   r  r  r  r-   r.   r    r  z(get_application_urls.<locals>.<listcomp>r   zNo target group found for app z with protocol z and route prefix 	localhostwshttpz://z6is_websocket=True is not supported with gRPC protocol.zUnsupported protocol: /)r   r  rS   rT   r   r   rY   r  r  rv   r   
ValueErrorr  ipHTTPr   portGRPCrstripappend)r   r   r  r  r  r  r  serve_detailsr  r  urlsr  r   r  schemeurlr-   r  r.   get_application_urls  sL   







r  c              	   C   s   t t| |||||S )a  Get the URL of the application.

    Args:
        protocol: The protocol to use for the application.
        app_name: The name of the application.
        use_localhost: Whether to use localhost instead of the IP address.
            Set to True if Serve deployments are not exposed publicly or
            for low latency benchmarking.
        is_websocket: Whether the url should be served as a websocket.
        exclude_route_prefix: The route prefix to exclude from the application.
        from_proxy_manager: Whether the caller is a proxy manager.
    Returns:
        The URL of the application. If there are multiple URLs, a random one is returned.
    )randomchoicer  )r   r   r  r  r  r  r-   r-   r.   get_application_url)  s   r  c                 C   s   t  j|  jtjksJ dS r   r   r   r-   r-   r.   check_runningK  s   r  r/  c              
      sT   dd idt f fdd}zt|d d W S  ty) } zt|d }~ww )Nrespr3   c               	      s@   zt d d} tj| dd< W dS  tjtfy   Y dS w )Nr  r  timeoutr  TF)r  httpxrY   RequestError
IndexError)r  r   result_holderr  r-   r.   _attemptS  s   z&request_with_retries.<locals>._attemptr  )r\   r   r   TimeoutError)r  r   r  er-   r  r.   request_with_retriesP  s   
r  rs   )F)r  )srG   r  r   r  r'   r1   
contextlibr   r   r   typingr   r   r   r   r	   r
   r   r  r  r   starlette.requestsr   r   r   ray._common.network_utilsr   ray._common.test_utilsr   ray._common.utilsr   	ray.actorr   ray.serve._private.clientr   ray.serve._private.commonr   r   r   r   ray.serve._private.constantsr   r   #ray.serve._private.deployment_stater   r   ray.serve._private.proxyr   ray.serve._private.usager   ray.serve.contextr   ray.serve.generatedr   r   ray.serve.schemar    r!   ray.util.stater"   r  r   r$   rB   rL   r]   ru   rw   r   r   r   
deploymentr   bindget_pid_entrypointr   r   rT   r\   r   r   r   r   r   r   r   r   rv   r   r   r  r  r  r(  r-  r;  r>  rB  rG  rQ  rY  rZ  ro  r  r  r  r  r  r  r  r  r  r  r  r  r-   r-   r-   r.   <module>   s   $$	(
	



	
+





	.&*







C

"