diff --git a/Cargo.lock b/Cargo.lock index 716b6ee..0f15e2f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1783,6 +1783,7 @@ dependencies = [ "opendal", "opus2", "patricia_tree 0.10.1", + "rayon", "rhai", "rustls 0.23.40", "secrecy 0.10.3", diff --git a/Cargo.toml b/Cargo.toml index 830806b..53d6b0d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,6 +56,7 @@ opendal = { git = "https://github.com/apache/opendal", rev = "ecf840b04afd2be109 ] } opus2 = "0.4.0" patricia_tree = "0.10.1" +rayon = "1.12" rhai = { version = "1.23.6", features = ["sync"] } rustls = "0.23" secrecy = { version = "0.10.3", features = ["serde"] } diff --git a/src/main.rs b/src/main.rs index c83741b..8500bbd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use fomo_reducer::{ RecordingManager, RenderManager, State, Storage, UserManager, VCsSender, all_commands, command, heat_seek, initialize_vcs, update_vcs, }; +use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use secrecy::{ExposeSecret, SecretString}; use snafu::{OptionExt, ResultExt, Snafu}; use songbird::{Config, Songbird, driver::DecodeConfig, shards::TwilightMap}; @@ -342,14 +343,36 @@ async fn main() -> Result<(), MainError> { let (mut watchdog_tx, mut watchdog_rx) = futures::channel::mpsc::channel(watchdog_channel_size.get()); - std::thread::spawn(move || { - loop { - if watchdog_tx.try_send(()).is_err() { - tracing::error!("tokio runtime deadlocked"); - std::process::exit(1); - } + std::thread::spawn({ + let discord_voice_channel_corresponding_text_channel = + discord_voice_channel_corresponding_text_channel.clone(); + let discord_client = discord_client.clone(); + let vcs_watcher = vcs_sender.subscribe(); - std::thread::sleep(watchdog_frequency); + move || { + loop { + if watchdog_tx.try_send(()).is_err() { + tracing::error!("tokio runtime deadlocked"); + + vcs_watcher.borrow().par_iter().for_each(|(&guild_id, vcs_in_guild)| { + if let Some(&voice_channel_id) = vcs_in_guild.get_left_for(&discord_user_id) { + let text_channel_id = + discord_voice_channel_corresponding_text_channel + .get(&guild_id) + .and_then(|guild_mappings| { + guild_mappings.get_right_for(&voice_channel_id).copied() + }) + .unwrap_or(voice_channel_id); + + let _ = futures::executor::block_on(discord_client.create_message(text_channel_id).content("so sorry I died, I'm in purgatory now, I don't like it here.\nbut I will be back in 5-20 minutes (even if it says I'm still there, I'm not currently recording and will be disconnected soon before later reconnecting and announcing recording again)").into_future()); + } + }); + + std::process::exit(1); + } + + std::thread::sleep(watchdog_frequency); + } } });