From e36c385f15eb9ba95925abcc99eb4068d453b030 Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Thu, 18 Feb 2021 03:42:49 +0900 Subject: [PATCH] Update to codeforces package with sound ratelimiting --- Cargo.lock | 5 +++-- youmubot-cf/src/announcer.rs | 10 ++++------ youmubot-cf/src/hook.rs | 27 +++++++++++---------------- youmubot-cf/src/lib.rs | 16 ++++++---------- youmubot-cf/src/live.rs | 6 ++---- 5 files changed, 26 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2c9f428..a125dfb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -154,10 +154,11 @@ dependencies = [ [[package]] name = "codeforces" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df54b4689d51d58162c8b76a642ba44d6128b68f29c3fbc23815e6ea4bfef15" +checksum = "f0167d57615475a20056a4ce224d143cf603f7159e3102ac5e6a3a1d9ea1c71a" dependencies = [ + "flume", "futures-util", "reqwest", "serde", diff --git a/youmubot-cf/src/announcer.rs b/youmubot-cf/src/announcer.rs index 722289c..f65d68f 100644 --- a/youmubot-cf/src/announcer.rs +++ b/youmubot-cf/src/announcer.rs @@ -74,13 +74,13 @@ async fn update_user( user_id: UserId, cfu: &mut CfUser, ) -> Result<()> { - let info = User::info(&*client.borrow().await?, &[cfu.handle.as_str()]) + let info = User::info(&*client, &[cfu.handle.as_str()]) .await? .into_iter() .next() .ok_or(Error::msg("Not found"))?; - let rating_changes = info.rating_changes(&*client.borrow().await?).await?; + let rating_changes = info.rating_changes(&*client).await?; let channels_list = channels.channels_of(&http, user_id).await; cfu.last_update = Utc::now(); @@ -119,10 +119,8 @@ async fn update_user( return Ok(()); } let (contest, _, _) = - codeforces::Contest::standings(&*client.borrow().await?, rc.contest_id, |f| { - f.limit(1, 1) - }) - .await?; + codeforces::Contest::standings(&*client, rc.contest_id, |f| f.limit(1, 1)) + .await?; channels .iter() .map(|channel| { diff --git a/youmubot-cf/src/hook.rs b/youmubot-cf/src/hook.rs index 9e76496..95946f3 100644 --- a/youmubot-cf/src/hook.rs +++ b/youmubot-cf/src/hook.rs @@ -42,7 +42,7 @@ impl TypeMapKey for ContestCache { impl ContestCache { /// Creates a new, empty cache. pub(crate) async fn new(http: Client) -> Result { - let contests_list = Contest::list(&*http.borrow().await?, true).await?; + let contests_list = Contest::list(&*http, true).await?; Ok(Self { contests: HashMap::new(), all_list: RwLock::new((contests_list, Instant::now())), @@ -64,17 +64,14 @@ impl ContestCache { &self, contest_id: u64, ) -> Result<(Contest, Option>)> { - let (c, p) = - match Contest::standings(&*self.http.borrow().await?, contest_id, |f| f.limit(1, 1)) - .await - { - Ok((c, p, _)) => (c, Some(p)), - Err(codeforces::Error::Codeforces(s)) if s.ends_with("has not started") => { - let c = self.get_from_list(contest_id).await?; - (c, None) - } - Err(v) => return Err(Error::from(v)), - }; + let (c, p) = match Contest::standings(&*self.http, contest_id, |f| f.limit(1, 1)).await { + Ok((c, p, _)) => (c, Some(p)), + Err(codeforces::Error::Codeforces(s)) if s.ends_with("has not started") => { + let c = self.get_from_list(contest_id).await?; + (c, None) + } + Err(v) => return Err(Error::from(v)), + }; self.contests.insert(contest_id, (c, p)); Ok(self.contests.get(&contest_id).unwrap().clone()) } @@ -83,10 +80,8 @@ impl ContestCache { let last_updated = self.all_list.read().await.1.clone(); if Instant::now() - last_updated > std::time::Duration::from_secs(60 * 60) { // We update at most once an hour. - *self.all_list.write().await = ( - Contest::list(&*self.http.borrow().await?, true).await?, - Instant::now(), - ); + *self.all_list.write().await = + (Contest::list(&*self.http, true).await?, Instant::now()); } self.all_list .read() diff --git a/youmubot-cf/src/lib.rs b/youmubot-cf/src/lib.rs index b9eda5d..21adae3 100644 --- a/youmubot-cf/src/lib.rs +++ b/youmubot-cf/src/lib.rs @@ -22,7 +22,7 @@ mod live; struct CFClient; impl TypeMapKey for CFClient { - type Value = Arc>; + type Value = Arc; } use db::{CfSavedUsers, CfUser}; @@ -33,11 +33,7 @@ pub use hook::InfoHook; pub async fn setup(path: &std::path::Path, data: &mut TypeMap, announcers: &mut AnnouncerHandler) { CfSavedUsers::insert_into(data, path.join("cf_saved_users.yaml")) .expect("Must be able to set up DB"); - let client = Arc::new(ratelimit::Ratelimit::new( - codeforces::Client::new(), - 4, - std::time::Duration::from_secs(1), - )); + let client = Arc::new(codeforces::Client::new()); data.insert::(hook::ContestCache::new(client.clone()).await.unwrap()); data.insert::(client); announcers.add("codeforces", announcer::Announcer); @@ -78,7 +74,7 @@ pub async fn profile(ctx: &Context, m: &Message, mut args: Args) -> CommandResul } }; - let account = codeforces::User::info(&*http.borrow().await?, &[&handle[..]]) + let account = codeforces::User::info(&*http, &[&handle[..]]) .await? .into_iter() .next(); @@ -110,7 +106,7 @@ pub async fn save(ctx: &Context, m: &Message, mut args: Args) -> CommandResult { let handle = args.single::()?; let http = data.get::().unwrap(); - let account = codeforces::User::info(&*http.borrow().await?, &[&handle[..]]) + let account = codeforces::User::info(&*http, &[&handle[..]]) .await? .into_iter() .next(); @@ -122,7 +118,7 @@ pub async fn save(ctx: &Context, m: &Message, mut args: Args) -> CommandResult { } Some(acc) => { // Collect rating changes data. - let rating_changes = acc.rating_changes(&*http.borrow().await?).await?; + let rating_changes = acc.rating_changes(&*http).await?; let mut db = CfSavedUsers::open(&*data); m.reply( &ctx, @@ -272,7 +268,7 @@ pub async fn contestranks(ctx: &Context, m: &Message, mut args: Args) -> Command .collect::>() .await; let http = data.get::().unwrap(); - let (contest, problems, ranks) = Contest::standings(&*http.borrow().await?, contest_id, |f| { + let (contest, problems, ranks) = Contest::standings(&*http, contest_id, |f| { f.handles(members.iter().map(|(k, _)| k.clone()).collect()) }) .await?; diff --git a/youmubot-cf/src/live.rs b/youmubot-cf/src/live.rs index ee69c4c..46c3f64 100644 --- a/youmubot-cf/src/live.rs +++ b/youmubot-cf/src/live.rs @@ -57,7 +57,7 @@ pub async fn watch_contest( let http = data.get::().unwrap(); let (mut contest, problems, _) = - Contest::standings(&*http.borrow().await?, contest_id, |f| f.limit(1, 1)).await?; + Contest::standings(&*http, contest_id, |f| f.limit(1, 1)).await?; msg.edit(&ctx, |e| { e.content(format!( @@ -79,9 +79,7 @@ pub async fn watch_contest( msg.pin(ctx).await.ok(); loop { - if let Ok(messages) = - scan_changes(&*http.borrow().await?, &mut member_results, &mut contest).await - { + if let Ok(messages) = scan_changes(&*http, &mut member_results, &mut contest).await { for message in messages { channel .send_message(&ctx, |e| {