sidekiq-grouping 1.0.8 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f9c96db0ae5af0c9a398f9e2a0718b55ede63741
4
- data.tar.gz: 69adc754a26f5d4ba89f876f5e39803ba06d7e1f
2
+ SHA256:
3
+ metadata.gz: 4dbe0fe595dfbe28a39a687925d5078d7c1df9d7793df783cf4ed448910136f9
4
+ data.tar.gz: a2f48474c1ec7ec9a632999f17cf6159d15490dfa6d06ff4eb5b85221fec776e
5
5
  SHA512:
6
- metadata.gz: 80ae9e4599902073a2fd7336622f9b15b59f8cd3da25121b6d319dd2cb71f2aa2df56d9e14dbfe682f7b5b1d6d806c90a73cbaadd68f28bcf6f1e1655fa736aa
7
- data.tar.gz: 086a0e13a585b06858d34752866099c9efa914139decaac83832dca5571d048ef8532a48cfe0395a92370f4c3554643afcb0f7a93d2330ab0fb517c757deae86
6
+ metadata.gz: fb1a5cc739670f30b05cd477c3797eca72d0469307ebf4e8ea13841d49ed050b2a0814f11e29b81ce5ce7d039e99f6661110b528d8ccf22cd609654fd445b4b0
7
+ data.tar.gz: 31f85b457287ae7e1dee1c52e008099f9806cd520132c7bad048a42d4c67ee0550cb51610d95059b3135c7a39b2865058f2d2092623864b71c23010bebc03017
data/.gitignore CHANGED
@@ -4,6 +4,7 @@
4
4
  .config
5
5
  .yardoc
6
6
  Gemfile.lock
