aboutsummaryrefslogtreecommitdiff
path: root/src/cache
diff options
context:
space:
mode:
authorLakelezz <[email protected]>2018-12-18 20:55:32 +0100
committerAlex M. M <[email protected]>2018-12-18 20:55:32 +0100
commit8cb1bdc6cf992cc55810f5af753666d54f2237d5 (patch)
tree052e2f425a6117e45323886bb2b2b683b6d5a1e8 /src/cache
parentMutably borrow on `ChannelId`'s `edit`-method. (#447) (diff)
downloadserenity-8cb1bdc6cf992cc55810f5af753666d54f2237d5.tar.xz
serenity-8cb1bdc6cf992cc55810f5af753666d54f2237d5.zip
Remove global Cache (#448)
* Update to use Rust 2018. * Update examples and use Rust 2018. * Pass cache via `Context` around instead of being global. * Remove `lazy_static` from `cache`-feature. * Update examples to use `Context`'s cache. * Replace cache's update-timeout-setting with `update_cache_timeout`. * Update documentation to stop using global cache. * Move `HttpAndCache` to `lib.rs`. * Add `__nonexhaustive`-field to `CacheAndHttp`. * Add `__nonexhaustive` in `CacheAndHttp`-initialisers. * Avoid `__nonexhaustive`-usage in doctest. * Remove unnecessary comma in `cfg`-attribute.
Diffstat (limited to 'src/cache')
-rw-r--r--src/cache/mod.rs156
-rw-r--r--src/cache/settings.rs54
2 files changed, 91 insertions, 119 deletions
diff --git a/src/cache/mod.rs b/src/cache/mod.rs
index a2c133f..6dbf097 100644
--- a/src/cache/mod.rs
+++ b/src/cache/mod.rs
@@ -42,6 +42,7 @@
//! [`CACHE`]: ../struct.CACHE.html
//! [`http`]: ../http/index.html
+use std::str::FromStr;
use crate::model::prelude::*;
use parking_lot::RwLock;
use std::collections::{
@@ -53,7 +54,6 @@ use std::collections::{
use std::{
default::Default,
sync::Arc,
- time::Duration,
};
mod cache_update;
@@ -64,6 +64,30 @@ pub use self::settings::Settings;
type MessageCache = HashMap<ChannelId, HashMap<MessageId, Message>>;
+pub trait FromStrAndCache: Sized {
+ type Err;
+
+ fn from_str(cache: &Arc<RwLock<Cache>>, s: &str) -> Result<Self, Self::Err>;
+}
+
+pub trait StrExt: Sized {
+ fn parse_cached<F: FromStrAndCache>(&self, cache: &Arc<RwLock<Cache>>) -> Result<F, F::Err>;
+}
+
+impl<'a> StrExt for &'a str {
+ fn parse_cached<F: FromStrAndCache>(&self, cache: &Arc<RwLock<Cache>>) -> Result<F, F::Err> {
+ F::from_str(&cache, &self)
+ }
+}
+
+impl<F: FromStr> FromStrAndCache for F {
+ type Err = F::Err;
+
+ fn from_str(_cache: &Arc<RwLock<Cache>>, s: &str) -> Result<Self, Self::Err> {
+ s.parse::<F>()
+ }
+}
+
/// A cache of all events received over a [`Shard`], where storing at least
/// some data from the event is possible.
///
@@ -222,7 +246,6 @@ impl Cache {
/// #
/// # #[cfg(feature = "client")]
/// # fn main() {
- /// use serenity::CACHE;
/// use std::thread;
/// use std::time::Duration;
///
@@ -241,7 +264,7 @@ impl Cache {
/// // seconds.
/// thread::sleep(Duration::from_secs(5));
///
- /// println!("{} unknown members", CACHE.read().unknown_members());
+ /// println!("{} unknown members", ctx.cache.read().unknown_members());
/// }
/// }
///
@@ -284,9 +307,15 @@ impl Cache {
/// Printing the count of all private channels and groups:
///
/// ```rust,no_run
- /// use serenity::CACHE;
- ///
- /// let amount = CACHE.read().all_private_channels().len();
+ /// # extern crate parking_lot;
+ /// # extern crate serenity;
+ /// #
+ /// # use serenity::{cache::Cache};
+ /// # use parking_lot::RwLock;
+ /// # use std::sync::Arc;
+ /// #
+ /// # let cache = Arc::new(RwLock::new(Cache::default()));
+ /// let amount = cache.read().all_private_channels().len();
///
/// println!("There are {} private channels", amount);
/// ```
@@ -316,13 +345,11 @@ impl Cache {
/// # use serenity::model::prelude::*;
/// # use serenity::prelude::*;
/// #
- /// use serenity::CACHE;
- ///
/// struct Handler;
///
/// impl EventHandler for Handler {
- /// fn ready(&self, _: Context, _: Ready) {
- /// let guilds = CACHE.read().guilds.len();
+ /// fn ready(&self, context: Context, _: Ready) {
+ /// let guilds = context.cache.read().guilds.len();
///
/// println!("Guilds in the Cache: {}", guilds);
/// }
@@ -397,20 +424,21 @@ impl Cache {
/// Retrieve a guild from the cache and print its name:
///
/// ```rust,no_run
- /// # use std::error::Error;
+ /// # extern crate parking_lot;
+ /// # extern crate serenity;
/// #
- /// # fn try_main() -> Result<(), Box<Error>> {
- /// use serenity::CACHE;
- ///
- /// if let Some(guild) = CACHE.read().guild(7) {
+ /// # use serenity::{cache::Cache};
+ /// # use parking_lot::RwLock;
+ /// # use std::{error::Error, sync::Arc};
+ /// #
+ /// # fn main() -> Result<(), Box<Error>> {
+ /// # let cache = Arc::new(RwLock::new(Cache::default()));
+ /// // assuming the cache is in scope, e.g. via `Context`
+ /// if let Some(guild) = cache.read().guild(7) {
/// println!("Guild name: {}", guild.read().name);
/// }
/// # Ok(())
/// # }
- /// #
- /// # fn main() {
- /// # try_main().unwrap();
- /// # }
/// ```
#[inline]
pub fn guild<G: Into<GuildId>>(&self, id: G) -> Option<Arc<RwLock<Guild>>> {
@@ -438,13 +466,11 @@ impl Cache {
/// # use serenity::model::prelude::*;
/// # use serenity::prelude::*;
/// #
- /// use serenity::CACHE;
- ///
/// struct Handler;
///
/// impl EventHandler for Handler {
- /// fn message(&self, ctx: Context, message: Message) {
- /// let cache = CACHE.read();
+ /// fn message(&self, context: Context, message: Message) {
+ /// let cache = context.cache.read();
///
/// let channel = match cache.guild_channel(message.channel_id) {
/// Some(channel) => channel,
@@ -496,20 +522,20 @@ impl Cache {
/// Retrieve a group from the cache and print its owner's id:
///
/// ```rust,no_run
- /// # use std::error::Error;
+ /// # extern crate parking_lot;
+ /// # extern crate serenity;
/// #
- /// # fn try_main() -> Result<(), Box<Error>> {
- /// use serenity::CACHE;
- ///
- /// if let Some(group) = CACHE.read().group(7) {
+ /// # use serenity::cache::Cache;
+ /// # use parking_lot::RwLock;
+ /// # use std::{error::Error, sync::Arc};
+ /// #
+ /// # fn main() -> Result<(), Box<Error>> {
+ /// # let cache = Arc::new(RwLock::new(Cache::default()));
+ /// if let Some(group) = cache.read().group(7) {
/// println!("Owner Id: {}", group.read().owner_id);
/// }
/// # Ok(())
/// # }
- /// #
- /// # fn main() {
- /// # try_main().unwrap();
- /// # }
/// ```
#[inline]
pub fn group<C: Into<ChannelId>>(&self, id: C) -> Option<Arc<RwLock<Group>>> {
@@ -532,9 +558,16 @@ impl Cache {
/// [`Client::on_message`] context:
///
/// ```rust,ignore
- /// use serenity::CACHE;
+ /// # extern crate parking_lot;
+ /// # extern crate serenity;
+ /// #
+ /// # use serenity::{cache::Cache, model::prelude::*, prelude::*};
+ /// # use parking_lot::RwLock;
+ /// # use std::sync::Arc;
+ /// #
+ /// # let cache = Arc::new(RwLock::new(Cache::default()));
+ /// let cache = cache.read();
///
- /// let cache = CACHE.read();
/// let member = {
/// let channel = match cache.guild_channel(message.channel_id) {
/// Some(channel) => channel,
@@ -589,12 +622,19 @@ impl Cache {
/// name:
///
/// ```rust,no_run
+ /// # extern crate parking_lot;
+ /// # extern crate serenity;
+ /// #
/// # use std::error::Error;
/// #
+ /// # use serenity::{cache::Cache, model::prelude::*, prelude::*};
+ /// # use parking_lot::RwLock;
+ /// # use std::sync::Arc;
+ /// #
/// # fn try_main() -> Result<(), Box<Error>> {
- /// use serenity::CACHE;
- ///
- /// let cache = CACHE.read();
+ /// # let cache = Arc::new(RwLock::new(Cache::default()));
+ /// # let cache = cache.read();
+ /// // assuming the cache has been unlocked
///
/// if let Some(channel) = cache.private_channel(7) {
/// let channel_reader = channel.read();
@@ -635,20 +675,21 @@ impl Cache {
/// Retrieve a role from the cache and print its name:
///
/// ```rust,no_run
- /// # use std::error::Error;
+ /// # extern crate parking_lot;
+ /// # extern crate serenity;
/// #
- /// # fn try_main() -> Result<(), Box<Error>> {
- /// use serenity::CACHE;
- ///
- /// if let Some(role) = CACHE.read().role(7, 77) {
+ /// # use serenity::cache::Cache;
+ /// # use parking_lot::RwLock;
+ /// # use std::{error::Error, sync::Arc};
+ /// #
+ /// # fn main() -> Result<(), Box<Error>> {
+ /// # let cache = Arc::new(RwLock::new(Cache::default()));
+ /// // assuming the cache is in scope, e.g. via `Context`
+ /// if let Some(role) = cache.read().role(7, 77) {
/// println!("Role with Id 77 is called {}", role.name);
/// }
/// # Ok(())
/// # }
- /// #
- /// # fn main() {
- /// # try_main().unwrap();
- /// # }
/// ```
#[inline]
pub fn role<G, R>(&self, guild_id: G, role_id: R) -> Option<Role>
@@ -707,20 +748,14 @@ impl Cache {
/// Retrieve a user from the cache and print their name:
///
/// ```rust,no_run
+ /// # use serenity::command;
/// # use std::error::Error;
/// #
- /// # fn try_main() -> Result<(), Box<Error>> {
- /// use serenity::CACHE;
- ///
- /// if let Some(user) = CACHE.read().user(7) {
+ /// # command!(test(context) {
+ /// if let Some(user) = context.cache.read().user(7) {
/// println!("User with Id 7 is currently named {}", user.read().name);
/// }
- /// # Ok(())
- /// # }
- /// #
- /// # fn main() {
- /// # try_main().unwrap();
- /// # }
+ /// # });
/// ```
#[inline]
pub fn user<U: Into<UserId>>(&self, user_id: U) -> Option<Arc<RwLock<User>>> {
@@ -757,15 +792,6 @@ 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 975ddc6..3fabb5a 100644
--- a/src/cache/settings.rs
+++ b/src/cache/settings.rs
@@ -1,5 +1,3 @@
-use std::time::Duration;
-
/// Settings for the cache.
///
/// # Examples
@@ -18,15 +16,6 @@ pub struct Settings {
///
/// 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: (),
}
@@ -34,7 +23,6 @@ impl Default for Settings {
fn default() -> Self {
Settings {
max_messages: usize::default(),
- cache_lock_time: Some(Duration::from_millis(10)),
__nonexhaustive: (),
}
}
@@ -68,46 +56,4 @@ 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
- }
}