require 'sidekiq/client' require 'sidekiq/circuit_breaker/manager' require 'sidekiq/circuit_breaker/scope' module Sidekiq module CircuitBreaker module Middleware class Client include Sidekiq::CircuitBreaker::Scope def call(worker_class, msg, queue, redis_pool) begin worker = constantize(worker_class) rescue NameError return yield end circuit_breaker = worker.respond_to?(:sidekiq_circuit_breaker_enabled?) return yield unless circuit_breaker options = worker.sidekiq_circuit_breaker_options scope = extract_scope(worker_class, msg, options) mgr = CircuitBreaker::Manager.new(scope, options) if mgr.open? && msg['at'].nil? msg['at'] = (Time.now + (mgr.time_to_close + additional_seconds)).to_f end yield end private def additional_seconds rand(3..10) end private def constantize(str) names = str.split('::') names.shift if names.empty? || names.first.empty? names.inject(Object) do |constant, name| constant.const_defined?(name, false) ? constant.const_get(name, false) : constant.const_missing(name) end end end end end end