sidekiq 4.0.0.pre2 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sidekiq might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9ae613def4b402732162cb005ca3179a1a810e09
4
- data.tar.gz: 36aab3dd08ed5370fce1f2a6de7fae6973222dfb
3
+ metadata.gz: 154fd4d987e5f7c32fad42a20176d27e958bd49f
4
+ data.tar.gz: a33449473a2210e1f79e3f814c50f6fe982ff101
5
5
  SHA512:
6
- metadata.gz: a2b0c7ab9631689ea1afd0bdbb0d5eb0122ac4258b245c91c7ffed51b3d65dfb3c1c5b5492c235f8ab0ef628b5a154e2a9cab4a9cb75dc2e1f2029670f63d223
7
- data.tar.gz: 1d1391df672310f61563ba6a5125602104690a587da72a58038f33492626ab80cad60a7bba61507cadbf26d0bcc9d864d863adb43592e6543965072c5240af86
6
+ metadata.gz: 264d2c5a210a978ca8ce9f2a78962cc4f4d62966444788b7d942644881baec212133123f3434ffafdcc21d5bd9c0130eef007195a945f86771a33da5b2d1fbea
7
+ data.tar.gz: 6e651a3d38dd4518a3db01abd5febdb9a4c739d16873f2ce3ffa4998bd5f5a2285303437cc6f489cb43d032590bf741006d50170470c333ed31cfa62c1168178
@@ -25,6 +25,16 @@ gem 'redis-namespace'
25
25
  `concurrency + 2` connections in your pool or Sidekiq will exit.
26
26
  When in doubt, let Sidekiq size the connection pool for you.
27
27
 
28
+ * There's a new testing API based off the `Sidekiq::Queues` namespace. All
29
+ assertions made against the Worker class still work as expected.
30
+ ```ruby
31
+ assert_equal 0, Sidekiq::Queues["default"].size
32
+ HardWorker.perform_async("log")
33
+ assert_equal 1, Sidekiq::Queues["default"].size
34
+ assert_equal "log", Sidekiq::Queues["default"].first['args'][0]
35
+ Sidekiq::Queues.clear_all
36
+ ```
37
+
28
38
  ## Upgrade
29
39
 
30
40
  First, make sure you are using Redis 2.8 or greater. Next:
data/Changes.md CHANGED
@@ -7,6 +7,16 @@
7
7
  and to remove dependencies. This has resulted in major speedups, as
