Class: Sidekiq::Throttled::ExpirableList

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/sidekiq/throttled/expirable_list.rb

Overview

List that tracks when elements were added and enumerates over those not older than `ttl` seconds ago.

## Implementation

Internally list holds an array of arrays. Thus ecah element is a tuple of timestamp (when element was added) and element itself:

[
  [ 1234567890.12345, "default" ],
  [ 1234567890.34567, "urgent" ],
  [ 1234579621.56789, "urgent" ],
  ...
]

It does not deduplicates elements. Eviction happens only upon elements retrieval (see #each).

Instance Method Summary collapse

Constructor Details

#initialize(ttl) ⇒ ExpirableList

Returns a new instance of ExpirableList

Parameters:

  • ttl (Float)

    elements time-to-live in seconds



30
31
32
33
34
# File 'lib/sidekiq/throttled/expirable_list.rb', line 30

def initialize(ttl)
  @ttl = ttl.to_f
  @arr = []
  @mon = Monitor.new
end

Instance Method Details

#<<(element) ⇒ ExpirableList

Pushes given element into the list.

Returns:



40
41
42
43
# File 'lib/sidekiq/throttled/expirable_list.rb', line 40

def <<(element)
  @mon.synchronize { @arr << [Time.now.to_f, element] }
  self
end

#each {|element| ... } ⇒ Enumerator, ExpirableList

Evicts expired elements and calls the given block once for each element left, passing that element as a parameter.

Yields:

  • (element)

Returns:

  • (Enumerator)

    if no block given

  • (ExpirableList)

    self if block given



51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/sidekiq/throttled/expirable_list.rb', line 51

def each
  return to_enum __method__ unless block_given?

  @mon.synchronize do
    horizon = Time.now.to_f - @ttl

    # drop all elements older than horizon
    @arr.shift while @arr[0] && @arr[0][0] < horizon

    @arr.each { |x| yield x[1] }
  end

  self
end