Skip to content

Commit

Permalink
add additional event handlers for better caching
Browse files Browse the repository at this point in the history
  • Loading branch information
Jacherr committed Apr 3, 2024
1 parent 68ee365 commit ca95da1
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 27 deletions.
2 changes: 1 addition & 1 deletion assyst-core/src/command/misc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub async fn remind(_ctxt: CommandCtxt<'_>, _when: Time, _text: Rest) -> anyhow:

#[command(
description = "enlarges an image",
aliases = ["e"],
aliases = ["e", "repost", "reupload"],
cooldown = Duration::from_secs(2),
access = Availability::Public,
category = Category::Misc,
Expand Down
14 changes: 14 additions & 0 deletions assyst-core/src/gateway_handler/event_handlers/channel_update.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use tracing::debug;
use twilight_model::gateway::payload::incoming::ChannelUpdate;

use crate::assyst::ThreadSafeAssyst;

pub fn handle(assyst: ThreadSafeAssyst, event: ChannelUpdate) {
if let Some(nsfw) = event.nsfw {
assyst
.rest_cache_handler
.update_channel_age_restricted_status(event.id.get(), nsfw);

debug!("Updated channel {} age restricted status to {nsfw}", event.id.get());
};
}
16 changes: 16 additions & 0 deletions assyst-core/src/gateway_handler/event_handlers/guild_update.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use tracing::debug;
use twilight_model::gateway::payload::incoming::GuildUpdate;

use crate::assyst::ThreadSafeAssyst;

pub fn handle(assyst: ThreadSafeAssyst, event: GuildUpdate) {
assyst
.rest_cache_handler
.set_guild_owner(event.id.get(), event.owner_id.get());

assyst
.rest_cache_handler
.set_guild_upload_limit_bytes(event.id.get(), event.premium_tier);

debug!("Updated guild {} cache info", event.id.get());
}
2 changes: 2 additions & 0 deletions assyst-core/src/gateway_handler/event_handlers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::command::{CommandCtxt, TCommand};

pub mod channel_update;
pub mod guild_create;
pub mod guild_delete;
pub mod guild_update;
pub mod message_create;
pub mod message_delete;
pub mod message_update;
Expand Down
6 changes: 5 additions & 1 deletion assyst-core/src/gateway_handler/incoming_event.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use twilight_model::gateway::event::{DispatchEvent, GatewayEvent};
use twilight_model::gateway::payload::incoming::{
GuildCreate, GuildDelete, MessageCreate, MessageDelete, MessageUpdate, Ready,
ChannelUpdate, GuildCreate, GuildDelete, GuildUpdate, MessageCreate, MessageDelete, MessageUpdate, Ready,
};

#[derive(Debug)]
Expand All @@ -10,7 +10,9 @@ pub enum IncomingEvent {
MessageDelete(MessageDelete),
GuildCreate(Box<GuildCreate>), // same problem
GuildDelete(GuildDelete),
GuildUpdate(GuildUpdate),
ShardReady(Ready),
ChannelUpdate(ChannelUpdate),
}
impl TryFrom<GatewayEvent> for IncomingEvent {
type Error = ();
Expand All @@ -23,7 +25,9 @@ impl TryFrom<GatewayEvent> for IncomingEvent {
DispatchEvent::MessageDelete(message) => Ok(IncomingEvent::MessageDelete(message)),
DispatchEvent::GuildCreate(guild) => Ok(IncomingEvent::GuildCreate(guild)),
DispatchEvent::GuildDelete(guild) => Ok(IncomingEvent::GuildDelete(guild)),
DispatchEvent::GuildUpdate(guild) => Ok(IncomingEvent::GuildUpdate(*guild)),
DispatchEvent::Ready(ready) => Ok(IncomingEvent::ShardReady(*ready)),
DispatchEvent::ChannelUpdate(channel) => Ok(IncomingEvent::ChannelUpdate(*channel)),
_ => Err(()),
},
_ => Err(()),
Expand Down
6 changes: 6 additions & 0 deletions assyst-core/src/gateway_handler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,11 @@ pub async fn handle_raw_event(context: ThreadSafeAssyst, event: IncomingEvent) {
IncomingEvent::GuildDelete(event) => {
event_handlers::guild_delete::handle(context, event).await;
},
IncomingEvent::GuildUpdate(event) => {
event_handlers::guild_update::handle(context, event);
},
IncomingEvent::ChannelUpdate(event) => {
event_handlers::channel_update::handle(context, event);
},
}
}
4 changes: 1 addition & 3 deletions assyst-core/src/persistent_cache_handler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ use tokio::sync::oneshot;
use tracing::{info, warn};
use twilight_model::gateway::payload::incoming::{GuildCreate, GuildDelete, Ready};

/// Main cache handler for Assyst, except the database cache. Abstracts away the two main caches:
/// assyst-cache (persistent across assyst-core restarts) and the local cache (emptied on
/// assyst-core restarts).
/// Handles communication with assyst-cache.
pub struct PersistentCacheHandler {
pub cache_tx: UnboundedSender<CacheJobSend>,
}
Expand Down
3 changes: 2 additions & 1 deletion assyst-core/src/rest/r34.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ static R34_URL: &'static str = "https://api.rule34.xxx/index.php?tags=";
#[derive(Deserialize, Clone)]
pub struct R34Result {
pub file_url: String,
pub score: i32,
#[serde(rename = "score")]
pub _score: i32,
}

pub async fn get_random_r34(assyst: ThreadSafeAssyst, tags: &str) -> anyhow::Result<R34Result> {
Expand Down
42 changes: 21 additions & 21 deletions assyst-core/src/rest/rest_cache_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,19 @@ fn default_cache<K: TCacheK, V: TCacheV>() -> Cache<K, V> {
.build()
}

fn default_limited_cache<K: TCacheK, V: TCacheV>() -> Cache<K, V> {
Cache::builder()
.max_capacity(100)
.time_to_live(Duration::from_secs(60))
.build()
}

pub struct RestCacheHandler {
http_client: Arc<HttpClient>,
guild_upload_limits: Cache<u64, u64>,
channel_nsfw_status: Cache<u64, bool>,
guild_owners: Cache<u64, u64>,
guild_managers: Cache<(u64, u64), bool>,
}
impl RestCacheHandler {
pub fn new(client: Arc<HttpClient>) -> RestCacheHandler {
RestCacheHandler {
http_client: client,
guild_upload_limits: default_cache(),
// reduced limits for this one because the nsfw status can easily change at any time
channel_nsfw_status: default_limited_cache(),
channel_nsfw_status: default_cache(),
guild_owners: default_cache(),
// same here, a user can easily be removed as a guild manager
guild_managers: default_limited_cache(),
}
}

Expand All @@ -55,15 +44,25 @@ impl RestCacheHandler {
self.guild_upload_limits.run_pending_tasks();
self.channel_nsfw_status.run_pending_tasks();
self.guild_owners.run_pending_tasks();
self.guild_managers.run_pending_tasks();

size += self.guild_upload_limits.entry_count() * size_of::<(u64, u64)>() as u64;
size += self.channel_nsfw_status.entry_count() * size_of::<(u64, bool)>() as u64;
size += self.guild_owners.entry_count() * size_of::<(u64, u64)>() as u64;
size += self.guild_managers.entry_count() * size_of::<((u64, u64), u64)>() as u64;
size
}

pub fn set_guild_upload_limit_bytes(&self, guild_id: u64, tier: PremiumTier) {
let amount = match tier {
PremiumTier::None | PremiumTier::Tier1 => NORMAL_DISCORD_UPLOAD_LIMIT_BYTES,
PremiumTier::Tier2 => PREMIUM_TIER2_DISCORD_UPLOAD_LIMIT_BYTES,
PremiumTier::Tier3 => PREMIUM_TIER3_DISCORD_UPLOAD_LIMIT_BYTES,
PremiumTier::Other(_) => NORMAL_DISCORD_UPLOAD_LIMIT_BYTES,
_ => NORMAL_DISCORD_UPLOAD_LIMIT_BYTES,
};

self.guild_upload_limits.insert(guild_id, amount);
}

pub async fn get_guild_upload_limit_bytes(&self, guild_id: u64) -> anyhow::Result<u64> {
if let Some(amount) = self.guild_upload_limits.get(&guild_id) {
return Ok(amount);
Expand Down Expand Up @@ -91,6 +90,10 @@ impl RestCacheHandler {
Ok(amount)
}

pub fn update_channel_age_restricted_status(&self, channel_id: u64, status: bool) {
self.channel_nsfw_status.insert(channel_id, status);
}

pub async fn channel_is_age_restricted(&self, channel_id: u64) -> anyhow::Result<bool> {
if let Some(nsfw) = self.channel_nsfw_status.get(&channel_id) {
return Ok(nsfw);
Expand All @@ -110,6 +113,10 @@ impl RestCacheHandler {
Ok(nsfw)
}

pub fn set_guild_owner(&self, guild_id: u64, owner_id: u64) {
self.guild_owners.insert(guild_id, owner_id);
}

pub async fn get_guild_owner(&self, guild_id: u64) -> anyhow::Result<u64> {
if let Some(owner) = self.guild_owners.get(&guild_id) {
return Ok(owner);
Expand All @@ -132,10 +139,6 @@ impl RestCacheHandler {
/// Checks if a user is a guild manager, i.e., owns the server, has Administrator, or has Manage
/// Server permissions.
pub async fn user_is_guild_manager(&self, guild_id: u64, user_id: u64) -> anyhow::Result<bool> {
if let Some(manager) = self.guild_managers.get(&(guild_id, user_id)) {
return Ok(manager);
}

// guild owner *or* manage server *or* admin
// get owner
let owner = self.get_guild_owner(guild_id).await?;
Expand Down Expand Up @@ -167,9 +170,6 @@ impl RestCacheHandler {
== Permissions::ADMINISTRATOR.bits()
|| member_permissions & Permissions::MANAGE_GUILD.bits() == Permissions::MANAGE_GUILD.bits();

self.guild_managers
.insert((guild_id, user_id), owner == user_id || member_is_manager);

Ok(owner == user_id || member_is_manager)
}
}

0 comments on commit ca95da1

Please sign in to comment.