sidekiq-throttled 0.11.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +51 -0
- data/.rubocop/layout.yml +24 -0
- data/.rubocop/lint.yml +41 -0
- data/.rubocop/metrics.yml +4 -0
- data/.rubocop/performance.yml +25 -0
- data/.rubocop/rspec.yml +3 -0
- data/.rubocop/style.yml +84 -0
- data/.rubocop.yml +13 -68
- data/.rubocop_todo.yml +10 -35
- data/.travis.yml +2 -1
- data/Appraisals +16 -0
- data/CHANGES.md +53 -0
- data/Gemfile +6 -5
- data/LICENSE.md +2 -1
- data/README.md +49 -18
- data/gemfiles/sidekiq_5.0.gemfile +6 -5
- data/gemfiles/sidekiq_5.1.gemfile +6 -5
- data/gemfiles/sidekiq_5.2.gemfile +6 -5
- data/gemfiles/sidekiq_6.0.gemfile +31 -0
- data/gemfiles/sidekiq_6.1.gemfile +31 -0
- data/gemfiles/sidekiq_6.2.gemfile +31 -0
- data/gemfiles/sidekiq_6.3.gemfile +31 -0
- data/lib/sidekiq/throttled/communicator/callbacks.rb +8 -9
- data/lib/sidekiq/throttled/communicator/listener.rb +3 -3
- data/lib/sidekiq/throttled/expirable_list.rb +1 -1
- data/lib/sidekiq/throttled/fetch.rb +34 -20
- data/lib/sidekiq/throttled/queue_name.rb +1 -1
- data/lib/sidekiq/throttled/registry.rb +2 -5
- data/lib/sidekiq/throttled/strategy/concurrency.rb +5 -5
- data/lib/sidekiq/throttled/strategy/threshold.rb +6 -5
- data/lib/sidekiq/throttled/strategy.rb +15 -20
- data/lib/sidekiq/throttled/strategy_collection.rb +69 -0
- data/lib/sidekiq/throttled/utils.rb +1 -1
- data/lib/sidekiq/throttled/version.rb +1 -1
- data/lib/sidekiq/throttled/web/stats.rb +2 -6
- data/lib/sidekiq/throttled/web/summary_fix.rb +3 -2
- data/lib/sidekiq/throttled/web/throttled.html.erb +6 -2
- data/lib/sidekiq/throttled/web.rb +1 -1
- data/lib/sidekiq/throttled/worker.rb +2 -2
- data/lib/sidekiq/throttled.rb +14 -2
- data/sidekiq-throttled.gemspec +3 -1
- metadata +21 -9
| @@ -2,6 +2,7 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            # internal
         | 
| 4 4 | 
             
            require "sidekiq/throttled/errors"
         | 
| 5 | 
            +
            require "sidekiq/throttled/strategy_collection"
         | 
| 5 6 | 
             
            require "sidekiq/throttled/strategy/concurrency"
         | 
| 6 7 | 
             
            require "sidekiq/throttled/strategy/threshold"
         | 
| 7 8 |  | 
| @@ -30,15 +31,20 @@ module Sidekiq | |
| 30 31 | 
             
                  #   See keyword args of {Strategy::Threshold#initialize} for details.
         | 
| 31 32 | 
             
                  # @param [#call] key_suffix Dynamic key suffix generator.
         | 
| 32 33 | 
             
                  # @param [#call] observer Process called after throttled.
         | 
| 33 | 
            -
                  def initialize(
         | 
| 34 | 
            -
                     | 
| 35 | 
            -
                    concurrency: nil, threshold: nil, key_suffix: nil, observer: nil
         | 
| 36 | 
            -
                  )
         | 
| 37 | 
            -
                    @observer    = observer
         | 
| 38 | 
            -
                    @concurrency = make_strategy(Concurrency, name, key_suffix, concurrency)
         | 
| 39 | 
            -
                    @threshold   = make_strategy(Threshold, name, key_suffix, threshold)
         | 
| 34 | 
            +
                  def initialize(name, concurrency: nil, threshold: nil, key_suffix: nil, observer: nil) # rubocop:disable Metrics/MethodLength
         | 
