Skip to content

Commit 6483630

Browse files
alexandruagalxiord
authored andcommitted
rate_limiter: added immutable accessor methods
Added immutable accessor methods for some of the fields in TokenBucket and RateLimiter. Signed-off-by: Alexandru Agache <[email protected]>
1 parent afaa3d5 commit 6483630

File tree

1 file changed

+58
-22
lines changed

1 file changed

+58
-22
lines changed

rate_limiter/src/lib.rs

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ pub struct TokenBucket {
9494
// Bucket defining traits.
9595
size: u64,
9696
one_time_burst: Option<u64>,
97+
// Complete refill time in milliseconds.
9798
refill_time: u64,
9899

99100
// Internal state descriptors.
@@ -218,6 +219,26 @@ impl TokenBucket {
218219
}
219220
self.budget = std::cmp::min(self.budget + tokens, self.size);
220221
}
222+
223+
/// Returns the capacity of the token bucket.
224+
pub fn capacity(&self) -> u64 {
225+
self.size
226+
}
227+
228+
/// Returns the remaining one time burst budget.
229+
pub fn one_time_burst(&self) -> u64 {
230+
self.one_time_burst.unwrap_or(0)
231+
}
232+
233+
/// Returns the time in milliseconds required to to completely fill the bucket.
234+
pub fn refill_time_ms(&self) -> u64 {
235+
self.refill_time
236+
}
237+
238+
/// Returns the current budget (one time burst allowance notwithstanding).
239+
pub fn budget(&self) -> u64 {
240+
self.budget
241+
}
221242
}
222243

223244
/// Enum that describes the type of token used.
@@ -479,6 +500,16 @@ impl RateLimiter {
479500
)),
480501
}
481502
}
503+
504+
/// Returns an immutable view of the inner bandwidth token bucket.
505+
pub fn bandwidth(&self) -> Option<&TokenBucket> {
506+
self.bandwidth.as_ref()
507+
}
508+
509+
/// Returns an immutable view of the inner ops token bucket.
510+
pub fn ops(&self) -> Option<&TokenBucket> {
511+
self.ops.as_ref()
512+
}
482513
}
483514

484515
impl AsRawFd for RateLimiter {
@@ -517,14 +548,6 @@ mod tests {
517548
self.last_update = time::precise_time_ns();
518549
}
519550

520-
fn get_capacity(&self) -> u64 {
521-
self.size
522-
}
523-
524-
fn get_current_budget(&self) -> u64 {
525-
self.budget
526-
}
527-
528551
fn get_last_update(&self) -> u64 {
529552
self.last_update
530553
}
@@ -536,10 +559,6 @@ mod tests {
536559
fn get_processed_refill_time(&self) -> u64 {
537560
self.processed_refill_time
538561
}
539-
540-
fn get_one_time_burst(&self) -> u64 {
541-
self.one_time_burst.unwrap_or(0)
542-
}
543562
}
544563

545564
impl RateLimiter {
@@ -555,8 +574,8 @@ mod tests {
555574
fn test_token_bucket_create() {
556575
let before = time::precise_time_ns();
557576
let tb = TokenBucket::new(1000, None, 1000);
558-
assert_eq!(tb.get_capacity(), 1000);
559-
assert_eq!(tb.get_current_budget(), 1000);
577+
assert_eq!(tb.capacity(), 1000);
578+
assert_eq!(tb.budget(), 1000);
560579
assert!(tb.get_last_update() >= before);
561580
assert!(tb.get_last_update() <= time::precise_time_ns());
562581
assert_eq!(tb.get_processed_capacity(), 1);
@@ -587,30 +606,30 @@ mod tests {
587606
let mut tb = TokenBucket::new(capacity, None, refill_ms as u64);
588607

589608
assert!(tb.reduce(123));
590-
assert_eq!(tb.get_current_budget(), capacity - 123);
609+
assert_eq!(tb.budget(), capacity - 123);
591610

592611
thread::sleep(Duration::from_millis(123));
593612
assert!(tb.reduce(1));
594-
assert_eq!(tb.get_current_budget(), capacity - 1);
613+
assert_eq!(tb.budget(), capacity - 1);
595614
assert!(tb.reduce(100));
596615
assert!(!tb.reduce(capacity));
597616

598617
// token bucket with capacity 1000 and refill time of 1000 milliseconds
599618
let mut tb = TokenBucket::new(1000, Some(1100), 1000);
600619
// safely assuming the thread can run these 3 commands in less than 500ms
601620
assert!(tb.reduce(1000));
602-
assert_eq!(tb.get_one_time_burst(), 100);
621+
assert_eq!(tb.one_time_burst(), 100);
603622
assert!(tb.reduce(500));
604-
assert_eq!(tb.get_one_time_burst(), 0);
623+
assert_eq!(tb.one_time_burst(), 0);
605624
assert!(tb.reduce(500));
606625
assert!(!tb.reduce(500));
607626
thread::sleep(Duration::from_millis(500));
608627
assert!(tb.reduce(500));
609628

610629
let before = time::precise_time_ns();
611630
tb.reset();
612-
assert_eq!(tb.get_capacity(), 1000);
613-
assert_eq!(tb.get_current_budget(), 1000);
631+
assert_eq!(tb.capacity(), 1000);
632+
assert_eq!(tb.budget(), 1000);
614633
assert!(tb.get_last_update() >= before);
615634
assert!(tb.get_last_update() <= time::precise_time_ns());
616635
}
@@ -635,6 +654,23 @@ mod tests {
635654
assert_eq!(l.as_raw_fd(), -1);
636655
}
637656

657+
#[test]
658+
fn test_rate_limiter_new() {
659+
let l = RateLimiter::new(1000, Some(1001), 1002, 1003, Some(1004), 1005).unwrap();
660+
661+
let bw = l.bandwidth.unwrap();
662+
assert_eq!(bw.capacity(), 1000);
663+
assert_eq!(bw.one_time_burst(), 1001);
664+
assert_eq!(bw.refill_time_ms(), 1002);
665+
assert_eq!(bw.budget(), 1000);
666+
667+
let ops = l.ops.unwrap();
668+
assert_eq!(ops.capacity(), 1003);
669+
assert_eq!(ops.one_time_burst(), 1004);
670+
assert_eq!(ops.refill_time_ms(), 1005);
671+
assert_eq!(ops.budget(), 1003);
672+
}
673+
638674
#[test]
639675
fn test_rate_limiter_manual_replenish() {
640676
// rate limiter with limit of 1000 bytes/s and 1000 ops/s
@@ -645,14 +681,14 @@ mod tests {
645681
l.manual_replenish(23, TokenType::Bytes);
646682
{
647683
let bytes_tb = l.get_token_bucket(TokenType::Bytes).unwrap();
648-
assert_eq!(bytes_tb.get_current_budget(), 900);
684+
assert_eq!(bytes_tb.budget(), 900);
649685
}
650686
// consume 123 ops
651687
assert!(l.consume(123, TokenType::Ops));
652688
l.manual_replenish(23, TokenType::Ops);
653689
{
654690
let bytes_tb = l.get_token_bucket(TokenType::Ops).unwrap();
655-
assert_eq!(bytes_tb.get_current_budget(), 900);
691+
assert_eq!(bytes_tb.budget(), 900);
656692
}
657693
}
658694

0 commit comments

Comments
 (0)