1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use crate::{config::*, RequestReport};
use std::time::Duration;
pub trait Timeout: Send + 'static {
fn get_timeout(&self, size: usize, retries: usize) -> Duration;
fn update(&mut self, _: &RequestReport);
fn get_estimate(&self) -> f64;
}
pub struct TimeoutState {
seconds_per_unit_estimate: f64,
cfg: AlgorithmConfig,
specific: SpecificTimings,
}
impl TimeoutState {
pub fn new(cfg: AlgorithmConfig, specific: SpecificTimings) -> TimeoutState {
TimeoutState {
seconds_per_unit_estimate: specific.seconds_per_unit,
cfg,
specific,
}
}
}
impl Timeout for TimeoutState {
fn get_estimate(&self) -> f64 {
self.seconds_per_unit_estimate
}
fn get_timeout(&self, size: usize, retries: usize) -> Duration {
let backoff = self.cfg.backoff.powi(retries as i32);
let time_estimate = (size as f64) * self.seconds_per_unit_estimate * backoff;
Duration::from_secs_f64(
self.cfg.base_timeout * backoff + self.cfg.timeout_fraction * time_estimate,
)
}
fn update(&mut self, result: &RequestReport) {
if result.size > self.specific.minimum_units_for_estimation {
let target = result.success_time.as_secs_f64() / (result.size as f64);
self.seconds_per_unit_estimate = self.cfg.avg_power * self.seconds_per_unit_estimate
+ (1.0 - self.cfg.avg_power) * target;
}
}
}