| 35 | 
            +
                    @observer = observer
         | 
| 40 36 |  | 
| 41 | 
            -
                     | 
| 37 | 
            +
                    @concurrency = StrategyCollection.new(concurrency,
         | 
| 38 | 
            +
                      :strategy   => Concurrency,
         | 
| 39 | 
            +
                      :name       => name,
         | 
| 40 | 
            +
                      :key_suffix => key_suffix)
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                    @threshold = StrategyCollection.new(threshold,
         | 
| 43 | 
            +
                      :strategy   => Threshold,
         | 
| 44 | 
            +
                      :name       => name,
         | 
| 45 | 
            +
                      :key_suffix => key_suffix)
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                    return if @concurrency.any? || @threshold.any?
         | 
| 42 48 |  | 
| 43 49 | 
             
                    raise ArgumentError, "Neither :concurrency nor :threshold given"
         | 
| 44 50 | 
             
                  end
         | 
| @@ -60,6 +66,7 @@ module Sidekiq | |
| 60 66 |  | 
| 61 67 | 
             
                    if @threshold&.throttled?(*job_args)
         | 
| 62 68 | 
             
                      @observer&.call(:threshold, *job_args)
         | 
| 69 | 
            +
             | 
| 63 70 | 
             
                      finalize!(jid, *job_args)
         | 
| 64 71 | 
             
                      return true
         | 
| 65 72 | 
             
                    end
         | 
| @@ -79,18 +86,6 @@ module Sidekiq | |
| 79 86 | 
             
                    @concurrency&.reset!
         | 
| 80 87 | 
             
                    @threshold&.reset!
         | 
| 81 88 | 
             
                  end
         | 
| 82 | 
            -
             | 
| 83 | 
            -
                  private
         | 
| 84 | 
            -
             | 
| 85 | 
            -
                  # @return [Base, nil]
         | 
| 86 | 
            -
                  def make_strategy(strategy, name, key_suffix, options)
         | 
| 87 | 
            -
                    return unless options
         | 
| 88 | 
            -
             | 
| 89 | 
            -
                    strategy.new("throttled:#{name}", {
         | 
| 90 | 
            -
                      :key_suffix => key_suffix,
         | 
| 91 | 
            -
                      **options
         | 
| 92 | 
            -
                    })
         | 
| 93 | 
            -
                  end
         | 
| 94 89 | 
             
                end
         | 
| 95 90 | 
             
              end
         | 
| 96 91 | 
             
            end
         | 
| @@ -0,0 +1,69 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # internal
         | 
| 4 | 
            +
            module Sidekiq
         | 
| 5 | 
            +
              module Throttled
         | 
| 6 | 
            +
                # Collection which transparently group several meta-strategies of one kind
         | 
| 7 | 
            +
                #
         | 
| 8 | 
            +
                # @private
         | 
| 9 | 
            +
                class StrategyCollection
         | 
| 10 | 
            +
                  include Enumerable
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                  attr_reader :strategies
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  # @param [Hash, Array, nil] strategies Concurrency or Threshold options
         | 
| 15 | 
            +
                  #   or array of options.
         | 
| 16 | 
            +
                  #   See keyword args of {Strategy::Concurrency#initialize} for details.
         | 
| 17 | 
            +
                  #   See keyword args of {Strategy::Threshold#initialize} for details.
         | 
| 18 | 
            +
                  # @param [Class] strategy class of strategy: Concurrency or Threshold
         | 
| 19 | 
            +
                  # @param [#to_s] name
         | 
| 20 | 
            +
                  # @param [#call] key_suffix Dynamic key suffix generator.
         | 
| 21 | 
            +
                  def initialize(strategies, strategy:, name:, key_suffix:)
         | 
| 22 | 
            +
                    strategies = (strategies.is_a?(Hash) ? [strategies] : Array(strategies))
         | 
| 23 | 
            +
                    @strategies = strategies.map do |options|
         | 
| 24 | 
            +
                      make_strategy(strategy, name, key_suffix, options)
         | 
| 25 | 
            +
                    end
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  # @param [#call] block
         | 
