feat: don't block bot startup waiting to initialize vcs

This commit is contained in:
2026-05-31 14:24:09 -04:00
parent f5b6dc5c76
commit 5e989289bd
2 changed files with 38 additions and 44 deletions

View File

@@ -285,14 +285,14 @@ async fn main() -> Result<(), MainError> {
let discord_opt_in_command_name = discord_opt_in_command.name.into();
let discord_opt_out_command_name = discord_opt_out_command.name.into();
let vcs = initialize_vcs(&discord_client).await;
let command_router = CommandRouter::from_iter(commands);
let command_router = Arc::new(command_router);
let discord_client = Arc::new(discord_client);
let songbird = Arc::new(songbird);
let vcs_sender = VCsSender::new(vcs);
let vcs_sender = VCsSender::new(Default::default());
let initializing_vcs = initialize_vcs(&vcs_sender, &discord_client);
let bot_data = bot_data.into_inner();
let recording_data = recording_data.into_inner();
@@ -327,7 +327,7 @@ async fn main() -> Result<(), MainError> {
cancellation_token: cancellation_token.clone(),
discord_application_id,
discord_bot_owner_user_id,
discord_client,
discord_client: discord_client.clone(),
discord_info_command_id,
discord_info_command_name,
discord_opt_in_command_id,
@@ -340,7 +340,7 @@ async fn main() -> Result<(), MainError> {
render_manager,
songbird,
user_manager,
vcs_sender,
vcs_sender: vcs_sender.clone(),
};
let heat_seeking = tokio::spawn(heat_seek(state.clone()));
@@ -394,6 +394,7 @@ async fn main() -> Result<(), MainError> {
});
let finished_naturally = async move {
initializing_vcs.await;
heat_seeking.await.unwrap();
run_shards.await;
};

View File

@@ -20,17 +20,19 @@ pub type VCsInGuild =
pub type VCs = BTreeMap<Id<GuildMarker>, VCsInGuild>;
pub type VCsSender = watch::Sender<VCs>;
#[tracing::instrument(skip(discord_client), ret)]
#[tracing::instrument(skip(vcs_sender, discord_client))]
async fn initialize_user_in_vc(
vcs_sender: &VCsSender,
discord_client: &twilight_http::Client,
guild_id: Id<GuildMarker>,
user_id: Id<UserMarker>,
) -> Option<(Id<ChannelMarker>, UserInVCData)> {
) {
if let Ok(voice_state_res) = discord_client.user_voice_state(guild_id, user_id).await
&& let Ok(voice_state) = voice_state_res.model().await
{
tracing::info!(?user_id, ?voice_state);
if let Some(voice_channel_id) = voice_state.channel_id {
let voice_status = VoiceStatus::builder()
.self_deafened(voice_state.self_deaf)
.self_muted(voice_state.self_mute)
@@ -41,55 +43,46 @@ async fn initialize_user_in_vc(
.build();
let user_in_vc_data = voice_status.into();
voice_state
.channel_id
.map(|channel_id| (channel_id, user_in_vc_data))
} else {
None // TODO
vcs_sender.send_modify(|vcs| {
vcs.entry(guild_id)
.or_default()
.insert(voice_channel_id, user_id, user_in_vc_data);
});
}
}
}
#[tracing::instrument(skip(discord_client), ret)]
#[tracing::instrument(skip(vcs_sender, discord_client))]
async fn initialize_server_vcs(
vcs_sender: &VCsSender,
discord_client: &twilight_http::Client,
id: Id<GuildMarker>,
) -> VCsInGuild {
) {
if let Ok(guild_members_res) = discord_client.guild_members(id).limit(999).await
&& let Ok(guild_members) = guild_members_res.model().await
{
FuturesUnordered::from_iter(guild_members.into_iter().map(|member| async move {
(
member.user.id,
initialize_user_in_vc(discord_client, id, member.user.id).await,
)
}))
.filter_map(
|(user_id, channel_id_and_user_in_vc_data_option)| async move {
channel_id_and_user_in_vc_data_option
.map(|(channel_id, user_in_vc_data)| (channel_id, user_id, user_in_vc_data))
},
FuturesUnordered::from_iter(
guild_members.into_iter().map(|member| {
initialize_user_in_vc(vcs_sender, discord_client, id, member.user.id)
}),
)
.collect()
.await
} else {
Default::default()
}
}
#[tracing::instrument(skip(discord_client), ret)]
pub async fn initialize_vcs(discord_client: &twilight_http::Client) -> VCs {
pub async fn initialize_vcs(vcs_sender: &VCsSender, discord_client: &twilight_http::Client) {
if let Ok(guilds_res) = discord_client.current_user_guilds().limit(200).await
&& let Ok(guilds) = guilds_res.model().await
{
FuturesUnordered::from_iter(guilds.into_iter().map(|guild| async move {
let guild_vcs = initialize_server_vcs(discord_client, guild.id).await;
(guild.id, guild_vcs)
}))
FuturesUnordered::from_iter(
guilds
.into_iter()
.map(|guild| initialize_server_vcs(vcs_sender, discord_client, guild.id)),
)
.collect()
.await
} else {
Default::default()
}
}