7
+ gemfiles/*.lock
7
8
  InstalledFiles
8
9
  _yardoc
9
10
  coverage
data/.travis.yml CHANGED
@@ -1,7 +1,18 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 2.2
4
+ - 2.3.1
5
+ - 2.4
6
+ - 2.5
7
+
4
8
  cache: bundler
5
9
 
6
10
  services:
7
11
  - redis-server
12
+
13
+ gemfile:
14
+ - gemfiles/sidekiq_4.0.gemfile
15
+ - gemfiles/sidekiq_4.1.gemfile
16
+ - gemfiles/sidekiq_4.2.gemfile
17
+ - gemfiles/sidekiq_5.0.gemfile
18
+ - gemfiles/sidekiq_master.gemfile
data/Appraisals ADDED
@@ -0,0 +1,19 @@
1
+ appraise 'sidekiq-4.0' do
2
+ gem 'sidekiq', '~> 4.0.0'
3
+ end
4
+
5
+ appraise 'sidekiq-4.1' do
6
+ gem 'sidekiq', '~> 4.1.0'
7
+ end
8
+
9
+ appraise 'sidekiq-4.2' do
10
+ gem 'sidekiq', '~> 4.2.0'
11
+ end
12
+
13
+ appraise 'sidekiq-5.0' do
14
+ gem 'sidekiq', '~> 5.0.0'
15
+ end
16
+
17
+ appraise 'sidekiq-master' do
18
+ gem 'sidekiq', github: 'mperham/sidekiq'
19
+ end
data/README.md CHANGED
@@ -111,6 +111,8 @@ This jobs will be grouped into the single job with the single argument:
111
111
  # => [[5]]
112
112
  ```
113
113
 
114
+ - `tests_env` is used to silence some logging in test environments (see below). Default: true if `Rails.env.test?`, false otherwise.
115
+
114
116
  ## Web UI
115
117
 
116
118
  ![Web UI](web.png)
@@ -123,15 +125,75 @@ require "sidekiq/grouping/web"
123
125
 
124
126
  ## Configuration
125
127
 
128
+ Specify grouping configuration inside of sidekiq.yml:
129
+
130
+ ```yml
131
+ grouping:
132
+ :poll_interval: 5 # Amount of time between polling batches
133
+ :max_batch_size: 5000 # Maximum batch size allowed
134
+ :lock_ttl: 1 # Batch queue flush lock timeout job enqueues
135
+ ```
136
+
137
+ Or set it in your code:
138
+
126
139
  ```ruby
127
- Sidekiq::Grouping::Config.poll_interval = 5 # Amount of time between polling batches
128
- Sidekiq::Grouping::Config.max_batch_size = 5000 # Maximum batch size allowed
129
- Sidekiq::Grouping::Config.lock_ttl = 1 # Batch queue flush lock timeout job enqueues
140
+ Sidekiq::Grouping::Config.poll_interval = 5
141
+ Sidekiq::Grouping::Config.max_batch_size = 5000
142
+ Sidekiq::Grouping::Config.lock_ttl = 1
130
143
  ```
131
144
 
132
- ## TODO
145
+ Note that you should set poll_interval option inside of sidekiq.yml to take effect. Setting this param in your ruby code won't change actual polling frequency.
146
+
147
+ ## Testing with Sidekiq::Testing.fake!
148
+
149
+ Sidekiq::Grouping uses internal queues for grouping tasks. If you need to force flush internal queues into normal Sidekiq queues, use `Sidekiq::Grouping.force_flush_for_test!`.
150
+
151
+ See example:
152
+
153
+ ```ruby
154
+ # worker
155
+ class GroupedWorker
156
+
157
+ include Sidekiq::Worker
158
+ sidekiq_options(
159
+ queue: :custom_queue,
160
+ retry: 5,
161
+ batch_flush_size: 9,
162
+ batch_flush_interval: 10,
163
+ batch_size: 3,
164
+ batch_unique: true
165
+ )
133
166
 
134
- 1. Add support redis_pool option.
167
+ def perform(grouped_arguments)
168
+ # ... important payload
169
+ end
170
+
171
+ end
172
+
173
+ # test itself
174
+ RSpec.describe GroupedWorker, type: :worker do
175
+
176
+ describe '#perform' do
177
+ it 'calls perform with array of arguments' do
178
+ Sidekiq::Testing.fake! do
179
+ described_class.perform_async(1)
180
+ described_class.perform_async(1)
181
+ described_class.perform_async(2)
182
+ described_class.perform_async(2)
183
+
184
+ # All 4 above asks will be put to :custom_queue despite of :batch_flush_size is set to 9.
185
+ Sidekiq::Grouping.force_flush_for_test!
186
+
187
+ last_job = described_class.jobs.last
188
+ expect(last_job['args']).to eq([[[1], [2]]])
189
+ expect(last_job['queue']).to eq('custom_queue')
190
+ end
191
+ end
192
+ end
193
+
194
+ end
195
+
196
+ ```
135
197
 
136
198
  ## Installation
137
199
 
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "sidekiq", "~> 4.0.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "sidekiq", "~> 4.1.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "sidekiq", "~> 4.2.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "sidekiq", "~> 5.0.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "sidekiq", github: "mperham/sidekiq"
6
+
7
+ gemspec path: "../"
@@ -1,15 +1,29 @@
1
1
  module Sidekiq::Grouping::Config
2
2
  include ActiveSupport::Configurable
3
3
 
4
+ def self.options
5
+ Sidekiq.options[:grouping] || Sidekiq.options["grouping"] || {} # sidekiq 5.x use symbol in keys
6
+ end
7
+
4
8
  # Queue size overflow check polling interval
5
- config_accessor :poll_interval
6
- config.poll_interval = 3
9
+ config_accessor :poll_interval do
10
+ options[:poll_interval] || 3
11
+ end
7
12
 
8
13
  # Maximum batch size
9
- config_accessor :max_batch_size
10
- config.max_batch_size = 1000
14
+ config_accessor :max_batch_size do
15
+ options[:max_batch_size] || 1000
16
+ end
11
17
 
12
18
  # Batch queue flush lock timeout
13
- config_accessor :lock_ttl
14
- config.lock_ttl = 1
19
+ config_accessor :lock_ttl do
20
+ options[:lock_ttl] || 1
21
+ end
22
+
23
+ # Option to override how Sidekiq::Grouping know about tests env
24
+ config_accessor :tests_env do
25
+ options[:tests_env] || (
26
+ defined?(::Rails) && Rails.respond_to?(:env) && Rails.env.test?
27
+ )
28
+ end
15
29
  end
@@ -3,18 +3,40 @@ class Sidekiq::Grouping::Flusher
3
3
  batches = Sidekiq::Grouping::Batch.all.map do |batch|
4
4
  batch if batch.could_flush?
5
5
  end
6
- batches.compact!
7
- flush_concrete(batches)
6
+ flush_batches(batches)
7
+ end
8
+
9
+ def force_flush_for_test!
10
+ unless Sidekiq::Grouping::Config.tests_env
11
+ Sidekiq::Grouping.logger.warn(
12
+ "**************************************************"
13
+ )
14
+ Sidekiq::Grouping.logger.warn([
15
+ "⛔️ force_flush_for_test! for testing API, ",
16
+ "but this is not the test environment. ",
17
+ "Please check your environment or ",
18
+ "change 'tests_env' to cover this one"
19
+ ].join)
20
+ Sidekiq::Grouping.logger.warn(
21
+ "**************************************************"
22
+ )
23
+ end
24
+ flush_batches(Sidekiq::Grouping::Batch.all)
8
25
  end
9
26
 
10
27
  private
11
28
 
29
+ def flush_batches(batches)
30
+ batches.compact!
31
+ flush_concrete(batches)
32
+ end
33
+
12
34
  def flush_concrete(batches)
13
35
  return if batches.empty?
14
36
  names = batches.map { |batch| "#{batch.worker_class} in #{batch.queue}" }
15
37
  Sidekiq::Grouping.logger.info(
16
38
  "[Sidekiq::Grouping] Trying to flush batched queues: #{names.join(',')}"
17
- )
39
+ ) unless Sidekiq::Grouping::Config.tests_env
18
40
  batches.each(&:flush)
19
41
  end
20
42
  end
@@ -13,10 +13,10 @@ module Sidekiq
13
13
 
14
14
  def push_msg(name, msg, remember_unique = false)
15
15
  redis do |conn|
16
- conn.multi do
17
- conn.sadd(ns('batches'), name)
18
- conn.rpush(ns(name), msg)
19
- conn.sadd(unique_messages_key(name), msg) if remember_unique
16
+ conn.multi do |pipeline|
17
+ pipeline.sadd(ns("batches"), name)
18
+ pipeline.rpush(ns(name), msg)
19
+ pipeline.sadd(unique_messages_key(name), msg) if remember_unique
20
20
  end
21
21
  end
22
22
  end
@@ -32,7 +32,7 @@ module Sidekiq
32
32
  end
33
33
 
34
34
  def batches
35
- redis { |conn| conn.smembers(ns('batches')) }
35
+ redis { |conn| conn.smembers(ns("batches")) }
36
36
  end
37
37
 
38
38
  def pluck(name, limit)
@@ -1,5 +1,5 @@
1
1
  module Sidekiq
2
2
  module Grouping
3
- VERSION = "1.0.8"
3
+ VERSION = "1.1.0"
4
4
  end
5
5
  end
@@ -11,11 +11,11 @@ module Sidekiq
11
11
  erb File.read(File.join(VIEWS, 'index.erb')), locals: {view_path: VIEWS}
12
12
  end
13
13
 
14
- app.post "/grouping/*/delete" do |name|
15
- worker_class, queue = Sidekiq::Grouping::Batch.extract_worker_klass_and_queue(name)
14
+ app.post "/grouping/:name/delete" do
15
+ worker_class, queue = Sidekiq::Grouping::Batch.extract_worker_klass_and_queue(params['name'])
16
16
  batch = Sidekiq::Grouping::Batch.new(worker_class, queue)
