Skip to content

Commit

Permalink
io_loop: clear serialized frames on exit
Browse files Browse the repository at this point in the history
When we hit an error, we properly cleared these, but on the 'correct' exit path, we didn't.
Let's use the frames poison as error if any, or fallback to ConnectionClosed

Fixes #409

Signed-off-by: Marc-Antoine Perennou <[email protected]>
  • Loading branch information
Keruspe committed Jul 16, 2024
1 parent 77c2bea commit 39adb1d
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/frames.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ impl Frames {
pub(crate) fn clear_expected_replies(&self, channel_id: ChannelId, error: Error) {
self.inner.lock().clear_expected_replies(channel_id, error);
}

pub(crate) fn poison(&self) -> Option<Error> {
self.inner.lock().poison.clone()
}
}

#[derive(Default)]
Expand Down
11 changes: 10 additions & 1 deletion src/io_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ impl IoLoop {
}
}
self.heartbeat.cancel();
self.clear_serialized_frames(
self.frames.poison().unwrap_or_else(|| {
Error::InvalidConnectionState(ConnectionState::Closed)
}),
);
let internal_rpc = self.internal_rpc.clone();
if self.killswitch.killed() {
internal_rpc.register_internal_future(std::future::poll_fn(move |cx| {
Expand Down Expand Up @@ -247,12 +252,16 @@ impl IoLoop {
}
self.stop();
self.channels.set_connection_error(error.clone());
self.clear_serialized_frames(error.clone());
Err(error)
}

fn clear_serialized_frames(&mut self, error: Error) {
for (_, resolver) in std::mem::take(&mut self.serialized_frames) {
if let Some(resolver) = resolver {
resolver.swear(Err(error.clone()));
}
}
Err(error)
}

fn attempt_flush(&mut self, writable_context: &mut Context<'_>) -> Result<()> {
Expand Down

0 comments on commit 39adb1d

Please sign in to comment.