Skip to content

Commit

Permalink
use moka instead of stretto (#191)
Browse files Browse the repository at this point in the history
  • Loading branch information
circuitsacul authored Jan 26, 2023
1 parent c0b6cfe commit 27c814b
Show file tree
Hide file tree
Showing 12 changed files with 282 additions and 167 deletions.
267 changes: 194 additions & 73 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ serde_json = "1.0"
serde = "1.0.139"
emojis = "0.5.1"
dashmap = "5.3.4"
stretto = { version = "0.7.0", features = ["async"] }
regex = "1.6.0"
lazy_static = "1.4.0"
humantime = "2.1.0"
Expand All @@ -37,3 +36,4 @@ snafu = { version = "0.7.4", features = ["backtraces-impl-backtrace-crate"] }
serde_with = "2.2.0"
psutil = "3.2.2"
rust-fuzzy-search = "0.1.1"
moka = { version = "0.9.6", features = ["future"] }
91 changes: 39 additions & 52 deletions src/cache/cache_struct.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{hash::Hash, sync::Arc};
use std::{hash::Hash, sync::Arc, time::Duration};

use dashmap::{DashMap, DashSet};
use moka::future::Cache as MokaCache;
use twilight_gateway::Event;
use twilight_model::{
channel::{Channel, ChannelType, Webhook},
Expand All @@ -15,7 +16,7 @@ use twilight_model::{
use crate::{
cache::models::channel::CachedChannel,
client::bot::StarboardBot,
constants,
constants::{self, MEMBERS_TTL},
errors::StarboardResult,
utils::{
async_dash::{AsyncDashMap, AsyncDashSet},
Expand Down Expand Up @@ -75,45 +76,55 @@ impl From<Option<Arc<CachedMessage>>> for MessageResult {
}
}

fn stretto_cache<K: Hash + Eq, V: Send + Sync + 'static>(size: u32) -> stretto::AsyncCache<K, V> {
stretto::AsyncCacheBuilder::new((size * 10) as usize, size.into())
.set_ignore_internal_cost(true)
.finalize(tokio::spawn)
.unwrap()
fn moka_cache<K, V>(capacity: u64, idle: Duration) -> MokaCache<K, V>
where
K: Eq + Hash + Send + Sync + 'static,
V: Clone + Send + Sync + 'static,
{
MokaCache::builder()
.max_capacity(capacity)
.time_to_idle(idle)
.build()
}

pub struct Cache {
// discord side
pub guilds: AsyncDashMap<Id<GuildMarker>, CachedGuild>,
pub webhooks: AsyncDashMap<Id<WebhookMarker>, Arc<Webhook>>,
pub messages: stretto::AsyncCache<Id<MessageMarker>, Option<Arc<CachedMessage>>>,
pub users: stretto::AsyncCache<Id<UserMarker>, Option<Arc<CachedUser>>>,
pub messages: MokaCache<Id<MessageMarker>, Option<Arc<CachedMessage>>>,
pub users: MokaCache<Id<UserMarker>, Option<Arc<CachedUser>>>,
#[allow(clippy::type_complexity)]
pub members: stretto::AsyncCache<(Id<GuildMarker>, Id<UserMarker>), Option<Arc<CachedMember>>>,
pub members: MokaCache<(Id<GuildMarker>, Id<UserMarker>), Option<Arc<CachedMember>>>,

// database side
pub autostar_channel_ids: AsyncDashSet<Id<ChannelMarker>>,
pub guild_vote_emojis: AsyncDashMap<i64, Vec<String>>,

// misc
pub responses: stretto::AsyncCache<Id<MessageMarker>, Id<MessageMarker>>,
pub auto_deleted_posts: stretto::AsyncCache<Id<MessageMarker>, ()>,
pub responses: MokaCache<Id<MessageMarker>, Id<MessageMarker>>,
pub auto_deleted_posts: MokaCache<Id<MessageMarker>, ()>,
}

impl Cache {
pub fn new(autostar_channel_ids: DashSet<Id<ChannelMarker>>) -> Self {
Self {
guilds: DashMap::new().into(),
webhooks: DashMap::new().into(),
messages: stretto_cache(constants::MAX_MESSAGES),
users: stretto_cache(constants::MAX_USERS),
members: stretto_cache(constants::MAX_MEMBERS),
messages: moka_cache(constants::MAX_MESSAGES, constants::MESSAGES_TTL),
users: moka_cache(constants::MAX_USERS, constants::USERS_TTL),
members: moka_cache(constants::MAX_MEMBERS, MEMBERS_TTL),

autostar_channel_ids: autostar_channel_ids.into(),
guild_vote_emojis: DashMap::new().into(),

responses: stretto_cache(constants::MAX_STORED_RESPONSES),
auto_deleted_posts: stretto_cache(constants::MAX_STORED_AUTO_DELETES),
responses: moka_cache(
constants::MAX_STORED_RESPONSES,
constants::STORED_RESPONSES_TTL,
),
auto_deleted_posts: moka_cache(
constants::MAX_STORED_AUTO_DELETES,
constants::AUTO_DELETES_TTL,
),
}
}

Expand Down Expand Up @@ -143,33 +154,6 @@ impl Cache {
);
}

// insert wrappers
pub async fn insert_user(&self, key: Id<UserMarker>, val: Option<Arc<CachedUser>>) -> bool {
self.users
.insert_with_ttl(key, val, 1, constants::USERS_TTL)
.await
}

pub async fn insert_member(
&self,
key: (Id<GuildMarker>, Id<UserMarker>),
val: Option<Arc<CachedMember>>,
) -> bool {
self.members
.insert_with_ttl(key, val, 1, constants::MEMBERS_TTL)
.await
}

pub async fn insert_message(
&self,
key: Id<MessageMarker>,
val: Option<Arc<CachedMessage>>,
) -> bool {
self.messages
.insert_with_ttl(key, val, 1, constants::MESSAGES_TTL)
.await
}

// helper methods
pub fn guild_emoji_exists(&self, guild_id: Id<GuildMarker>, emoji_id: Id<EmojiMarker>) -> bool {
self.guilds.with(&guild_id, |_, guild| {
Expand Down Expand Up @@ -267,7 +251,7 @@ impl Cache {
user_id: Id<UserMarker>,
) -> StarboardResult<Option<Arc<CachedUser>>> {
if let Some(cached) = self.users.get(&user_id) {
return Ok(cached.value().clone());
return Ok(cached);
}

let user_get = bot.http.user(user_id).await;
Expand All @@ -282,7 +266,7 @@ impl Cache {
}
};

self.insert_user(user_id, user.clone()).await;
self.users.insert(user_id, user.clone()).await;

Ok(user)
}
Expand All @@ -294,14 +278,15 @@ impl Cache {
user_id: Id<UserMarker>,
) -> StarboardResult<Option<Arc<CachedMember>>> {
if let Some(cached) = self.members.get(&(guild_id, user_id)) {
return Ok(cached.value().clone());
return Ok(cached);
}

let get = bot.http.guild_member(guild_id, user_id).await;
let member = match get {
Ok(member) => {
let member = member.model().await?;
self.insert_user(member.user.id, Some(Arc::new((&member.user).into())))
self.users
.insert(member.user.id, Some(Arc::new((&member.user).into())))
.await;
Some(Arc::new(member.into()))
}
Expand All @@ -311,7 +296,8 @@ impl Cache {
},
};

self.insert_member((guild_id, user_id), member.clone())
self.members
.insert((guild_id, user_id), member.clone())
.await;

Ok(member)
Expand Down Expand Up @@ -357,7 +343,7 @@ impl Cache {
message_id: Id<MessageMarker>,
) -> StarboardResult<MessageResult> {
if let Some(cached) = self.messages.get(&message_id) {
return Ok(cached.value().clone().into());
return Ok(cached.into());
}

let msg = bot.http.message(channel_id, message_id).await;
Expand All @@ -374,13 +360,14 @@ impl Cache {
}
Ok(msg) => {
let msg = msg.model().await?;
self.insert_user(msg.author.id, Some(Arc::new((&msg.author).into())))
self.users
.insert(msg.author.id, Some(Arc::new((&msg.author).into())))
.await;
Some(Arc::new(msg.into()))
}
};

self.insert_message(message_id, msg.clone()).await;
self.messages.insert(message_id, msg.clone()).await;

Ok(msg.into())
}
Expand Down
29 changes: 16 additions & 13 deletions src/cache/events/member.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,28 @@ use crate::cache::{cache_struct::Cache, update::UpdateCache};
#[async_trait]
impl UpdateCache for MemberRemove {
async fn update_cache(&self, cache: &Cache) {
cache.members.remove(&(self.guild_id, self.user.id)).await;
cache
.members
.invalidate(&(self.guild_id, self.user.id))
.await;
}
}

#[async_trait]
impl UpdateCache for MemberUpdate {
async fn update_cache(&self, cache: &Cache) {
cache
.members
.insert_if_present(
(self.guild_id, self.user.id),
Some(Arc::new(self.into())),
1,
)
.await;
if cache.members.contains_key(&(self.guild_id, self.user.id)) {
cache
.members
.insert((self.guild_id, self.user.id), Some(Arc::new(self.into())))
.await;
}

cache
.users
.insert_if_present(self.user.id, Some(Arc::new((&self.user).into())), 1)
.await;
if cache.users.contains_key(&self.user.id) {
cache
.users
.insert(self.user.id, Some(Arc::new((&self.user).into())))
.await;
}
}
}
26 changes: 14 additions & 12 deletions src/cache/events/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,40 +16,42 @@ impl UpdateCache for MessageCreate {
}

let message = CachedMessage::from(&self.0);
cache.insert_message(self.id, Some(Arc::new(message))).await;
cache
.messages
.insert(self.id, Some(Arc::new(message)))
.await;
}
}

#[async_trait]
impl UpdateCache for MessageDelete {
async fn update_cache(&self, cache: &Cache) {
cache.messages.insert_if_present(self.id, None, 1).await;
if cache.messages.contains_key(&self.id) {
cache.messages.insert(self.id, None).await;
}
}
}

#[async_trait]
impl UpdateCache for MessageDeleteBulk {
async fn update_cache(&self, cache: &Cache) {
for id in &self.ids {
cache.messages.insert_if_present(*id, None, 1).await;
if cache.messages.contains_key(id) {
cache.messages.insert(*id, None).await;
}
}
}
}

#[async_trait]
impl UpdateCache for MessageUpdate {
async fn update_cache(&self, cache: &Cache) {
let cached = {
let cached = cache.messages.get(&self.id);

match cached {
None => return,
Some(msg) => msg.value().clone(),
}
let Some(cached) = cache.messages.get(&self.id) else {
return;
};

let Some(cached) = cached else {
cache.messages.remove(&self.id).await;
cache.messages.invalidate(&self.id).await;
return;
};

Expand Down Expand Up @@ -81,7 +83,7 @@ impl UpdateCache for MessageUpdate {

cache
.messages
.insert_if_present(self.id, Some(Arc::new(message)), 1)
.insert(self.id, Some(Arc::new(message)))
.await;
}
}
2 changes: 1 addition & 1 deletion src/cache/events/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl UpdateCache for ThreadDelete {
guild.active_thread_parents.remove(&self.id);
guild
});
cache.messages.remove(&self.id.get().into_id()).await;
cache.messages.invalidate(&self.id.get().into_id()).await;
}
}

Expand Down
11 changes: 6 additions & 5 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,16 @@ pub const UPDATE_PATREON_DELAY: Duration = Duration::from_secs(60);
pub const UPDATE_SUPPORTER_ROLES_DELAY: Duration = Duration::from_secs(60);

// Cache size
pub const MAX_MESSAGES: u32 = 100_000;
pub const MAX_MESSAGES: u64 = 100_000;
pub const MESSAGES_TTL: Duration = Duration::from_secs(60 * 60);
pub const MAX_USERS: u32 = 100_000;
pub const MAX_USERS: u64 = 100_000;
pub const USERS_TTL: Duration = Duration::from_secs(60 * 60);
pub const MAX_MEMBERS: u32 = 100_000;
pub const MAX_MEMBERS: u64 = 100_000;
pub const MEMBERS_TTL: Duration = Duration::from_secs(60 * 60);

pub const MAX_STORED_RESPONSES: u32 = 10;
pub const MAX_STORED_AUTO_DELETES: u32 = 10_000;
pub const MAX_STORED_RESPONSES: u64 = 10;
pub const STORED_RESPONSES_TTL: Duration = Duration::from_secs(60 * 10);
pub const MAX_STORED_AUTO_DELETES: u64 = 10_000;
pub const AUTO_DELETES_TTL: Duration = Duration::from_secs(10);

// Cooldowns
Expand Down
3 changes: 1 addition & 2 deletions src/core/starboard/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use twilight_model::id::{marker::MessageMarker, Id};
use crate::{
cache::MessageResult,
client::bot::StarboardBot,
constants,
core::{
embedder::Embedder,
emoji::{EmojiCommon, SimpleEmoji},
Expand Down Expand Up @@ -296,7 +295,7 @@ impl RefreshStarboard {
.bot
.cache
.auto_deleted_posts
.insert_with_ttl(sb_message_id, (), 0, constants::AUTO_DELETES_TTL)
.insert(sb_message_id, ())
.await;
let deleted = embedder.delete(&self.refresh.bot, sb_message_id).await?;
(false, deleted)
Expand Down
2 changes: 1 addition & 1 deletion src/core/starboard/link_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub async fn handle_message_delete(
message_id: Id<MessageMarker>,
) -> StarboardResult<()> {
if bot.cache.auto_deleted_posts.get(&message_id).is_some() {
bot.cache.auto_deleted_posts.remove(&message_id).await;
bot.cache.auto_deleted_posts.invalidate(&message_id).await;
return Ok(());
}

Expand Down
6 changes: 4 additions & 2 deletions src/core/starboard/reaction_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@ pub async fn handle_reaction_add(
}

bot.cache
.insert_member(
.members
.insert(
(reactor_member.guild_id, reactor_member.user.id),
Some(Arc::new(reactor_member.into())),
)
.await;
bot.cache
.insert_user(
.users
.insert(
reactor_member.user.id,
Some(Arc::new((&reactor_member.user).into())),
)
Expand Down
Loading

0 comments on commit 27c814b

Please sign in to comment.