@@ -2177,7 +2177,7 @@ def _memoized_walk(obj, memo_attr: str, token, compute):
21772177 token=None means "uncacheable right now": recompute and drop the memo.
21782178 Callers must treat returned collections as immutable (they are shared).
21792179 """
2180- memo = getattr (obj , memo_attr )
2180+ memo = getattr (obj , memo_attr , None )
21812181 if token is not None and memo is not None and memo [0 ] == token :
21822182 return memo [1 ]
21832183 result = compute ()
@@ -2200,7 +2200,7 @@ def __init__(self, on_replica_state_change=None):
22002200
22012201 @property
22022202 def mutation_version (self ) -> int :
2203- return self . _mutation_version
2203+ return getattr ( self , " _mutation_version" , 0 )
22042204
22052205 def __getstate__ (self ):
22062206 # Exclude the callback to keep the container picklable (the callback
@@ -2224,7 +2224,7 @@ def add(self, state: ReplicaState, replica: DeploymentReplica):
22242224 self ._replicas [state ].append (replica )
22252225 self ._replica_id_index [replica .replica_id ] = replica
22262226 self ._sv_counts [(state , replica .version )] += 1
2227- self ._mutation_version += 1
2227+ self ._mutation_version = getattr ( self , "_mutation_version" , 0 ) + 1
22282228 if self ._on_replica_state_change and state != old_state :
22292229 self ._on_replica_state_change (old_state , state )
22302230
@@ -2323,7 +2323,7 @@ def pop(
23232323 self ._replica_id_index .pop (replica .replica_id , None )
23242324
23252325 if replicas :
2326- self ._mutation_version += 1
2326+ self ._mutation_version = getattr ( self , "_mutation_version" , 0 ) + 1
23272327 return replicas
23282328
23292329 def count (
@@ -2398,7 +2398,7 @@ def remove(self, replica_ids: Set[ReplicaID]) -> List[DeploymentReplica]:
23982398 if found_any :
23992399 self ._replicas [state ] = remaining
24002400 if removed :
2401- self ._mutation_version += 1
2401+ self ._mutation_version = getattr ( self , "_mutation_version" , 0 ) + 1
24022402 return removed
24032403
24042404 def __str__ (self ):
@@ -3368,20 +3368,20 @@ def get_alive_replica_actor_ids(self) -> Set[str]:
33683368 self ,
33693369 "_alive_replica_actor_ids_memo" ,
33703370 self ._membership_cache_token (),
3371- lambda : { replica .actor_id for replica in self ._replicas .get ()} ,
3371+ lambda : frozenset ( replica .actor_id for replica in self ._replicas .get ()) ,
33723372 )
33733373
33743374 def get_running_replica_ids (self ) -> List [ReplicaID ]:
33753375 return _memoized_walk (
33763376 self ,
33773377 "_running_replica_ids_memo" ,
33783378 self ._membership_cache_token (),
3379- lambda : [
3379+ lambda : tuple (
33803380 replica .replica_id
33813381 for replica in self ._replicas .get (
33823382 [ReplicaState .RUNNING , ReplicaState .PENDING_MIGRATION ]
33833383 )
3384- ] ,
3384+ ) ,
33853385 )
33863386
33873387 def get_running_replica_infos (self ) -> List [RunningReplicaInfo ]:
@@ -3438,11 +3438,11 @@ def get_active_node_ids(self) -> Set[str]:
34383438 self ,
34393439 "_active_node_ids_memo" ,
34403440 self ._membership_cache_token (),
3441- lambda : {
3441+ lambda : frozenset (
34423442 replica .actor_node_id
34433443 for replica in self ._replicas .get (active_states )
34443444 if replica .actor_node_id is not None
3445- } ,
3445+ ) ,
34463446 )
34473447
34483448 def list_replica_details (self ) -> List [ReplicaDetails ]:
@@ -5060,10 +5060,11 @@ def _maybe_check_rank_consistency(self) -> None:
50605060 ):
50615061 return
50625062 version = self ._replicas .mutation_version
5063- if version == self . _last_rank_membership_version :
5063+ if version == getattr ( self , " _last_rank_membership_version" , None ) :
50645064 return
50655065 active_replicas = self ._replicas .get ()
50665066 if not active_replicas :
5067+ self ._last_rank_membership_version = version
50675068 return
50685069 replicas_to_reconfigure = (
50695070 self ._rank_manager .check_rank_consistency_and_reassign_minimally (
0 commit comments