
    &`iʗ                        d dl 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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mZmZ d dlmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z( d dl)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m&Z3 d dl4m5Z5m6Z6 d dl7m8Z8 dede9dee9e:f         fdZ; G d d          Z< G d de<          Z= G d d          Z> G d d          Z?da@	 d"deAdee         deAfdZBd e/deAfd!ZCdS )#    )Counterdefaultdict)deepcopy)datetime)Enum)chain)AnyDictListOptionalTupleN)binary_to_hex)	GcsClient)	constants)	format_pgformat_resource_demand_summaryparse_usage)NODE_DEATH_CAUSE_RAYLET_DIEDClusterConstraintDemandClusterStatusLaunchRequestNodeInfo	NodeUsagePlacementGroupResourceDemandRayTaskActorDemandResourceDemandResourceDemandSummaryResourceRequestByCountResourceUsageStats)
AffinityConstraintAntiAffinityConstraintAutoscalingStateClusterResourceStateGetClusterStatusReply	NodeState
NodeStatusPlacementConstraintResourceRequestr   )LabelSelectorLabelSelectorConstraint)internal_kv_get_gcs_clientdatakeyreturnc                 x    t          t                    }| D ]"}t          ||          }||xx         dz  cc<   #|S )z
    Count the number of items by the given keys.
    Args:
        data: the data to be counted
        keys: the keys to count by
    Returns:
        counts: the counts
       )r   intgetattr)r-   r.   countsitemkey_names        k/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/ray/autoscaler/v2/utils.py	_count_byr8   3   sS     F  4%%xAM    c                   >    e Zd ZdZed             Zed             ZdS )ProtobufUtilz/
    A utility class for protobuf objects.
    c                 *    ddl m}  || dd          S )a  
        Convert a protobuf object to a dict.

        This is a slow conversion, and should only be used for debugging or
        latency insensitve code.

        Args:
            proto: the protobuf object
        Returns:
            dict: the dict
        r   )message_to_dictT)preserving_proto_field_name$always_print_fields_with_no_presence)ray._private.protobuf_compatr=   )protor=   s     r7   to_dictzProtobufUtil.to_dictH   s9     	A@@@@@(,15
 
 
 	
r9   c                     d | D             S )z
        Convert a list of protobuf objects to a list of dicts.

        Args:
            protos: the list of protobuf objects
        Returns:
            dict_list: the list of dicts
        c                 B    g | ]}t                               |          S  )r;   rB   ).0rA   s     r7   
<listcomp>z-ProtobufUtil.to_dict_list.<locals>.<listcomp>g   s&    @@@$$U++@@@r9   rE   )protoss    r7   to_dict_listzProtobufUtil.to_dict_list]   s     A@@@@@r9   N)__name__
__module____qualname____doc__staticmethodrB   rI   rE   r9   r7   r;   r;   C   sY          
 
 \
( 	A 	A \	A 	A 	Ar9   r;   c                      e Zd ZdZ G d de          Zedee         dee	         fd            Z
edee	         dee         fd            Zed	edeeef         fd
            Zedee         deeeef                  fd            Ze	 	 ddeeef         deeeeeef                           deeeeeeee         f                                    defd            Zedee         dee         fd            Zdee         defdZdS )ResourceRequestUtilzQ
    A utility class for resource requests, autoscaler.proto.ResourceRequest
    c                       e Zd ZdZdZdZdS )+ResourceRequestUtil.PlacementConstraintTypez=
        The affinity type for the resource request.
        ANTI_AFFINITYAFFINITYN)rJ   rK   rL   rM   rS   rT   rE   r9   r7   PlacementConstraintTyperR   o   s$        	 	 (r9   rU   requestsr/   c                 F   t          t                    }| D ]&}|                                }||xx         dz  cc<   'g }|                                D ]L\  }}t	                      }|                    |           |                    t          ||                     M|S )
        Aggregate resource requests by shape.
        Args:
            requests: the list of resource requests
        Returns:
            resource_requests_by_count: the aggregated resource requests by count
        r1   requestcount)r   r2   SerializeToStringitemsr)   ParseFromStringappendResourceRequestByCountProto)rV   resource_requests_by_countrZ   serialized_requestresultsr[   s         r7   group_by_countz"ResourceRequestUtil.group_by_countw   s     &1%5%5" 	@ 	@G!(!:!:!<!<&'9:::a?::::)C)I)I)K)K 	V 	V%%''G##$6777NN6weTTTUUUUr9   requests_by_countc                 :    g }| D ]}||j         g|j        z  z  }|S )z
        Flatten the resource requests by count to resource requests.
        Args:
            requests_by_count: the resource requests by count
        Returns:
            requests: the flattened resource requests
        rY   )re   reqsrs      r7   ungroup_by_countz$ResourceRequestUtil.ungroup_by_count   s4     " 	* 	*AQYK!'))DDr9   rZ   c                     t          t                    }| j                                        D ]\  }}||xx         |z  cc<   t	          |          S )z
        Convert the resource request by count to resource map.
        Args:
            request: the resource request
        Returns:
            resource_map: the resource map
        )r   floatresources_bundler]   dict)rZ   resource_mapkvs       r7   to_resource_mapz#ResourceRequestUtil.to_resource_map   sY     #5)),2244 	! 	!DAqOOOq OOOOL!!!r9   c                     d | D             S )z
        Convert the resource requests by count to resource map.
        Args:
            requests: the resource requests
        Returns:
            resource_maps: list of resource map
        c                 B    g | ]}t                               |          S rE   )rP   rq   rF   rh   s     r7   rG   z8ResourceRequestUtil.to_resource_maps.<locals>.<listcomp>   s'    III1#33A66IIIr9   rE   )rV   s    r7   to_resource_mapsz$ResourceRequestUtil.to_resource_maps   s     JIIIIIr9   Nresources_mapconstraintslabel_selectorsc           	         t                      }|                                 D ]\  }}||j        |<   ||D ]\  }}}|t          j        j        k    r8|j                            t          t          ||                               S|t          j        j
        k    r8|j                            t          t          ||                               t          d|           |`|D ]]}	t                      }
