use RateLimitConfig for HttpClient and pull

Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
This commit is contained in:
Dietmar Maurer
2021-11-22 06:26:55 +01:00
parent 6eb756bcab
commit 2d5287fbbc
6 changed files with 77 additions and 42 deletions

View File

@ -24,7 +24,7 @@ use proxmox_http::client::{HttpsConnector, RateLimiter};
use proxmox_http::uri::build_authority;
use proxmox_async::broadcast_future::BroadcastFuture;
use pbs_api_types::{Authid, Userid};
use pbs_api_types::{Authid, Userid, RateLimitConfig};
use pbs_tools::json::json_object_to_query;
use pbs_tools::ticket;
use pbs_tools::percent_encoding::DEFAULT_ENCODE_SET;
@ -51,8 +51,7 @@ pub struct HttpClientOptions {
ticket_cache: bool,
fingerprint_cache: bool,
verify_cert: bool,
rate_limit: Option<u64>,
bucket_size: Option<u64>,
limit: RateLimitConfig,
}
impl HttpClientOptions {
@ -112,13 +111,8 @@ impl HttpClientOptions {
self
}
pub fn rate_limit(mut self, rate_limit: Option<u64>) -> Self {
self.rate_limit = rate_limit;
self
}
pub fn bucket_size(mut self, bucket_size: Option<u64>) -> Self {
self.bucket_size = bucket_size;
pub fn rate_limit(mut self, rate_limit: RateLimitConfig) -> Self {
self.limit = rate_limit;
self
}
}
@ -133,8 +127,7 @@ impl Default for HttpClientOptions {
ticket_cache: false,
fingerprint_cache: false,
verify_cert: true,
rate_limit: None,
bucket_size: None,
limit: RateLimitConfig::default(), // unlimited
}
}
}
@ -359,10 +352,18 @@ impl HttpClient {
httpc.set_connect_timeout(Some(std::time::Duration::new(10, 0)));
let mut https = HttpsConnector::with_connector(httpc, ssl_connector_builder.build(), PROXMOX_BACKUP_TCP_KEEPALIVE_TIME);
if let Some(rate_limit) = options.rate_limit {
let bucket_size = options.bucket_size.unwrap_or_else(|| rate_limit*3);
https.set_read_limiter(Some(Arc::new(Mutex::new(RateLimiter::new(rate_limit, bucket_size)))));
https.set_write_limiter(Some(Arc::new(Mutex::new(RateLimiter::new(rate_limit, bucket_size)))));
if let Some(rate_in) = options.limit.rate_in {
let burst_in = options.limit.burst_in.unwrap_or_else(|| rate_in).as_u64();
https.set_read_limiter(Some(Arc::new(Mutex::new(
RateLimiter::new(rate_in.as_u64(), burst_in)
))));
}
if let Some(rate_out) = options.limit.rate_out {
let burst_out = options.limit.burst_out.unwrap_or_else(|| rate_out).as_u64();
https.set_write_limiter(Some(Arc::new(Mutex::new(
RateLimiter::new(rate_out.as_u64(), burst_out)
))));
}
let client = Client::builder()

View File

@ -14,7 +14,7 @@ use proxmox_schema::*;
use proxmox_router::cli::{complete_file_name, shellword_split};
use proxmox::tools::fs::file_get_json;
use pbs_api_types::{BACKUP_REPO_URL, Authid, UserWithTokens};
use pbs_api_types::{BACKUP_REPO_URL, Authid, RateLimitConfig, UserWithTokens};
use pbs_datastore::BackupDir;
use pbs_tools::json::json_object_to_query;
@ -135,16 +135,16 @@ pub fn extract_repository_from_map(param: &HashMap<String, String>) -> Option<Ba
}
pub fn connect(repo: &BackupRepository) -> Result<HttpClient, Error> {
connect_do(repo.host(), repo.port(), repo.auth_id(), None, None)
let rate_limit = RateLimitConfig::default(); // unlimited
connect_do(repo.host(), repo.port(), repo.auth_id(), rate_limit)
.map_err(|err| format_err!("error building client for repository {} - {}", repo, err))
}
pub fn connect_rate_limited(
repo: &BackupRepository,
rate: Option<u64>,
bucket_size: Option<u64>,
rate_limit: RateLimitConfig,
) -> Result<HttpClient, Error> {
connect_do(repo.host(), repo.port(), repo.auth_id(), rate, bucket_size)
connect_do(repo.host(), repo.port(), repo.auth_id(), rate_limit)
.map_err(|err| format_err!("error building client for repository {} - {}", repo, err))
}
@ -152,15 +152,13 @@ fn connect_do(
server: &str,
port: u16,
auth_id: &Authid,
rate_limit: Option<u64>,
bucket_size: Option<u64>,
rate_limit: RateLimitConfig,
) -> Result<HttpClient, Error> {
let fingerprint = std::env::var(ENV_VAR_PBS_FINGERPRINT).ok();
let password = get_secret_from_env(ENV_VAR_PBS_PASSWORD)?;
let options = HttpClientOptions::new_interactive(password, fingerprint)
.rate_limit(rate_limit)
.bucket_size(bucket_size);
.rate_limit(rate_limit);
HttpClient::new(server, port, auth_id, options)
}