Sha256: 322f7dc2b53ff1953f239beae2db71bb2cc18e132aa76eb061dfef07993a7f4a

Contents?: true

Size: 952 Bytes

Versions: 1

Compression:

Stored size: 952 Bytes

Contents

require "redlock"

# https://medium.com/@jaimersonn/throttling-api-calls-in-a-distributed-environment-76d2789a796d
class DistributedRateQueue
  attr_reader :lock_duration, :lock_manager, :key

  def initialize(redis_urls:, key:, rate: 60, interval: 60)
    @lock_duration = ((interval / rate.to_f) * 1000).to_i # Redlock deals with miliseconds
    @lock_manager = Redlock::Client.new(redis_urls)
    @key = key
  end

  def shift(&block)
    if lock_manager.lock(key, lock_duration)
      # puts "timestamp: #{Time.now.to_i}"
      yield
    else
      # Logger.log("Lock not acquired, waiting for next turn...", Process.pid)
      wait_for_next_turn
      shift(&block)
    end
  end

  private

  def wait_for_next_turn
    wait = lock_manager.get_remaining_ttl_for_resource(key)
    return if wait.nil?
    return unless wait.positive?

    # Logger.log("Waiting for #{wait / 1000.0} seconds", Process.pid)
    Kernel.sleep(wait / 1000.0)
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
throttled_json_rpc_client-0.2.0 lib/limiter/distributed_rate_queue.rb