# frozen_string_literal: true # internal module Sidekiq module Throttled # Collection which transparently group several meta-strategies of one kind # # @private class StrategyCollection include Enumerable attr_reader :strategies # @param [Hash, Array, nil] strategies Concurrency or Threshold options # or array of options. # See keyword args of {Strategy::Concurrency#initialize} for details. # See keyword args of {Strategy::Threshold#initialize} for details. # @param [Class] strategy class of strategy: Concurrency or Threshold # @param [#to_s] name # @param [#call] key_suffix Dynamic key suffix generator. def initialize(strategies, strategy:, name:, key_suffix:) @strategies = (strategies.is_a?(Hash) ? [strategies] : Array(strategies)).map do |options| make_strategy(strategy, name, key_suffix, options) end end # @param [#call] block # Iterates each strategy in collection def each(...) @strategies.each(...) end # @return [Boolean] whenever any strategy in collection has dynamic config def dynamic? any?(&:dynamic?) end # @return [Boolean] whenever job is throttled or not # by any strategy in collection. def throttled?(...) any? { |s| s.throttled?(...) } end # @return [Float] How long, in seconds, before we'll next be able to take on jobs def retry_in(*args) map { |s| s.retry_in(*args) }.max end # Marks job as being processed. # @return [void] def finalize!(...) each { |c| c.finalize!(...) } end # Resets count of jobs of all avaliable strategies # @return [void] def reset! each(&:reset!) end private # @return [Base, nil] def make_strategy(strategy, name, key_suffix, options) return unless options strategy.new("throttled:#{name}", key_suffix: key_suffix, **options) end end end end