@@ -2,20 +2,22 @@ use std::{
22 collections:: { BTreeSet , hash_map} ,
33 hash:: Hash ,
44 net:: { IpAddr , SocketAddr } ,
5+ ops:: DerefMut ,
56 sync:: { Arc , Mutex } ,
67 time:: Duration ,
78} ;
89
9- use iroh_base:: { EndpointId , RelayUrl } ;
10+ use iroh_base:: { EndpointAddr , EndpointId , RelayUrl } ;
11+ use n0_future:: task:: JoinSet ;
1012use rustc_hash:: FxHashMap ;
1113use serde:: { Deserialize , Serialize } ;
1214use tokio:: sync:: mpsc;
13- use tracing:: warn;
15+ use tracing:: { debug , error , warn} ;
1416
1517pub ( crate ) use self :: remote_state:: PathsWatcher ;
18+ use self :: remote_state:: RemoteStateActor ;
1619pub ( super ) use self :: remote_state:: RemoteStateMessage ;
1720pub use self :: remote_state:: { PathInfo , PathInfoList } ;
18- use self :: remote_state:: { RemoteStateActor , RemoteStateHandle } ;
1921use super :: {
2022 DirectAddr , DiscoState , MagicsockMetrics ,
2123 mapped_addrs:: { AddrMap , EndpointIdMappedAddr , RelayMappedAddr } ,
@@ -45,7 +47,7 @@ pub(crate) struct RemoteMap {
4547 // State we keep about remote endpoints.
4648 //
4749 /// The actors tracking each remote endpoint.
48- actor_handles : Mutex < FxHashMap < EndpointId , RemoteStateHandle > > ,
50+ actor_senders : Mutex < FxHashMap < EndpointId , GuardedSender < RemoteStateMessage > > > ,
4951 /// The mapping between [`EndpointId`]s and [`EndpointIdMappedAddr`]s.
5052 pub ( super ) endpoint_mapped_addrs : AddrMap < EndpointId , EndpointIdMappedAddr > ,
5153 /// The mapping between endpoints via a relay and their [`RelayMappedAddr`]s.
@@ -61,6 +63,7 @@ pub(crate) struct RemoteMap {
6163 disco : DiscoState ,
6264 sender : TransportsSender ,
6365 discovery : ConcurrentDiscovery ,
66+ actor_tasks : Mutex < JoinSet < Vec < RemoteStateMessage > > > ,
6467}
6568
6669impl RemoteMap {
@@ -75,7 +78,7 @@ impl RemoteMap {
7578 discovery : ConcurrentDiscovery ,
7679 ) -> Self {
7780 Self {
78- actor_handles : Mutex :: new ( FxHashMap :: default ( ) ) ,
81+ actor_senders : Mutex :: new ( FxHashMap :: default ( ) ) ,
7982 endpoint_mapped_addrs : Default :: default ( ) ,
8083 relay_mapped_addrs : Default :: default ( ) ,
8184 local_endpoint_id,
@@ -84,6 +87,7 @@ impl RemoteMap {
8487 disco,
8588 sender,
8689 discovery,
90+ actor_tasks : Default :: default ( ) ,
8791 }
8892 }
8993
@@ -96,8 +100,19 @@ impl RemoteMap {
96100 /// This should be called periodically to remove handles to endpoint state actors
97101 /// that have shutdown after their idle timeout expired.
98102 pub ( super ) fn remove_closed_remote_state_actors ( & self ) {
99- let mut handles = self . actor_handles . lock ( ) . expect ( "poisoned" ) ;
100- handles. retain ( |_eid, handle| !handle. sender . is_closed ( ) )
103+ let mut senders = self . actor_senders . lock ( ) . expect ( "poisoned" ) ;
104+ senders. retain ( |_eid, sender| !sender. is_closed ( ) ) ;
105+ while let Some ( result) = self . actor_tasks . lock ( ) . expect ( "poisoned" ) . try_join_next ( ) {
106+ match result {
107+ Ok ( leftover_msgs) => debug ! ( ?leftover_msgs, "TODO: handle leftover messages" ) ,
108+ Err ( err) => {
109+ if let Ok ( panic) = err. try_into_panic ( ) {
110+ error ! ( "RemoteStateActor panicked." ) ;
111+ std:: panic:: resume_unwind ( panic) ;
112+ }
113+ }
114+ }
115+ }
101116 }
102117
103118 /// Returns the sender for the [`RemoteStateActor`].
@@ -106,10 +121,10 @@ impl RemoteMap {
106121 ///
107122 /// [`RemoteStateActor`]: remote_state::RemoteStateActor
108123 pub ( super ) fn remote_state_actor ( & self , eid : EndpointId ) -> mpsc:: Sender < RemoteStateMessage > {
109- let mut handles = self . actor_handles . lock ( ) . expect ( "poisoned" ) ;
124+ let mut handles = self . actor_senders . lock ( ) . expect ( "poisoned" ) ;
110125 match handles. entry ( eid) {
111126 hash_map:: Entry :: Occupied ( mut entry) => {
112- if let Some ( sender) = entry. get ( ) . sender . get ( ) {
127+ if let Some ( sender) = entry. get ( ) . get ( ) {
113128 sender
114129 } else {
115130 // The actor is dead: Start a new actor.
@@ -132,10 +147,13 @@ impl RemoteMap {
132147 fn start_remote_state_actor (
133148 & self ,
134149 eid : EndpointId ,
135- ) -> ( RemoteStateHandle , mpsc:: Sender < RemoteStateMessage > ) {
150+ ) -> (
151+ GuardedSender < RemoteStateMessage > ,
152+ mpsc:: Sender < RemoteStateMessage > ,
153+ ) {
136154 // Ensure there is a RemoteMappedAddr for this EndpointId.
137155 self . endpoint_mapped_addrs . get ( & eid) ;
138- let handle = RemoteStateActor :: new (
156+ let sender = RemoteStateActor :: new (
139157 eid,
140158 self . local_endpoint_id ,
141159 self . local_addrs . clone ( ) ,
@@ -145,9 +163,9 @@ impl RemoteMap {
145163 self . sender . clone ( ) ,
146164 self . discovery . clone ( ) ,
147165 )
148- . start ( ) ;
149- let sender = handle . sender . get ( ) . expect ( "just created" ) ;
150- ( handle , sender )
166+ . start ( self . actor_tasks . lock ( ) . expect ( "poisoned" ) . deref_mut ( ) ) ;
167+ let tx = sender. get ( ) . expect ( "just created" ) ;
168+ ( sender , tx )
151169 }
152170
153171 pub ( super ) fn handle_ping ( & self , msg : disco:: Ping , sender : EndpointId , src : transports:: Addr ) {
0 commit comments