Skip to content

Commit

Permalink
Add middleware for retrying requests automatically (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
filiptibell authored Jun 9, 2024
1 parent 3a7bce9 commit 127da30
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 15 deletions.
144 changes: 141 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ reqwest = { version = "0.12", default-features = false, features = [
"brotli",
"deflate",
] }
reqwest-middleware = "0.3"
reqwest-retry = "0.5"
reqwest-tracing = "0.5"
tokio = { version = "1.36", features = ["full"] }
tracing = "0.1"

Expand Down
41 changes: 41 additions & 0 deletions lib/sources/client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use std::time::Duration;

use reqwest::{header::HeaderMap, Client, Error};
use reqwest_middleware::{ClientBuilder, ClientWithMiddleware};
use reqwest_retry::{policies::ExponentialBackoff, RetryTransientMiddleware};
use reqwest_tracing::TracingMiddleware;

/*
Adds middleware for:
- Retrying failed requests with exponential backoff
- Tracing of HTTP requests
*/
fn add_client_middleware(client: Client) -> ClientWithMiddleware {
ClientBuilder::new(client)
.with(RetryTransientMiddleware::new_with_policy(
ExponentialBackoff::builder().build_with_max_retries(3),
))
.with(TracingMiddleware::default())
.build()
}

/**
Creates a client with:
- HTTPS only
- Timeouts for connection and response
- All common compression algorithms enabled
*/
pub fn create_client(default_headers: HeaderMap) -> Result<ClientWithMiddleware, Error> {
let client = Client::builder()
.default_headers(default_headers)
.https_only(true)
.connect_timeout(Duration::from_secs(15))
.timeout(Duration::from_secs(60))
.gzip(true)
.brotli(true)
.deflate(true)
.build()?;
Ok(add_client_middleware(client))
}
16 changes: 4 additions & 12 deletions lib/sources/github/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::time::Duration;

use reqwest_middleware::ClientWithMiddleware;
use semver::Version;
use serde::de::DeserializeOwned;
use tracing::{debug, instrument};
Expand All @@ -11,7 +10,7 @@ use reqwest::{

use crate::tool::{ToolId, ToolSpec};

use super::{Artifact, ArtifactProvider};
use super::{client::create_client, Artifact, ArtifactProvider};

const BASE_URL: &str = "https://api.github.com";

Expand All @@ -24,7 +23,7 @@ pub use self::result::{GithubError, GithubResult};

#[derive(Debug, Clone)]
pub struct GithubProvider {
client: reqwest::Client,
client: ClientWithMiddleware,
has_auth: bool,
}

Expand All @@ -45,14 +44,7 @@ impl GithubProvider {
headers
};

let client = reqwest::Client::builder()
.default_headers(headers)
.gzip(true)
.brotli(true)
.deflate(true)
.connect_timeout(Duration::from_secs(15))
.timeout(Duration::from_secs(60))
.build()?;
let client = create_client(headers)?;

Ok(Self { client, has_auth })
}
Expand Down
8 changes: 8 additions & 0 deletions lib/sources/github/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ pub enum GithubError {
ReleaseNotFound(Box<ToolSpec>),
#[error("failed to build client - invalid header value: {0}")]
ReqwestHeader(Box<InvalidHeaderValue>),
#[error("reqwest middleware error: {0}")]
ReqwestMiddleware(Box<reqwest_middleware::Error>),
#[error("reqwest error: {0}")]
Reqwest(Box<reqwest::Error>),
#[error("other error: {0}")]
Expand All @@ -29,6 +31,12 @@ impl From<InvalidHeaderValue> for GithubError {
}
}

impl From<reqwest_middleware::Error> for GithubError {
fn from(err: reqwest_middleware::Error) -> Self {
GithubError::ReqwestMiddleware(err.into())
}
}

impl From<ReqwestError> for GithubError {
fn from(err: ReqwestError) -> Self {
GithubError::Reqwest(err.into())
Expand Down
1 change: 1 addition & 0 deletions lib/sources/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod artifact;
mod client;
mod decompression;
mod extraction;
mod source;
Expand Down

0 comments on commit 127da30

Please sign in to comment.