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_in_command_name = discord_opt_in_command.name.into();
|
||||||
let discord_opt_out_command_name = discord_opt_out_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 = CommandRouter::from_iter(commands);
|
||||||
let command_router = Arc::new(command_router);
|
let command_router = Arc::new(command_router);
|
||||||
|
|
||||||
let discord_client = Arc::new(discord_client);
|
let discord_client = Arc::new(discord_client);
|
||||||
let songbird = Arc::new(songbird);
|
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 bot_data = bot_data.into_inner();
|
||||||
let recording_data = recording_data.into_inner();
|
let recording_data = recording_data.into_inner();
|
||||||
@@ -327,7 +327,7 @@ async fn main() -> Result<(), MainError> {
|
|||||||
cancellation_token: cancellation_token.clone(),
|
cancellation_token: cancellation_token.clone(),
|
||||||
discord_application_id,
|
discord_application_id,
|
||||||
discord_bot_owner_user_id,
|
discord_bot_owner_user_id,
|
||||||
discord_client,
|
discord_client: discord_client.clone(),
|
||||||
discord_info_command_id,
|
discord_info_command_id,
|
||||||
discord_info_command_name,
|
discord_info_command_name,
|
||||||
discord_opt_in_command_id,
|
discord_opt_in_command_id,
|
||||||
@@ -340,7 +340,7 @@ async fn main() -> Result<(), MainError> {
|
|||||||
render_manager,
|
render_manager,
|
||||||
songbird,
|
songbird,
|
||||||
user_manager,
|
user_manager,
|
||||||
vcs_sender,
|
vcs_sender: vcs_sender.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let heat_seeking = tokio::spawn(heat_seek(state.clone()));
|
let heat_seeking = tokio::spawn(heat_seek(state.clone()));
|
||||||
@@ -394,6 +394,7 @@ async fn main() -> Result<(), MainError> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let finished_naturally = async move {
|
let finished_naturally = async move {
|
||||||
|
initializing_vcs.await;
|
||||||
heat_seeking.await.unwrap();
|
heat_seeking.await.unwrap();
|
||||||
run_shards.await;
|
run_shards.await;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,17 +20,19 @@ pub type VCsInGuild =
|
|||||||
pub type VCs = BTreeMap<Id<GuildMarker>, VCsInGuild>;
|
pub type VCs = BTreeMap<Id<GuildMarker>, VCsInGuild>;
|
||||||
pub type VCsSender = watch::Sender<VCs>;
|
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(
|
async fn initialize_user_in_vc(
|
||||||
|
vcs_sender: &VCsSender,
|
||||||
discord_client: &twilight_http::Client,
|
discord_client: &twilight_http::Client,
|
||||||
guild_id: Id<GuildMarker>,
|
guild_id: Id<GuildMarker>,
|
||||||
user_id: Id<UserMarker>,
|
user_id: Id<UserMarker>,
|
||||||
) -> Option<(Id<ChannelMarker>, UserInVCData)> {
|
) {
|
||||||
if let Ok(voice_state_res) = discord_client.user_voice_state(guild_id, user_id).await
|
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
|
&& let Ok(voice_state) = voice_state_res.model().await
|
||||||
{
|
{
|
||||||
tracing::info!(?user_id, ?voice_state);
|
tracing::info!(?user_id, ?voice_state);
|
||||||
|
|
||||||
|
if let Some(voice_channel_id) = voice_state.channel_id {
|
||||||
let voice_status = VoiceStatus::builder()
|
let voice_status = VoiceStatus::builder()
|
||||||
.self_deafened(voice_state.self_deaf)
|
.self_deafened(voice_state.self_deaf)
|
||||||
.self_muted(voice_state.self_mute)
|
.self_muted(voice_state.self_mute)
|
||||||
@@ -41,55 +43,46 @@ async fn initialize_user_in_vc(
|
|||||||
.build();
|
.build();
|
||||||
let user_in_vc_data = voice_status.into();
|
let user_in_vc_data = voice_status.into();
|
||||||
|
|
||||||
voice_state
|
vcs_sender.send_modify(|vcs| {
|
||||||
.channel_id
|
vcs.entry(guild_id)
|
||||||
.map(|channel_id| (channel_id, user_in_vc_data))
|
.or_default()
|
||||||
} else {
|
.insert(voice_channel_id, user_id, user_in_vc_data);
|
||||||
None // TODO
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(discord_client), ret)]
|
#[tracing::instrument(skip(vcs_sender, discord_client))]
|
||||||
async fn initialize_server_vcs(
|
async fn initialize_server_vcs(
|
||||||
|
vcs_sender: &VCsSender,
|
||||||
discord_client: &twilight_http::Client,
|
discord_client: &twilight_http::Client,
|
||||||
id: Id<GuildMarker>,
|
id: Id<GuildMarker>,
|
||||||
) -> VCsInGuild {
|
) {
|
||||||
if let Ok(guild_members_res) = discord_client.guild_members(id).limit(999).await
|
if let Ok(guild_members_res) = discord_client.guild_members(id).limit(999).await
|
||||||
&& let Ok(guild_members) = guild_members_res.model().await
|
&& let Ok(guild_members) = guild_members_res.model().await
|
||||||
{
|
{
|
||||||
FuturesUnordered::from_iter(guild_members.into_iter().map(|member| async move {
|
FuturesUnordered::from_iter(
|
||||||
(
|
guild_members.into_iter().map(|member| {
|
||||||
member.user.id,
|
initialize_user_in_vc(vcs_sender, discord_client, id, 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))
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
.collect()
|
.collect()
|
||||||
.await
|
.await
|
||||||
} else {
|
|
||||||
Default::default()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(discord_client), ret)]
|
#[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
|
if let Ok(guilds_res) = discord_client.current_user_guilds().limit(200).await
|
||||||
&& let Ok(guilds) = guilds_res.model().await
|
&& let Ok(guilds) = guilds_res.model().await
|
||||||
{
|
{
|
||||||
FuturesUnordered::from_iter(guilds.into_iter().map(|guild| async move {
|
FuturesUnordered::from_iter(
|
||||||
let guild_vcs = initialize_server_vcs(discord_client, guild.id).await;
|
guilds
|
||||||
|
.into_iter()
|
||||||
(guild.id, guild_vcs)
|
.map(|guild| initialize_server_vcs(vcs_sender, discord_client, guild.id)),
|
||||||
}))
|
)
|
||||||
.collect()
|
.collect()
|
||||||
.await
|
.await
|
||||||
} else {
|
|
||||||
Default::default()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user