|	D ]0\  }}}|
j                            t          |||                     1|j                            |
           ^|S )aP  
        Make a resource request from the given resources map.
        Args:
            resources_map: Mapping of resource names to quantities.
            constraints: Placement constraints. Each tuple is (constraint_type,
                label_key, label_value), where `constraint_type` is a
                PlacementConstraintType (AFFINITY or ANTI_AFFINITY).
            label_selectors: Optional list of label selectors. Each selector is
                a list of (label_key, operator_enum, label_values) tuples.
        Returns:
            request: the ResourceRequest object
        N
label_namelabel_valueaffinity)anti_affinityzUnknown constraint type: )	label_keyoperatorlabel_values)r)   r]   rl   rP   rU   rT   placement_constraintsr_   r(   r!   rS   r"   
ValueErrorr*   label_constraintsr+   rx   )rv   rw   rx   rZ   resource_namequantityconstraint_typelabelvalueselectorselector_protor   operator_enumr   s                 r7   makezResourceRequestUtil.make   s   $ "##'4':':'<'< 	? 	?#M86>G$]33"1< T T-#*BKL L 188+%7+0e& & &      $*BPQ Q 188+*@+0e+ + +      %%R%R%RSSS&+ 
? 
?!.>F  :I}l"4;;/&/%2)5      '..~>>>>r9   resource_requestsc                    t          t                    }g }| D ]}t          |j                  dk    s
J d            t          |j                  dk    r|                    |           R|j        d         }|                    d          rO|j        }|j        |j        t          
                    |j                  f}||                             |           |                    d          r|                    |           |                                D ]\  \  }}}	}
t                      }|
D ]G}|j                                        D ]+\  }}|j                            |d          |z   |j        |<   ,Ht!          ||          }|j                            t#          |                     |j                            |
d         j                   |                    |           |S )a  
        Combine the resource requests with affinity constraints
        into the same request. This is so that requests with affinity
         constraints could be considered and placed together.

        It merges the resource requests with the same affinity constraints
        into one request, and dedup the placement constraints.

        This assumes following:
            1. There's only at most 1 placement constraint, either an affinity
            constraint OR an anti-affinity constraint.

        Args:
            resource_requests: The list of resource requests to be combined.
        Returns:
            A list of combined resource requests.
        r1   zmThere should be at most 1 placement constraint, either an affinity constraint OR an anti-affinity constraint.r   r~   r   rz   r}   )r   listlenr   r_   HasFieldr~   r{   r|   rP   _label_selector_keyrx   r]   r)   rl   getr!   r(   extend)r   requests_by_affinitycombined_requestsrZ   
