Skip to content

Commit de05f27

Browse files
committed
Send back leftover messages
1 parent 3a8c0af commit de05f27

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
@@ -63,7 +63,7 @@ pub(crate) struct RemoteMap {
6363
disco: DiscoState,
6464
sender: TransportsSender,
6565
discovery: ConcurrentDiscovery,
66-
actor_tasks: Mutex<JoinSet<Vec<RemoteStateMessage>>>,
66+
actor_tasks: Mutex<JoinSet<(EndpointId, Vec<RemoteStateMessage>)>>,
6767
}
6868

6969
impl RemoteMap {
@@ -104,7 +104,22 @@ impl RemoteMap {
104104
senders.retain(|_eid, sender| !sender.is_closed());
105105
while let Some(result) = self.actor_tasks.lock().expect("poisoned").try_join_next() {
106106
match result {
107-
Ok(leftover_msgs) => debug!(?leftover_msgs, "TODO: handle leftover messages"),
107+
Ok((eid, leftover_msgs)) => {
108+
let entry = senders.entry(eid);
109+
if leftover_msgs.is_empty() {
110+
match entry {
111+
hash_map::Entry::Occupied(occupied_entry) => occupied_entry.remove(),
112+
hash_map::Entry::Vacant(_) => {
113+
panic!("this should be impossible TODO(matheus23)");
114+
}
115+
};
116+
} else {
117+
// The remote actor got messages while it was closing, so we're restarting
118+
debug!(%eid, "restarting terminated remote state actor: messages received during shutdown");
119+
let sender = self.start_remote_state_actor(eid, leftover_msgs);
120+
entry.insert_entry(sender);
121+
}
122+
}
108123
Err(err) => {
109124
if let Ok(panic) = err.try_into_panic() {
110125
error!("RemoteStateActor panicked.");
@@ -125,7 +140,7 @@ impl RemoteMap {
125140
match handles.entry(eid) {
126141
hash_map::Entry::Occupied(entry) => entry.get().clone(),
127142
hash_map::Entry::Vacant(entry) => {
128-
let sender = self.start_remote_state_actor(eid);
143+
let sender = self.start_remote_state_actor(eid, vec![]);
129144
entry.insert(sender.clone());
130145
sender
131146
}
@@ -135,7 +150,11 @@ impl RemoteMap {
135150
/// Starts a new remote state actor and returns a handle and a sender.
136151
///
137152
/// The handle is not inserted into the endpoint map, this must be done by the caller of this function.
138-
fn start_remote_state_actor(&self, eid: EndpointId) -> mpsc::Sender<RemoteStateMessage> {
153+
fn start_remote_state_actor(
154+
&self,
155+
eid: EndpointId,
156+
initial_msgs: Vec<RemoteStateMessage>,
157+
) -> mpsc::Sender<RemoteStateMessage> {
139158
// Ensure there is a RemoteMappedAddr for this EndpointId.
140159
self.endpoint_mapped_addrs.get(&eid);
141160
RemoteStateActor::new(
@@ -148,7 +167,10 @@ impl RemoteMap {
148167
self.sender.clone(),
149168
self.discovery.clone(),
150169
)
151-
.start(self.actor_tasks.lock().expect("poisoned").deref_mut())
170+
.start(
171+
initial_msgs,
172+
self.actor_tasks.lock().expect("poisoned").deref_mut(),
173+
)
152174
}
153175

154176
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
@@ -208,7 +208,8 @@ impl RemoteStateActor {
208208

209209
pub(super) fn start(
210210
self,
211-
tasks: &mut JoinSet<Vec<RemoteStateMessage>>,
211+
initial_msgs: Vec<RemoteStateMessage>,
212+
tasks: &mut JoinSet<(EndpointId, Vec<RemoteStateMessage>)>,
212213
) -> mpsc::Sender<RemoteStateMessage> {
213214
let (tx, rx) = mpsc::channel(16);
214215
let me = self.local_endpoint_id;
@@ -219,7 +220,7 @@ impl RemoteStateActor {
219220
// we don't explicitly set a span we get the spans from whatever call happens to
220221
// first create the actor, which is often very confusing as it then keeps those
221222
// spans for all logging of the actor.
222-
tasks.spawn(self.run(rx).instrument(info_span!(
223+
tasks.spawn(self.run(initial_msgs, rx).instrument(info_span!(
223224
parent: None,
224225
"RemoteStateActor",
225226
me = %me.fmt_short(),
@@ -235,9 +236,13 @@ impl RemoteStateActor {
235236
/// discipline is needed to not turn pending for a long time.
236237
async fn run(
237238
mut self,
239+
initial_msgs: Vec<RemoteStateMessage>,
238240
mut inbox: mpsc::Receiver<RemoteStateMessage>,
239-
) -> Vec<RemoteStateMessage> {
241+
) -> (EndpointId, Vec<RemoteStateMessage>) {
240242
trace!("actor started");
243+
for msg in initial_msgs {
244+
self.handle_message(msg).await;
245+
}
241246
let idle_timeout = time::sleep(ACTOR_MAX_IDLE_TIMEOUT);
242247
n0_future::pin!(idle_timeout);
243248
let leftover_msgs = loop {
@@ -312,7 +317,7 @@ impl RemoteStateActor {
312317
};
313318

314319
trace!("actor terminating");
315-
leftover_msgs
320+
(self.endpoint_id, leftover_msgs)
316321
}
317322

318323
/// Handles an actor message.

0 commit comments

Comments
 (0)