Skip to content

Commit 4c4d11d

Browse files
committed
Send back leftover messages
1 parent 969754d commit 4c4d11d

File tree

2 files changed

+36
-9
lines changed

2 files changed

+36
-9
lines changed

iroh/src/magicsock/remote_map.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ pub(crate) struct RemoteMap {
6464
disco: DiscoState,
6565
sender: TransportsSender,
6666
discovery: ConcurrentDiscovery,
67-
actor_tasks: Mutex<JoinSet<Vec<RemoteStateMessage>>>,
67+
actor_tasks: Mutex<JoinSet<(EndpointId, Vec<RemoteStateMessage>)>>,
6868
}
6969

7070
impl RemoteMap {
@@ -105,7 +105,22 @@ impl RemoteMap {
105105
senders.retain(|_eid, sender| !sender.is_closed());
106106
while let Some(result) = self.actor_tasks.lock().expect("poisoned").try_join_next() {
107107
match result {
108-
Ok(leftover_msgs) => debug!(?leftover_msgs, "TODO: handle leftover messages"),
108+
Ok((eid, leftover_msgs)) => {
109+
let entry = senders.entry(eid);
110+
if leftover_msgs.is_empty() {
111+
match entry {
112+
hash_map::Entry::Occupied(occupied_entry) => occupied_entry.remove(),
113+
hash_map::Entry::Vacant(_) => {
114+
panic!("this should be impossible TODO(matheus23)");
115+
}
116+
};
117+
} else {
118+
// The remote actor got messages while it was closing, so we're restarting
119+
debug!(%eid, "restarting terminated remote state actor: messages received during shutdown");
120+
let sender = self.start_remote_state_actor(eid, leftover_msgs);
121+
entry.insert_entry(sender);
122+
}
123+
}
109124
Err(err) => {
110125
if let Ok(panic) = err.try_into_panic() {
111126
error!("RemoteStateActor panicked.");
@@ -126,7 +141,7 @@ impl RemoteMap {
126141
match handles.entry(eid) {
127142
hash_map::Entry::Occupied(entry) => entry.get().clone(),
128143
hash_map::Entry::Vacant(entry) => {
129-
let sender = self.start_remote_state_actor(eid);
144+
let sender = self.start_remote_state_actor(eid, vec![]);
130145
entry.insert(sender.clone());
131146
sender
132147
}
@@ -136,7 +151,11 @@ impl RemoteMap {
136151
/// Starts a new remote state actor and returns a handle and a sender.
137152
///
138153
/// The handle is not inserted into the endpoint map, this must be done by the caller of this function.
139-
fn start_remote_state_actor(&self, eid: EndpointId) -> mpsc::Sender<RemoteStateMessage> {
154+
fn start_remote_state_actor(
155+
&self,
156+
eid: EndpointId,
157+
initial_msgs: Vec<RemoteStateMessage>,
158+
) -> mpsc::Sender<RemoteStateMessage> {
140159
// Ensure there is a RemoteMappedAddr for this EndpointId.
141160
self.endpoint_mapped_addrs.get(&eid);
142161
RemoteStateActor::new(
@@ -149,7 +168,10 @@ impl RemoteMap {
149168
self.sender.clone(),
150169
self.discovery.clone(),
151170
)
152-
.start(self.actor_tasks.lock().expect("poisoned").deref_mut())
171+
.start(
172+
initial_msgs,
173+
self.actor_tasks.lock().expect("poisoned").deref_mut(),
174+
)
153175
}
154176

155177
pub(super) fn handle_ping(&self, msg: disco::Ping, sender: EndpointId, src: transports::Addr) {

iroh/src/magicsock/remote_map/remote_state.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,8 @@ impl RemoteStateActor {
210210

211211
pub(super) fn start(
212212
self,
213-
tasks: &mut JoinSet<Vec<RemoteStateMessage>>,
213+
initial_msgs: Vec<RemoteStateMessage>,
214+
tasks: &mut JoinSet<(EndpointId, Vec<RemoteStateMessage>)>,
214215
) -> mpsc::Sender<RemoteStateMessage> {
215216
let (tx, rx) = mpsc::channel(16);
216217
let me = self.local_endpoint_id;
@@ -221,7 +222,7 @@ impl RemoteStateActor {
221222
// we don't explicitly set a span we get the spans from whatever call happens to
222223
// first create the actor, which is often very confusing as it then keeps those
223224
// spans for all logging of the actor.
224-
tasks.spawn(self.run(rx).instrument(info_span!(
225+
tasks.spawn(self.run(initial_msgs, rx).instrument(info_span!(
225226
parent: None,
226227
"RemoteStateActor",
227228
me = %me.fmt_short(),
@@ -237,9 +238,13 @@ impl RemoteStateActor {
237238
/// discipline is needed to not turn pending for a long time.
238239
async fn run(
239240
mut self,
241+
initial_msgs: Vec<RemoteStateMessage>,
240242
mut inbox: mpsc::Receiver<RemoteStateMessage>,
241-
) -> Vec<RemoteStateMessage> {
243+
) -> (EndpointId, Vec<RemoteStateMessage>) {
242244
trace!("actor started");
245+
for msg in initial_msgs {
246+
self.handle_message(msg).await;
247+
}
243248
let idle_timeout = time::sleep(ACTOR_MAX_IDLE_TIMEOUT);
244249
n0_future::pin!(idle_timeout);
245250
let leftover_msgs = loop {
@@ -318,7 +323,7 @@ impl RemoteStateActor {
318323
};
319324

320325
trace!("actor terminating");
321-
leftover_msgs
326+
(self.endpoint_id, leftover_msgs)
322327
}
323328

324329
/// Handles an actor message.

0 commit comments

Comments
 (0)