17
17
  batch.delete
18
- redirect "#{root_path}/grouping"
18
+ redirect "#{root_path}grouping"
19
19
  end
20
20
  end
21
21
 
@@ -25,4 +25,3 @@ end
25
25
 
26
26
  Sidekiq::Web.register(Sidekiq::Grouping::Web)
27
27
  Sidekiq::Web.tabs["Grouping"] = "grouping"
28
-
@@ -1,3 +1,4 @@
1
+ require "active_support"
1
2
  require "active_support/core_ext/string"
2
3
  require "active_support/configurable"
3
4
  require "active_support/core_ext/numeric/time"
@@ -19,6 +20,10 @@ module Sidekiq::Grouping
19
20
  @logger ||= Sidekiq.logger
20
21
  end
21
22
 
23
+ def force_flush_for_test!
24
+ Sidekiq::Grouping::Flusher.new.force_flush_for_test!
25
+ end
26
+
22
27
  def start!
23
28
  interval = Sidekiq::Grouping::Config.poll_interval
24
29
  @observer = Sidekiq::Grouping::FlusherObserver.new
@@ -18,12 +18,13 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.5"
21
+ spec.add_development_dependency "bundler", "> 1.5"
22
22
  spec.add_development_dependency "rake"
23
23
  spec.add_development_dependency "rspec"
