@@ -149,15 +149,17 @@ impl Registry {
149149 ) -> ( String , u64 ) {
150150 let connection_id = self . next_connection_id . fetch_add ( 1 , Ordering :: Relaxed ) + 1 ;
151151
152- // Disambiguate duplicate names using the unique connection ID.
153- let peers = self . peers . load ( ) ;
154- let peer_id = if peers. contains_key ( & id) {
155- let disambiguated = format ! ( "{id}#{connection_id}" ) ;
156- tracing:: info!( "Peer name {id:?} already registered, using {disambiguated:?}" ) ;
157- disambiguated
158- } else {
159- id. clone ( )
160- } ;
152+ // If a peer with the same name already exists, evict it — the new
153+ // connection supersedes the old one (reconnect scenario). Send a
154+ // Disconnect so the old transport closes cleanly.
155+ if self . peers . load ( ) . contains_key ( & id) {
156+ tracing:: info!( "Peer {id:?} reconnected, replacing existing entry" ) ;
157+ self . send_disconnect ( & id, "superseded by new connection" ) ;
158+ // Remove from peers map; the old session task will notice its
159+ // control channel closed and clean up.
160+ self . unregister ( & id) ;
161+ }
162+ let peer_id = id. clone ( ) ;
161163
162164 let info = PeerInfo {
163165 id : peer_id. clone ( ) ,
@@ -503,21 +505,16 @@ mod tests {
503505 ) ;
504506 assert_eq ! ( id1, "peer1" ) ;
505507
508+ // Re-register same name — old entry is evicted, new one takes the name.
506509 let ( id2, _) = registry. register (
507510 "peer1" . into ( ) ,
508511 "1.2.3.4:9999" . into ( ) ,
509512 NodeRole :: Exit ,
510513 ConnectionSide :: Accept ,
511514 ) ;
512- assert ! (
513- id2. starts_with( "peer1#" ) ,
514- "expected disambiguated id, got {id2}"
515- ) ;
516- assert_eq ! ( registry. count( ) , 2 ) ;
515+ assert_eq ! ( id2, "peer1" , "reconnect should reuse the name" ) ;
516+ assert_eq ! ( registry. count( ) , 1 , "old entry should be evicted" ) ;
517517
518- // Both are independently unregisterable.
519- registry. unregister ( & id1) ;
520- assert_eq ! ( registry. count( ) , 1 ) ;
521518 registry. unregister ( & id2) ;
522519 assert_eq ! ( registry. count( ) , 0 ) ;
523520 }
@@ -542,19 +539,20 @@ mod tests {
542539 ConnectionSide :: Accept ,
543540 ) ;
544541 assert_eq ! ( peer_id1, "peer1" ) ;
545- // Re-register same peer — now disambiguated as "peer1#N" .
542+ // Re-register same peer — old entry is evicted, new one takes the name .
546543 let ( peer_id2, gen2) = registry. register (
547544 "peer1" . into ( ) ,
548545 "1.2.3.4:9999" . into ( ) ,
549546 NodeRole :: Exit ,
550547 ConnectionSide :: Accept ,
551548 ) ;
549+ assert_eq ! ( peer_id2, "peer1" ) ;
552550 assert_ne ! ( gen1, gen2) ;
553- assert_eq ! ( registry. count( ) , 2 ) ;
551+ assert_eq ! ( registry. count( ) , 1 ) ;
554552
555- // Old task unregisters with stale connection_id on the original key — should succeed
556- // since the original "peer1" entry still exists .
557- assert ! ( registry. unregister_if_current( & peer_id1, gen1) . is_some ( ) ) ;
553+ // Old task tries to unregister with stale connection_id — should be a no-op
554+ // since the entry now belongs to the new connection .
555+ assert ! ( registry. unregister_if_current( & peer_id1, gen1) . is_none ( ) ) ;
558556 assert_eq ! ( registry. count( ) , 1 ) ;
559557
560558 // New task unregisters with current connection_id — should succeed.
0 commit comments