sidekiq 3.4.1 → 3.4.2
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 +4 -4
- data/Changes.md +13 -0
- data/Gemfile +4 -0
- data/Pro-2.0-Upgrade.md +2 -2
- data/Pro-Changes.md +7 -0
- data/README.md +0 -1
- data/bin/sidekiq +5 -0
- data/lib/sidekiq/api.rb +4 -4
- data/lib/sidekiq/client.rb +3 -4
- data/lib/sidekiq/fetch.rb +1 -1
- data/lib/sidekiq/util.rb +13 -0
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web.rb +3 -1
- data/lib/sidekiq/web_helpers.rb +18 -3
- data/lib/sidekiq/worker.rb +2 -0
- data/sidekiq.gemspec +10 -10
- data/test/helper.rb +17 -8
- data/test/test_api.rb +6 -0
- data/test/test_cli.rb +24 -0
- data/test/test_rails.rb +23 -0
- data/test/test_retry.rb +22 -5
- data/test/test_scheduled.rb +2 -2
- data/test/test_sidekiq.rb +18 -0
- data/test/test_util.rb +18 -0
- data/test/test_web.rb +7 -1
- data/web/assets/stylesheets/application.css +3 -3
- data/web/views/_nav.erb +2 -2
- data/web/views/_poll_js.erb +5 -0
- data/web/views/{_poll.erb → _poll_link.erb} +0 -3
- data/web/views/busy.erb +2 -0
- data/web/views/dead.erb +1 -0
- data/web/views/layout.erb +1 -0
- data/web/views/morgue.erb +3 -0
- data/web/views/queue.erb +1 -0
- data/web/views/queues.erb +1 -0
- data/web/views/retries.erb +3 -0
- data/web/views/retry.erb +1 -0
- data/web/views/scheduled.erb +1 -0
- data/web/views/scheduled_job_info.erb +1 -0
- metadata +63 -38
- data/test/test_worker_generator.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 608ba6cc7b3fc425bc309c318204b5eae5bc467b
|
4
|
+
data.tar.gz: aaa3c0a205cce3385119d36bf2bf19a18678f9af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: da37f47a821a70ea4ccbd31957354ade6415bc83b8a053d5acbbafcbc7cc33e90ea5d1bbd97b079c740ab4c0f12a759b2ae009e6dbaae2ca709aae5958e1e719
|
7
|
+
data.tar.gz: 25eb856dc4b4c6698b6167d1fa57e874670b6169a63e8eaa9d178aa1a0240d4195a216530fb07f7f65f1076461ab92095714d776c20e53debae6a01efadd1909
|
data/Changes.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
3.4.2
|
2
|
+
-----------
|
3
|
+
|
4
|
+
- Don't allow `Sidekiq::Worker` in ActiveJob::Base classes. [#2424]
|
5
|
+
- Safer display of job data in Web UI [#2405]
|
6
|
+
- Fix CSRF vulenerability in Web UI, thanks to Egor Homakov for
|
7
|
+
reporting. [#2422] If you are running the Web UI as a standalone Rack app,
|
8
|
+
ensure you have a [session middleware
|
9
|
+
configured](https://github.com/mperham/sidekiq/wiki/Monitoring#standalone):
|
10
|
+
```ruby
|
11
|
+
use Rack::Session::Cookie, :secret => "some unique secret string here"
|
12
|
+
```
|
13
|
+
|
1
14
|
3.4.1
|
2
15
|
-----------
|
3
16
|
|
data/Gemfile
CHANGED
data/Pro-2.0-Upgrade.md
CHANGED
@@ -97,8 +97,8 @@ lots of jobs.
|
|
97
97
|
Sidekiq Pro functionality is affected by this change but some 3rd party
|
98
98
|
plugins might be.
|
99
99
|
- The Lua script used inside the reliable scheduler is not safe for use
|
100
|
-
with Redis Cluster
|
101
|
-
It is safe to use with a typical master/slave replication setup.
|
100
|
+
with Redis Cluster or other multi-master Redis solutions.
|
101
|
+
It is safe to use with Redis Sentinel or a typical master/slave replication setup.
|
102
102
|
|
103
103
|
**You no longer require anything to use the Reliability features.**
|
104
104
|
|
data/Pro-Changes.md
CHANGED
@@ -6,6 +6,13 @@ Please see [http://sidekiq.org/pro](http://sidekiq.org/pro) for more details and
|
|
6
6
|
HEAD
|
7
7
|
-----------
|
8
8
|
|
9
|
+
- Atomic scheduler now sets `enqueued_at` [#2414]
|
10
|
+
- Batches now account for jobs which are stopped by client middleware [#2406]
|
11
|
+
|
12
|
+
2.0.4
|
13
|
+
-----------
|
14
|
+
|
15
|
+
- Reliable push now supports sharding [#2409]
|
9
16
|
- Reliable push now only catches Redis exceptions [#2307]
|
10
17
|
|
11
18
|
2.0.3
|
data/README.md
CHANGED
@@ -4,7 +4,6 @@ Sidekiq
|
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/sidekiq.svg)](https://rubygems.org/gems/sidekiq)
|
5
5
|
[![Code Climate](https://codeclimate.com/github/mperham/sidekiq.svg)](https://codeclimate.com/github/mperham/sidekiq)
|
6
6
|
[![Build Status](https://travis-ci.org/mperham/sidekiq.svg)](https://travis-ci.org/mperham/sidekiq)
|
7
|
-
[![Coverage Status](https://coveralls.io/repos/mperham/sidekiq/badge.svg?branch=master)](https://coveralls.io/r/mperham/sidekiq)
|
8
7
|
[![Gitter Chat](https://badges.gitter.im/mperham/sidekiq.svg)](https://gitter.im/mperham/sidekiq)
|
9
8
|
|
10
9
|
|
data/bin/sidekiq
CHANGED
data/lib/sidekiq/api.rb
CHANGED
@@ -159,14 +159,15 @@ module Sidekiq
|
|
159
159
|
|
160
160
|
while i < @days_previous
|
161
161
|
date = @start_date - i
|
162
|
-
|
163
|
-
|
162
|
+
datestr = date.strftime("%Y-%m-%d".freeze)
|
163
|
+
keys << "stat:#{stat}:#{datestr}"
|
164
|
+
dates << datestr
|
164
165
|
i += 1
|
165
166
|
end
|
166
167
|
|
167
168
|
Sidekiq.redis do |conn|
|
168
169
|
conn.mget(keys).each_with_index do |value, idx|
|
169
|
-
stat_hash[dates[idx]
|
170
|
+
stat_hash[dates[idx]] = value ? value.to_i : 0
|
170
171
|
end
|
171
172
|
end
|
172
173
|
|
@@ -262,7 +263,6 @@ module Sidekiq
|
|
262
263
|
# removed from the queue via Job#delete.
|
263
264
|
#
|
264
265
|
class Job
|
265
|
-
KNOWN_WRAPPERS = [/\ASidekiq::Extensions::Delayed/, "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper"]
|
266
266
|
attr_reader :item
|
267
267
|
|
268
268
|
def initialize(item, queue_name=nil)
|
data/lib/sidekiq/client.rb
CHANGED
@@ -210,10 +210,9 @@ module Sidekiq
|
|
210
210
|
end
|
211
211
|
|
212
212
|
def normalize_item(item)
|
213
|
-
raise(ArgumentError, "
|
214
|
-
raise(ArgumentError, "
|
215
|
-
raise(ArgumentError, "
|
216
|
-
raise(ArgumentError, "Message class must be either a Class or String representation of the class name") unless item['class'].is_a?(Class) || item['class'].is_a?(String)
|
213
|
+
raise(ArgumentError, "Job must be a Hash with 'class' and 'args' keys: { 'class' => SomeWorker, 'args' => ['bob', 1, :foo => 'bar'] }") unless item.is_a?(Hash) && item.has_key?('class'.freeze) && item.has_key?('args'.freeze)
|
214
|
+
raise(ArgumentError, "Job args must be an Array") unless item['args'].is_a?(Array)
|
215
|
+
raise(ArgumentError, "Job class must be either a Class or String representation of the class name") unless item['class'.freeze].is_a?(Class) || item['class'.freeze].is_a?(String)
|
217
216
|
|
218
217
|
normalized_hash(item['class'.freeze])
|
219
218
|
.each{ |key, value| item[key] = value if item[key].nil? }
|
data/lib/sidekiq/fetch.rb
CHANGED
data/lib/sidekiq/util.rb
CHANGED
@@ -51,5 +51,18 @@ module Sidekiq
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
def want_a_hertz_donut?
|
55
|
+
# what's a hertz donut?
|
56
|
+
# punch! Hurts, don't it?
|
57
|
+
info = Sidekiq.redis {|c| c.info }
|
58
|
+
if info['connected_clients'].to_i > 1000 && info['hz'].to_i >= 10
|
59
|
+
Sidekiq.logger.warn { "Your Redis `hz` setting is too high at #{info['hz']}. See mperham/sidekiq#2431. Set it to 3 in #{info[:config_file]}" }
|
60
|
+
true
|
61
|
+
else
|
62
|
+
Sidekiq.logger.debug { "Redis hz: #{info['hz']}. Client count: #{info['connected_clients']}" }
|
63
|
+
false
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
54
67
|
end
|
55
68
|
end
|
data/lib/sidekiq/version.rb
CHANGED
data/lib/sidekiq/web.rb
CHANGED
@@ -11,6 +11,8 @@ module Sidekiq
|
|
11
11
|
class Web < Sinatra::Base
|
12
12
|
include Sidekiq::Paginator
|
13
13
|
|
14
|
+
use Rack::Protection, :use => :authenticity_token unless ENV['RACK_ENV'] == 'test'
|
15
|
+
|
14
16
|
set :root, File.expand_path(File.dirname(__FILE__) + "/../../web")
|
15
17
|
set :public_folder, proc { "#{root}/assets" }
|
16
18
|
set :views, proc { "#{root}/views" }
|
@@ -98,7 +100,7 @@ module Sidekiq
|
|
98
100
|
end
|
99
101
|
|
100
102
|
post '/morgue' do
|
101
|
-
|
103
|
+
redirect request.path unless params['key']
|
102
104
|
|
103
105
|
params['key'].each do |key|
|
104
106
|
job = Sidekiq::DeadSet.new.fetch(*parse_params(key)).first
|
data/lib/sidekiq/web_helpers.rb
CHANGED
@@ -45,7 +45,7 @@ module Sidekiq
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def display_custom_head
|
48
|
-
return unless @head_html
|
48
|
+
return unless defined?(@head_html)
|
49
49
|
@head_html.map { |block| capture(&block) }.join
|
50
50
|
end
|
51
51
|
|
@@ -169,11 +169,26 @@ module Sidekiq
|
|
169
169
|
|
170
170
|
def display_args(args, truncate_after_chars = 2000)
|
171
171
|
args.map do |arg|
|
172
|
-
|
173
|
-
h(truncate(a))
|
172
|
+
h(truncate(to_display(arg)))
|
174
173
|
end.join(", ")
|
175
174
|
end
|
176
175
|
|
176
|
+
def csrf_tag
|
177
|
+
"<input type='hidden' name='authenticity_token' value='#{session[:csrf]}'/>"
|
178
|
+
end
|
179
|
+
|
180
|
+
def to_display(arg)
|
181
|
+
begin
|
182
|
+
arg.inspect
|
183
|
+
rescue
|
184
|
+
begin
|
185
|
+
arg.to_s
|
186
|
+
rescue => ex
|
187
|
+
"Cannot display argument: [#{ex.class.name}] #{ex.message}"
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
177
192
|
RETRY_JOB_KEYS = Set.new(%w(
|
178
193
|
queue class args retry_count retried_at failed_at
|
179
194
|
jid error_message error_class backtrace
|
data/lib/sidekiq/worker.rb
CHANGED
@@ -24,6 +24,8 @@ module Sidekiq
|
|
24
24
|
attr_accessor :jid
|
25
25
|
|
26
26
|
def self.included(base)
|
27
|
+
raise ArgumentError, "You cannot include Sidekiq::Worker in an ActiveJob: #{base.name}" if base.ancestors.any? {|c| c.name == 'ActiveJob::Base' }
|
28
|
+
|
27
29
|
base.extend(ClassMethods)
|
28
30
|
base.class_attribute :sidekiq_options_hash
|
29
31
|
base.class_attribute :sidekiq_retry_in_block
|
data/sidekiq.gemspec
CHANGED
@@ -4,7 +4,8 @@ require File.expand_path('../lib/sidekiq/version', __FILE__)
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
5
|
gem.authors = ["Mike Perham"]
|
6
6
|
gem.email = ["mperham@gmail.com"]
|
7
|
-
gem.
|
7
|
+
gem.summary = "Simple, efficient background processing for Ruby"
|
8
|
+
gem.description = "Simple, efficient background processing for Ruby."
|
8
9
|
gem.homepage = "http://sidekiq.org"
|
9
10
|
gem.license = "LGPL-3.0"
|
10
11
|
|
@@ -14,14 +15,13 @@ Gem::Specification.new do |gem|
|
|
14
15
|
gem.name = "sidekiq"
|
15
16
|
gem.require_paths = ["lib"]
|
16
17
|
gem.version = Sidekiq::VERSION
|
17
|
-
gem.add_dependency 'redis', '>= 3.
|
18
|
-
gem.add_dependency 'redis-namespace', '>= 1.
|
19
|
-
gem.add_dependency 'connection_pool', '>= 2.
|
18
|
+
gem.add_dependency 'redis', '~> 3.2', '>= 3.2.1'
|
19
|
+
gem.add_dependency 'redis-namespace', '~> 1.5', '>= 1.5.2'
|
20
|
+
gem.add_dependency 'connection_pool', '~> 2.2', '>= 2.2.0'
|
20
21
|
gem.add_dependency 'celluloid', '~> 0.16.0'
|
21
|
-
gem.add_dependency 'json'
|
22
|
-
gem.add_development_dependency 'sinatra'
|
23
|
-
gem.add_development_dependency 'minitest', '~> 5.
|
24
|
-
gem.add_development_dependency 'rake'
|
25
|
-
gem.add_development_dependency 'rails', '~> 4.
|
26
|
-
gem.add_development_dependency 'coveralls'
|
22
|
+
gem.add_dependency 'json', '~> 1.0'
|
23
|
+
gem.add_development_dependency 'sinatra', '~> 1.4', '>= 1.4.6'
|
24
|
+
gem.add_development_dependency 'minitest', '~> 5.7', '>= 5.7.0'
|
25
|
+
gem.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
gem.add_development_dependency 'rails', '~> 4', '>= 3.2.0'
|
27
27
|
end
|
data/test/helper.rb
CHANGED
@@ -1,18 +1,13 @@
|
|
1
|
+
$CELLULOID_DEBUG = false
|
1
2
|
$TESTING = true
|
2
|
-
|
3
|
-
Coveralls.wear! do
|
4
|
-
add_filter "/test/"
|
5
|
-
add_filter "/myapp/"
|
6
|
-
end
|
7
|
-
|
8
|
-
ENV['RACK_ENV'] = ENV['RAILS_ENV'] = 'test'
|
9
|
-
if ENV.has_key?("SIMPLECOV")
|
3
|
+
if ENV["COVERAGE"]
|
10
4
|
require 'simplecov'
|
11
5
|
SimpleCov.start do
|
12
6
|
add_filter "/test/"
|
13
7
|
add_filter "/myapp/"
|
14
8
|
end
|
15
9
|
end
|
10
|
+
ENV['RACK_ENV'] = ENV['RAILS_ENV'] = 'test'
|
16
11
|
|
17
12
|
begin
|
18
13
|
require 'pry-byebug'
|
@@ -37,3 +32,17 @@ REDIS = Sidekiq::RedisConnection.create(:url => REDIS_URL, :namespace => 'testy'
|
|
37
32
|
Sidekiq.configure_client do |config|
|
38
33
|
config.redis = { :url => REDIS_URL, :namespace => 'testy' }
|
39
34
|
end
|
35
|
+
|
36
|
+
def capture_logging(lvl=Logger::INFO)
|
37
|
+
old = Sidekiq.logger
|
38
|
+
begin
|
39
|
+
out = StringIO.new
|
40
|
+
logger = Logger.new(out)
|
41
|
+
logger.level = lvl
|
42
|
+
Sidekiq.logger = logger
|
43
|
+
yield
|
44
|
+
out.string
|
45
|
+
ensure
|
46
|
+
Sidekiq.logger = old
|
47
|
+
end
|
48
|
+
end
|
data/test/test_api.rb
CHANGED
@@ -4,10 +4,16 @@ class TestApi < Sidekiq::Test
|
|
4
4
|
|
5
5
|
describe "stats" do
|
6
6
|
before do
|
7
|
+
@before = DateTime::DATE_FORMATS[:default]
|
8
|
+
DateTime::DATE_FORMATS[:default] = "%d/%m/%Y %H:%M:%S"
|
7
9
|
Sidekiq.redis = REDIS
|
8
10
|
Sidekiq.redis {|c| c.flushdb }
|
9
11
|
end
|
10
12
|
|
13
|
+
after do
|
14
|
+
DateTime::DATE_FORMATS[:default] = @before
|
15
|
+
end
|
16
|
+
|
11
17
|
describe "processed" do
|
12
18
|
it "is initially zero" do
|
13
19
|
s = Sidekiq::Stats.new
|
data/test/test_cli.rb
CHANGED
@@ -362,4 +362,28 @@ class TestCli < Sidekiq::Test
|
|
362
362
|
end
|
363
363
|
end
|
364
364
|
|
365
|
+
describe 'misc' do
|
366
|
+
it 'handles interrupts' do
|
367
|
+
cli = Sidekiq::CLI.new
|
368
|
+
assert_raises Interrupt do
|
369
|
+
cli.handle_signal('INT')
|
370
|
+
end
|
371
|
+
assert_raises Interrupt do
|
372
|
+
cli.handle_signal('TERM')
|
373
|
+
end
|
374
|
+
cli.handle_signal('USR2')
|
375
|
+
cli.handle_signal('TTIN')
|
376
|
+
end
|
377
|
+
|
378
|
+
it 'can fire events' do
|
379
|
+
count = 0
|
380
|
+
Sidekiq.options[:lifecycle_events][:startup] = [proc {
|
381
|
+
count += 1
|
382
|
+
}]
|
383
|
+
cli = Sidekiq::CLI.new
|
384
|
+
cli.fire_event(:startup)
|
385
|
+
assert_equal 1, count
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
365
389
|
end
|
data/test/test_rails.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
require 'sidekiq'
|
3
|
+
require 'sidekiq/web_helpers'
|
4
|
+
|
5
|
+
$HAS_AJ = true
|
6
|
+
begin
|
7
|
+
require 'active_job'
|
8
|
+
rescue LoadError
|
9
|
+
$HAS_AJ = false
|
10
|
+
end
|
11
|
+
|
12
|
+
class TestRails < Sidekiq::Test
|
13
|
+
|
14
|
+
describe 'ActiveJob' do
|
15
|
+
it 'does not allow Sidekiq::Worker in AJ::Base classes' do
|
16
|
+
ex = assert_raises ArgumentError do
|
17
|
+
c = Class.new(ActiveJob::Base)
|
18
|
+
c.send(:include, Sidekiq::Worker)
|
19
|
+
end
|
20
|
+
assert_includes ex.message, "cannot include"
|
21
|
+
end if $HAS_AJ
|
22
|
+
end
|
23
|
+
end
|
data/test/test_retry.rb
CHANGED
@@ -39,18 +39,35 @@ class TestRetry < Sidekiq::Test
|
|
39
39
|
it 'allows a numeric retry' do
|
40
40
|
@redis.expect :zadd, 1, ['retry', String, String]
|
41
41
|
msg = { 'class' => 'Bob', 'args' => [1,2,'foo'], 'retry' => 2 }
|
42
|
-
msg2 = msg.dup
|
43
42
|
handler = Sidekiq::Middleware::Server::RetryJobs.new
|
44
43
|
assert_raises RuntimeError do
|
45
|
-
handler.call(worker,
|
44
|
+
handler.call(worker, msg, 'default') do
|
46
45
|
raise "kerblammo!"
|
47
46
|
end
|
48
47
|
end
|
49
|
-
|
50
|
-
assert_equal({"class"=>"Bob", "args"=>[1, 2, "foo"], "retry"=>2, "queue"=>"default", "error_message"=>"kerblammo!", "error_class"=>"RuntimeError", "retry_count"=>0},
|
48
|
+
msg.delete('failed_at')
|
49
|
+
assert_equal({"class"=>"Bob", "args"=>[1, 2, "foo"], "retry"=>2, "queue"=>"default", "error_message"=>"kerblammo!", "error_class"=>"RuntimeError", "retry_count"=>0}, msg)
|
51
50
|
@redis.verify
|
52
51
|
end
|
53
52
|
|
53
|
+
it 'allows 0 retry => no retry and dead queue' do
|
54
|
+
@redis.expect :zadd, 1, ['dead', Float, String]
|
55
|
+
@redis.expect :zremrangebyscore, 0, ['dead', String, Float]
|
56
|
+
@redis.expect :zremrangebyrank, 0, ['dead', Numeric, Numeric]
|
57
|
+
msg = { 'class' => 'Bob', 'args' => [1,2,'foo'], 'retry' => 0 }
|
58
|
+
msg2 = msg.dup
|
59
|
+
handler = Sidekiq::Middleware::Server::RetryJobs.new
|
60
|
+
assert_raises RuntimeError do
|
61
|
+
handler.call(worker, msg, 'default') do
|
62
|
+
raise "kerblammo!"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
msg.delete('failed_at')
|
66
|
+
expected = msg2.merge "queue"=>"default", "error_message"=>"kerblammo!", "error_class"=>"RuntimeError", "retry_count"=>0
|
67
|
+
assert_equal expected, msg
|
68
|
+
@redis.verify # not called
|
69
|
+
end
|
70
|
+
|
54
71
|
it 'handles zany characters in error message, #1705' do
|
55
72
|
skip 'skipped! test requires ruby 2.1+' if RUBY_VERSION <= '2.1.0'
|
56
73
|
@redis.expect :zadd, 1, ['retry', String, String]
|
@@ -354,7 +371,7 @@ class TestRetry < Sidekiq::Test
|
|
354
371
|
rescue ::StandardError => e1
|
355
372
|
begin
|
356
373
|
raise ::StandardError, 'Error 2'
|
357
|
-
rescue ::StandardError
|
374
|
+
rescue ::StandardError
|
358
375
|
raise e1
|
359
376
|
end
|
360
377
|
end
|
data/test/test_scheduled.rb
CHANGED
@@ -98,8 +98,8 @@ class TestScheduled < Sidekiq::Test
|
|
98
98
|
i = 500
|
99
99
|
intervals = i.times.map{ @poller.send(:random_poll_interval) }
|
100
100
|
|
101
|
-
assert intervals.all?{|
|
102
|
-
assert intervals.all?{|
|
101
|
+
assert intervals.all?{|x| x >= 5}
|
102
|
+
assert intervals.all?{|x| x <= 15}
|
103
103
|
assert_in_delta 10, intervals.reduce(&:+).to_f / i, 0.5
|
104
104
|
end
|
105
105
|
end
|
data/test/test_sidekiq.rb
CHANGED
@@ -66,4 +66,22 @@ class TestSidekiq < Sidekiq::Test
|
|
66
66
|
assert_equal 'cat', Sidekiq.default_worker_options['queue']
|
67
67
|
end
|
68
68
|
end
|
69
|
+
|
70
|
+
describe 'error handling' do
|
71
|
+
it 'deals with user-specified error handlers which raise errors' do
|
72
|
+
output = capture_logging do
|
73
|
+
begin
|
74
|
+
Sidekiq.error_handlers << proc {|x, hash|
|
75
|
+
raise 'boom'
|
76
|
+
}
|
77
|
+
cli = Sidekiq::CLI.new
|
78
|
+
cli.handle_exception(RuntimeError.new("hello"))
|
79
|
+
ensure
|
80
|
+
Sidekiq.error_handlers.pop
|
81
|
+
end
|
82
|
+
end
|
83
|
+
assert_includes output, "boom"
|
84
|
+
assert_includes output, "ERROR"
|
85
|
+
end
|
86
|
+
end
|
69
87
|
end
|
data/test/test_util.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
require 'sidekiq'
|
3
|
+
require 'sidekiq/web_helpers'
|
4
|
+
|
5
|
+
class TestUtil < Sidekiq::Test
|
6
|
+
|
7
|
+
class Helpers
|
8
|
+
include Sidekiq::Util
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_hertz_donut
|
12
|
+
obj = Helpers.new
|
13
|
+
output = capture_logging(Logger::DEBUG) do
|
14
|
+
assert_equal false, obj.want_a_hertz_donut?
|
15
|
+
end
|
16
|
+
assert_includes output, "hz: 10"
|
17
|
+
end
|
18
|
+
end
|
data/test/test_web.rb
CHANGED
@@ -292,7 +292,13 @@ class TestWeb < Sidekiq::Test
|
|
292
292
|
|
293
293
|
get '/queues/default'
|
294
294
|
assert_equal 200, last_response.status
|
295
|
-
assert_match
|
295
|
+
assert_match(/#{msg['args'][2]}/, last_response.body)
|
296
|
+
end
|
297
|
+
|
298
|
+
it 'calls updatePage() once when polling' do
|
299
|
+
get '/busy?poll=true'
|
300
|
+
assert_equal 200, last_response.status
|
301
|
+
assert_equal 1, last_response.body.scan('updatePage(').count
|
296
302
|
end
|
297
303
|
|
298
304
|
it 'escape job args and error messages' do
|
@@ -759,16 +759,16 @@ div.interval-slider input {
|
|
759
759
|
|
760
760
|
@media (min-width: 992px) {
|
761
761
|
.redis-url {
|
762
|
-
max-width:
|
762
|
+
max-width: 390px;
|
763
763
|
}
|
764
764
|
|
765
765
|
.redis-namespace {
|
766
|
-
max-width:
|
766
|
+
max-width: 300px;
|
767
767
|
}
|
768
768
|
}
|
769
769
|
@media (min-width: 1200px) {
|
770
770
|
.redis-url {
|
771
|
-
max-width:
|
771
|
+
max-width: 480px;
|
772
772
|
}
|
773
773
|
|
774
774
|
.redis-namespace {
|
data/web/views/_nav.erb
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
<span class="icon-bar"></span>
|
8
8
|
</button>
|
9
9
|
<div class="navbar-toggle collapsed navbar-livereload">
|
10
|
-
<%= erb :
|
10
|
+
<%= erb :_poll_link %>
|
11
11
|
<% if Sidekiq::Web.app_url %>
|
12
12
|
<a class="btn btn-inverse" href="<%= Sidekiq::Web.app_url %>">Back to App</a>
|
13
13
|
<% end %>
|
@@ -54,7 +54,7 @@
|
|
54
54
|
<ul class="nav navbar-nav navbar-right navbar-livereload" data-navbar="static">
|
55
55
|
<li>
|
56
56
|
<div class="poll-wrapper pull-right">
|
57
|
-
<%= erb :
|
57
|
+
<%= erb :_poll_link %>
|
58
58
|
<% if Sidekiq::Web.app_url %>
|
59
59
|
<a class="btn btn-inverse" href="<%= Sidekiq::Web.app_url %>">Back to App</a>
|
60
60
|
<% end %>
|
@@ -1,8 +1,5 @@
|
|
1
1
|
<% if current_path != '' %>
|
2
2
|
<% if params[:poll] %>
|
3
|
-
<script>
|
4
|
-
updatePage('<%= root_path + current_path %>')
|
5
|
-
</script>
|
6
3
|
<a id="live-poll" class="btn btn-primary active" href="<%= root_path + current_path %>"><%= t('StopPolling') %></a>
|
7
4
|
<% else %>
|
8
5
|
<a id="live-poll" class="btn btn-primary" href="<%= root_path + current_path %>?<%= qparams(poll: true) %>"><%= t('LivePoll') %></a>
|
data/web/views/busy.erb
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
</div>
|
5
5
|
<div class="col-sm-4 pull-right">
|
6
6
|
<form method="POST" style="margin-top: 20px; margin-bottom: 10px;">
|
7
|
+
<%= csrf_tag %>
|
7
8
|
<div class="btn-group pull-right">
|
8
9
|
<button class="btn btn-warn" type="submit" name="quiet" value="1"><%= t('QuietAll') %></button>
|
9
10
|
<button class="btn btn-danger" type="submit" name="stop" value="1"><%= t('StopAll') %></button>
|
@@ -40,6 +41,7 @@
|
|
40
41
|
<td>
|
41
42
|
<div class="btn-group pull-right">
|
42
43
|
<form method="POST">
|
44
|
+
<%= csrf_tag %>
|
43
45
|
<input type="hidden" name="identity" value="<%= process['identity'] %>"/>
|
44
46
|
<button class="btn btn-warn" type="submit" name="quiet" value="1"><%= t('Quiet') %></button>
|
45
47
|
<button class="btn btn-danger" type="submit" name="stop" value="1"><%= t('Stop') %></button>
|
data/web/views/dead.erb
CHANGED
@@ -27,6 +27,7 @@
|
|
27
27
|
</div>
|
28
28
|
|
29
29
|
<form class="form-horizontal" action="<%= root_path %>morgue/<%= job_params(@dead, @dead.score) %>" method="post">
|
30
|
+
<%= csrf_tag %>
|
30
31
|
<a class="btn btn-default" href="<%= root_path %>morgue"><%= t('GoBack') %></a>
|
31
32
|
<input class="btn btn-primary" type="submit" name="retry" value="<%= t('RetryNow') %>" />
|
32
33
|
<input class="btn btn-danger" type="submit" name="delete" value="<%= t('Delete') %>" />
|
data/web/views/layout.erb
CHANGED
data/web/views/morgue.erb
CHANGED
@@ -12,6 +12,7 @@
|
|
12
12
|
|
13
13
|
<% if @dead.size > 0 %>
|
14
14
|
<form action="<%= root_path %>morgue" method="post">
|
15
|
+
<%= csrf_tag %>
|
15
16
|
<div class="table_container">
|
16
17
|
<table class="table table-striped table-bordered table-white">
|
17
18
|
<thead>
|
@@ -57,9 +58,11 @@
|
|
57
58
|
</form>
|
58
59
|
|
59
60
|
<form action="<%= root_path %>morgue/all/delete" method="post">
|
61
|
+
<%= csrf_tag %>
|
60
62
|
<input class="btn btn-danger btn-xs pull-right" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
|
61
63
|
</form>
|
62
64
|
<form action="<%= root_path %>morgue/all/retry" method="post">
|
65
|
+
<%= csrf_tag %>
|
63
66
|
<input class="btn btn-danger btn-xs pull-right" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
|
64
67
|
</form>
|
65
68
|
|
data/web/views/queue.erb
CHANGED
@@ -33,6 +33,7 @@
|
|
33
33
|
</td>
|
34
34
|
<td>
|
35
35
|
<form action="<%= root_path %>queues/<%= @name %>/delete" method="post">
|
36
|
+
<%= csrf_tag %>
|
36
37
|
<input name="key_val" value="<%= h Sidekiq.dump_json(msg.item) %>" type="hidden" />
|
37
38
|
<input class="btn btn-danger btn-xs" type="submit" name="delete" value="<%= t('Delete') %>" data-confirm="<%= t('AreYouSure') %>" />
|
38
39
|
</form>
|
data/web/views/queues.erb
CHANGED
@@ -18,6 +18,7 @@
|
|
18
18
|
<td><%= number_with_delimiter(queue.size) %> </td>
|
19
19
|
<td width="20%">
|
20
20
|
<form action="<%=root_path %>queues/<%= queue.name %>" method="post">
|
21
|
+
<%= csrf_tag %>
|
21
22
|
<input class="btn btn-danger btn-xs" type="submit" name="delete" value="<%= t('Delete') %>" data-confirm="<%= t('AreYouSureDeleteQueue', :queue => h(queue.name)) %>" />
|
22
23
|
</form>
|
23
24
|
</td>
|
data/web/views/retries.erb
CHANGED
@@ -12,6 +12,7 @@
|
|
12
12
|
|
13
13
|
<% if @retries.size > 0 %>
|
14
14
|
<form action="<%= root_path %>retries" method="post">
|
15
|
+
<%= csrf_tag %>
|
15
16
|
<div class="table_container">
|
16
17
|
<table class="table table-striped table-bordered table-white">
|
17
18
|
<thead>
|
@@ -60,9 +61,11 @@
|
|
60
61
|
</form>
|
61
62
|
|
62
63
|
<form action="<%= root_path %>retries/all/delete" method="post">
|
64
|
+
<%= csrf_tag %>
|
63
65
|
<input class="btn btn-danger btn-xs pull-right" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
|
64
66
|
</form>
|
65
67
|
<form action="<%= root_path %>retries/all/retry" method="post">
|
68
|
+
<%= csrf_tag %>
|
66
69
|
<input class="btn btn-danger btn-xs pull-right" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
|
67
70
|
</form>
|
68
71
|
|
data/web/views/retry.erb
CHANGED
@@ -27,6 +27,7 @@
|
|
27
27
|
</div>
|
28
28
|
|
29
29
|
<form class="form-horizontal" action="<%= root_path %>retries/<%= job_params(@retry, @retry.score) %>" method="post">
|
30
|
+
<%= csrf_tag %>
|
30
31
|
<a class="btn btn-default" href="<%= root_path %>retries"><%= t('GoBack') %></a>
|
31
32
|
<input class="btn btn-primary" type="submit" name="retry" value="<%= t('RetryNow') %>" />
|
32
33
|
<input class="btn btn-danger" type="submit" name="delete" value="<%= t('Delete') %>" />
|
data/web/views/scheduled.erb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
<%= erb :_job_info, :locals => {:job => @job, :type => :scheduled} %>
|
2
2
|
|
3
3
|
<form class="form-horizontal" action="<%= root_path %>scheduled/<%= job_params(@job, @job.score) %>" method="post">
|
4
|
+
<%= csrf_tag %>
|
4
5
|
<a class="btn btn-default" href="<%= root_path %>scheduled"><%= t('GoBack') %></a>
|
5
6
|
<input class="btn btn-primary" type="submit" name="add_to_queue" value="<%= t('AddToQueue') %>" />
|
6
7
|
<input class="btn btn-danger" type="submit" name="delete" value="<%= t('Delete') %>" />
|
metadata
CHANGED
@@ -1,57 +1,75 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.4.
|
4
|
+
version: 3.4.2
|
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
|
+
date: 2015-07-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.2'
|
17
20
|
- - ">="
|
18
21
|
- !ruby/object:Gem::Version
|
19
|
-
version: 3.
|
22
|
+
version: 3.2.1
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.2'
|
24
30
|
- - ">="
|
25
31
|
- !ruby/object:Gem::Version
|
26
|
-
version: 3.
|
32
|
+
version: 3.2.1
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: redis-namespace
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.5'
|
31
40
|
- - ">="
|
32
41
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
42
|
+
version: 1.5.2
|
34
43
|
type: :runtime
|
35
44
|
prerelease: false
|
36
45
|
version_requirements: !ruby/object:Gem::Requirement
|
37
46
|
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '1.5'
|
38
50
|
- - ">="
|
39
51
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
52
|
+
version: 1.5.2
|
41
53
|
- !ruby/object:Gem::Dependency
|
42
54
|
name: connection_pool
|
43
55
|
requirement: !ruby/object:Gem::Requirement
|
44
56
|
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '2.2'
|
45
60
|
- - ">="
|
46
61
|
- !ruby/object:Gem::Version
|
47
|
-
version: 2.
|
62
|
+
version: 2.2.0
|
48
63
|
type: :runtime
|
49
64
|
prerelease: false
|
50
65
|
version_requirements: !ruby/object:Gem::Requirement
|
51
66
|
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '2.2'
|
52
70
|
- - ">="
|
53
71
|
- !ruby/object:Gem::Version
|
54
|
-
version: 2.
|
72
|
+
version: 2.2.0
|
55
73
|
- !ruby/object:Gem::Dependency
|
56
74
|
name: celluloid
|
57
75
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,87 +88,91 @@ dependencies:
|
|
70
88
|
name: json
|
71
89
|
requirement: !ruby/object:Gem::Requirement
|
72
90
|
requirements:
|
73
|
-
- - "
|
91
|
+
- - "~>"
|
74
92
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
93
|
+
version: '1.0'
|
76
94
|
type: :runtime
|
77
95
|
prerelease: false
|
78
96
|
version_requirements: !ruby/object:Gem::Requirement
|
79
97
|
requirements:
|
80
|
-
- - "
|
98
|
+
- - "~>"
|
81
99
|
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
100
|
+
version: '1.0'
|
83
101
|
- !ruby/object:Gem::Dependency
|
84
102
|
name: sinatra
|
85
103
|
requirement: !ruby/object:Gem::Requirement
|
86
104
|
requirements:
|
105
|
+
- - "~>"
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '1.4'
|
87
108
|
- - ">="
|
88
109
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
110
|
+
version: 1.4.6
|
90
111
|
type: :development
|
91
112
|
prerelease: false
|
92
113
|
version_requirements: !ruby/object:Gem::Requirement
|
93
114
|
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.4'
|
94
118
|
- - ">="
|
95
119
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
120
|
+
version: 1.4.6
|
97
121
|
- !ruby/object:Gem::Dependency
|
98
122
|
name: minitest
|
99
123
|
requirement: !ruby/object:Gem::Requirement
|
100
124
|
requirements:
|
101
125
|
- - "~>"
|
102
126
|
- !ruby/object:Gem::Version
|
103
|
-
version: 5.
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: 5.3.3
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: rake
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
127
|
+
version: '5.7'
|
115
128
|
- - ">="
|
116
129
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
130
|
+
version: 5.7.0
|
118
131
|
type: :development
|
119
132
|
prerelease: false
|
120
133
|
version_requirements: !ruby/object:Gem::Requirement
|
121
134
|
requirements:
|
135
|
+
- - "~>"
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '5.7'
|
122
138
|
- - ">="
|
123
139
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
140
|
+
version: 5.7.0
|
125
141
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
142
|
+
name: rake
|
127
143
|
requirement: !ruby/object:Gem::Requirement
|
128
144
|
requirements:
|
129
145
|
- - "~>"
|
130
146
|
- !ruby/object:Gem::Version
|
131
|
-
version:
|
147
|
+
version: '10.0'
|
132
148
|
type: :development
|
133
149
|
prerelease: false
|
134
150
|
version_requirements: !ruby/object:Gem::Requirement
|
135
151
|
requirements:
|
136
152
|
- - "~>"
|
137
153
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
154
|
+
version: '10.0'
|
139
155
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
156
|
+
name: rails
|
141
157
|
requirement: !ruby/object:Gem::Requirement
|
142
158
|
requirements:
|
159
|
+
- - "~>"
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '4'
|
143
162
|
- - ">="
|
144
163
|
- !ruby/object:Gem::Version
|
145
|
-
version:
|
164
|
+
version: 3.2.0
|
146
165
|
type: :development
|
147
166
|
prerelease: false
|
148
167
|
version_requirements: !ruby/object:Gem::Requirement
|
149
168
|
requirements:
|
169
|
+
- - "~>"
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: '4'
|
150
172
|
- - ">="
|
151
173
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
153
|
-
description: Simple, efficient background processing for Ruby
|
174
|
+
version: 3.2.0
|
175
|
+
description: Simple, efficient background processing for Ruby.
|
154
176
|
email:
|
155
177
|
- mperham@gmail.com
|
156
178
|
executables:
|
@@ -225,6 +247,7 @@ files:
|
|
225
247
|
- test/test_manager.rb
|
226
248
|
- test/test_middleware.rb
|
227
249
|
- test/test_processor.rb
|
250
|
+
- test/test_rails.rb
|
228
251
|
- test/test_redis_connection.rb
|
229
252
|
- test/test_retry.rb
|
230
253
|
- test/test_scheduled.rb
|
@@ -233,9 +256,9 @@ files:
|
|
233
256
|
- test/test_testing.rb
|
234
257
|
- test/test_testing_fake.rb
|
235
258
|
- test/test_testing_inline.rb
|
259
|
+
- test/test_util.rb
|
236
260
|
- test/test_web.rb
|
237
261
|
- test/test_web_helpers.rb
|
238
|
-
- test/test_worker_generator.rb
|
239
262
|
- web/assets/images/bootstrap/glyphicons-halflings-white.png
|
240
263
|
- web/assets/images/bootstrap/glyphicons-halflings.png
|
241
264
|
- web/assets/images/logo.png
|
@@ -316,7 +339,8 @@ files:
|
|
316
339
|
- web/views/_job_info.erb
|
317
340
|
- web/views/_nav.erb
|
318
341
|
- web/views/_paging.erb
|
319
|
-
- web/views/
|
342
|
+
- web/views/_poll_js.erb
|
343
|
+
- web/views/_poll_link.erb
|
320
344
|
- web/views/_status.erb
|
321
345
|
- web/views/_summary.erb
|
322
346
|
- web/views/busy.erb
|
@@ -370,6 +394,7 @@ test_files:
|
|
370
394
|
- test/test_manager.rb
|
371
395
|
- test/test_middleware.rb
|
372
396
|
- test/test_processor.rb
|
397
|
+
- test/test_rails.rb
|
373
398
|
- test/test_redis_connection.rb
|
374
399
|
- test/test_retry.rb
|
375
400
|
- test/test_scheduled.rb
|
@@ -378,6 +403,6 @@ test_files:
|
|
378
403
|
- test/test_testing.rb
|
379
404
|
- test/test_testing_fake.rb
|
380
405
|
- test/test_testing_inline.rb
|
406
|
+
- test/test_util.rb
|
381
407
|
- test/test_web.rb
|
382
408
|
- test/test_web_helpers.rb
|
383
|
-
- test/test_worker_generator.rb
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require_relative 'helper'
|
2
|
-
require 'rails/generators/test_case'
|
3
|
-
require 'generators/sidekiq/worker_generator'
|
4
|
-
|
5
|
-
class WorkerGeneratorTest < Rails::Generators::TestCase
|
6
|
-
tests Sidekiq::Generators::WorkerGenerator
|
7
|
-
arguments %w(foo)
|
8
|
-
destination File.expand_path("../tmp", File.dirname(__FILE__))
|
9
|
-
setup :prepare_destination
|
10
|
-
|
11
|
-
test "worker is created and its test" do
|
12
|
-
run_generator
|
13
|
-
|
14
|
-
assert_file "app/workers/foo_worker.rb"
|
15
|
-
assert_file "test/workers/foo_worker_test.rb"
|
16
|
-
end
|
17
|
-
end
|