diff options
| author | Lakelezz <[email protected]> | 2018-12-18 20:55:32 +0100 |
|---|---|---|
| committer | Alex M. M <[email protected]> | 2018-12-18 20:55:32 +0100 |
| commit | 8cb1bdc6cf992cc55810f5af753666d54f2237d5 (patch) | |
| tree | 052e2f425a6117e45323886bb2b2b683b6d5a1e8 /src/client/mod.rs | |
| parent | Mutably borrow on `ChannelId`'s `edit`-method. (#447) (diff) | |
| download | serenity-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/client/mod.rs')
| -rw-r--r-- | src/client/mod.rs | 120 |
1 files changed, 118 insertions, 2 deletions
diff --git a/src/client/mod.rs b/src/client/mod.rs index 4bd9d11..bbedf89 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -32,18 +32,22 @@ pub use self::{ event_handler::EventHandler }; +pub use crate::CacheAndHttp; + // Note: the following re-exports are here for backwards compatibility pub use crate::gateway; pub use crate::http as rest; #[cfg(feature = "cache")] -pub use crate::CACHE; +pub use crate::cache::Cache; +#[cfg(feature = "cache")] +use parking_lot::RwLock; use crate::http; use crate::internal::prelude::*; use parking_lot::Mutex; use self::bridge::gateway::{ShardManager, ShardManagerMonitor, ShardManagerOptions}; -use std::sync::Arc; +use std::{sync::Arc, time::Duration}; use threadpool::ThreadPool; use typemap::ShareMap; @@ -295,6 +299,7 @@ pub struct Client { /// This is wrapped in an `Arc<Mutex<T>>` so all shards will have an updated /// value available. pub ws_uri: Arc<Mutex<String>>, + pub cache_and_http: Arc<CacheAndHttp>, } impl Client { @@ -354,6 +359,115 @@ impl Client { UserId(0), ))); + let cache_and_http = Arc::new(CacheAndHttp { + #[cfg(feature = "cache")] + cache: Arc::new(RwLock::new(Cache::default())), + #[cfg(feature = "cache")] + update_cache_timeout: None, + __nonexhaustive: (), + }); + + let (shard_manager, shard_manager_worker) = { + ShardManager::new(ShardManagerOptions { + data: &data, + event_handler: &event_handler, + #[cfg(feature = "framework")] + framework: &framework, + shard_index: 0, + shard_init: 0, + shard_total: 0, + threadpool: threadpool.clone(), + token: &locked, + #[cfg(feature = "voice")] + voice_manager: &voice_manager, + ws_url: &url, + cache_and_http: &cache_and_http, + }) + }; + + Ok(Client { + token: locked, + ws_uri: url, + #[cfg(feature = "framework")] + framework, + data, + shard_manager, + shard_manager_worker, + threadpool, + #[cfg(feature = "voice")] + voice_manager, + cache_and_http, + }) + } + + /// Creates a Client for a bot user and sets a cache update timeout. + /// If set to some duration, updating the cache will try to claim a + /// write-lock for given duration and skip received event but also + /// issue a deadlock-warning upon failure. + /// If `duration` is set to `None`, updating the cache will try to claim + /// a write-lock until success and potentially deadlock. + /// + /// Discord has a requirement of prefixing bot tokens with `"Bot "`, which + /// this function will automatically do for you if not already included. + /// + /// # Examples + /// + /// Create a Client, using a token from an environment variable: + /// + /// ```rust,no_run + /// # use serenity::prelude::EventHandler; + /// struct Handler; + /// + /// impl EventHandler for Handler {} + /// # use std::error::Error; + /// # + /// # fn try_main() -> Result<(), Box<Error>> { + /// use serenity::Client; + /// use std::env; + /// + /// let token = env::var("DISCORD_TOKEN")?; + /// let client = Client::new_with_cache_update_timeout(&token, Handler, None)?; + /// # Ok(()) + /// # } + /// # + /// # fn main() { + /// # try_main().unwrap(); + /// # } + /// ``` + #[cfg(feature = "cache")] + pub fn new_with_cache_update_timeout<H>(token: &str, handler: H, duration: Option<Duration>) -> Result<Self> + where H: EventHandler + Send + Sync + 'static { + let token = token.trim(); + + let token = if token.starts_with("Bot ") { + token.to_string() + } else { + format!("Bot {}", token) + }; + + http::set_token(&token); + let locked = Arc::new(Mutex::new(token)); + + let name = "serenity client".to_owned(); + let threadpool = ThreadPool::with_name(name, 5); + let url = Arc::new(Mutex::new(http::get_gateway()?.url)); + let data = Arc::new(Mutex::new(ShareMap::custom())); + let event_handler = Arc::new(handler); + + #[cfg(feature = "framework")] + let framework = Arc::new(Mutex::new(None)); + #[cfg(feature = "voice")] + let voice_manager = Arc::new(Mutex::new(ClientVoiceManager::new( + 0, + UserId(0), + ))); + + let cache_and_http = Arc::new(CacheAndHttp { + cache: Arc::new(RwLock::new(Cache::default())), + update_cache_timeout: duration, + __nonexhaustive: (), + }); + let (shard_manager, shard_manager_worker) = { ShardManager::new(ShardManagerOptions { data: &data, @@ -368,6 +482,7 @@ impl Client { #[cfg(feature = "voice")] voice_manager: &voice_manager, ws_url: &url, + cache_and_http: &cache_and_http, }) }; @@ -382,6 +497,7 @@ impl Client { threadpool, #[cfg(feature = "voice")] voice_manager, + cache_and_http, }) } |