class Sidekiq::Throttled::ExpirableList
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 each element is a tuple of monotonic timestamp (when element was added) and element itself:
[ [ 123456.7890, "default" ], [ 123456.7891, "urgent" ], [ 123457.9621, "urgent" ], ... ]
It does not deduplicates elements. Eviction happens only upon elements retrieval (see {#each}).
@see ruby-concurrency.github.io/concurrent-ruby/Concurrent.html#monotonic_time-class_method @see ruby-doc.org/core/Process.html#method-c-clock_gettime @see linux.die.net/man/3/clock_gettime
@private
Public Class Methods
@param ttl [Float] elements time-to-live in seconds
# File lib/sidekiq/throttled/expirable_list.rb, line 36 def initialize(ttl) @ttl = ttl.to_f @arr = [] @mon = Monitor.new end
Public Instance Methods
Pushes given element into the list.
@params element [Object] @return [ExpirableList] self
# File lib/sidekiq/throttled/expirable_list.rb, line 46 def <<(element) @mon.synchronize { @arr << [Concurrent.monotonic_time, element] } self end
Evicts expired elements and calls the given block once for each element left, passing that element as a parameter.
@yield [element] @return [Enumerator] if no block given @return [ExpirableList] self if block given
# File lib/sidekiq/throttled/expirable_list.rb, line 57 def each return to_enum __method__ unless block_given? @mon.synchronize do horizon = Concurrent.monotonic_time - @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