Hone logo
Hone
Problems

Token Bucket Algorithm Implementation in Go

The token bucket algorithm is a widely used rate-limiting technique. It allows you to control the rate at which requests or operations can be processed, preventing overload and ensuring fairness. This challenge asks you to implement a token bucket in Go, enabling you to manage resource consumption effectively.

Problem Description

You are tasked with creating a TokenBucket struct in Go that implements the token bucket algorithm. The bucket should have a capacity (maximum number of tokens), a refill rate (tokens added per second), and a current token count. The TokenBucket should provide methods to:

  1. NewTokenBucket(capacity int, refillRate float64): Constructor to initialize a new token bucket with the given capacity and refill rate.
  2. AllowRequest(amount int): Attempts to consume amount tokens from the bucket. If sufficient tokens are available, the tokens are consumed, and the method returns true. If not enough tokens are available, the method returns false.
  3. Refill(): Refills the bucket with tokens based on the refill rate and the elapsed time since the last refill. The refill should be proportional to the time passed. For simplicity, assume the time passed is always 1 second.
  4. GetTokensAvailable() int: Returns the number of tokens currently available in the bucket.

The bucket should automatically refill tokens at the specified rate. The refill rate is tokens per second. The AllowRequest method should check if there are enough tokens before consuming them.

Examples

Example 1:

Input: capacity = 10, refillRate = 2.0, amount = 5
Initial state: tokens = 10
AllowRequest(5)
Output: true
Explanation: The bucket has 10 tokens, which is enough to satisfy the request for 5 tokens. Tokens are consumed, leaving 5 tokens.

Example 2:

Input: capacity = 10, refillRate = 2.0, amount = 15
Initial state: tokens = 10
AllowRequest(15)
Output: false
Explanation: The bucket only has 10 tokens, which is not enough to satisfy the request for 15 tokens. The request is denied.

Example 3:

Input: capacity = 10, refillRate = 2.0
Initial state: tokens = 0
Refill()
Output: tokens = 2
Explanation: The bucket refills with 2 tokens (refillRate * 1 second).

Constraints

  • capacity must be a positive integer.
  • refillRate must be a non-negative floating-point number.
  • amount in AllowRequest must be a non-negative integer.
  • The number of tokens in the bucket should never exceed capacity.
  • The refill rate is tokens per second. Assume the time passed for refill is always 1 second.
  • The implementation should be reasonably efficient. Avoid unnecessary allocations.

Notes

  • Consider using a sync.Mutex to protect the bucket's state if you plan to use it concurrently. For this challenge, you can assume single-threaded usage, so a mutex is not strictly required, but it's good practice to think about.
  • The refill logic should be straightforward: add refillRate tokens to the bucket, but don't exceed the capacity.
  • Think about how to handle the case where the request amount is zero.
  • Focus on correctness and clarity of the code. Good variable names and comments are appreciated.
  • The GetTokensAvailable() method is primarily for testing and debugging purposes. It should return the current token count accurately.
Loading editor...
go