xmtp_common/
rate_limit.rs1use crate::time::{Duration, Instant};
4
5pub struct Bucket {
7 rate: f64,
8 capacity: f64,
9 tokens: f64,
10 updated: Instant,
11}
12
13impl Bucket {
14 pub fn new(rate: u32, burst: u32) -> Self {
16 Self {
17 rate: rate as f64,
18 capacity: burst as f64,
19 tokens: burst as f64,
20 updated: Instant::now(),
21 }
22 }
23
24 fn refill(&mut self) {
25 let now = Instant::now();
26 self.tokens = (self.tokens + now.duration_since(self.updated).as_secs_f64() * self.rate)
27 .min(self.capacity);
28 self.updated = now;
29 }
30
31 pub fn take(&mut self) -> bool {
33 self.refill();
34 if self.tokens < 1.0 {
35 false
36 } else {
37 self.tokens -= 1.0;
38 true
39 }
40 }
41
42 pub fn refund(&mut self) {
44 self.tokens = (self.tokens + 1.0).min(self.capacity);
45 }
46
47 pub fn wait(&mut self) -> Duration {
49 self.refill();
50 if self.tokens >= 1.0 {
51 Duration::ZERO
52 } else if self.rate == 0.0 || self.capacity < 1.0 {
53 Duration::MAX
54 } else {
55 Duration::from_secs_f64((1.0 - self.tokens) / self.rate)
56 }
57 }
58}