From c6aa8e5d13681662c658c5a7eef220b93d431104 Mon Sep 17 00:00:00 2001 From: Jacob Date: Fri, 29 May 2026 22:22:15 -0400 Subject: [PATCH] fix: scope borrow in heat seeking to try to prevent deadlock --- src/heat_seek.rs | 85 +++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/src/heat_seek.rs b/src/heat_seek.rs index ece7319..bd4a69a 100644 --- a/src/heat_seek.rs +++ b/src/heat_seek.rs @@ -30,48 +30,53 @@ pub async fn heat_seek(state: State) { let mut vcs_in_guild_senders = BTreeMap::default(); loop { - for (&guild_id, vcs_in_guild) in &*vcs_watcher.borrow() { - let vcs_in_guild_sender = vcs_in_guild_senders.entry(guild_id).or_insert_with(|| { - let (vcs_in_guild_sender, vcs_in_guild_watcher) = - watch::channel(Default::default()); - let (channel_heat_sender, channel_heat_watcher) = - watch::channel(Default::default()); - let (heat_map_sender, heat_map_watcher) = watch::channel(Default::default()); - let (hottest_vc_sender, hottest_vc_watcher) = watch::channel(Default::default()); + { + for (&guild_id, vcs_in_guild) in &*vcs_watcher.borrow() { + let vcs_in_guild_sender = + vcs_in_guild_senders.entry(guild_id).or_insert_with(|| { + let (vcs_in_guild_sender, vcs_in_guild_watcher) = + watch::channel(Default::default()); + let (channel_heat_sender, channel_heat_watcher) = + watch::channel(Default::default()); + let (heat_map_sender, heat_map_watcher) = + watch::channel(Default::default()); + let (hottest_vc_sender, hottest_vc_watcher) = + watch::channel(Default::default()); - tokio::spawn( - evaluate_heat() - .bot_manager(state.bot_manager.clone()) - .bot_owner_user_id(state.discord_bot_owner_user_id) - .bot_user_id(state.discord_user_id) - .cancellation_token(state.cancellation_token.clone()) - .channel_heat_sender(channel_heat_sender) - .vcs_in_guild_watcher(vcs_in_guild_watcher) - .call(), - ); - tokio::spawn( - map_heat() - .cancellation_token(state.cancellation_token.clone()) - .channel_heat_watcher(channel_heat_watcher) - .heat_map_sender(heat_map_sender) - .call(), - ); - tokio::spawn( - track_hottest_vc() - .cancellation_token(state.cancellation_token.clone()) - .heat_map_watcher(heat_map_watcher) - .hottest_vc_sender(hottest_vc_sender) - .call(), - ); - tokio::spawn(follow_hottest_vc( - state.clone(), - guild_id, - hottest_vc_watcher, - )); + tokio::spawn( + evaluate_heat() + .bot_manager(state.bot_manager.clone()) + .bot_owner_user_id(state.discord_bot_owner_user_id) + .bot_user_id(state.discord_user_id) + .cancellation_token(state.cancellation_token.clone()) + .channel_heat_sender(channel_heat_sender) + .vcs_in_guild_watcher(vcs_in_guild_watcher) + .call(), + ); + tokio::spawn( + map_heat() + .cancellation_token(state.cancellation_token.clone()) + .channel_heat_watcher(channel_heat_watcher) + .heat_map_sender(heat_map_sender) + .call(), + ); + tokio::spawn( + track_hottest_vc() + .cancellation_token(state.cancellation_token.clone()) + .heat_map_watcher(heat_map_watcher) + .hottest_vc_sender(hottest_vc_sender) + .call(), + ); + tokio::spawn(follow_hottest_vc( + state.clone(), + guild_id, + hottest_vc_watcher, + )); - vcs_in_guild_sender - }); - vcs_in_guild_sender.send_replace(Arc::new(vcs_in_guild.clone())); + vcs_in_guild_sender + }); + vcs_in_guild_sender.send_replace(Arc::new(vcs_in_guild.clone())); + } } if matches!(