constraintr~   r.   affinity_label_nameaffinity_label_valuelabel_selector_keyrV   combined_requestro   rp   affinity_constraints                  r7   combine_requests_with_affinityz2ResourceRequestUtil.combine_requests_with_affinity   sF   2  	 46( 	2 	2Gw455:::P ;::
 7011Q66!((111 6q9J"":.. 2%.'(';;G<STT
 %S)009999$$_55 2!((111 ,1133		7 	7  
 .00 $  #4::<<  DAq(9==aCCaG %5a88 #5.<P# # # 299#-@AAA   ,33HQK4OPPP$$%56666  r9   c                    g }| D ]q}g }|j         D ]C}|                    |j        |j        t	          t          |j                            f           D|                    t	          |                     rt	          |          S )z
        Convert label selectors into a hashable form for grouping.
        This is used for gang requests with identical label_selectors.
        )r   r_   r   r   tuplesortedr   )rx   resultr   rw   r   s        r7   r   z'ResourceRequestUtil._label_selector_keyO  s     ' 
	. 
	.HK&8  
""","+fZ%<==>>    MM%,,----V}}r9   )NN)rJ   rK   rL   rM   r   rU   rN   r   r)   r`   rd   ri   r
   strrk   rq   ru   r   r   r2   r   r   r*   r   rE   r9   r7   rP   rP   j   s=            $    '	)	*   \.  ;<	o	   \  " "	c5j	" " " \" 
J'
J	d3:	
J 
J 
J \
J  QULP= =CJ'=d5)@#s)J#KLM= "$tE#sDI2E,F'G"HI= 
	= = = \=~ O!0O!	o	O! O! O! \O!bm,	     r9   rP   c                      e Zd ZdZeddededefd            Ze	de
e         de
e         defd	            Ze	dededeeffd
            Ze	dedefd            Ze	dedefd            Ze	dededefd            Ze	dedefd            Ze	de
e         defd            Ze	dedefd            Ze	dededefd            ZdS )ClusterStatusFormatterzA
    A formatter to format the ClusterStatus into a string.

    Fr-   verboser/   c                 B   |                      ||          \  }}d|z  }|                     |          }|                     |          }|                     |          }|                     ||          }	|                     ||          }
|                     |j        j                  }| 	                    |          }|sdn| 
                    |j        |j                  }|d|d|d|d||	dd|d|
d	|d
||g}d                    |          }|                                S )N- zNode statuszActive:zIdle:zPending:	ResourceszTotal Usage:zFrom request_resources:zPending Demands:
)_header_info_available_node_report_idle_node_report_pending_node_report_failed_node_report_cluster_usage_report_constraint_reportresource_demandscluster_constraint_demand_demand_report_node_usage_reportactive_nodes
idle_nodesjoinstrip)clsr-   r   headerseparator_len	separatoravailable_node_reportidle_node_reportpending_reportfailure_reportcluster_usage_reportconstraints_reportdemand_reportnode_usage_reportformatted_output_linesformatted_outputs                   r7   formatzClusterStatusFormatter.formatk  s[    # 0 0w ? ?-'	 !$ : :4 @ @006611$7700w??"88wGG 33!;
 
 **400 LBB''(94?KK 	 ! %)"
.  99%;<<%%'''r9   r   r   c                     i }i }i }i }i }t          | |          D ]a}d |j        j        D             ||j        <   |j        ||j        <   |j        j        ||j        <   |j        ||j        <   |j        ||j        <   bg }|                                D ]V\  }	}
|	                    d           d||	          }|	|v r||	         }|d| dz  }|	                    |           |	                    d|	            |
                    |	d          dk    r|	                    d||	          d	           |	                    d
           t          |
d          D ]}|	                    d|            |
                    |	g           }|	                    d           |t          |          dk    r|	                    d           9|D ]}|	                    d|            Xd                    |          S )ap  [Example]:
        Node: raycluster-autoscaler-small-group-worker-n8hrw (small-group)
         Id: cc22041297e5fc153b5357e41f184c8000869e8de97252cc0291fd17
         Usage:
          1.0/1.0 CPU
          0B/953.67MiB memory
          0B/251.76MiB object_store_memory
         Activity:
          Resource: CPU currently in use.
          Busy workers on node.
        c                 6    i | ]}|j         |j        |j        fS rE   r   usedtotalrF   us     r7   
<dictcomp>z=ClusterStatusFormatter._node_usage_report.<locals>.<dictcomp>  s2     . . .78!&!'!2. . .r9   r   zNode: z ()z Id: r   z Idle: z msz Usage:T)r   z  z
 Activity:Nz  (no activity)r   )r   resource_usageusagenode_idray_node_type_nameidle_time_msinstance_idnode_activityr]   r_   r   r   r   r   )r   r   node_id_to_usagenode_id_to_typenode_id_to_idle_timenode_id_to_instance_idnode_id_to_activitiesnodenode_usage_report_linesr   r   node_type_line	node_typeline
activitiesactivitys                   r7   r   z)ClusterStatusFormatter._node_usage_report  s    GI*,/11368 ,
33 	E 	ED. .<@<O<U. . .T\* -1,CODL)151D1Q .373C"4<0262D!$,//"$.4466 	D 	DNGU#**2...G&<W&EGGN/))+G4	"3y"3"3"33#**>:::#**+<7+<+<===#''33a77'..@27;@@@   $**9555#E4888 < <'..{D{{;;;;.227B??J#**<888!S__%9%9'../@AAAA * D DH+22???CCCCD yy0111r9   c                    | j         j        rt          j        | j         j                  nt          j                    }| j         j        }| j         j        }| j         j        }dd| dz   dz   }t          |          }|rvg }|r|	                    d|dd           |r|	                    d|dd           |r|	                    d|dd           |r|d	d	
                    |          z   d	z   z  }||fS )
Nz========z Autoscaler status:  zGCS request time: 3fsz)Node Provider non_terminated_nodes time: zAutoscaler iteration time: r   )statsrequest_ts_sr   fromtimestampnowgcs_request_time_s#none_terminated_node_request_time_sautoscaler_iteration_time_sr   r_   r   )	r-   r   timegcs_request_timenon_terminated_nodes_timeautoscaler_update_timer   r   detailss	            r7   r   z#ClusterStatusFormatter._header_info  sP   
 z& H"4:#:;;; 	  :8$(J$R!!%!G 9$9999GCF  	;G LJ4DJJJJKKK( _@Y____   & N2HNNNN    ;$7!3!33d::}$$r9   c                     t          | j        d          }|sdS d                    d |                                D                       S )Nr   z (no active nodes)r   c              3   ,   K   | ]\  }}d | d | V  dS r   NrE   rF   r   r[   s      r7   	<genexpr>z@ClusterStatusFormatter._available_node_report.<locals>.<genexpr>  H       
 
(8	5###	##
 
 
 
 
 
r9   )r8   r   r   r]   )r-   r   s     r7   r   z-ClusterStatusFormatter._available_node_report  sc     !24HII  	(''yy 
 
<H<N<N<P<P
 
 
 
 
 	
r9   c                     t          | j        d          }|sdS d                    d |                                D                       S )Nr   z (no idle nodes)r   c              3   ,   K   | ]\  }}d | d | V  dS r   rE   r   s      r7   r   z;ClusterStatusFormatter._idle_node_report.<locals>.<genexpr>  r   r9   )r8   r   r   r]   )r-   r   s     r7   r   z(ClusterStatusFormatter._idle_node_report
  sb    t0DEE
  	&%%yy 
 
<F<L<L<N<N
 
 
 
 
 	
r9   c                    g }| j         rt          | j         d d          }|D ]r}|j        }d}|j        }t	          j        |j                  }|j        dd|j        dd|j	        d}	d| d| d	|	 d
}
|r|
d| z  }
|
                    |
           s| j        D ](}|
                    d|j         d|j         d
           )|d t          j                 }d}||rd                    |          ndz  }|S )Nc                     | j         S N)r   )launchs    r7   <lambda>z<ClusterStatusFormatter._failed_node_report.<locals>.<lambda>  s	    6#6 r9   T)r.   reverseLaunchFailed02d:r   : z (latest_attempt: r   z - z: NodeTerminated (instance_id: zRecent failures:
r   z (no failures))failed_launchesr   r   r   r   r   r   hourminutesecondr_   failed_nodesr   r   !AUTOSCALER_MAX_FAILURES_DISPLAYEDr   )r-   r   failure_linessorted_failed_launchesfailed_launchr   categorydescriptionattempted_timeformatted_timer   r   r   s                r7   r   z*ClusterStatusFormatter._failed_node_report  s     	+%+$66& & &" "8 + +)<	)+3!)!78R!S!S$2$7!u!u!un>S!u!u!uZhZo!u!u!uU9UUUUNUUU 0/+///D$$T**** % 	 	D  _D+__DL\___   
 &&S	(S&ST .(5KDIIm$$$;K	
 r9   c                     d t          | j        d                                          D             }|                    d d | j        D             D                        |rd                    |          S dS )Nc                 &    g | ]\  }}d | d| dS )r   , z
 launchingrE   r   s      r7   rG   z?ClusterStatusFormatter._pending_node_report.<locals>.<listcomp>B  s?     
 
 
 	5 /	..U...
 
 
r9   r   c              3   X   K   | ]%\  }}}d | d| d|                                  V  &dS )r   r  r  N)lower)rF   ipr   statuss       r7   r   z>ClusterStatusFormatter._pending_node_report.<locals>.<genexpr>J  s\       
 
%Iv 433i336<<>>33
 
 
 
 
 
r9   c              3   >   K   | ]}|j         |j        |j        fV  d S r  )r   r   r   )rF   r   s     r7   r   z>ClusterStatusFormatter._pending_node_report.<locals>.<genexpr>L  sE       * * !4#:DLI* * * * * *r9   r   z (no pending nodes))r8   pending_launchesr]   r   pending_nodesr   )r-   pending_liness     r7   r   z+ClusterStatusFormatter._pending_node_report?  s    
 
$-%';% %egg	
 
 
 	 
 
* * .* * *
 
 
 	
 	
 	
  	,99]+++$$r9   r   c                     g }d | D             }|D ]!\  }}|                     d| d| d           "|rd                    |          S dS )a]  Returns a formatted string describing the resource constraints from request_resources().

        Args:
            data: ClusterStatus object containing resource demand information.

        Returns:
            String containing the formatted constraints report, either listing each constraint
            and count or indicating no constraints exist.

        Example:
            >>> cluster_constraint_demand = [
            ...     ClusterConstraintDemand(bundles_by_count=[
            ...         ResourceRequestByCount(bundle={"CPU": 4}, count=2),
            ...         ResourceRequestByCount(bundle={"GPU": 1}, count=1)
            ...     ])
            ... ]
            >>> ClusterStatusFormatter._constraint_report(cluster_constraint_demand)
            " {'CPU': 4}: 2 from request_resources()\n {'GPU': 1}: 1 from request_resources()"
        c                 >    g | ]}|j         D ]}|j        |j        fS rE   bundles_by_countbundler[   )rF   constraint_demandbcs      r7   rG   z=ClusterStatusFormatter._constraint_report.<locals>.<listcomp>o  sK     
 
 
!'8
 
  Y!
 
 
 
r9   r   r  z from request_resources()r   z (none))r_   r   )r   constraint_linesrequest_demandr%  r[   s        r7   r   z)ClusterStatusFormatter._constraint_reportW  s    . 
 
%>
 
 

 , 	T 	TMFE##$R$R$R%$R$R$RSSSS 	/99-...yr9   c                   	 d | j         j        D             }g }|r"|                    t          |                     d | j         j        D             }d | j         j        D             	t          |          }	fd|                                D             }|D ]0\  }}t          |          }|                    d| d| d           1|rd	                    |          S d	S )
Nc                 >    g | ]}|j         D ]}|j        |j        fS rE   r#  )rF   demandr%  s      r7   rG   z9ClusterStatusFormatter._demand_report.<locals>.<listcomp>}  sK     
 
 
 1
 
  ]FL)
 
 
 
r9   c                 0    g | ]}|j          d |j         S |strategystaterF   	pg_demands     r7   rG   z9ClusterStatusFormatter._demand_report.<locals>.<listcomp>  s;     
 
 
 !55IO55
 
 
r9   c                 2    i | ]}|j          d |j         |S r.  r0  r3  s     r7   r   z9ClusterStatusFormatter._demand_report.<locals>.<dictcomp>  s=     #
 #
 #
 !55IO55y#
 #
 #
r9   c                 d    g | ],\  }}|         j         d  |         j        D             d|f-S )c                 *    g | ]}|j         |j        fS rE   r%  r[   )rF   r%  s     r7   rG   zDClusterStatusFormatter._demand_report.<locals>.<listcomp>.<listcomp>  s1          "  5     r9   )r1  bundles)r1  r$  )rF   pg_strfreqpg_demand_str_to_demands      r7   rG   z9ClusterStatusFormatter._demand_report.<locals>.<listcomp>  so     
 
 
  !8 ? H   &=f&E&V       	
 
 
r9   r   r  z+ pending placement groupsr   z (no resource demands))
r   ray_task_actor_demandr   r   placement_group_demandr   r]   r   r_   r   )
r-   r   demand_linespg_demand_strspg_freqsr4  pgr[   r:  r<  s
            @r7   r   z%ClusterStatusFormatter._demand_reportz  sQ   
 
/E
 
 

  	R >?O P PQQQ
 
!2I
 
 
#
 #
!2I#
 #
 #
 >**
 
 
 
 !) 0 0
 
 
	 # 	Q 	QIBr]]F OF O Oe O O OPPPP  	+99\***''r9   c                     d | j         D             }t          ||          }d |D             dgz   }d                    |          S )Nc                 6    i | ]}|j         |j        |j        fS rE   r   r   s     r7   r   z@ClusterStatusFormatter._cluster_usage_report.<locals>.<dictcomp>  s2     
 
 
34AOafag.
 
 
r9   c                     g | ]}d | S )r   rE   )rF   r   s     r7   rG   z@ClusterStatusFormatter._cluster_usage_report.<locals>.<listcomp>  s    ;;;t
D

;;;r9   r   r   )cluster_resource_usager   r   )r-   r   r   usage_linesusage_reports        r7   r   z,ClusterStatusFormatter._cluster_usage_report  sb    
 
8<8S
 
 

 "%11 <;{;;;rdByy&&&r9   N)F)rJ   rK   rL   rM   classmethodr   boolr   r   rN   r   r   r   r2   r   r   r   r   r   r   r   r   r   rE   r9   r7   r   r   e  s/        
 .( .(- .($ .(3 .( .( .( [.(` ;28n;226x.;2	;2 ;2 ;2 \;2z "%= "%4 "%S#J "% "% "% \"%H 
] 
s 
 
 
 \
 
 
# 
 
 
 \
 '- '$ '3 ' ' ' \'R %= %S % % % \%.  #'(?#@ 	      \ D +(] +(s +( +( +( \+(Z 'M 'D 'S ' ' ' \' ' 'r9   r   c            	          e Zd Zedededefd            Zedededefd            Zede	de
e         fd            Zed	e
e         de
e         fd
            Zededeeef         deeef         fd            Zede	de
e         fd            Zede	dee
e         e
e         f         fd            Zededee
e         e
e         f         fd            Zedede
e         fd            ZdS )ClusterStatusParserrA   r   r/   c                 p   |                      |j                  \  }}}|                     |j                  }|                     |j                  \  }}|                     |j                  }	|                     |j                  }
|                     ||          }t          |||||||	|
|	  	        S )N)	r   r   r  r	  r  r  rF  r   r   )	_parse_nodescluster_resource_state_parse_pendingautoscaling_state_parse_launch_requests_parse_cluster_resource_usage_parse_resource_demands_parse_statsr   )r   rA   r   r   r   r  r  r  r	  rF  r   s              r7   from_get_cluster_status_replyz1ClusterStatusParser.from_get_cluster_status_reply  s    
 251A1A(2
 2
.j,
 **5+BCC -0,F,F#-
 -
)/
 "%!B!B("
 "

 66u7STT   ..%!-+'%#9-

 

 

 
	
r9   replyc                     t          |          }|j        |_        t          |j        j                  |_        t          |j        j                  |_        |S )z
        Parse the stats from the get cluster status reply.
        Args:
            reply: the get cluster status reply
            stats: the stats
        Returns:
            stats: the parsed stats
        )r   r   r   rQ  autoscaler_state_versionautoscaler_versionrO  cluster_resource_state_version)r   rW  r   s      r7   rU  z ClusterStatusParser._parse_stats  sR     #(#; #&u'>'W#X#X /2(G0
 0
, r9   r2  c                    g }g }g }|j         D ]E}t          t          |j        j        |j                  g          }|                    |           F|j        D ]E}t          | 	                    |j
                  |j                  }|                    |           F|j        D ]6}t          d |j        D                       }|                    |           7t          |||          S )z
        Parse the resource demands from the cluster resource state.
        Args:
            state: the cluster resource state
        Returns:
            resource_demands: the resource demands
        )r$  )r$  r   c                     g | ]A}t          t          |j        j                                                  |j                   BS )r8  )r   rm   rZ   rl   r]   r[   rt   s     r7   rG   z?ClusterStatusParser._parse_resource_demands.<locals>.<listcomp>  sY     " " "  +#AI$>$D$D$F$FGGqw  " " "r9   )r=  r>  r   )pending_resource_requestsr   r   rZ   rl   r[   r_   pending_gang_resource_requestsr   %_aggregate_resource_requests_by_shaperV   r   cluster_resource_constraintsr   r   r   )	r   r2  task_actor_demandr4  r&  request_countr,  gang_requestconstraint_requests	            r7   rT  z+ClusterStatusParser._parse_resource_demands  sU    	"< 		- 		-M'*%->@S "  F $$V,,,,!@ 	% 	%L1!$!J!J )" " %,	  F V$$$$"'"D 		- 		-," " 0A	" " "  F $$V,,,,$"3#,&7
 
 
 	
r9   rV   c                     t          t                    }|D ]8}t          |j                                                  }||xx         dz  cc<   9d |                                D             S )rX   r1   c                 N    g | ]"\  }}t          t          |          |          #S rE   )r   rm   )rF   r%  r[   s      r7   rG   zMClusterStatusParser._aggregate_resource_requests_by_shape.<locals>.<listcomp><  s<     
 
 
 #4<<77
 
 
r9   )r   r2   	frozensetrl   r]   )r   rV   ra   rZ   r%  s        r7   r`  z9ClusterStatusParser._aggregate_resource_requests_by_shape*  s     &1%5%5" 	4 	4Gw7==??@@F&v...!3....
 
!;!A!A!C!C
 
 
 	
r9   
node_stater   c                    t          d           }|j                                        D ]1\  }}||         dxx         |z  cc<   ||         dxx         |z  cc<   2|j                                        D ]\  }}||         dxx         |z  cc<   |                                D ]A\  }\  }}	|||         _        ||         xj        |z  c_        ||         xj        |	z  c_        B|S )a&  
        Parse the node resource usage from the node state.
        Args:
            node_state: the node state
            usage: the usage dict to be updated. This is a dict of
                {resource_name: ResourceUsage}
        Returns:
            usage: the updated usage dict
        c                  
    ddgS )Ng        rE   rE   r9   r7   r  z@ClusterStatusParser._parse_node_resource_usage.<locals>.<lambda>O  s
    c
 r9   r1   r   )r   total_resourcesr]   available_resourcesr   r   r   )
r   ri  r   dr   resource_totalresource_availablero   r   r   s
             r7   _parse_node_resource_usagez.ClusterStatusParser._parse_node_resource_usageA  s(    **++-7-G-M-M-O-O 	2 	2)M>mQ>1mQ>1
 +1133	6 	6 
mQ#55 !"		 	$ 	$A}e%&E!H"!HMMT!MM!HNNe#NNNr9   c                     t          t                    }|j        D ]-}|j        t          j        k    r|                     ||          }.t          |                                          S )z
        Parse the cluster resource usage from the cluster resource state.
        Args:
            state: the cluster resource state
        Returns:
            cluster_resource_usage: the cluster resource usage
        )	r   r   node_statesr  r'   DEADrq  r   values)r   r2  rF  ri  s       r7   rS  z1ClusterStatusParser._parse_cluster_resource_usagec  sn     "-]!;!;+ 	 	J JO33),)G)G 6* *& *1133444r9   c                 z   g }g }g }|j         D ]}t          |j                  }t          |j                  dk    rd| }n|j        }d}d}	|j        t          j        k    rt          }	nvt          t                    }
|                     ||
          }
t          t          |
                                          |j        t          j        k    r|j        nd          }t#          |j        t          j        |j                  t          |j                  |j        ||j        ||	|j        t/          |j                  
  
        }|j        t          j        k    r|                    |           g|j        t          j        k    r|                    |           |                    |           |||fS )a&  
        Parse the node info from the cluster resource state.
        Args:
            state: the cluster resource state
        Returns:
            active_nodes: the list of non-idle nodes
            idle_nodes: the list of idle nodes
            dead_nodes: the list of dead nodes
        r   node_N)r   r   )
instance_type_namenode_statusr   
ip_addressr   r   r   failure_detailr   labels)rs  r   r   r   r   r  r'   rt  r   r   r   rq  r   r   ru  IDLEidle_duration_msr   rx  Namenode_ip_addressr   r   rm   r|  r_   )r   r2  r   
dead_nodesr   ri  r   r   node_resource_usager{  r   	node_infos               r7   rN  z ClusterStatusParser._parse_nodesz  s    

+ /	/ /	/J#J$677G:011Q66 &7W%6%6""%/%B" #'!N JO33 ">#M2266z5II&/u||~~..!(JO;; ",!<!<	' ' '# !#-#@&OJ,=>>%j&899%5#5&22-(6J-..  I  JO33!!),,,,"jo55!!),,,,##I....Z33r9   c           
         g }|j         D ]N}t          |j        |j        |j        t          j        j        |j                  }|                    |           Og }|j	        D ]Z}t          |j        |j        |j        t          j        j
        |j        |j        |j                  }|                    |           [||fS )aJ  
        Parse the launch requests from the autoscaling state.
        Args:
            state: the autoscaling state, empty if there's no autoscaling state
                being reported.
        Returns:
            pending_launches: the list of pending launches
            failed_launches: the list of failed launches
        )rx  r   r[   r2  r   )rx  r   r[   r2  r   r   failed_ts_s)pending_instance_requestsr   rx  r   r[   StatusPENDING
request_tsr_   failed_instance_requestsFAILEDstart_tsreason	failed_ts)r   r2  r  pending_requestr  r	  failed_requests          r7   rR  z*ClusterStatusParser._parse_launch_requests  s     $> 		, 		,O"#2#E#2#E%+#*2,7  F ##F++++#< 	+ 	+N"#1#D#1#D$*#*1+4&-*4  F ""6****00r9   c           
          g }|j         D ]B}|                    t          |j        |j        |j        |j        |j                             C|S )a  
        Parse the pending requests/nodes from the autoscaling state.
        Args:
            state: the autoscaling state, empty if there's no autoscaling state
                being reported.
        Returns:
            pending_nodes: the list of pending nodes
        )rx  r   r   r   rz  )pending_instancesr_   r   rx  r   r   r   rz  )r   r2  r  pending_nodes       r7   rP  z"ClusterStatusParser._parse_pending  sp     !3 		 		L  '3'F'3'F(0 , 8+6      r9   N)rJ   rK   rL   rI  r%   r    r   rV  rU  r$   r   r   rT  r)   r   r`  r&   r
   r   r   rq  rS  r   r   rN  r#   r   rR  rP  rE   r9   r7   rL  rL    s;       %
)%
27%
	%
 %
 %
 [%
N !6 u     [( 1
(1
	n	1
 1
 1
 [1
f 
'
 
$	%
 
 
 [
, "+/]0B+C	c= 	!   [B 5#5 
m	5 5 5 [5, A4#A4 
tH~tH~-	.A4 A4 A4 [A4F &1$&1	tM"D$77	8&1 &1 &1 [&1P #3 X    [  r9   rL  Ffetch_from_server
gcs_clientc                 f   t           j                                        r| sdS t          	| st          S |t	                      }|s
J d            |                    t           j        j                                        t           j        j	                                                  dk    at          S )a6  
    Check if the autoscaler is v2 from reading GCS internal KV.

    If the method is called multiple times, the result will be cached in the module.

    Args:
        fetch_from_server: If True, fetch the value from the GCS server, otherwise
            use the cached value.
        gcs_client: The GCS client to use. If not provided, the default GCS
            client will be used.

    Returns:
        is_v2: True if the autoscaler is v2, False otherwise.

    Raises:
        Exception: if GCS address could not be resolved (e.g. ray.init() not called)
    TNzGCS client is not available. Please initialize the global GCS client first by calling ray.init() or explicitly calls to _initialize_internal_kv().)	namespace   1)
ray_configenable_autoscaler_v2cached_is_autoscaler_v2r,   internal_kv_get_rayletGCS_AUTOSCALER_V2_ENABLED_KEYencodeGCS_AUTOSCALER_STATE_NAMESPACE)r  r  s     r7   is_autoscaler_v2r    s    * {'')) 2C 
 t *3D*&&/11
  	X : 	""K5<<>>k@GGII 	# 	
 	
 		  #"r9   ri  c                 .    dt          | j                  v S )z
    Check if the node is a head node from the node state.

    Args:
        node_state: the node state
    Returns:
        is_head: True if the node is a head node, False otherwise.
    znode:__internal_head__)rm   rl  )ri  s    r7   is_head_noder  7  s     $tJ,F'G'GGGr9   )FN)Dcollectionsr   r   copyr   r   enumr   	itertoolsr   typingr	   r
   r   r   r   r  ray._common.utilsr   ray._rayletr   ray.autoscaler._privater   ray.autoscaler._private.utilr   r   r   ray.autoscaler.v2.schemar   r   r   r   r   r   r   r   r   r   r   r   r    !ray.core.generated.autoscaler_pb2r!   r"   r#   r$   r%   r&   r'   r(   r)   r`   ray.core.generated.common_pb2r*   r+   ray.experimental.internal_kvr,   r   r2   r8   r;   rP   r   rL  r  rJ  r  r  rE   r9   r7   <module>r     s   , , , , , , , ,                         3 3 3 3 3 3 3 3 3 3 3 3 3 3 



 + + + + + + ! ! ! ! ! ! - - - - - -         
                                                            D C C C C CC c d38n     $A $A $A $A $A $A $A $ANx x x x x, x x xvP' P' P' P' P' P' P' P'f
E E E E E E E EP
   HL1# 1#1#19)1D1#	1# 1# 1# 1#hHY H4 H H H H H Hr9   