sidekiq 0.11.0 → 0.11.1
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.
- data/Changes.md +8 -0
- data/examples/config.yml +2 -2
- data/lib/sidekiq/capistrano.rb +2 -2
- data/lib/sidekiq/cli.rb +9 -6
- data/lib/sidekiq/fetch.rb +17 -6
- data/lib/sidekiq/redis_connection.rb +2 -1
- data/lib/sidekiq/version.rb +1 -1
- data/test/config.yml +2 -2
- data/test/helper.rb +1 -1
- data/test/test_cli.rb +9 -7
- data/test/test_stats.rb +16 -14
- metadata +24 -24
data/Changes.md
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
HEAD
|
2
2
|
-----------
|
3
3
|
|
4
|
+
- Fix fetch breaking retry when used with Redis namespaces. [#109]
|
5
|
+
- Redis connection now just a plain ConnectionPool, not CP::Wrapper.
|
6
|
+
- Capistrano initial deploy fix [#106]
|
7
|
+
- Re-implemented weighted queues support (ryanlecompte)
|
8
|
+
|
9
|
+
0.11.0
|
10
|
+
-----------
|
11
|
+
|
4
12
|
- Client-side API changes, added sidekiq\_options for Sidekiq::Worker.
|
5
13
|
As a side effect of this change, the client API works on Ruby 1.8.
|
6
14
|
It's not officially supported but should work [#103]
|
data/examples/config.yml
CHANGED
data/lib/sidekiq/capistrano.rb
CHANGED
@@ -8,12 +8,12 @@ Capistrano::Configuration.instance.load do
|
|
8
8
|
|
9
9
|
desc "Quiet sidekiq (stop accepting new work)"
|
10
10
|
task :quiet do
|
11
|
-
run "cd #{current_path} && bundle exec sidekiqctl quiet #{current_path}/tmp/pids/sidekiq.pid"
|
11
|
+
run "cd #{current_path} && if [ -f #{current_path}/tmp/pids/sidekiq.pid ]; then bundle exec sidekiqctl quiet #{current_path}/tmp/pids/sidekiq.pid ; fi"
|
12
12
|
end
|
13
13
|
|
14
14
|
desc "Stop sidekiq"
|
15
15
|
task :stop do
|
16
|
-
run "cd #{current_path} && bundle exec sidekiqctl stop #{current_path}/tmp/pids/sidekiq.pid #{fetch :sidekiq_timeout}"
|
16
|
+
run "cd #{current_path} && if [ -f #{current_path}/tmp/pids/sidekiq.pid ]; then bundle exec sidekiqctl stop #{current_path}/tmp/pids/sidekiq.pid #{fetch :sidekiq_timeout} ; fi"
|
17
17
|
end
|
18
18
|
|
19
19
|
desc "Start sidekiq"
|
data/lib/sidekiq/cli.rb
CHANGED
@@ -99,6 +99,7 @@ module Sidekiq
|
|
99
99
|
|
100
100
|
def validate!
|
101
101
|
options[:queues] << 'default' if options[:queues].empty?
|
102
|
+
options[:queues].shuffle!
|
102
103
|
|
103
104
|
if !File.exist?(options[:require]) ||
|
104
105
|
(File.directory?(options[:require]) && !File.exist?("#{options[:require]}/config/application.rb"))
|
@@ -115,8 +116,9 @@ module Sidekiq
|
|
115
116
|
opts = {}
|
116
117
|
|
117
118
|
@parser = OptionParser.new do |o|
|
118
|
-
|
119
|
-
|
119
|
+
o.on "-q", "--queue QUEUE,WEIGHT", "Queue to process, with optional weight" do |arg|
|
120
|
+
q, weight = arg.split(",")
|
121
|
+
parse_queues(opts, q, weight)
|
120
122
|
end
|
121
123
|
|
122
124
|
o.on "-v", "--verbose", "Print more verbose output" do
|
@@ -175,14 +177,15 @@ module Sidekiq
|
|
175
177
|
if cli[:config_file] && File.exist?(cli[:config_file])
|
176
178
|
opts = YAML.load_file cli[:config_file]
|
177
179
|
queues = opts.delete(:queues) || []
|
178
|
-
queues.each { |name,
|
180
|
+
queues.each { |name, weight| parse_queues(opts, name, weight) }
|
179
181
|
end
|
180
182
|
opts
|
181
183
|
end
|
182
184
|
|
183
|
-
def parse_queues(opts, q)
|
184
|
-
(
|
185
|
+
def parse_queues(opts, q, weight)
|
186
|
+
(weight || 1).to_i.times do
|
187
|
+
(opts[:queues] ||= []) << q
|
188
|
+
end
|
185
189
|
end
|
186
|
-
|
187
190
|
end
|
188
191
|
end
|
data/lib/sidekiq/fetch.rb
CHANGED
@@ -10,14 +10,13 @@ module Sidekiq
|
|
10
10
|
include Celluloid
|
11
11
|
include Sidekiq::Util
|
12
12
|
|
13
|
+
# Timeout for Redis#blpop.
|
13
14
|
TIMEOUT = 1
|
14
15
|
|
15
16
|
def initialize(mgr, queues)
|
16
|
-
@cmd = queues.map { |q| "queue:#{q}" }
|
17
17
|
@mgr = mgr
|
18
|
-
|
19
|
-
|
20
|
-
@cmd << TIMEOUT
|
18
|
+
@queues = queues.map { |q| "queue:#{q}" }
|
19
|
+
@num_queues = queues.uniq.size
|
21
20
|
end
|
22
21
|
|
23
22
|
# Fetching is straightforward: the Manager makes a fetch
|
@@ -32,15 +31,27 @@ module Sidekiq
|
|
32
31
|
watchdog('Fetcher#fetch died') do
|
33
32
|
queue = nil
|
34
33
|
msg = nil
|
35
|
-
Sidekiq.redis { |conn|
|
34
|
+
Sidekiq.redis { |conn| queue, msg = conn.blpop(*queues_cmd) }
|
36
35
|
|
37
36
|
if msg
|
38
|
-
@mgr.assign!(msg, queue.gsub(
|
37
|
+
@mgr.assign!(msg, queue.gsub(/.*queue:/, ''))
|
39
38
|
else
|
40
39
|
after(0) { fetch }
|
41
40
|
end
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|
44
|
+
private
|
45
|
+
|
46
|
+
# Creating the Redis#blpop command takes into account any
|
47
|
+
# configured queue weights. By default Redis#blpop returns
|
48
|
+
# data from the first queue that has pending elements. We
|
49
|
+
# recreate the queue command each time we invoke Redis#blpop
|
50
|
+
# to honor weights and avoid queue starvation.
|
51
|
+
def queues_cmd
|
52
|
+
cmd = @queues.sample(@num_queues)
|
53
|
+
cmd << TIMEOUT
|
54
|
+
cmd
|
55
|
+
end
|
45
56
|
end
|
46
57
|
end
|
@@ -6,7 +6,8 @@ module Sidekiq
|
|
6
6
|
class RedisConnection
|
7
7
|
def self.create(options={})
|
8
8
|
url = options[:url] || ENV['REDISTOGO_URL'] || 'redis://localhost:6379/0'
|
9
|
-
|
9
|
+
size = (options[:size] || Sidekiq.options[:concurrency] || 25)
|
10
|
+
ConnectionPool.new(:timeout => 1, :size => size) do
|
10
11
|
build_client(url, options[:namespace])
|
11
12
|
end
|
12
13
|
end
|
data/lib/sidekiq/version.rb
CHANGED
data/test/config.yml
CHANGED
data/test/helper.rb
CHANGED
@@ -12,4 +12,4 @@ require 'sidekiq/util'
|
|
12
12
|
Sidekiq::Util.logger.level = Logger::ERROR
|
13
13
|
|
14
14
|
require 'sidekiq/redis_connection'
|
15
|
-
REDIS = Sidekiq::RedisConnection.create(:url => "redis://localhost/15")
|
15
|
+
REDIS = Sidekiq::RedisConnection.create(:url => "redis://localhost/15", :namespace => 'testy')
|
data/test/test_cli.rb
CHANGED
@@ -45,9 +45,9 @@ class TestCli < MiniTest::Unit::TestCase
|
|
45
45
|
assert_equal 30, Sidekiq.options[:timeout]
|
46
46
|
end
|
47
47
|
|
48
|
-
it 'handles multiple queues' do
|
49
|
-
@cli.parse(['sidekiq', '-q', 'foo', '-q', 'bar', '-r', './test/fake_env.rb'])
|
50
|
-
assert_equal %w(foo
|
48
|
+
it 'handles multiple queues with weights' do
|
49
|
+
@cli.parse(['sidekiq', '-q', 'foo,3', '-q', 'bar', '-r', './test/fake_env.rb'])
|
50
|
+
assert_equal %w(bar foo foo foo), Sidekiq.options[:queues].sort
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'sets verbose' do
|
@@ -110,7 +110,8 @@ class TestCli < MiniTest::Unit::TestCase
|
|
110
110
|
end
|
111
111
|
|
112
112
|
it 'sets queues' do
|
113
|
-
assert_equal
|
113
|
+
assert_equal 2, Sidekiq.options[:queues].count { |q| q == 'often' }
|
114
|
+
assert_equal 1, Sidekiq.options[:queues].count { |q| q == 'seldom' }
|
114
115
|
end
|
115
116
|
end
|
116
117
|
|
@@ -132,8 +133,8 @@ class TestCli < MiniTest::Unit::TestCase
|
|
132
133
|
'-c', '100',
|
133
134
|
'-r', @tmp_lib_path,
|
134
135
|
'-P', @tmp_path,
|
135
|
-
'-q', 'often',
|
136
|
-
'-q', 'seldom'])
|
136
|
+
'-q', 'often,7',
|
137
|
+
'-q', 'seldom,3'])
|
137
138
|
end
|
138
139
|
|
139
140
|
after do
|
@@ -158,7 +159,8 @@ class TestCli < MiniTest::Unit::TestCase
|
|
158
159
|
end
|
159
160
|
|
160
161
|
it 'sets queues' do
|
161
|
-
assert_equal
|
162
|
+
assert_equal 7, Sidekiq.options[:queues].count { |q| q == 'often' }
|
163
|
+
assert_equal 3, Sidekiq.options[:queues].count { |q| q == 'seldom' }
|
162
164
|
end
|
163
165
|
end
|
164
166
|
end
|
data/test/test_stats.rb
CHANGED
@@ -55,23 +55,25 @@ class TestStats < MiniTest::Unit::TestCase
|
|
55
55
|
msg = { 'class' => DumbWorker.to_s, 'args' => [nil] }
|
56
56
|
boss = MiniTest::Mock.new
|
57
57
|
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
@redis.with do |conn|
|
59
|
+
assert_equal [], conn.smembers('workers')
|
60
|
+
assert_equal 0, conn.get('stat:failed').to_i
|
61
|
+
assert_equal 0, conn.get('stat:processed').to_i
|
61
62
|
|
62
|
-
|
63
|
-
|
63
|
+
processor = Sidekiq::Processor.new(boss)
|
64
|
+
assert_equal 1, conn.smembers('workers').size
|
64
65
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
66
|
+
pstr = processor.to_s
|
67
|
+
assert_raises RuntimeError do
|
68
|
+
processor.process(msg, 'xyzzy')
|
69
|
+
end
|
69
70
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
71
|
+
set = conn.smembers('workers')
|
72
|
+
assert_equal 0, set.size
|
73
|
+
assert_equal 1, conn.get('stat:failed').to_i
|
74
|
+
assert_equal 1, conn.get('stat:processed').to_i
|
75
|
+
assert_equal nil, conn.get("stat:processed:#{pstr}")
|
76
|
+
end
|
75
77
|
end
|
76
78
|
|
77
79
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.
|
4
|
+
version: 0.11.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-04-
|
12
|
+
date: 2012-04-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
16
|
-
requirement: &
|
16
|
+
requirement: &70115690910620 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70115690910620
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: redis-namespace
|
27
|
-
requirement: &
|
27
|
+
requirement: &70115690910180 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70115690910180
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: connection_pool
|
38
|
-
requirement: &
|
38
|
+
requirement: &70115690926040 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 0.9.0
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70115690926040
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: celluloid
|
49
|
-
requirement: &
|
49
|
+
requirement: &70115690925540 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 0.10.0
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70115690925540
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: multi_json
|
60
|
-
requirement: &
|
60
|
+
requirement: &70115690925160 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70115690925160
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: minitest
|
71
|
-
requirement: &
|
71
|
+
requirement: &70115690924700 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70115690924700
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: sinatra
|
82
|
-
requirement: &
|
82
|
+
requirement: &70115690924280 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70115690924280
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: slim
|
93
|
-
requirement: &
|
93
|
+
requirement: &70115690923860 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ! '>='
|
@@ -98,10 +98,10 @@ dependencies:
|
|
98
98
|
version: '0'
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *70115690923860
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: rake
|
104
|
-
requirement: &
|
104
|
+
requirement: &70115690923440 !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
107
|
- - ! '>='
|
@@ -109,10 +109,10 @@ dependencies:
|
|
109
109
|
version: '0'
|
110
110
|
type: :development
|
111
111
|
prerelease: false
|
112
|
-
version_requirements: *
|
112
|
+
version_requirements: *70115690923440
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: actionmailer
|
115
|
-
requirement: &
|
115
|
+
requirement: &70115690922940 !ruby/object:Gem::Requirement
|
116
116
|
none: false
|
117
117
|
requirements:
|
118
118
|
- - ~>
|
@@ -120,10 +120,10 @@ dependencies:
|
|
120
120
|
version: '3'
|
121
121
|
type: :development
|
122
122
|
prerelease: false
|
123
|
-
version_requirements: *
|
123
|
+
version_requirements: *70115690922940
|
124
124
|
- !ruby/object:Gem::Dependency
|
125
125
|
name: activerecord
|
126
|
-
requirement: &
|
126
|
+
requirement: &70115690922440 !ruby/object:Gem::Requirement
|
127
127
|
none: false
|
128
128
|
requirements:
|
129
129
|
- - ~>
|
@@ -131,7 +131,7 @@ dependencies:
|
|
131
131
|
version: '3'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
|
-
version_requirements: *
|
134
|
+
version_requirements: *70115690922440
|
135
135
|
description: Simple, efficient message processing for Ruby
|
136
136
|
email:
|
137
137
|
- mperham@gmail.com
|