24
24
  spec.add_development_dependency "simplecov"
25
25
  spec.add_development_dependency "rspec-sidekiq"
26
26
  spec.add_development_dependency "timecop"
27
+ spec.add_development_dependency "appraisal"
27
28
 
28
29
  spec.add_dependency "activesupport"
29
30
  spec.add_dependency "sidekiq", ">= 3.4.2"
@@ -6,7 +6,7 @@ describe Sidekiq::Grouping::Batch do
6
6
  context 'adding' do
7
7
  it 'must enqueue unbatched worker' do
8
8
  RegularWorker.perform_async('bar')
9
- expect(RegularWorker).to have_enqueued_job('bar')
9
+ expect(RegularWorker).to have_enqueued_sidekiq_job("bar")
10
10
  end
11
11
 
12
12
  it 'must not enqueue batched worker' do
@@ -67,7 +67,9 @@ describe Sidekiq::Grouping::Batch do
67
67
  expect(batch.could_flush?).to be_falsy
68
68
  10.times { |n| BatchedSizeWorker.perform_async("bar#{n}") }
69
69
  batch.flush
70
- expect(BatchedSizeWorker).to have_enqueued_job([["bar0"], ["bar1"]])
70
+ expect(BatchedSizeWorker).to(
71
+ have_enqueued_sidekiq_job([["bar0"], ["bar1"]])
72
+ )
71
73
  expect(batch.size).to eq(7)
72
74
  end
73
75
  end
@@ -124,7 +126,7 @@ describe Sidekiq::Grouping::Batch do
124
126
 
125
127
  private
126
128
  def expect_batch(klass, queue)
127
- expect(klass).to_not have_enqueued_job('bar')
129
+ expect(klass).to_not have_enqueued_sidekiq_job("bar")
128
130
  batch = subject.new(klass.name, queue)
129
131
  stats = subject.all
130
132
  expect(batch.size).to eq(1)
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-grouping
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.8
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Sokolov
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-12 00:00:00.000000000 Z
11
+ date: 2022-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.5'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.5'
27
27
  - !ruby/object:Gem::Dependency
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: appraisal
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: activesupport
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -136,7 +150,7 @@ dependencies:
136
150
  - - ">="
137
151
  - !ruby/object:Gem::Version
138
152
  version: '0'
139
- description:
153
+ description:
140
154
  email:
141
155
  - gzigzigzeo@gmail.com
142
156
  executables: []
@@ -146,10 +160,16 @@ files:
146
160
  - ".gitignore"
147
161
  - ".rubocop.yml"
148
162
  - ".travis.yml"
163
+ - Appraisals
149
164
  - Gemfile
150
165
  - LICENSE.txt
151
166
  - README.md
152
167
  - Rakefile
168
+ - gemfiles/sidekiq_4.0.gemfile
169
+ - gemfiles/sidekiq_4.1.gemfile
170
+ - gemfiles/sidekiq_4.2.gemfile
171
+ - gemfiles/sidekiq_5.0.gemfile
172
+ - gemfiles/sidekiq_master.gemfile
153
173
  - lib/sidekiq/grouping.rb
154
174
  - lib/sidekiq/grouping/batch.rb
155
175
  - lib/sidekiq/grouping/config.rb
@@ -170,7 +190,7 @@ homepage: http://github.com/gzigzigzeo/sidekiq-grouping
170
190
  licenses:
171
191
  - MIT
172
192
  metadata: {}
173
- post_install_message:
193
+ post_install_message:
174
194
  rdoc_options: []
175
195
  require_paths:
176
196
  - lib
@@ -185,9 +205,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
185
205
  - !ruby/object:Gem::Version
186
206
  version: '0'
187
207
  requirements: []
188
- rubyforge_project:
189
- rubygems_version: 2.5.1
190
- signing_key:
208
+ rubygems_version: 3.1.6
209
+ signing_key:
191
210
  specification_version: 4
192
211
  summary: Allows identical sidekiq jobs to be processed with a single background call
193
212
  test_files: