Attempts to consume tokens and returns whether that is possible. If rate limiting is disabled on provided `token_type`, this function will always succeed.
(&self, tokens: u64, token_type: TokenType)
| 376 | /// |
| 377 | /// If rate limiting is disabled on provided `token_type`, this function will always succeed. |
| 378 | pub fn consume(&self, tokens: u64, token_type: TokenType) -> bool { |
| 379 | // If the timer is active, we can't consume tokens from any bucket and the function fails. |
| 380 | if self.is_blocked() { |
| 381 | return false; |
| 382 | } |
| 383 | let mut guard = self.inner.lock().unwrap(); |
| 384 | // Identify the required token bucket. |
| 385 | let token_bucket = match token_type { |
| 386 | TokenType::Bytes => guard.bandwidth.as_mut(), |
| 387 | TokenType::Ops => guard.ops.as_mut(), |
| 388 | }; |
| 389 | // Try to consume from the token bucket. |
| 390 | if let Some(bucket) = token_bucket { |
| 391 | let refill_time = bucket.refill_time_ms(); |
| 392 | match bucket.reduce(tokens) { |
| 393 | // When we report budget is over, there will be no further calls here, |
| 394 | // register a timer to replenish the bucket and resume processing; |
| 395 | // make sure there is only one running timer for this limiter. |
| 396 | BucketReduction::Failure => { |
| 397 | if !self.is_blocked() { |
| 398 | guard.activate_timer(TIMER_REFILL_DUR, &self.timer_active); |
| 399 | } |
| 400 | false |
| 401 | } |
| 402 | // The operation succeeded and further calls can be made. |
| 403 | BucketReduction::Success => true, |
| 404 | // The operation succeeded as the tokens have been consumed |
| 405 | // but the timer still needs to be armed. |
| 406 | BucketReduction::OverConsumption(ratio) => { |
| 407 | // The operation "borrowed" a number of tokens `ratio` times |
| 408 | // greater than the size of the bucket, and since it takes |
| 409 | // `refill_time` milliseconds to fill an empty bucket, in |
| 410 | // order to enforce the bandwidth limit we need to prevent |
| 411 | // further calls to the rate limiter for |
| 412 | // `ratio * refill_time` milliseconds. |
| 413 | guard.activate_timer( |
| 414 | Duration::from_millis((ratio * refill_time as f64) as u64), |
| 415 | &self.timer_active, |
| 416 | ); |
| 417 | true |
| 418 | } |
| 419 | } |
| 420 | } else { |
| 421 | // If bucket is not present rate limiting is disabled on token type, |
| 422 | // consume() will always succeed. |
| 423 | true |
| 424 | } |
| 425 | } |
| 426 | |
| 427 | /// Adds tokens of `token_type` to their respective bucket. |
| 428 | /// |
no test coverage detected