class Redrate::Ring

Public Class Methods

new(size, key, default) click to toggle source
# File lib/redrate/ring.rb, line 8
def initialize(size, key, default)
  @redis = Redis.current
  @redlock = Redlock::Client.new([@redis])
  @size = size
  @key = key
  @default = default

  initialize_ring
end

Public Instance Methods

current() click to toggle source
# File lib/redrate/ring.rb, line 22
def current
  (@redis.lindex(ring_key, head) || @default).to_i
end
head() click to toggle source
# File lib/redrate/ring.rb, line 18
def head
  @redis.get(head_key).to_i
end
lock() { || ... } click to toggle source
# File lib/redrate/ring.rb, line 35
def lock
  completed = false
  timeout_time = monotonic_time + 2000
  while !completed && (monotonic_time < timeout_time)
    @redlock.lock(lock_key, 2000) do |locked|
      if locked
        yield
        completed = true
      end
    end
  end
end
now() click to toggle source
# File lib/redrate/ring.rb, line 48
def now
  @redis.time[0]
end
rotate!() click to toggle source
# File lib/redrate/ring.rb, line 26
def rotate!
  current_head = head
  current_time = now
  @redis.pipelined do
    @redis.lset(ring_key, current_head, current_time.to_s)
    @redis.set(head_key, (current_head + 1) % @size)
  end
end

Private Instance Methods

head_key() click to toggle source
# File lib/redrate/ring.rb, line 54
def head_key
  @head_key ||= key_for(:head)
end
initialize_ring() click to toggle source
# File lib/redrate/ring.rb, line 70
def initialize_ring
  return unless @redis.llen(ring_key).zero?

  @redis.pipelined do
    1.upto(@size) do
      @redis.lpush(ring_key, @default)
    end
    @redis.set(head_key, 0)
  end
end
key_for(thing) click to toggle source
# File lib/redrate/ring.rb, line 66
def key_for(thing)
  ['rate', @key, thing].join(':')
end
lock_key() click to toggle source
# File lib/redrate/ring.rb, line 62
def lock_key
  @lock_key ||= key_for(:lock)
end
monotonic_time() click to toggle source
# File lib/redrate/ring.rb, line 81
def monotonic_time
  Process.clock_gettime(Process::CLOCK_MONOTONIC)
end
ring_key() click to toggle source
# File lib/redrate/ring.rb, line 58
def ring_key
  @ring_key ||= key_for(:ring)
end