From 7c326e003e2cfa94daa842eeaa00956601bdad50 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sat, 20 Sep 2025 12:35:32 +0000 Subject: [PATCH] fix(connlib): fuse event-loop future inside client session (#10399) A `Future` in Rust should not be polled once it has been completed as that may lead to panics or otherwise undesirable behaviour. To avoid this, a `Future` can be `fuse`d which will make it return `Poll::Pending` indefinitely after it has returned `Ready`. We have received several Sentry alerts of poll-after-completion panics that I believe are all stemming from this particular code. --- rust/client-shared/src/lib.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rust/client-shared/src/lib.rs b/rust/client-shared/src/lib.rs index cdc0f1ee5..6804a7379 100644 --- a/rust/client-shared/src/lib.rs +++ b/rust/client-shared/src/lib.rs @@ -8,6 +8,7 @@ pub use firezone_tunnel::messages::client::{IngressMessages, ResourceDescription use anyhow::Result; use connlib_model::{ResourceId, ResourceView}; use eventloop::{Command, Eventloop}; +use futures::future::Fuse; use futures::{FutureExt, StreamExt}; use phoenix_channel::{PhoenixChannel, PublicKeyParam}; use socket_factory::{SocketFactory, TcpSocket, UdpSocket}; @@ -38,7 +39,7 @@ pub struct Session { #[derive(Debug)] pub struct EventStream { - eventloop: JoinHandle>, + eventloop: Fuse>>, resource_list_receiver: WatchStream>, tun_config_receiver: WatchStream>, } @@ -81,7 +82,7 @@ impl Session { ( Self { channel: cmd_tx }, EventStream { - eventloop, + eventloop: eventloop.fuse(), resource_list_receiver: WatchStream::from_changes(resource_list_receiver), tun_config_receiver: WatchStream::from_changes(tun_config_receiver), },