8
8
  [detailed on my blog](http://www.mikeperham.com/2015/10/14/optimizing-sidekiq/).
9
9
  - See the [4.0 upgrade notes](4.0-Upgrade.md) for more detail.
10
+ - There's a new testing API based off the `Sidekiq::Queues` namespace. All
11
+ assertions made against the Worker class still work as expected.
12
+ [#2659, brandonhilkert]
13
+ ```ruby
14
+ assert_equal 0, Sidekiq::Queues["default"].size
15
+ HardWorker.perform_async("log")
16
+ assert_equal 1, Sidekiq::Queues["default"].size
17
+ assert_equal "log", Sidekiq::Queues["default"].first['args'][0]
18
+ Sidekiq::Queues.clear_all
19
+ ```
10
20
 
11
21
  3.5.3
12
22
  -----------
@@ -3,9 +3,23 @@ Sidekiq Enterprise Changelog
3
3
 
4
4
  Please see [http://sidekiq.org/](http://sidekiq.org/) for more details and how to buy.
5
5
 
6
+ 1.0.0.pre1
7
+ ----------
8
+
9
+ - Enterprise 1.x targets Sidekiq 4.x.
10
+ - Rewrite several features to remove Celluloid dependency. No
11
+ functional changes.
12
+
13
+ 0.7.8
14
+ ----------
15
+
16
+ - Fix `unique_for: false` [#2658]
17
+
18
+
6
19
  0.7.7
7
20
  ----------
8
21
 
22
+ - Enterprise 0.x targets Sidekiq 3.x.
9
23
  - Fix racy shutdown event which could lead to disappearing periodic
10
24
  jobs, requires Sidekiq >= 3.5.3.
11
25
  - Add new :leader event which is fired when a process gains leadership.
@@ -3,11 +3,22 @@ Sidekiq Pro Changelog
3
3
 
4
4
  Please see [http://sidekiq.org/](http://sidekiq.org/) for more details and how to buy.
5
5
 
6
- 3.0.0
6
+ 3.0.0.pre2
7
+ -----------
8
+
9
+ - Fix excessive connection usage by reliable fetch.
10
+
11
+ 3.0.0.pre1
7
12
  -----------
8
13
 
9
14
  - See the [Pro 3.0 release notes](Pro-3.0-Upgrade.md).
10
15
 
16
+ 2.1.3
17
+ -----------
18
+
19
+ - Don't enable strict priority if using weighted queueing like `-q a,1 -q b,1`
20
+ - Safer JSON mangling in Lua [#2639]
21
+
11
22
  2.1.2
12
23
  -----------
13
24
 
@@ -41,9 +41,13 @@ class Sidekiqctl
41
41
  end
42
42
 
43
43
  def fetch_process
44
- Process.getpgid(pid)
44
+ Process.kill(0, pid)
45
45
  rescue Errno::ESRCH
46
46
  done "Process doesn't exist", :error
47
+ # We were not allowed to send a signal, but the process must have existed
48
+ # when Process.kill() was called.
49
+ rescue Errno::EPERM
50
+ return pid
47
51
  end
48
52
 
49
53
  def done(msg, error = nil)
@@ -67,10 +71,12 @@ class Sidekiqctl
67
71
  `kill -TERM #{pid}`
68
72
  kill_timeout.times do
69
73
  begin
70
- Process.getpgid(pid)
74
+ Process.kill(0, pid)
71
75
  rescue Errno::ESRCH
72
76
  FileUtils.rm_f pidfile
73
77
  done 'Sidekiq shut down gracefully.'
78
+ rescue Errno::EPERM
79
+ done 'Not permitted to shut down Sidekiq.'
74
80
  end
75
81
  sleep 1
76
82
  end
@@ -5,6 +5,7 @@
5
5
  $TESTING = false
6
6
 
7
7
  #require 'ruby-prof'
8
+ Bundler.require(:default)
8
9
 
9
10
  require_relative '../lib/sidekiq/cli'
10
11
  require_relative '../lib/sidekiq/launcher'
@@ -30,6 +31,7 @@ Sidekiq.configure_server do |config|
30
31
  config.options[:queues] << 'default'
31
32
  config.logger.level = Logger::ERROR
32
33
  config.average_scheduled_poll_interval = 2
34
+ config.reliable! if defined?(Sidekiq::Pro)
33
35
  end
34
36
 
35
37
  class LoadWorker
@@ -140,6 +142,7 @@ end
140
142
  begin
141
143
  #RubyProf::exclude_threads = [ Monitoring ]
142
144
  #RubyProf.start
145
+ fire_event(:startup)
143
146
  Sidekiq.logger.error "Simulating 1ms of latency between Sidekiq and redis"
144
147
  Toxiproxy[:redis].downstream(:latency, latency: 1).apply do
145
148
  launcher = Sidekiq::Launcher.new(Sidekiq.options)
@@ -69,7 +69,7 @@ module Sidekiq
69
69
  # touch the connection pool so it is created before we
70
70
  # fire startup and start multithreading.
71
71
  ver = conn.info['redis_version']
72
- raise "Oops, you are using Redis v#{ver}, Sidekiq requires Redis v2.8.0 or greater" if ver < '2.8'
72
+ raise "You are using Redis v#{ver}, Sidekiq requires Redis v2.8.0 or greater" if ver < '2.8'
73
73
  end
74
74
 
75
75
  # Before this point, the process is initializing with just the main thread.
@@ -68,15 +68,15 @@ module Sidekiq
68
68
  def raw_push(payloads)
69
69
  if Sidekiq::Testing.fake?
70
70
  payloads.each do |job|
71
- job['class'].constantize.jobs << Sidekiq.load_json(Sidekiq.dump_json(job))
71
+ Queues.jobs[job['queue']] << Sidekiq.load_json(Sidekiq.dump_json(job))
72
72
  end
73
73
  true
74
74
  elsif Sidekiq::Testing.inline?
75
75
  payloads.each do |job|
76
- job['jid'] ||= SecureRandom.hex(12)
77
76
  klass = job['class'].constantize
78
- klass.jobs.unshift Sidekiq.load_json(Sidekiq.dump_json(job))
79
- klass.perform_one
77
+ job['id'] ||= SecureRandom.hex(12)
78
+ job_hash = Sidekiq.load_json(Sidekiq.dump_json(job))
79
+ klass.process_job(job_hash)
80
80
  end
81
81
  true
82
82
  else
@@ -85,6 +85,64 @@ module Sidekiq
85
85
  end
86
86
  end
87
87
 
88
+ module Queues
89
+ ##
90
+ # The Queues class is only for testing the fake queue implementation.
91
+ # The data is structured as a hash with queue name as hash key and array
92
+ # of job data as the value.
93
+ #
94
+ # {
95
+ # "default"=>[
96
+ # {
97
+ # "class"=>"TestTesting::QueueWorker",
98
+ # "args"=>[1, 2],
99
+ # "retry"=>true,
100
+ # "queue"=>"default",
101
+ # "jid"=>"abc5b065c5c4b27fc1102833",
102
+ # "created_at"=>1447445554.419934
103
+ # }
104
+ # ]
105
+ # }
106
+ #
107
+ # Example:
108
+ #
109
+ # require 'sidekiq/testing'
110
+ #
111
+ # assert_equal 0, Sidekiq::Queues["default"].size
112
+ # HardWorker.perform_async(:something)
113
+ # assert_equal 1, Sidekiq::Queues["default"].size
114
+ # assert_equal :something, Sidekiq::Queues["default"].first['args'][0]
115
+ #
116
+ # You can also clear all workers' jobs:
117
+ #
118
+ # assert_equal 0, Sidekiq::Queues["default"].size
119
+ # HardWorker.perform_async(:something)
120
+ # Sidekiq::Queues.clear_all
121
+ # assert_equal 0, Sidekiq::Queues["default"].size
122
+ #
123
+ # This can be useful to make sure jobs don't linger between tests:
124
+ #
125
+ # RSpec.configure do |config|
126
+ # config.before(:each) do
127
+ # Sidekiq::Queues.clear_all
128
+ # end
129
+ # end
130
+ #
131
+ class << self
132
+ def [](queue)
133
+ jobs[queue.to_s]
134
+ end
135
+
136
+ def jobs
137
+ @jobs ||= Hash.new { |hash, key| hash[key] = [] }
138
+ end
139
+
140
+ def clear_all
141
+ jobs.clear
142
+ end
143
+ end
144
+ end
145
+
88
146
  module Worker
89
147
  ##
90
148
  # The Sidekiq testing infrastructure overrides perform_async
@@ -143,28 +201,36 @@ module Sidekiq
143
201
  #
144
202
  module ClassMethods
145
203
 
204
+ # Queue for this worker
205
+ def queue
206
+ self.sidekiq_options["queue"].to_s
207
+ end
208
+
146
209
  # Jobs queued for this worker
147
210
  def jobs
148
- Worker.jobs[self]
211
+ Queues.jobs[queue].select { |job| job["class"] == self.to_s }
149
212
  end
150
213
 
151
214
  # Clear all jobs for this worker
152
215
  def clear
153
- jobs.clear
216
+ Queues.jobs[queue].clear
154
217
  end
155
218
 
156
219
  # Drain and run all jobs for this worker
157
220
  def drain
158
- while job = jobs.shift do
159
- process_job(job)
221
+ while jobs.any?
222
+ next_job = jobs.first
223
+ Queues.jobs[queue].delete_if { |job| job["jid"] == next_job["jid"] }
224
+ process_job(next_job)
160
225
  end
161
226
  end
162
227
 
163
228
  # Pop out a single job and perform it
164
229
  def perform_one
165
230
  raise(EmptyQueueError, "perform_one called with empty job queue") if jobs.empty?
166
- job = jobs.shift
167
- process_job(job)
231
+ next_job = jobs.first
232
+ Queues.jobs[queue].delete_if { |job| job["jid"] == next_job["jid"] }
233
+ process_job(next_job)
168
234
  end
169
235
 
170
236
  def process_job(job)
@@ -183,18 +249,22 @@ module Sidekiq
183
249
 
184
250
  class << self
185
251
  def jobs # :nodoc:
186
- @jobs ||= Hash.new { |hash, key| hash[key] = [] }
252
+ Queues.jobs.values.flatten
187
253
  end
188
254
 
189
255
  # Clear all queued jobs across all workers
190
256
  def clear_all
191
- jobs.clear
257
+ Queues.clear_all
192
258
  end
193
259
 
194
260
  # Drain all queued jobs across all workers
195
261
  def drain_all
196
- until jobs.values.all?(&:empty?) do
197
- jobs.keys.each(&:drain)
262
+ while jobs.any?
263
+ worker_classes = jobs.map { |job| job["class"] }.uniq
264
+
265
+ worker_classes.each do |worker_class|
266
+ worker_class.constantize.drain
267
+ end
198
268
  end
199
269
  end
200
270
  end
@@ -1,3 +1,3 @@
1
1
  module Sidekiq
2
- VERSION = "4.0.0.pre2"
2
+ VERSION = "4.0.0"
3
3
  end
@@ -160,7 +160,7 @@ module Sidekiq
160
160
  options = options.stringify_keys
161
161
  params.merge(options).map do |key, value|
162
162
  SAFE_QPARAMS.include?(key) ? "#{key}=#{value}" : next
163
- end.join("&")
163
+ end.compact.join("&")
164
164
  end
165
165
 
166
166
  def truncate(text, truncate_after_chars = 2000)
@@ -245,5 +245,12 @@ module Sidekiq
245
245
  def product_version
246
246
  "Sidekiq v#{Sidekiq::VERSION}"
247
247
  end
248
+
249
+ def redis_connection_and_namespace
250
+ @redis_connection_and_namespace ||= begin
251
+ namespace_suffix = namespace == nil ? '' : "##{namespace}"
252
+ "#{redis_connection}#{namespace_suffix}"
253
+ end
254
+ end
248
255
  end
249
256
  end
@@ -16,10 +16,10 @@ Gem::Specification.new do |gem|
16
16
  gem.require_paths = ["lib"]
17
17
  gem.version = Sidekiq::VERSION
18
18
  gem.add_dependency 'redis', '~> 3.2', '>= 3.2.1'
19
- gem.add_dependency 'redis-namespace', '~> 1.5', '>= 1.5.2'
20
19
  gem.add_dependency 'connection_pool', '~> 2.2', '>= 2.2.0'
21
20
  gem.add_dependency 'json', '~> 1.0'
22
- gem.add_dependency 'concurrent-ruby', '1.0.0.pre4'
21
+ gem.add_dependency 'concurrent-ruby', '~> 1.0'
22
+ gem.add_development_dependency 'redis-namespace', '~> 1.5', '>= 1.5.2'
23
23
  gem.add_development_dependency 'sinatra', '~> 1.4', '>= 1.4.6'
24
24
  gem.add_development_dependency 'minitest', '~> 5.7', '>= 5.7.0'
25
25
  gem.add_development_dependency 'rake', '~> 10.0'
@@ -54,6 +54,7 @@ class TestTesting < Sidekiq::Test
54
54
 
55
55
  after do
56
56
  Sidekiq::Testing.disable!
57
+ Sidekiq::Queues.clear_all
57
58
  end
58
59
 
59
60
  it 'stubs the async call' do
@@ -93,7 +94,7 @@ class TestTesting < Sidekiq::Test
93
94
  it 'stubs the enqueue_to call' do
94
95
  assert_equal 0, EnqueuedWorker.jobs.size
95
96
  assert Sidekiq::Client.enqueue_to('someq', EnqueuedWorker, 1, 2)
96
- assert_equal 1, EnqueuedWorker.jobs.size
97
+ assert_equal 1, Sidekiq::Queues['someq'].size
97
98
  end
98
99
 
99
100
  it 'executes all stored jobs' do
@@ -263,6 +264,68 @@ class TestTesting < Sidekiq::Test
263
264
  it 'can execute a job' do
264
265
  DirectWorker.execute_job(DirectWorker.new, [2, 3])
265
266
  end
267
+ end
268
+
269
+ describe 'queue testing' do
270
+ before do
271
+ require 'sidekiq/testing'
272
+ Sidekiq::Testing.fake!
273
+ end
274
+
275
+ after do
276
+ Sidekiq::Testing.disable!
277
+ Sidekiq::Queues.clear_all
278
+ end
266
279
 
280
+ class QueueWorker
281
+ include Sidekiq::Worker
282
+ def perform(a, b)
283
+ a + b
284
+ end
285
+ end
286
+
287
+ class AltQueueWorker
288
+ include Sidekiq::Worker
289
+ sidekiq_options queue: :alt
290
+ def perform(a, b)
291
+ a + b
292
+ end
293
+ end
294
+
295
+ it 'finds enqueued jobs' do
296
+ assert_equal 0, Sidekiq::Queues["default"].size
297
+
298
+ QueueWorker.perform_async(1, 2)
299
+ QueueWorker.perform_async(1, 2)
300
+ AltQueueWorker.perform_async(1, 2)
301
+
302
+ assert_equal 2, Sidekiq::Queues["default"].size
303
+ assert_equal [1, 2], Sidekiq::Queues["default"].first["args"]
304
+
305
+ assert_equal 1, Sidekiq::Queues["alt"].size
306
+ end
307
+
308
+ it 'clears out all queues' do
309
+ assert_equal 0, Sidekiq::Queues["default"].size
310
+
311
+ QueueWorker.perform_async(1, 2)
312
+ QueueWorker.perform_async(1, 2)
313
+ AltQueueWorker.perform_async(1, 2)
314
+
315
+ Sidekiq::Queues.clear_all
316
+
317
+ assert_equal 0, Sidekiq::Queues["default"].size
318
+ assert_equal 0, Sidekiq::Queues["alt"].size
319
+ end
320
+
321
+ it 'finds jobs enqueued by client' do
322
+ Sidekiq::Client.push(
323
+ 'class' => 'NonExistentWorker',
324
+ 'queue' => 'missing',
325
+ 'args' => [1]
326
+ )
327
+
328
+ assert_equal 1, Sidekiq::Queues["missing"].size
329
+ end
267
330
  end
268
331
  end
@@ -748,3 +748,7 @@ div.interval-slider input {
748
748
  max-width: 350px;
749
749
  }
750
750
  }
751
+
752
+ .redis-url {
753
+ text-overflow: ellipsis;
754
+ }
@@ -6,16 +6,11 @@
6
6
  <p class="navbar-text" style="color:white;"><%= product_version %></p>
7
7
  </li>
8
8
  <li>
9
- <p class="navbar-text redis-url">Redis: <%= redis_connection %></p>
9
+ <p class="navbar-text redis-url" title="<%= redis_connection_and_namespace %>"><%= redis_connection_and_namespace %></p>
10
10
  </li>
11
11
  <li>
12
- <p class="navbar-text"><%= t('Time') %>: <%= Time.now.utc.strftime('%H:%M:%S UTC') %></p>
12
+ <p class="navbar-text"><%= Time.now.utc.strftime('%H:%M:%S UTC') %></p>
13
13
  </li>
14
- <% if namespace %>
15
- <li>
16
- <p class="navbar-text redis-namespace"><%= t('Namespace') %>: <%= namespace %></p>
17
- </li>
18
- <% end %>
19
14
  </ul>
20
15
  </div>
21
16
  </div>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.pre2
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Perham
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-02 00:00:00.000000000 Z
11
+ date: 2015-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -31,47 +31,41 @@ dependencies:
31
31
  - !ruby/object:Gem::Version
32
32
  version: 3.2.1
33
33
  - !ruby/object:Gem::Dependency
34
- name: redis-namespace
34
+ name: connection_pool
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: '1.5'
39
+ version: '2.2'
40
40
  - - ">="
41
41
  - !ruby/object:Gem::Version
42
- version: 1.5.2
42
+ version: 2.2.0
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - "~>"
48
48
  - !ruby/object:Gem::Version
49
- version: '1.5'
49
+ version: '2.2'
50
50
  - - ">="
51
51
  - !ruby/object:Gem::Version
52
- version: 1.5.2
52
+ version: 2.2.0
53
53
  - !ruby/object:Gem::Dependency
54
- name: connection_pool
54
+ name: json
55
55
  requirement: !ruby/object:Gem::Requirement
56
56
  requirements:
57
57
  - - "~>"
58
58
  - !ruby/object:Gem::Version
59
- version: '2.2'
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- version: 2.2.0
59
+ version: '1.0'
63
60
  type: :runtime
64
61
  prerelease: false
65
62
  version_requirements: !ruby/object:Gem::Requirement
66
63
  requirements:
67
64
  - - "~>"
68
65
  - !ruby/object:Gem::Version
69
- version: '2.2'
70
- - - ">="
71
- - !ruby/object:Gem::Version
72
- version: 2.2.0
66
+ version: '1.0'
73
67
  - !ruby/object:Gem::Dependency
74
- name: json
68
+ name: concurrent-ruby
75
69
  requirement: !ruby/object:Gem::Requirement
76
70
  requirements:
77
71
  - - "~>"
@@ -85,19 +79,25 @@ dependencies:
85
79
  - !ruby/object:Gem::Version
86
80
  version: '1.0'
87
81
  - !ruby/object:Gem::Dependency
88
- name: concurrent-ruby
82
+ name: redis-namespace
89
83
  requirement: !ruby/object:Gem::Requirement
90
84
  requirements:
91
- - - '='
85
+ - - "~>"
92
86
  - !ruby/object:Gem::Version
93
- version: 1.0.0.pre4
94
- type: :runtime
87
+ version: '1.5'
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 1.5.2
91
+ type: :development
95
92
  prerelease: false
96
93
  version_requirements: !ruby/object:Gem::Requirement
97
94
  requirements:
98
- - - '='
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '1.5'
98
+ - - ">="
99
99
  - !ruby/object:Gem::Version
100
- version: 1.0.0.pre4
100
+ version: 1.5.2
101
101
  - !ruby/object:Gem::Dependency
102
102
  name: sinatra
103
103
  requirement: !ruby/object:Gem::Requirement
@@ -376,9 +376,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
376
376
  version: '0'
377
377
  required_rubygems_version: !ruby/object:Gem::Requirement
378
378
  requirements:
379
- - - ">"
379
+ - - ">="
380
380
  - !ruby/object:Gem::Version
381
- version: 1.3.1
381
+ version: '0'
382
382
  requirements: []
383
383
  rubyforge_project:
384
384
  rubygems_version: 2.4.5