feat: don't block bot startup waiting to initialize vcs
This commit is contained in:
11
src/main.rs
11
src/main.rs
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user