| 29 | 
            +
                  # Iterates each strategy in collection
         | 
| 30 | 
            +
                  def each(&block)
         | 
| 31 | 
            +
                    @strategies.each(&block)
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  # @return [Boolean] whenever any strategy in collection has dynamic config
         | 
| 35 | 
            +
                  def dynamic?
         | 
| 36 | 
            +
                    any?(&:dynamic?)
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  # @return [Boolean] whenever job is throttled or not
         | 
| 40 | 
            +
                  # by any strategy in collection.
         | 
| 41 | 
            +
                  def throttled?(*args)
         | 
| 42 | 
            +
                    any? { |s| s.throttled?(*args) }
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  # Marks job as being processed.
         | 
| 46 | 
            +
                  # @return [void]
         | 
| 47 | 
            +
                  def finalize!(*args)
         | 
| 48 | 
            +
                    each { |c| c.finalize!(*args) }
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  # Resets count of jobs of all avaliable strategies
         | 
| 52 | 
            +
                  # @return [void]
         | 
| 53 | 
            +
                  def reset!
         | 
| 54 | 
            +
                    each(&:reset!)
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  private
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                  # @return [Base, nil]
         | 
| 60 | 
            +
                  def make_strategy(strategy, name, key_suffix, options)
         | 
| 61 | 
            +
                    return unless options
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                    strategy.new("throttled:#{name}",
         | 
| 64 | 
            +
                      :key_suffix => key_suffix,
         | 
| 65 | 
            +
                      **options)
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
              end
         | 
| 69 | 
            +
            end
         | 
| @@ -9,7 +9,7 @@ module Sidekiq | |
| 9 9 | 
             
                  # @param name [#to_s] Constant name
         | 
| 10 10 | 
             
                  # @return [Object, nil] Resolved constant or nil if failed.
         | 
| 11 11 | 
             
                  def constantize(name)
         | 
