diff options
| author | Zeyla Hellyer <[email protected]> | 2017-10-10 20:08:11 -0700 |
|---|---|---|
| committer | Zeyla Hellyer <[email protected]> | 2017-10-10 20:08:11 -0700 |
| commit | 93e0a4215c915b98cf433ac6d0bcfbc60f0168ec (patch) | |
| tree | 727111506d1f89cd8a511b8b79c102131222421f /src/gateway | |
| parent | Resume on resumable session invalidations (diff) | |
| download | serenity-93e0a4215c915b98cf433ac6d0bcfbc60f0168ec.tar.xz serenity-93e0a4215c915b98cf433ac6d0bcfbc60f0168ec.zip | |
Switch to parking_lot::{Mutex, RwLock}
Switch to the `parking_lot` crate's implementations of
`std::sync::Mutex` and `std::sync::RwLock`, which are more efficient.
A writeup on why `parking_lot` is more efficient can be read here:
<https://github.com/Amanieu/parking_lot>
Upgrade path:
Modify `mutex.lock().unwrap()` usage to `mutex.lock()` (not needing to
unwrap or handle a result), and
`rwlock.read().unwrap()`/`rwlock.write().unwrap()` usage to
`rwlock.read()` and `rwlock.write()`.
For example, modify:
```rust
use serenity::CACHE;
println!("{}", CACHE.read().unwrap().user.id);
```
to:
```rust
use serenity::CACHE;
println!("{}", CACHE.read().user.id);
```
Diffstat (limited to 'src/gateway')
| -rw-r--r-- | src/gateway/shard.rs | 165 |
1 files changed, 132 insertions, 33 deletions
diff --git a/src/gateway/shard.rs b/src/gateway/shard.rs index 7e81813..379d183 100644 --- a/src/gateway/shard.rs +++ b/src/gateway/shard.rs @@ -1,9 +1,10 @@ use chrono::Utc; +use parking_lot::Mutex; use serde_json::Value; use std::env::consts; use std::io::Write; use std::net::Shutdown; -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use std::time::{Duration as StdDuration, Instant}; use super::{ConnectionStage, GatewayError}; use websocket::client::Url; @@ -108,25 +109,39 @@ impl Shard { /// Instantiating a new Shard manually for a bot with no shards, and /// then listening for events: /// - /// ```rust,ignore + /// ```rust,no_run + /// extern crate parking_lot; + /// extern crate serenity; + /// # + /// # use std::error::Error; + /// # + /// # fn try_main() -> Result<(), Box<Error>> { + /// # + /// use parking_lot::Mutex; /// use serenity::gateway::Shard; /// use serenity::http; /// use std::env; + /// use std::sync::Arc; /// - /// let token = env::var("DISCORD_BOT_TOKEN").expect("Token in environment"); + /// let token = Arc::new(Mutex::new(env::var("DISCORD_BOT_TOKEN")?)); /// // retrieve the gateway response, which contains the URL to connect to - /// let gateway = http::get_gateway().expect("Valid gateway response").url; - /// let shard = Shard::new(&gateway, &token, None) - /// .expect("Working shard"); + /// let gateway = Arc::new(Mutex::new(http::get_gateway()?.url)); + /// let shard = Shard::new(gateway, token, [0, 1])?; /// /// // at this point, you can create a `loop`, and receive events and match /// // their variants + /// # Ok(()) + /// # } + /// # + /// # fn main() { + /// # try_main().unwrap(); + /// # } /// ``` pub fn new(ws_url: Arc<Mutex<String>>, token: Arc<Mutex<String>>, shard_info: [u64; 2]) -> Result<Shard> { - let client = connect(&*ws_url.lock().unwrap())?; + let client = connect(&*ws_url.lock())?; let current_presence = (None, OnlineStatus::Online, false); let heartbeat_instants = (None, None); @@ -188,14 +203,26 @@ impl Shard { /// Retrieving the shard info for the second shard, out of two shards total: /// /// ```rust,no_run + /// # extern crate parking_lot; + /// # extern crate serenity; + /// # + /// # use parking_lot::Mutex; /// # use serenity::client::gateway::Shard; - /// # use std::sync::{Arc, Mutex}; + /// # use std::error::Error; + /// # use std::sync::Arc; /// # - /// # let mutex = Arc::new(Mutex::new("".to_string())); + /// # fn try_main() -> Result<(), Box<Error>> { + /// # let mutex = Arc::new(Mutex::new("".to_string())); /// # - /// # let shard = Shard::new(mutex.clone(), mutex, [1, 2]).unwrap(); + /// # let shard = Shard::new(mutex.clone(), mutex, [1, 2]).unwrap(); /// # /// assert_eq!(shard.shard_info(), [1, 2]); + /// # Ok(()) + /// # } + /// # + /// # fn main() { + /// # try_main().unwrap(); + /// # } /// ``` pub fn shard_info(&self) -> [u64; 2] { self.shard_info } @@ -218,16 +245,28 @@ impl Shard { /// Setting the current game to playing `"Heroes of the Storm"`: /// /// ```rust,no_run + /// # extern crate parking_lot; + /// # extern crate serenity; + /// # + /// # use parking_lot::Mutex; /// # use serenity::client::gateway::Shard; - /// # use std::sync::{Arc, Mutex}; + /// # use std::error::Error; + /// # use std::sync::Arc; /// # - /// # let mutex = Arc::new(Mutex::new("".to_string())); + /// # fn try_main() -> Result<(), Box<Error>> { + /// # let mutex = Arc::new(Mutex::new("".to_string())); /// # - /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap(); + /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap(); /// # /// use serenity::model::Game; /// /// shard.set_game(Some(Game::playing("Heroes of the Storm"))); + /// # Ok(()) + /// # } + /// # + /// # fn main() { + /// # try_main().unwrap(); + /// # } /// ``` pub fn set_game(&mut self, game: Option<Game>) { self.current_presence.0 = game; @@ -247,16 +286,28 @@ impl Shard { /// Setting the current online status for the shard to [`DoNotDisturb`]. /// /// ```rust,no_run + /// # extern crate parking_lot; + /// # extern crate serenity; + /// # + /// # use parking_lot::Mutex; /// # use serenity::client::gateway::Shard; - /// # use std::sync::{Arc, Mutex}; + /// # use std::error::Error; + /// # use std::sync::Arc; /// # - /// # let mutex = Arc::new(Mutex::new("".to_string())); + /// # fn try_main() -> Result<(), Box<Error>> { + /// # let mutex = Arc::new(Mutex::new("".to_string())); /// # - /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap(); + /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap(); /// # /// use serenity::model::OnlineStatus; /// /// shard.set_status(OnlineStatus::DoNotDisturb); + /// # Ok(()) + /// # } + /// # + /// # fn main() { + /// # try_main().unwrap(); + /// # } /// ``` /// /// [`DoNotDisturb`]: ../../model/enum.OnlineStatus.html#variant.DoNotDisturb @@ -282,17 +333,29 @@ impl Shard { /// and not being afk: /// /// ```rust,no_run + /// # extern crate parking_lot; + /// # extern crate serenity; + /// # + /// # use parking_lot::Mutex; /// # use serenity::client::gateway::Shard; - /// # use std::sync::{Arc, Mutex}; + /// # use std::error::Error; + /// # use std::sync::Arc; /// # - /// # let mutex = Arc::new(Mutex::new("".to_string())); + /// # fn try_main() -> Result<(), Box<Error>> { + /// # let mutex = Arc::new(Mutex::new("".to_string())); /// # - /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap(); + /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap(); /// # /// use serenity::model::{Game, OnlineStatus}; /// /// shard.set_presence(Some(Game::playing("Heroes of the Storm")), OnlineStatus::Online, /// false); + /// # Ok(()) + /// # } + /// # + /// # fn main() { + /// # try_main().unwrap(); + /// # } /// ``` pub fn set_presence(&mut self, game: Option<Game>, mut status: OnlineStatus, afk: bool) { if status == OnlineStatus::Offline { @@ -638,36 +701,60 @@ impl Shard { /// specifying a query parameter: /// /// ```rust,no_run + /// # extern crate parking_lot; + /// # extern crate serenity; + /// # + /// # use parking_lot::Mutex; /// # use serenity::client::gateway::Shard; - /// # use std::sync::{Arc, Mutex}; + /// # use std::error::Error; + /// # use std::sync::Arc; /// # - /// # let mutex = Arc::new(Mutex::new("".to_string())); + /// # fn try_main() -> Result<(), Box<Error>> { + /// # let mutex = Arc::new(Mutex::new("".to_string())); /// # - /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap(); + /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1])?; /// # /// use serenity::model::GuildId; /// /// let guild_ids = vec![GuildId(81384788765712384)]; /// /// shard.chunk_guilds(&guild_ids, Some(2000), None); + /// # Ok(()) + /// # } + /// # + /// # fn main() { + /// # try_main().unwrap(); + /// # } /// ``` /// /// Chunk a single guild by Id, limiting to 20 members, and specifying a /// query parameter of `"do"`: /// /// ```rust,no_run + /// # extern crate parking_lot; + /// # extern crate serenity; + /// # + /// # use parking_lot::Mutex; /// # use serenity::client::gateway::Shard; - /// # use std::sync::{Arc, Mutex}; + /// # use std::error::Error; + /// # use std::sync::Arc; /// # - /// # let mutex = Arc::new(Mutex::new("".to_string())); + /// # fn try_main() -> Result<(), Box<Error>> { + /// # let mutex = Arc::new(Mutex::new("".to_string())); /// # - /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap(); + /// # let mut shard = Shard::new(mutex.clone(), mutex, [0, 1])?; /// # /// use serenity::model::GuildId; /// /// let guild_ids = vec![GuildId(81384788765712384)]; /// /// shard.chunk_guilds(&guild_ids, Some(20), Some("do")); + /// # Ok(()) + /// # } + /// # + /// # fn main() { + /// # try_main().unwrap(); + /// # } /// ``` /// /// [`Event::GuildMembersChunk`]: @@ -702,24 +789,36 @@ impl Shard { /// Retrieve the number of guilds a shard is responsible for: /// /// ```rust,no_run + /// # extern crate parking_lot; + /// # extern crate serenity; + /// # + /// # use parking_lot::Mutex; /// # use serenity::client::gateway::Shard; - /// # use std::sync::{Arc, Mutex}; + /// # use std::error::Error; + /// # use std::sync::Arc; /// # - /// # let mutex = Arc::new(Mutex::new("will anyone read this".to_string())); + /// # fn try_main() -> Result<(), Box<Error>> { + /// # let mutex = Arc::new(Mutex::new("will anyone read this".to_string())); /// # - /// # let shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap(); + /// # let shard = Shard::new(mutex.clone(), mutex, [0, 1]).unwrap(); /// # /// let info = shard.shard_info(); /// let guilds = shard.guilds_handled(); /// /// println!("Shard {:?} is responsible for {} guilds", info, guilds); + /// # Ok(()) + /// # } + /// # + /// # fn main() { + /// # try_main().unwrap(); + /// # } /// ``` /// /// [`Cache`]: ../ext/cache/struct.Cache.html /// [`Guild`]: ../model/struct.Guild.html #[cfg(feature = "cache")] pub fn guilds_handled(&self) -> u16 { - let cache = CACHE.read().unwrap(); + let cache = CACHE.read(); let (shard_id, shard_count) = (self.shard_info[0], self.shard_info[1]); @@ -926,7 +1025,7 @@ impl Shard { "d": { "session_id": session_id, "seq": self.seq, - "token": &*self.token.lock().unwrap(), + "token": &*self.token.lock(), }, })) } @@ -947,7 +1046,7 @@ impl Shard { // This is used to accurately assess whether the state of the shard is // accurate when a Hello is received. self.stage = ConnectionStage::Connecting; - self.client = connect(&self.ws_url.lock().unwrap())?; + self.client = connect(&self.ws_url.lock())?; self.stage = ConnectionStage::Handshake; Ok(()) @@ -960,7 +1059,7 @@ impl Shard { "compression": true, "large_threshold": constants::LARGE_THRESHOLD, "shard": self.shard_info, - "token": &*self.token.lock().unwrap(), + "token": &*self.token.lock(), "v": constants::GATEWAY_VERSION, "properties": { "$browser": "serenity", @@ -1015,7 +1114,7 @@ impl Shard { #[cfg(feature = "cache")] { - let mut cache = CACHE.write().unwrap(); + let mut cache = CACHE.write(); let current_user_id = cache.user.id; cache.presences.get_mut(¤t_user_id).map(|presence| { |