turbulence/
bandwidth_limiter.rs1use std::time::Duration;
2
3use crate::Runtime;
4
5pub struct BandwidthLimiter<R: Runtime> {
6 runtime: R,
7 bandwidth: u32,
8 burst_bandwidth: u32,
9 bytes_available: f64,
10 last_calculation: R::Instant,
11}
12
13impl<R: Runtime> BandwidthLimiter<R> {
14 pub fn new(runtime: R, bandwidth: u32, burst_bandwidth: u32) -> BandwidthLimiter<R> {
16 let last_calculation = runtime.now();
17 BandwidthLimiter {
18 runtime,
19 bandwidth,
20 burst_bandwidth,
21 bytes_available: burst_bandwidth as f64,
22 last_calculation,
23 }
24 }
25
26 pub async fn delay_until_available(&self) {
28 if self.bytes_available < 0. {
29 self.runtime
30 .sleep(Duration::from_secs_f64(
31 (-self.bytes_available) / self.bandwidth as f64,
32 ))
33 .await;
34 }
35 }
36
37 pub fn update_available(&mut self) {
40 let now = self.runtime.now();
41 self.bytes_available += self
42 .runtime
43 .duration_between(self.last_calculation, now)
44 .as_secs_f64()
45 * self.bandwidth as f64;
46 self.bytes_available = self.bytes_available.min(self.burst_bandwidth as f64);
47 self.last_calculation = now;
48 }
49
50 pub fn bytes_available(&self) -> bool {
55 self.bytes_available >= 0.
56 }
57
58 pub fn take_bytes(&mut self, bytes: u32) {
60 self.bytes_available -= bytes as f64
61 }
62}