8 releases

new 0.2.4 Oct 29, 2024
0.2.3 Dec 11, 2023
0.2.2 Nov 17, 2022
0.2.0 Jun 9, 2022
0.1.1 Jan 28, 2022

#469 in Network programming

Download history 576/week @ 2024-07-10 626/week @ 2024-07-17 778/week @ 2024-07-24 468/week @ 2024-07-31 357/week @ 2024-08-07 366/week @ 2024-08-14 311/week @ 2024-08-21 489/week @ 2024-08-28 328/week @ 2024-09-04 272/week @ 2024-09-11 350/week @ 2024-09-18 349/week @ 2024-09-25 217/week @ 2024-10-02 224/week @ 2024-10-09 234/week @ 2024-10-16 323/week @ 2024-10-23

1,058 downloads per month
Used in bevy_mod_pies_spacetrader…

MIT/Apache

19KB
325 lines

Hierarchical token Bucket

This crate implements Hierarchical Token Bucket algorithm with fixed structure https://en.wikipedia.org/wiki/Token_bucket#Hierarchical_token_bucket

Crate does not rely on periodic updates to maintain the token buckets which means it can be updated right before requesting tokens

use htb::*;
use std::time::Duration;

#[derive(Clone, Copy, Eq, PartialEq)]
enum Rate {
    Long,
    Short,
}

impl From<Rate> for usize {
    fn from(rate: Rate) -> Self {
        match rate {
            Rate::Long => 0,
            Rate::Short => 1,
        }
    }
}

// let's implement a rate limiter with two required properties:
// - packet rate should not exceed 250 msg per second
// - packet rate should not exceed 1500 msg per 15 seconds

let mut htb = HTB::new(&[
    BucketCfg {
        this: Rate::Long,
        parent: None,
        rate: (1500, Duration::from_secs(15)),
        capacity: 0,
    },
    BucketCfg {
        this: Rate::Short,
        parent: Some(Rate::Long),
        rate: (250, Duration::from_secs(1)),
        capacity: 250,
    },
])?;

// we are allowed a single 250 token burst
assert!(htb.take_n(Rate::Short, 250));
assert!(!htb.peek(Rate::Short));
htb.advance(Duration::from_secs(1));

// after this point established packet rate obeys "long" indefinitely
for _ in 0..10 {
    assert!(htb.take_n(Rate::Short, 100));
    assert!(!htb.peek(Rate::Short));
    htb.advance(Duration::from_secs(1));
}

// if we stop consuming tokens for some time
htb.advance(Duration::from_secs(10));
assert!(htb.take_n(Rate::Short, 250));
// we get more bursts
assert!(!htb.peek(Rate::Short));
# Ok::<(), Error>(())

Dependencies

~11–430KB