From fb860c52d26aa39d41764497eadad0e5ebd5e4f5 Mon Sep 17 00:00:00 2001 From: u5surf Date: Sat, 3 Oct 2020 06:33:57 +0900 Subject: [PATCH] Support exponential backoff in check_real #1 --- src/checker.rs | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/src/checker.rs b/src/checker.rs index 71650f1..9ab6398 100644 --- a/src/checker.rs +++ b/src/checker.rs @@ -6,6 +6,7 @@ use hubcaps::{Credentials, Github}; use regex::{Regex, RegexSet}; use reqwest::header::{self, HeaderMap, HeaderValue}; use std::{collections::HashSet, convert::TryFrom, time::Duration}; +use tokio::time::delay_for; use url::Url; pub(crate) enum RequestMethod { @@ -163,10 +164,23 @@ impl Checker { } pub async fn check_real(&self, url: &Url) -> Status { - let status = self.check_normal(&url).await; - if status.is_success() { - return status; - } + let mut retries: i64 = 3; + let mut wait: u64 = 1; + let status = loop { + let res = self.check_normal(&url).await; + match res.is_success() { + true => return res, + false => { + if retries > 0 { + retries -= 1; + delay_for(Duration::from_secs(wait)).await; + wait *= 2; + } else { + break res; + } + } + } + }; // Pull out the heavy weapons in case of a failed normal request. // This could be a Github URL and we run into the rate limiter. if let Ok((owner, repo)) = self.extract_github(url.as_str()) { @@ -262,7 +276,7 @@ impl Checker { mod test { use super::*; use http::StatusCode; - use std::time::Duration; + use std::time::{Duration, Instant}; use url::Url; use wiremock::matchers::method; use wiremock::{Mock, MockServer, ResponseTemplate}; @@ -295,6 +309,20 @@ mod test { assert!(matches!(res, Status::Failed(_))); } + #[tokio::test] + async fn test_exponetial_backoff() { + let start = Instant::now(); + let res = get_checker(false, HeaderMap::new()) + .check(&Uri::Website( + Url::parse("https://endler.dev/abcd").unwrap(), + )) + .await; + let end = start.elapsed(); + + assert!(matches!(res, Status::Failed(_))); + assert!(matches!(end.as_secs(), 7)); + } + #[test] fn test_is_github() { assert_eq!(