diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cache/mod.rs | 12 | ||||
| -rw-r--r-- | src/cache/settings.rs | 65 | ||||
| -rw-r--r-- | src/client/dispatch.rs | 25 |
3 files changed, 92 insertions, 10 deletions
diff --git a/src/cache/mod.rs b/src/cache/mod.rs index 780c364..f02d1c6 100644 --- a/src/cache/mod.rs +++ b/src/cache/mod.rs @@ -52,7 +52,8 @@ use std::collections::{ }; use std::{ default::Default, - sync::Arc + sync::Arc, + time::Duration, }; mod cache_update; @@ -756,6 +757,15 @@ impl Cache { e.update(self) } + /// Gets the duration it will try for when acquiring a write lock. + /// + /// Refer to the documentation for [`cache_lock_time`] for more information. + /// + /// [`cache_lock_time`]: struct.Settings.html#method.cache_lock_time + pub fn get_try_write_duration(&self) -> Option<Duration> { + self.settings.cache_lock_time + } + pub(crate) fn update_user_entry(&mut self, user: &User) { match self.users.entry(user.id) { Entry::Vacant(e) => { diff --git a/src/cache/settings.rs b/src/cache/settings.rs index 51bff4c..975ddc6 100644 --- a/src/cache/settings.rs +++ b/src/cache/settings.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + /// Settings for the cache. /// /// # Examples @@ -10,15 +12,34 @@ /// let mut settings = CacheSettings::new(); /// settings.max_messages(10); /// ``` -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug)] pub struct Settings { /// The maximum number of messages to store in a channel's message cache. /// /// Defaults to 0. pub max_messages: usize, + + /// The Duration cache updates will try to acquire write-locks for. + /// + /// Defaults to 10 milliseconds. + /// + /// **Note**: + /// If set to `None`, cache updates will acquire write-lock until available, + /// potentially deadlocking. + pub cache_lock_time: Option<Duration>, __nonexhaustive: (), } +impl Default for Settings { + fn default() -> Self { + Settings { + max_messages: usize::default(), + cache_lock_time: Some(Duration::from_millis(10)), + __nonexhaustive: (), + } + } +} + impl Settings { /// Creates new settings to be used with a cache. #[inline] @@ -47,4 +68,46 @@ impl Settings { self } + + /// Sets the duration that the cache will try to aquire a write lock. + /// + /// Refer to [`cache_lock_time`] for more information. + /// + /// **Note**: + /// Should be set before the client gets started, as it can not be + /// changed after the first read of the duration. + /// + /// # Examples + /// + /// Set the time that it will try to aquire a lock. + /// + /// ```rust,no_run + /// use std::time::Duration; + /// use std::env; + /// use serenity::prelude::*; + /// + /// struct Handler; + /// + /// impl EventHandler for Handler {} + /// + /// fn main() { + /// let token = env::var("DISCORD_TOKEN") + /// .expect("Expected a token in the environment"); + /// serenity::CACHE + /// .write().settings_mut() + /// .cache_lock_time(Some(Duration::from_secs(1))); + /// let mut client = Client::new(&token, Handler).unwrap(); + /// + /// if let Err(why) = client.start() { + /// println!("Client error: {:?}", why); + /// } + /// } + /// ``` + /// + /// [`cache_lock_time`]: #structfield.cache_lock_time + pub fn cache_lock_time(&mut self, duration: Option<Duration>) -> &mut Self { + self.cache_lock_time = duration; + + self + } } diff --git a/src/client/dispatch.rs b/src/client/dispatch.rs index 5f88c34..f3585a8 100644 --- a/src/client/dispatch.rs +++ b/src/client/dispatch.rs @@ -25,20 +25,29 @@ use std::time::Duration; #[cfg(feature = "cache")] use super::CACHE; +lazy_static! { + pub static ref CACHE_TRY_WRITE_DURATION: Option<Duration> = + CACHE.read().get_try_write_duration(); +} + macro_rules! update { ($event:expr) => { { #[cfg(feature = "cache")] { - if let Some(mut lock) = CACHE.try_write_for(Duration::from_millis(10)) { - lock.update(&mut $event) + if let Some(duration) = *CACHE_TRY_WRITE_DURATION { + CACHE.try_write_for(duration) + .and_then(|mut lock| lock.update(&mut $event)) + .or_else(|| { + warn!( + "[dispatch] Possible deadlock: couldn't unlock cache to update with event: {:?}", + $event, + ); + + None + }) } else { - warn!( - "[dispatch] Possible deadlock: couldn't unlock cache to update with event: {:?}", - $event, - ); - - None + CACHE.write().update(&mut $event) } } } |