From 7c9f561d2236b430f143e4502036ba066ca852e6 Mon Sep 17 00:00:00 2001 From: Michel de Graaf Date: Thu, 10 Sep 2026 14:28:04 +0200 Subject: [PATCH] fix(client): record a watch before the server can answer it watch_user sent the request and only then recorded the watch. The server's answer is applied on the ops thread, so a reply that got there first saw nothing to drop for a user who does not exist, and the add that followed left that user watched for good. The lock is now taken before the send and held until the watch is recorded, so the answer always lands on it; a send that fails still records nothing. --- soulseek-rs-lib/src/client/rooms.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/soulseek-rs-lib/src/client/rooms.rs b/soulseek-rs-lib/src/client/rooms.rs index d11da0c..671ff53 100644 --- a/soulseek-rs-lib/src/client/rooms.rs +++ b/soulseek-rs-lib/src/client/rooms.rs @@ -150,8 +150,11 @@ impl Client { /// Returns [`SoulseekRs::NotConnected`] if the client is not connected. pub fn watch_user(&self, username: &str) -> Result<()> { use crate::message::server::MessageFactory; + // Held across the send: the reply is applied under this lock, so it + // cannot land first and have its "does not exist" undone by the add. + let mut context = self.context.write_safe()?; self.send_server_message(MessageFactory::build_watch_user(username))?; - self.context.write_safe()?.add_watched_user(username); + context.add_watched_user(username); Ok(()) }