Skip to content

Commit 5c66034

Browse files
committed
Send back leftover messages
1 parent fbb053c commit 5c66034

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
@@ -62,7 +62,7 @@ pub(crate) struct RemoteMap {
6262
local_addrs: n0_watcher::Direct<BTreeSet<DirectAddr>>,
6363
disco: DiscoState,
6464
sender: TransportsSender,
65-
actor_tasks: Mutex<JoinSet<Vec<RemoteStateMessage>>>,
65+
actor_tasks: Mutex<JoinSet<(EndpointId, Vec<RemoteStateMessage>)>>,
6666
}
6767

6868
impl RemoteMap {
@@ -118,7 +118,22 @@ impl RemoteMap {
118118
senders.retain(|_eid, sender| !sender.is_closed());
119119
while let Some(result) = self.actor_tasks.lock().expect("poisoned").try_join_next() {
120120
match result {
121-
Ok(leftover_msgs) => debug!(?leftover_msgs, "TODO: handle leftover messages"),
121+
Ok((eid, leftover_msgs)) => {
122+
let entry = senders.entry(eid);
123+
if leftover_msgs.is_empty() {
124+
match entry {
125+
hash_map::Entry::Occupied(occupied_entry) => occupied_entry.remove(),
126+
hash_map::Entry::Vacant(_) => {
127+
panic!("this should be impossible TODO(matheus23)");
128+
}
129+
};
130+
} else {
131+
// The remote actor got messages while it was closing, so we're restarting
132+
debug!(%eid, "restarting terminated remote state actor: messages received during shutdown");
133+
let sender = self.start_remote_state_actor(eid, leftover_msgs);
134+
entry.insert_entry(sender);
135+
}
136+
}
122137
Err(err) => {
123138
if let Ok(panic) = err.try_into_panic() {
124139
error!("RemoteStateActor panicked.");
@@ -139,7 +154,7 @@ impl RemoteMap {
139154
match handles.entry(eid) {
140155
hash_map::Entry::Occupied(entry) => entry.get().clone(),
141156
hash_map::Entry::Vacant(entry) => {
142-
let sender = self.start_remote_state_actor(eid);
157+
let sender = self.start_remote_state_actor(eid, vec![]);
143158
entry.insert(sender.clone());
144159
sender
145160
}
@@ -149,7 +164,11 @@ impl RemoteMap {
149164
/// Starts a new remote state actor and returns a handle and a sender.
150165
///
151166
/// The handle is not inserted into the endpoint map, this must be done by the caller of this function.
152-
fn start_remote_state_actor(&self, eid: EndpointId) -> mpsc::Sender<RemoteStateMessage> {
167+
fn start_remote_state_actor(
168+
&self,
169+
eid: EndpointId,
170+
initial_msgs: Vec<RemoteStateMessage>,
171+
) -> mpsc::Sender<RemoteStateMessage> {
153172
// Ensure there is a RemoteMappedAddr for this EndpointId.
154173
self.endpoint_mapped_addrs.get(&eid);
155174
RemoteStateActor::new(
@@ -161,7 +180,10 @@ impl RemoteMap {
161180
self.metrics.clone(),
162181
self.sender.clone(),
163182
)
164-
.start(self.actor_tasks.lock().expect("poisoned").deref_mut())
183+
.start(
184+
initial_msgs,
185+
self.actor_tasks.lock().expect("poisoned").deref_mut(),
186+
)
165187
}
166188

167189
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
@@ -183,7 +183,8 @@ impl RemoteStateActor {
183183

184184
pub(super) fn start(
185185
self,
186-
tasks: &mut JoinSet<Vec<RemoteStateMessage>>,
186+
initial_msgs: Vec<RemoteStateMessage>,
187+
tasks: &mut JoinSet<(EndpointId, Vec<RemoteStateMessage>)>,
187188
) -> mpsc::Sender<RemoteStateMessage> {
188189
let (tx, rx) = mpsc::channel(16);
189190
let me = self.local_endpoint_id;
@@ -194,7 +195,7 @@ impl RemoteStateActor {
194195
// we don't explicitly set a span we get the spans from whatever call happens to
195196
// first create the actor, which is often very confusing as it then keeps those
196197
// spans for all logging of the actor.
197-
tasks.spawn(self.run(rx).instrument(info_span!(
198+
tasks.spawn(self.run(initial_msgs, rx).instrument(info_span!(
198199
parent: None,
199200
"RemoteStateActor",
200201
me = %me.fmt_short(),
@@ -210,9 +211,13 @@ impl RemoteStateActor {
210211
/// discipline is needed to not turn pending for a long time.
211212
async fn run(
212213
mut self,
214+
initial_msgs: Vec<RemoteStateMessage>,
213215
mut inbox: mpsc::Receiver<RemoteStateMessage>,
214-
) -> Vec<RemoteStateMessage> {
216+
) -> (EndpointId, Vec<RemoteStateMessage>) {
215217
trace!("actor started");
218+
for msg in initial_msgs {
219+
self.handle_message(msg).await;
220+
}
216221
let idle_timeout = time::sleep(ACTOR_MAX_IDLE_TIMEOUT);
217222
n0_future::pin!(idle_timeout);
218223
let leftover_msgs = loop {
@@ -284,7 +289,7 @@ impl RemoteStateActor {
284289
};
285290

286291
trace!("actor terminating");
287-
leftover_msgs
292+
(self.endpoint_id, leftover_msgs)
288293
}
289294

290295
/// Handles an actor message.

0 commit comments

Comments
 (0)