various: shared HTTP client with connection pooling
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Id13c17e9352da970a289f4e3ad909c5b6a6a6964
This commit is contained in:
parent
0cc72e9916
commit
7ee9ee1159
6 changed files with 64 additions and 20 deletions
16
src/http.rs
Normal file
16
src/http.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
use std::time::Duration;
|
||||
|
||||
use reqwest::Client;
|
||||
|
||||
pub fn create_http_client() -> Client {
|
||||
Client::builder()
|
||||
.pool_max_idle_per_host(10)
|
||||
.pool_idle_timeout(Duration::from_secs(30))
|
||||
.tcp_keepalive(Duration::from_secs(60))
|
||||
.tcp_nodelay(true)
|
||||
.connect_timeout(Duration::from_secs(15))
|
||||
.timeout(Duration::from_secs(30))
|
||||
.user_agent("Pakker/0.1.0")
|
||||
.build()
|
||||
.expect("Failed to build HTTP client")
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ mod error;
|
|||
mod export;
|
||||
mod fetch;
|
||||
mod git;
|
||||
mod http;
|
||||
mod ipc;
|
||||
mod model;
|
||||
mod platform;
|
||||
|
|
@ -23,8 +24,6 @@ use clap::Parser;
|
|||
use cli::{Cli, Commands};
|
||||
use error::PakkerError;
|
||||
|
||||
use crate::rate_limiter::RateLimiter;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), PakkerError> {
|
||||
let cli = Cli::parse();
|
||||
|
|
@ -48,8 +47,6 @@ async fn main() -> Result<(), PakkerError> {
|
|||
let lockfile_path = working_dir.join("pakker-lock.json");
|
||||
let config_path = working_dir.join("pakker.json");
|
||||
|
||||
let _rate_limiter = std::sync::Arc::new(RateLimiter::new(None));
|
||||
|
||||
match cli.command {
|
||||
Commands::Init(args) => {
|
||||
cli::commands::init::execute(args, &lockfile_path, &config_path).await
|
||||
|
|
|
|||
|
|
@ -10,11 +10,18 @@ pub use github::GitHubPlatform;
|
|||
pub use modrinth::ModrinthPlatform;
|
||||
pub use traits::PlatformClient;
|
||||
|
||||
use crate::{error::Result, rate_limiter::RateLimiter};
|
||||
use crate::{error::Result, http, rate_limiter::RateLimiter};
|
||||
|
||||
static HTTP_CLIENT: std::sync::LazyLock<Arc<reqwest::Client>> =
|
||||
std::sync::LazyLock::new(|| Arc::new(http::create_http_client()));
|
||||
|
||||
static RATE_LIMITER: std::sync::LazyLock<Arc<RateLimiter>> =
|
||||
std::sync::LazyLock::new(|| Arc::new(RateLimiter::new(None)));
|
||||
|
||||
pub fn get_http_client() -> Arc<reqwest::Client> {
|
||||
HTTP_CLIENT.clone()
|
||||
}
|
||||
|
||||
pub fn create_platform(
|
||||
platform: &str,
|
||||
api_key: Option<String>,
|
||||
|
|
@ -33,9 +40,21 @@ fn create_client(
|
|||
api_key: Option<String>,
|
||||
) -> Result<Box<dyn PlatformClient>> {
|
||||
match platform {
|
||||
"modrinth" => Ok(Box::new(ModrinthPlatform::new())),
|
||||
"curseforge" => Ok(Box::new(CurseForgePlatform::new(api_key))),
|
||||
"github" => Ok(Box::new(GitHubPlatform::new(api_key))),
|
||||
"modrinth" => {
|
||||
Ok(Box::new(ModrinthPlatform::with_client(get_http_client())))
|
||||
},
|
||||
"curseforge" => {
|
||||
Ok(Box::new(CurseForgePlatform::with_client(
|
||||
get_http_client(),
|
||||
api_key,
|
||||
)))
|
||||
},
|
||||
"github" => {
|
||||
Ok(Box::new(GitHubPlatform::with_client(
|
||||
get_http_client(),
|
||||
api_key,
|
||||
)))
|
||||
},
|
||||
_ => {
|
||||
Err(crate::error::PakkerError::ConfigError(format!(
|
||||
"Unknown platform: {platform}"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use reqwest::Client;
|
||||
|
|
@ -20,18 +20,22 @@ const LOADER_VERSION_TYPE_ID: i32 = 68441;
|
|||
const DEPENDENCY_RELATION_TYPE_REQUIRED: u32 = 3;
|
||||
|
||||
pub struct CurseForgePlatform {
|
||||
client: Client,
|
||||
client: Arc<Client>,
|
||||
api_key: Option<String>,
|
||||
}
|
||||
|
||||
impl CurseForgePlatform {
|
||||
pub fn new(api_key: Option<String>) -> Self {
|
||||
Self {
|
||||
client: Client::new(),
|
||||
client: Arc::new(Client::new()),
|
||||
api_key,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_client(client: Arc<Client>, api_key: Option<String>) -> Self {
|
||||
Self { client, api_key }
|
||||
}
|
||||
|
||||
fn get_headers(&self) -> Result<reqwest::header::HeaderMap> {
|
||||
let mut headers = reqwest::header::HeaderMap::new();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use regex::Regex;
|
||||
|
|
@ -20,9 +20,9 @@ pub struct GitHubPlatform {
|
|||
}
|
||||
|
||||
impl GitHubPlatform {
|
||||
pub fn new(token: Option<String>) -> Self {
|
||||
pub fn with_client(client: Arc<Client>, token: Option<String>) -> Self {
|
||||
Self {
|
||||
client: Client::new(),
|
||||
client: (*client).clone(),
|
||||
token,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use reqwest::Client;
|
||||
|
|
@ -14,16 +14,20 @@ use crate::{
|
|||
const MODRINTH_API_BASE: &str = "https://api.modrinth.com/v2";
|
||||
|
||||
pub struct ModrinthPlatform {
|
||||
client: Client,
|
||||
client: Arc<Client>,
|
||||
}
|
||||
|
||||
impl ModrinthPlatform {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
client: Client::new(),
|
||||
client: Arc::new(Client::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_client(client: Arc<Client>) -> Self {
|
||||
Self { client }
|
||||
}
|
||||
|
||||
async fn request_project_url(&self, url: &str) -> Result<Project> {
|
||||
let response = self.client.get(url).send().await?;
|
||||
if !response.status().is_success() {
|
||||
|
|
@ -295,13 +299,17 @@ struct ModrinthDependency {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::sync::Arc;
|
||||
|
||||
use reqwest::Client;
|
||||
|
||||
use super::*;
|
||||
|
||||
impl ModrinthPlatform {
|
||||
fn with_client(client: Client) -> Self {
|
||||
Self { client }
|
||||
fn with_raw_client(client: Client) -> Self {
|
||||
Self {
|
||||
client: Arc::new(client),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -309,7 +317,7 @@ mod tests {
|
|||
-> (ModrinthPlatform, mockito::ServerGuard) {
|
||||
let server = mockito::Server::new_async().await;
|
||||
let client = Client::new();
|
||||
let platform = ModrinthPlatform::with_client(client);
|
||||
let platform = ModrinthPlatform::with_raw_client(client);
|
||||
(platform, server)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue