s3_algo/
timeout.rs

1//! The `Timeout` trait defines the how the timeout value of a multi-file upload evolves based on
2//! past file upload results. A default implementation `TimeoutState` is provided.
3use crate::config::*;
4use crate::RequestReport;
5use std::time::Duration;
6pub trait Timeout: Send + 'static {
7    /// Size is in either bytes or objects, depending on the type of requests.
8    fn get_timeout(&self, size: usize, retries: usize) -> Duration;
9    /// Update the internal estimate of the extra timeout per unit of size
10    fn update(&mut self, _: &RequestReport);
11    /// get estimated upload speed
12    fn get_estimate(&self) -> f64;
13}
14/// State for timeouts, especially tailored toward uploading files.
15/// But can be useful in any case where the size of an operation in bytes is known.
16pub struct TimeoutState {
17    seconds_per_unit_estimate: f64,
18    cfg: AlgorithmConfig,
19    specific: SpecificTimings,
20}
21impl TimeoutState {
22    pub fn new(cfg: AlgorithmConfig, specific: SpecificTimings) -> TimeoutState {
23        TimeoutState {
24            seconds_per_unit_estimate: specific.seconds_per_unit,
25            cfg,
26            specific,
27        }
28    }
29}
30impl Timeout for TimeoutState {
31    /// Not used by algorithm
32    fn get_estimate(&self) -> f64 {
33        self.seconds_per_unit_estimate
34    }
35    fn get_timeout(&self, size: usize, retries: usize) -> Duration {
36        let backoff = self.cfg.backoff.powi(retries as i32);
37        let time_estimate = (size as f64) * self.seconds_per_unit_estimate * backoff;
38        Duration::from_secs_f64(
39            self.cfg.base_timeout * backoff + self.cfg.timeout_fraction * time_estimate,
40        )
41    }
42    fn update(&mut self, result: &RequestReport) {
43        if result.size > self.specific.minimum_units_for_estimation {
44            let target = result.success_time.as_secs_f64() / (result.size as f64);
45            self.seconds_per_unit_estimate = self.cfg.avg_power * self.seconds_per_unit_estimate
46                + (1.0 - self.cfg.avg_power) * target;
47        }
48    }
49}