|
1 | 1 | use std::prelude::v1::*;
|
2 | 2 |
|
3 | 3 | use crate::{
|
4 |
| - clock, middleware::RateLimitingMiddleware, state::keyed::KeyedStateStore, Jitter, NotUntil, |
5 |
| - RateLimiter, |
| 4 | + clock, errors::InsufficientCapacity, middleware::RateLimitingMiddleware, |
| 5 | + state::keyed::KeyedStateStore, Jitter, NotUntil, RateLimiter, |
6 | 6 | };
|
7 | 7 | use futures_timer::Delay;
|
8 |
| -use std::hash::Hash; |
| 8 | +use std::{hash::Hash, num::NonZeroU32}; |
9 | 9 |
|
10 | 10 | #[cfg(feature = "std")]
|
11 | 11 | /// # Keyed rate limiters - `async`/`await`
|
|
57 | 57 | }
|
58 | 58 | }
|
59 | 59 | }
|
| 60 | + |
| 61 | + /// Asynchronously resolves as soon as the rate limiter allows it. |
| 62 | + /// |
| 63 | + /// This is similar to `until_key_ready` except it waits for an abitrary number |
| 64 | + /// of `n` cells to be available. |
| 65 | + /// |
| 66 | + /// Returns `InsufficientCapacity` if the `n` provided exceeds the maximum |
| 67 | + /// capacity of the rate limiter. |
| 68 | + pub async fn until_key_n_ready( |
| 69 | + &self, |
| 70 | + key: &K, |
| 71 | + n: NonZeroU32, |
| 72 | + ) -> Result<MW::PositiveOutcome, InsufficientCapacity> { |
| 73 | + self.until_key_n_ready_with_jitter(key, n, Jitter::NONE) |
| 74 | + .await |
| 75 | + } |
| 76 | + |
| 77 | + /// Asynchronously resolves as soon as the rate limiter allows it, with a |
| 78 | + /// randomized wait period. |
| 79 | + /// |
| 80 | + /// This is similar to `until_key_ready_with_jitter` except it waits for an |
| 81 | + /// abitrary number of `n` cells to be available. |
| 82 | + /// |
| 83 | + /// Returns `InsufficientCapacity` if the `n` provided exceeds the maximum |
| 84 | + /// capacity of the rate limiter. |
| 85 | + pub async fn until_key_n_ready_with_jitter( |
| 86 | + &self, |
| 87 | + key: &K, |
| 88 | + n: NonZeroU32, |
| 89 | + jitter: Jitter, |
| 90 | + ) -> Result<MW::PositiveOutcome, InsufficientCapacity> { |
| 91 | + loop { |
| 92 | + match self.check_key_n(key, n)? { |
| 93 | + Ok(x) => { |
| 94 | + return Ok(x); |
| 95 | + } |
| 96 | + Err(negative) => { |
| 97 | + let delay = Delay::new(jitter + negative.wait_time_from(self.clock.now())); |
| 98 | + delay.await; |
| 99 | + } |
| 100 | + } |
| 101 | + } |
| 102 | + } |
60 | 103 | }
|
0 commit comments