Don't retry the members endpoint too much

This commit is contained in:
Natsu Kagami 2024-03-06 16:38:50 +01:00
parent 4ba64a466d
commit d23c86fb99
Signed by: nki
GPG key ID: 55A032EB38B49ADB

View file

@ -1,3 +1,4 @@
use anyhow::bail;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use serenity::model::{ use serenity::model::{
guild::Member, guild::Member,
@ -9,6 +10,7 @@ use std::sync::Arc;
use tokio::sync::Mutex; use tokio::sync::Mutex;
const VALID_CACHE_SECONDS: i64 = 15 * 60; // 15 minutes const VALID_CACHE_SECONDS: i64 = 15 * 60; // 15 minutes
const INVALID_CACHE_SECONDS: i64 = 2 * 60; // 2 minutes
type Map<K, V> = Mutex<HashMap<K, V>>; type Map<K, V> = Mutex<HashMap<K, V>>;
@ -16,7 +18,7 @@ type Map<K, V> = Mutex<HashMap<K, V>>;
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct MemberCache { pub struct MemberCache {
per_user: Map<(UserId, GuildId), Expiring<Option<Member>>>, per_user: Map<(UserId, GuildId), Expiring<Option<Member>>>,
per_guild: Map<GuildId, Expiring<Arc<[Member]>>>, per_guild: Map<GuildId, Expiring<Option<Arc<[Member]>>>>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -90,21 +92,32 @@ impl MemberCache {
// Check cache // Check cache
if let Entry::Occupied(oe) = &entry { if let Entry::Occupied(oe) = &entry {
if oe.get().timeout > now { if oe.get().timeout > now {
return Ok(oe.get().value.clone()); return match &oe.get().value {
Some(v) => Ok(v.clone()),
None => bail!("guild members for {} unavailable", guild_id),
};
} }
} }
// query // query
eprintln!("querying members of {}", guild_id); eprintln!("querying members of {}", guild_id);
let members: Arc<[Member]> = guild_id let members: Option<Arc<[Member]>> = guild_id
.members(cache_http.http(), None, None) .members(cache_http.http(), None, None)
.await? .await
.into(); .ok()
Ok(entry .map(|v| v.into());
match &entry
.or_insert(Expiring::new( .or_insert(Expiring::new(
members.clone(), members.clone(),
now + chrono::Duration::seconds(VALID_CACHE_SECONDS), now + chrono::Duration::seconds(if members.is_some() {
VALID_CACHE_SECONDS
} else {
INVALID_CACHE_SECONDS
}),
)) ))
.value .value
.clone()) {
Some(v) => Ok(v.clone()),
None => bail!("guild members for {} unavailable", guild_id),
}
} }
} }