Class: BozosBuckets::Bucket

Inherits:
Object
  • Object
show all
Defined in:
lib/bozos_buckets.rb

Overview

Class representing a token bucket

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(initial_token_count: 100, refill_rate: 1, max_token_count: 100) ⇒ Object

Constructs a Bucket instance

Parameters:

  • initial_token_count (Integer) (defaults to: 100)

    the number of tokens the bucket starts with

  • refill_rate (Double) (defaults to: 1)

    How many tokens per second should be added to the bucket. For example, 1 would be 1 token per second. 0.1 would be one token per 10 seconds

  • max_token_count (Integer) (defaults to: 100)

    the maximum number of tokens the bucket can hold. Defaults to the initial_token_count if not provided



20
21
22
23
24
25
# File 'lib/bozos_buckets.rb', line 20

def initialize(initial_token_count: 100, refill_rate: 1, max_token_count: 100)
  @current_token_count = initial_token_count
  @refill_rate = refill_rate
  @max_token_count = max_token_count || initial_token_count
  reset_last_refilled
end

Instance Attribute Details

#last_refilledObject (readonly)

Returns the value of attribute last_refilled.



8
9
10
# File 'lib/bozos_buckets.rb', line 8

def last_refilled
  @last_refilled
end

#max_token_countObject (readonly)

Returns the value of attribute max_token_count.



8
9
10
# File 'lib/bozos_buckets.rb', line 8

def max_token_count
  @max_token_count
end

#refill_rateObject (readonly)

Returns the value of attribute refill_rate.



8
9
10
# File 'lib/bozos_buckets.rb', line 8

def refill_rate
  @refill_rate
end

Instance Method Details

#current_token_countInteger

Returns the current count of available tokens, after refilling the bucket based on elapsed time. This method replaces the attr_reader to prevent clients from getting a stale value by reading the attr directly without refilling the bucket first

Returns:

  • (Integer)

    the current_token_count after refilling the bucket



65
66
67
68
# File 'lib/bozos_buckets.rb', line 65

def current_token_count
  refill_bucket
  @current_token_count
end

#refill_bucketInteger

Determines how many seconds have passed since the last time the bucket was used, calculates how many tokens should be added to the bucket, and adds them by updating @current_token_count

Returns:

  • (Integer)

    the current_token_count after refilling the bucket



50
51
52
53
54
55
56
57
# File 'lib/bozos_buckets.rb', line 50

def refill_bucket
  elapsed_seconds = Time.now.to_i - last_refilled
  tokens_to_add = (elapsed_seconds * refill_rate).floor

  reset_last_refilled

  @current_token_count = [@current_token_count + tokens_to_add, max_token_count].min
end

#use_tokens(count: 1) ⇒ Boolean

Attempt to use tokens from the bucket. If there are sufficient tokens, @current_token_count is decremented by the ‘count` and method returns `true`. If there are not sufficient tokens, method returns false without changing the @current_token_count

Parameters:

  • count (Integer) (defaults to: 1)

    Number of tokens that should be used

Returns:

  • (Boolean)

    Whether there were sufficient tokens when called



34
35
36
37
38
39
40
41
42
43
# File 'lib/bozos_buckets.rb', line 34

def use_tokens(count: 1)
  refill_bucket

  if (@current_token_count - count) >= 0
    @current_token_count -= count
    true
  else
    false
  end
end