| 12 | 
            -
                    name.to_s.sub( | 
| 12 | 
            +
                    name.to_s.sub(%r{^::}, "").split("::").inject(Object, &:const_get)
         | 
| 13 13 | 
             
                  rescue NameError
         | 
| 14 14 | 
             
                    Sidekiq.logger.warn { "Failed to constantize: #{name}" }
         | 
| 15 15 | 
             
                    nil
         | 
| @@ -14,9 +14,7 @@ module Sidekiq | |
| 14 14 |  | 
| 15 15 | 
             
                    # @param [Strategy::Concurrency, Strategy::Threshold] strategy
         | 
| 16 16 | 
             
                    def initialize(strategy)
         | 
| 17 | 
            -
                      if strategy&.dynamic?
         | 
| 18 | 
            -
                        raise ArgumentError, "Can't handle dynamic strategies"
         | 
| 19 | 
            -
                      end
         | 
| 17 | 
            +
                      raise ArgumentError, "Can't handle dynamic strategies" if strategy&.dynamic?
         | 
| 20 18 |  | 
| 21 19 | 
             
                      @strategy = strategy
         | 
| 22 20 | 
             
                    end
         | 
| @@ -27,9 +25,7 @@ module Sidekiq | |
| 27 25 |  | 
| 28 26 | 
             
                      html = humanize_integer(@strategy.limit) << " jobs"
         | 
| 29 27 |  | 
| 30 | 
            -
                      if @strategy.respond_to? | 
| 31 | 
            -
                        html << " per " << humanize_duration(@strategy.period)
         | 
| 32 | 
            -
                      end
         | 
| 28 | 
            +
                      html << " per " << humanize_duration(@strategy.period) if @strategy.respond_to?(:period)
         | 
| 33 29 |  | 
| 34 30 | 
             
                      html << "<br />" << colorize_count(@strategy.count, @strategy.limit)
         | 
| 35 31 | 
             
                    end
         | 
| @@ -4,14 +4,15 @@ module Sidekiq | |
| 4 4 | 
             
              module Throttled
         | 
| 5 5 | 
             
                module Web
         | 
| 6 6 | 
             
                  module SummaryFix
         | 
| 7 | 
            -
                    JAVASCRIPT = [File.read( | 
| 7 | 
            +
                    JAVASCRIPT = [File.read(File.expand_path("summary_fix.js", __dir__)).freeze].freeze
         | 
| 8 8 | 
             
                    HEADERS    = { "Content-Type" => "application/javascript" }.freeze
         | 
| 9 9 |  | 
| 10 10 | 
             
                    class << self
         | 
| 11 11 | 
             
                      attr_accessor :enabled
         | 
| 12 12 |  | 
| 13 13 | 
             
                      def apply!(app)
         | 
| 14 | 
            -
                        Sidekiq::WebAction. | 
| 14 | 
            +
                        Sidekiq::WebAction.prepend SummaryFix
         | 
| 15 | 
            +
             | 
| 15 16 | 
             
                        app.get("/throttled/summary_fix") do
         | 
| 16 17 | 
             
                          [200, HEADERS.dup, JAVASCRIPT.dup]
         | 
| 17 18 | 
             
                        end
         | 
| @@ -14,10 +14,14 @@ | |
| 14 14 | 
             
                  <tr>
         | 
| 15 15 | 
             
                    <td style="vertical-align:middle;"><%= name %></td>
         | 
| 16 16 | 
             
                    <td style="vertical-align:middle;text-align:center;">
         | 
| 17 | 
            -
                       | 
| 17 | 
            +
                      <% strategy.concurrency.each do |concurrency| %>
         | 
| 18 | 
            +
                        <%= Sidekiq::Throttled::Web::Stats.new(concurrency).to_html %>
         | 
| 19 | 
            +
                      <% end %>
         | 
| 18 20 | 
             
                    </td>
         | 
| 19 21 | 
             
                    <td style="vertical-align:middle;text-align:center;">
         | 
| 20 | 
            -
                       | 
| 22 | 
            +
                      <% strategy.threshold.each do |threshold| %>
         | 
| 23 | 
            +
                        <%= Sidekiq::Throttled::Web::Stats.new(threshold).to_html %>
         | 
| 24 | 
            +
                      <% end %>
         | 
| 21 25 | 
             
                    </td>
         | 
| 22 26 | 
             
                    <td style="vertical-align:middle;text-align:center;">
         | 
| 23 27 | 
             
                      <form action="<%= root_path %>throttled/<%= CGI.escape name %>/reset" method="post">
         | 
| @@ -77,7 +77,7 @@ module Sidekiq | |
| 77 77 | 
             
                      Registry.add(self, **kwargs)
         | 
| 78 78 | 
             
                    end
         | 
| 79 79 |  | 
| 80 | 
            -
                    # Adds current worker to preconfigured  | 
| 80 | 
            +
                    # Adds current worker to preconfigured throttling strategy. Allows
         | 
| 81 81 | 
             
                    # sharing same pool for multiple workers.
         | 
| 82 82 | 
             
                    #
         | 
| 83 83 | 
             
                    # First of all we need to create shared throttling strategy:
         | 
| @@ -85,7 +85,7 @@ module Sidekiq | |
| 85 85 | 
             
                    #     # Create google_api throttling strategy
         | 
| 86 86 | 
             
                    #     Sidekiq::Throttled::Registry.add(:google_api, {
         | 
| 87 87 | 
             
                    #       :threshold => { :limit => 123, :period => 1.hour },
         | 
| 88 | 
            -
                    #       :concurrency => { :limit =>  | 
| 88 | 
            +
                    #       :concurrency => { :limit => 10 }
         | 
| 89 89 | 
             
                    #     })
         | 
| 90 90 | 
             
                    #
         | 
| 91 91 | 
             
                    # Now we can assign it to our workers:
         | 
    
        data/lib/sidekiq/throttled.rb
    CHANGED
    
    | @@ -61,8 +61,7 @@ module Sidekiq | |
| 61 61 | 
             
                    QueuesPauser.instance.setup!
         | 
| 62 62 |  | 
| 63 63 | 
             
                    Sidekiq.configure_server do |config|
         | 
| 64 | 
            -
                       | 
| 65 | 
            -
                      Sidekiq.options[:fetch] = Sidekiq::Throttled::Fetch
         | 
| 64 | 
            +
                      setup_strategy!
         | 
| 66 65 |  | 
| 67 66 | 
             
                      require "sidekiq/throttled/middleware"
         | 
| 68 67 | 
             
                      config.server_middleware do |chain|
         | 
| @@ -93,6 +92,19 @@ module Sidekiq | |
| 93 92 |  | 
| 94 93 | 
             
                  private
         | 
| 95 94 |  | 
| 95 | 
            +
                  # @return [void]
         | 
| 96 | 
            +
                  def setup_strategy!
         | 
| 97 | 
            +
                    require "sidekiq/throttled/fetch"
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                    # https://github.com/mperham/sidekiq/commit/fce05c9d4b4c0411c982078a4cf3a63f20f739bc
         | 
| 100 | 
            +
                    Sidekiq.options[:fetch] =
         | 
| 101 | 
            +
                      if Gem::Version.new(Sidekiq::VERSION) < Gem::Version.new("6.1.0")
         | 
| 102 | 
            +
                        Sidekiq::Throttled::Fetch
         | 
| 103 | 
            +
                      else
         | 
| 104 | 
            +
                        Sidekiq::Throttled::Fetch.new(Sidekiq.options)
         | 
| 105 | 
            +
                      end
         | 
| 106 | 
            +
                  end
         | 
| 107 | 
            +
             | 
| 96 108 | 
             
                  # Tries to preload constant by it's name once.
         | 
| 97 109 | 
             
                  #
         | 
| 98 110 | 
             
                  # Somehow, sometimes, some classes are not eager loaded upon Rails init,
         | 
    
        data/sidekiq-throttled.gemspec
    CHANGED
    
    | @@ -24,9 +24,11 @@ Gem::Specification.new do |spec| | |
| 24 24 | 
             
              spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
         | 
| 25 25 | 
             
              spec.require_paths = ["lib"]
         | 
| 26 26 |  | 
| 27 | 
            +
              spec.required_ruby_version = ">= 2.6"
         | 
| 28 | 
            +
             | 
| 27 29 | 
             
              spec.add_runtime_dependency "concurrent-ruby"
         | 
| 28 30 | 
             
              spec.add_runtime_dependency "redis-prescription"
         | 
| 29 31 | 
             
              spec.add_runtime_dependency "sidekiq"
         | 
| 30 32 |  | 
| 31 | 
            -
              spec.add_development_dependency "bundler", " | 
| 33 | 
            +
              spec.add_development_dependency "bundler", ">= 2.0"
         | 
| 32 34 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: sidekiq-throttled
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.15.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Alexey V Zapparov
         | 
| 8 | 
            -
            autorequire: | 
| 8 | 
            +
            autorequire:
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2021-12-16 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: concurrent-ruby
         | 
| @@ -56,14 +56,14 @@ dependencies: | |
| 56 56 | 
             
              name: bundler
         | 
| 57 57 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 58 | 
             
                requirements:
         | 
| 59 | 
            -
                - - " | 
| 59 | 
            +
                - - ">="
         | 
| 60 60 | 
             
                  - !ruby/object:Gem::Version
         | 
| 61 61 | 
             
                    version: '2.0'
         | 
| 62 62 | 
             
              type: :development
         | 
| 63 63 | 
             
              prerelease: false
         | 
| 64 64 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 65 | 
             
                requirements:
         | 
| 66 | 
            -
                - - " | 
| 66 | 
            +
                - - ">="
         | 
| 67 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| 68 68 | 
             
                    version: '2.0'
         | 
| 69 69 | 
             
            description: Concurrency and threshold throttling for Sidekiq.
         | 
| @@ -74,9 +74,16 @@ extensions: [] | |
| 74 74 | 
             
            extra_rdoc_files: []
         | 
| 75 75 | 
             
            files:
         | 
| 76 76 | 
             
            - ".coveralls.yml"
         | 
| 77 | 
            +
            - ".github/workflows/ci.yml"
         | 
| 77 78 | 
             
            - ".gitignore"
         | 
| 78 79 | 
             
            - ".rspec"
         | 
| 79 80 | 
             
            - ".rubocop.yml"
         | 
| 81 | 
            +
            - ".rubocop/layout.yml"
         | 
| 82 | 
            +
            - ".rubocop/lint.yml"
         | 
| 83 | 
            +
            - ".rubocop/metrics.yml"
         | 
| 84 | 
            +
            - ".rubocop/performance.yml"
         | 
| 85 | 
            +
            - ".rubocop/rspec.yml"
         | 
| 86 | 
            +
            - ".rubocop/style.yml"
         | 
| 80 87 | 
             
            - ".rubocop_todo.yml"
         | 
| 81 88 | 
             
            - ".travis.yml"
         | 
| 82 89 | 
             
            - ".yardopts"
         | 
| @@ -90,6 +97,10 @@ files: | |
| 90 97 | 
             
            - gemfiles/sidekiq_5.0.gemfile
         | 
| 91 98 | 
             
            - gemfiles/sidekiq_5.1.gemfile
         | 
| 92 99 | 
             
            - gemfiles/sidekiq_5.2.gemfile
         | 
| 100 | 
            +
            - gemfiles/sidekiq_6.0.gemfile
         | 
| 101 | 
            +
            - gemfiles/sidekiq_6.1.gemfile
         | 
| 102 | 
            +
            - gemfiles/sidekiq_6.2.gemfile
         | 
| 103 | 
            +
            - gemfiles/sidekiq_6.3.gemfile
         | 
| 93 104 | 
             
            - lib/sidekiq/throttled.rb
         | 
| 94 105 | 
             
            - lib/sidekiq/throttled/communicator.rb
         | 
| 95 106 | 
             
            - lib/sidekiq/throttled/communicator/callbacks.rb
         | 
| @@ -110,6 +121,7 @@ files: | |
| 110 121 | 
             
            - lib/sidekiq/throttled/strategy/concurrency.rb
         | 
| 111 122 | 
             
            - lib/sidekiq/throttled/strategy/threshold.lua
         | 
| 112 123 | 
             
            - lib/sidekiq/throttled/strategy/threshold.rb
         | 
| 124 | 
            +
            - lib/sidekiq/throttled/strategy_collection.rb
         | 
| 113 125 | 
             
            - lib/sidekiq/throttled/testing.rb
         | 
| 114 126 | 
             
            - lib/sidekiq/throttled/utils.rb
         | 
| 115 127 | 
             
            - lib/sidekiq/throttled/version.rb
         | 
| @@ -125,7 +137,7 @@ homepage: https://github.com/sensortower/sidekiq-throttled | |
| 125 137 | 
             
            licenses:
         | 
| 126 138 | 
             
            - MIT
         | 
| 127 139 | 
             
            metadata: {}
         | 
| 128 | 
            -
            post_install_message: | 
| 140 | 
            +
            post_install_message:
         | 
| 129 141 | 
             
            rdoc_options: []
         | 
| 130 142 | 
             
            require_paths:
         | 
| 131 143 | 
             
            - lib
         | 
| @@ -133,15 +145,15 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 133 145 | 
             
              requirements:
         | 
| 134 146 | 
             
              - - ">="
         | 
| 135 147 | 
             
                - !ruby/object:Gem::Version
         | 
| 136 | 
            -
                  version: ' | 
| 148 | 
            +
                  version: '2.6'
         | 
| 137 149 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 138 150 | 
             
              requirements:
         | 
| 139 151 | 
             
              - - ">="
         | 
| 140 152 | 
             
                - !ruby/object:Gem::Version
         | 
| 141 153 | 
             
                  version: '0'
         | 
| 142 154 | 
             
            requirements: []
         | 
| 143 | 
            -
            rubygems_version: 3. | 
| 144 | 
            -
            signing_key: | 
| 155 | 
            +
            rubygems_version: 3.2.22
         | 
| 156 | 
            +
            signing_key:
         | 
| 145 157 | 
             
            specification_version: 4
         | 
| 146 158 | 
             
            summary: Concurrency and threshold throttling for Sidekiq.
         | 
| 147 159 | 
             
            test_files: []
         |