sidekiq 2.7.2 → 2.7.3

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 CHANGED
@@ -1,3 +1,10 @@
1
+ 2.7.3
2
+ -----------
3
+
4
+ - Real-time dashboard is now the default web page
5
+ - Make config file optional for capistrano
6
+ - Fix Retry All button in the Web UI
7
+
1
8
  2.7.2
2
9
  -----------
3
10
 
data/Gemfile CHANGED
@@ -7,6 +7,7 @@ gem 'sqlite3', :platform => :mri
7
7
 
8
8
  group :test do
9
9
  gem 'simplecov', :require => false
10
+ gem 'minitest-emoji', :require => false
10
11
  end
11
12
 
12
13
  group :development do
data/README.md CHANGED
@@ -63,7 +63,7 @@ Problems?
63
63
 
64
64
  **Please do not directly email any Sidekiq committers with questions or problems.** A community is best served when discussions are held in public.
65
65
 
66
- If you have a problem, please review the [FAQ](/mperham/sidekiq/wiki/FAQ) and [Troubleshooting](/mperham/sidekiq/wiki/Problems-and-Troubleshooting) wiki pages. Searching the issues for your problem is also a good idea. If that doesn't help, feel free to email the Sidekiq mailing list or open a new issue.
66
+ If you have a problem, please review the [FAQ](https://github.com/mperham/sidekiq/wiki/FAQ) and [Troubleshooting](https://github.com/mperham/sidekiq/wiki/Problems-and-Troubleshooting) wiki pages. Searching the issues for your problem is also a good idea. If that doesn't help, feel free to email the Sidekiq mailing list or open a new issue.
67
67
  The mailing list is the preferred place to ask questions on usage. If you are encountering what you think is a bug, please open an issue.
68
68
 
69
69
 
@@ -0,0 +1,46 @@
1
+ # /etc/init/sidekiq.conf - Sidekiq config
2
+
3
+ # This example config should work with Ubuntu 12.04+. It
4
+ # allows you to manage multiple Sidekiq instances with
5
+ # Upstart, Ubuntu's native service management tool.
6
+ #
7
+ # See workers.conf for how to manage all Sidekiq instances at once.
8
+ #
9
+ # Save this config as /etc/init/sidekiq.conf then mange sidekiq with:
10
+ # sudo start sidekiq index=0
11
+ # sudo stop sidekiq index=0
12
+ # sudo status sidekiq index=0
13
+ #
14
+ # or use the service command:
15
+ # sudo service sidekiq {start,stop,restart,status}
16
+ #
17
+
18
+ description "Sidekiq Background Worker"
19
+
20
+ # no "start on", we don't want to automatically start
21
+ stop on (stopping workers or runlevel [06])
22
+
23
+ # change to match your deployment user
24
+ setuid deploy
25
+ setgid deploy
26
+
27
+ respawn
28
+ respawn limit 3 30
29
+
30
+ instance $index
31
+
32
+ script
33
+ # this script runs in /bin/sh by default
34
+ # respawn as bash so we can source in rbenv
35
+ exec /bin/bash <<EOT
36
+ # use syslog for logging
37
+ exec &> /dev/kmsg
38
+
39
+ # pull in system rbenv
40
+ export HOME=/home/deploy
41
+ source /etc/profile.d/rbenv.sh
42
+
43
+ cd /opt/theclymb/current
44
+ exec bin/sidekiq -i ${index} -e production -C config/sidekiq.yml -P tmp/pids/sidekiq-${index}.pid
45
+ EOT
46
+ end script
@@ -0,0 +1,30 @@
1
+ # /etc/init/workers.conf - manage a set of Sidekiqs
2
+
3
+ # This example config should work with Ubuntu 12.04+. It
4
+ # allows you to manage multiple Sidekiq instances with
5
+ # Upstart, Ubuntu's native service management tool.
6
+ #
7
+ # See sidekiq.conf for how to manage a single Sidekiq instance.
8
+ #
9
+ # Use "stop workers" to stop all Sidekiq instances.
10
+ # Use "start workers" to start all instances.
11
+ # Use "restart workers" to restart all instances.
12
+ # Crazy, right?
13
+ #
14
+
15
+ description "manages the set of sidekiq processes"
16
+
17
+ # This starts upon bootup and stops on shutdown
18
+ start on runlevel [2345]
19
+ stop on runlevel [06]
20
+
21
+ # Set this to the number of Sidekiq processes you want
22
+ # to run on this machine
23
+ env NUM_WORKERS=2
24
+
25
+ pre-start script
26
+ for i in `seq 0 $((${NUM_WORKERS} - 1))`
27
+ do
28
+ start sidekiq index=$i
29
+ done
30
+ end script
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
  require 'sidekiq/version'
2
3
  require 'sidekiq/logging'
3
4
  require 'sidekiq/client'
@@ -26,6 +27,10 @@ module Sidekiq
26
27
  :profile => false,
27
28
  }
28
29
 
30
+ def self.❨╯°□°❩╯︵ ┻━┻
31
+ puts "Calm down, bro"
32
+ end
33
+
29
34
  def self.options
30
35
  @options ||= DEFAULTS.dup
31
36
  end
@@ -91,7 +96,7 @@ module Sidekiq
91
96
  end
92
97
 
93
98
  def self.load_json(string)
94
- MultiJson.decode(string)
99
+ MultiJson.decode(string, :symbolize_keys => false)
95
100
  end
96
101
 
97
102
  def self.dump_json(object)
@@ -342,6 +342,12 @@ module Sidekiq
342
342
  def initialize
343
343
  super 'retry'
344
344
  end
345
+
346
+ def retry_all
347
+ while size > 0
348
+ each(&:retry)
349
+ end
350
+ end
345
351
  end
346
352
 
347
353
 
@@ -36,7 +36,7 @@ Capistrano::Configuration.instance.load do
36
36
  task :start, :roles => lambda { fetch(:sidekiq_role) }, :on_no_matching_servers => :continue do
37
37
  rails_env = fetch(:rails_env, "production")
38
38
  for_each_process do |pid_file, idx|
39
- run "cd #{current_path} ; #{fetch(:sidekiq_cmd)} -d -e #{rails_env} -C #{current_path}/config/sidekiq.yml -i #{idx} -P #{pid_file} -L #{current_path}/log/sidekiq.log"
39
+ run "cd #{current_path} ; #{fetch(:sidekiq_cmd)} -d -e #{rails_env} -C #{current_path}/config/sidekiq.yml -i #{idx} -P #{pid_file} -L #{current_path}/log/sidekiq.log", :pty => false
40
40
  end
41
41
  end
42
42
 
@@ -18,7 +18,7 @@ end
18
18
 
19
19
  trap 'USR1' do
20
20
  Sidekiq.logger.info "Received USR1, no longer accepting new work"
21
- mgr = Sidekiq::CLI.instance.manager
21
+ mgr = Sidekiq::CLI.instance.launcher.manager
22
22
  mgr.async.stop if mgr
23
23
  end
24
24
 
@@ -49,6 +49,7 @@ require 'erb'
49
49
 
50
50
  require 'sidekiq'
51
51
  require 'sidekiq/util'
52
+ require 'sidekiq/launcher'
52
53
 
53
54
  module Sidekiq
54
55
  class CLI
@@ -57,7 +58,7 @@ module Sidekiq
57
58
 
58
59
  # Used for CLI testing
59
60
  attr_accessor :code
60
- attr_accessor :manager
61
+ attr_accessor :launcher
61
62
  attr_accessor :environment
62
63
 
63
64
  def initialize
@@ -89,21 +90,19 @@ module Sidekiq
89
90
  logger.info 'Starting processing, hit Ctrl-C to stop'
90
91
  end
91
92
 
92
- @manager = Sidekiq::Manager.new(options)
93
- poller = Sidekiq::Scheduled::Poller.new
93
+ @launcher = Sidekiq::Launcher.new(options)
94
+ launcher.procline(options[:tag] ? "#{options[:tag]} " : '')
95
+
94
96
  begin
95
97
  if options[:profile]
96
98
  require 'ruby-prof'
97
99
  RubyProf.start
98
100
  end
99
- @manager.async.start
100
- poller.async.poll(true)
101
+ launcher.run
101
102
  sleep
102
103
  rescue Interrupt
103
104
  logger.info 'Shutting down'
104
- poller.async.terminate if poller.alive?
105
- @manager.async.stop(:shutdown => true, :timeout => options[:timeout])
106
- @manager.wait(:shutdown)
105
+ launcher.stop
107
106
  # Explicitly exit so busy Processor threads can't block
108
107
  # process shutdown.
109
108
  exit(0)
@@ -316,9 +315,10 @@ module Sidekiq
316
315
  if File.exist?(cfile)
317
316
  opts = YAML.load(ERB.new(IO.read(cfile)).result)
318
317
  opts = opts.merge(opts.delete(environment) || {})
319
- parse_queues opts, opts.delete(:queues) || []
318
+ parse_queues(opts, opts.delete(:queues) || [])
320
319
  else
321
- raise ArgumentError, "can't find config file #{cfile}"
320
+ # allow a non-existent config file so Sidekiq
321
+ # can be deployed by cap with just the defaults.
322
322
  end
323
323
  opts
324
324
  end
@@ -0,0 +1,31 @@
1
+
2
+ require 'sidekiq/util'
3
+ require 'sidekiq/manager'
4
+ require 'sidekiq/scheduled'
5
+
6
+ module Sidekiq
7
+ class Launcher
8
+ attr_reader :manager, :poller, :options
9
+ def initialize(options)
10
+ @options = options
11
+ @manager = Sidekiq::Manager.new(options)
12
+ @poller = Sidekiq::Scheduled::Poller.new
13
+ end
14
+
15
+ def run
16
+ manager.async.start
17
+ poller.async.poll(true)
18
+ end
19
+
20
+ def stop
21
+ poller.async.terminate if poller.alive?
22
+ manager.async.stop(:shutdown => true, :timeout => options[:timeout])
23
+ manager.wait(:shutdown)
24
+ end
25
+
26
+ def procline(tag)
27
+ $0 = manager.procline(tag)
28
+ manager.after(5) { procline(tag) }
29
+ end
30
+ end
31
+ end
@@ -27,7 +27,6 @@ module Sidekiq
27
27
  @busy = []
28
28
  @fetcher = Fetcher.new(current_actor, options)
29
29
  @ready = @count.times.map { Processor.new_link(current_actor) }
30
- procline(options[:tag] ? "#{options[:tag]} " : '')
31
30
  end
32
31
 
33
32
  def stop(options={})
@@ -103,6 +102,10 @@ module Sidekiq
103
102
  end
104
103
  end
105
104
 
105
+ def procline(tag)
106
+ "sidekiq #{Sidekiq::VERSION} #{tag}[#{@busy.size} of #{@count} busy]#{stopped? ? ' stopping' : ''}"
107
+ end
108
+
106
109
  private
107
110
 
108
111
  def hard_shutdown_in(delay)
@@ -130,7 +133,7 @@ module Sidekiq
130
133
  workers_to_remove = workers.select do |worker_name|
131
134
  worker_name =~ /:#{process_id}-/
132
135
  end
133
- conn.srem('workers', workers_to_remove)
136
+ conn.srem('workers', workers_to_remove) if !workers_to_remove.empty?
134
137
  end
135
138
 
136
139
  logger.debug { "Terminating worker threads" }
@@ -156,10 +159,5 @@ module Sidekiq
156
159
  def stopped?
157
160
  @done
158
161
  end
159
-
160
- def procline(tag)
161
- $0 = "sidekiq #{Sidekiq::VERSION} #{tag}[#{@busy.size} of #{@count} busy]#{stopped? ? ' stopping' : ''}"
162
- after(5) { procline(tag) }
163
- end
164
162
  end
165
163
  end
@@ -1,3 +1,3 @@
1
1
  module Sidekiq
2
- VERSION = "2.7.2"
2
+ VERSION = "2.7.3"
3
3
  end
@@ -105,7 +105,7 @@ module Sidekiq
105
105
  end
106
106
  end
107
107
 
108
- get "/" do
108
+ get "/workers" do
109
109
  slim :index
110
110
  end
111
111
 
@@ -172,7 +172,7 @@ module Sidekiq
172
172
  end
173
173
 
174
174
  post "/retries/all/retry" do
175
- Sidekiq::RetrySet.new.each { |job| job.retry }
175
+ Sidekiq::RetrySet.new.retry_all
176
176
  redirect "#{root_path}retries"
177
177
  end
178
178
 
@@ -203,7 +203,7 @@ module Sidekiq
203
203
  redirect "#{root_path}scheduled"
204
204
  end
205
205
 
206
- get '/dashboard' do
206
+ get '/' do
207
207
  @redis_info = Sidekiq.redis { |conn| conn.info }.select{ |k, v| redis_keys.include? k }
208
208
  stats_history = Sidekiq::Stats::History.new((params[:days] || 30).to_i)
209
209
  @processed_history = stats_history.processed
@@ -220,6 +220,7 @@ module Sidekiq
220
220
  sidekiq: {
221
221
  processed: sidekiq_stats.processed,
222
222
  failed: sidekiq_stats.failed,
223
+ busy: workers.size,
223
224
  enqueued: sidekiq_stats.enqueued,
224
225
  scheduled: sidekiq_stats.scheduled_size,
225
226
  retries: sidekiq_stats.retry_size,
@@ -230,11 +231,11 @@ module Sidekiq
230
231
 
231
232
  def self.tabs
232
233
  @tabs ||= {
233
- "Workers" =>'',
234
- "Queues" =>'queues',
235
- "Retries" =>'retries',
236
- "Scheduled" =>'scheduled',
237
- "Dashboard" =>'dashboard'
234
+ "Dashboard" => '',
235
+ "Workers" => 'workers',
236
+ "Queues" => 'queues',
237
+ "Retries" => 'retries',
238
+ "Scheduled" => 'scheduled',
238
239
  }
239
240
  end
240
241
 
@@ -10,8 +10,8 @@ rescue LoadError
10
10
  end
11
11
 
12
12
  require 'minitest/unit'
13
- require 'minitest/pride'
14
13
  require 'minitest/autorun'
14
+ require 'minitest/emoji'
15
15
 
16
16
  require 'sidekiq'
17
17
  require 'sidekiq/util'
@@ -28,8 +28,8 @@ class TestWeb < MiniTest::Unit::TestCase
28
28
  end
29
29
  end
30
30
 
31
- it 'can display home' do
32
- get '/'
31
+ it 'can display workers' do
32
+ get '/workers'
33
33
  assert_equal 200, last_response.status
34
34
  assert_match /status-idle/, last_response.body
35
35
  end
@@ -194,8 +194,8 @@ class TestWeb < MiniTest::Unit::TestCase
194
194
  end
195
195
  end
196
196
 
197
- it 'can display the dashboard' do
198
- get '/dashboard'
197
+ it 'can display home' do
198
+ get '/'
199
199
  assert_equal 200, last_response.status
200
200
  end
201
201
 
@@ -207,6 +207,8 @@ class TestWeb < MiniTest::Unit::TestCase
207
207
  end
208
208
  2.times { add_retry }
209
209
  3.times { add_scheduled }
210
+ 4.times { add_worker }
211
+
210
212
  get '/dashboard/stats'
211
213
  @response = Sidekiq.load_json(last_response.body)
212
214
  end
@@ -221,19 +223,23 @@ class TestWeb < MiniTest::Unit::TestCase
221
223
  end
222
224
 
223
225
  it 'reports processed' do
224
- assert_equal @response["sidekiq"]["processed"], 5
226
+ assert_equal 5, @response["sidekiq"]["processed"]
225
227
  end
226
228
 
227
229
  it 'reports failed' do
228
- assert_equal @response["sidekiq"]["failed"], 2
230
+ assert_equal 2, @response["sidekiq"]["failed"]
231
+ end
232
+
233
+ it 'reports busy' do
234
+ assert_equal 4, @response["sidekiq"]["busy"]
229
235
  end
230
236
 
231
237
  it 'reports retries' do
232
- assert_equal @response["sidekiq"]["retries"], 2
238
+ assert_equal 2, @response["sidekiq"]["retries"]
233
239
  end
234
240
 
235
241
  it 'reports scheduled' do
236
- assert_equal @response["sidekiq"]["scheduled"], 3
242
+ assert_equal 3, @response["sidekiq"]["scheduled"]
237
243
  end
238
244
  end
239
245
 
@@ -271,5 +277,14 @@ class TestWeb < MiniTest::Unit::TestCase
271
277
  end
272
278
  [msg, score]
273
279
  end
280
+
281
+ def add_worker
282
+ process_id = rand(1000)
283
+ msg = "{\"queue\":\"default\",\"payload\":{\"retry\":true,\"queue\":\"default\",\"timeout\":20,\"backtrace\":5,\"class\":\"HardWorker\",\"args\":[\"bob\",10,5],\"jid\":\"2b5ad2b016f5e063a1c62872\"},\"run_at\":1361208995}"
284
+ Sidekiq.redis do |conn|
285
+ conn.sadd("workers", "mercury.home:#{process_id}-70215157189060:started")
286
+ conn.set("worker:mercury.home:#{process_id}-70215157189060:started", msg)
287
+ end
288
+ end
274
289
  end
275
290
  end
@@ -42,18 +42,18 @@ var realtimeGraph = function(updatePath) {
42
42
  $.getJSON($("#history").data("update-url"), function(data) {
43
43
 
44
44
  if (i === 0) {
45
- var processed = data.processed;
46
- var failed = data.failed;
45
+ var processed = data.sidekiq.processed;
46
+ var failed = data.sidekiq.failed;
47
47
  } else {
48
- var processed = data.processed - Sidekiq.processed;
49
- var failed = data.failed - Sidekiq.failed;
48
+ var processed = data.sidekiq.processed - Sidekiq.processed;
49
+ var failed = data.sidekiq.failed - Sidekiq.failed;
50
50
  }
51
51
 
52
52
  graph.series.addData({ failed: failed, processed: processed });
53
53
  graph.render();
54
54
 
55
- Sidekiq.processed = data.processed;
56
- Sidekiq.failed = data.failed;
55
+ Sidekiq.processed = data.sidekiq.processed;
56
+ Sidekiq.failed = data.sidekiq.failed;
57
57
 
58
58
  updateStatsSummary(data.sidekiq);
59
59
  updateRedisStats(data.redis);
@@ -114,6 +114,7 @@ var createSeries = function(obj) {
114
114
  var updateStatsSummary = function(data) {
115
115
  $('ul.summary li.processed span.count').html(data.processed.numberWithDelimiter())
116
116
  $('ul.summary li.failed span.count').html(data.failed.numberWithDelimiter())
117
+ $('ul.summary li.busy span.count').html(data.busy.numberWithDelimiter())
117
118
  $('ul.summary li.scheduled span.count').html(data.scheduled.numberWithDelimiter())
118
119
  $('ul.summary li.retries span.count').html(data.retries.numberWithDelimiter())
119
120
  $('ul.summary li.enqueued span.count').html(data.enqueued.numberWithDelimiter())
@@ -5,7 +5,7 @@ ul.unstyled.summary
5
5
  li.failed
6
6
  span.count #{number_with_delimiter(stats.failed)}
7
7
  span.desc Failed
8
- li
8
+ li.busy
9
9
  span.count #{number_with_delimiter(workers.size)}
10
10
  span.desc Busy
11
11
  li.scheduled
@@ -15,7 +15,7 @@ h5
15
15
  a href="#{{current_path}}" class="history-graph #{{"active" if params[:days].nil? || params[:days] == "30"}}" 1 month
16
16
  a href="#{{current_path}}?days=90" class="history-graph #{{"active" if params[:days] == "90"}}" 3 month
17
17
  a href="#{{current_path}}?days=180" class="history-graph #{{"active" if params[:days] == "180"}}" 6 month
18
- #history data-processed="#{Sidekiq.dump_json(@processed_history)}" data-failed="#{Sidekiq.dump_json(@failed_history)}" data-update-url="#{{current_path}}/stats"
18
+ #history data-processed="#{Sidekiq.dump_json(@processed_history)}" data-failed="#{Sidekiq.dump_json(@failed_history)}" data-update-url="#{{current_path}}dashboard/stats"
19
19
 
20
20
  br
21
21
  h5 Redis
@@ -36,7 +36,7 @@ html
36
36
  span.title Status
37
37
  == slim :_status
38
38
  == slim :_summary
39
- - unless current_path.include?("dashboard")
39
+ - unless current_path == ''
40
40
  .row
41
41
  .span2
42
42
  - if params[:poll]
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: 2.7.2
4
+ version: 2.7.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain:
12
12
  - .public_cert.pem
13
- date: 2013-02-08 00:00:00.000000000 Z
13
+ date: 2013-02-21 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: redis
@@ -225,7 +225,8 @@ files:
225
225
  - examples/scheduling.rb
226
226
  - examples/sidekiq
227
227
  - examples/sinkiq.rb
228
- - examples/upstart.conf
228
+ - examples/upstart/sidekiq.conf
229
+ - examples/upstart/workers.conf
229
230
  - examples/web-ui.png
230
231
  - lib/sidekiq.rb
231
232
  - lib/sidekiq/api.rb
@@ -239,6 +240,7 @@ files:
239
240
  - lib/sidekiq/extensions/class_methods.rb
240
241
  - lib/sidekiq/extensions/generic_proxy.rb
241
242
  - lib/sidekiq/fetch.rb
243
+ - lib/sidekiq/launcher.rb
242
244
  - lib/sidekiq/logging.rb
243
245
  - lib/sidekiq/manager.rb
244
246
  - lib/sidekiq/middleware/chain.rb
@@ -1,39 +0,0 @@
1
- # /etc/init/sidekiq.conf - Sidekiq config
2
-
3
- # This example config should work with Ubuntu 12.04+
4
- #
5
- # Save this config as /etc/init/sidekiq.conf then mange sidekiq with:
6
- # sudo start sidekiq
7
- # sudo stop sidekiq
8
- # sudo status sidekiq
9
- #
10
- # or use the service command:
11
- # sudo service sidekiq {start,stop,restart,status}
12
- #
13
- # This is the exact script used to manage Sidekiq on TheClymb.com
14
- #
15
-
16
- description "Sidekiq Background Worker System"
17
-
18
- start on runlevel [2345]
19
- stop on shutdown
20
-
21
- setuid deploy
22
- setgid deploy
23
-
24
- respawn
25
- respawn limit 3 30
26
-
27
- script
28
- # this script runs in /bin/sh by default
29
- # respawn as bash so we can source in rbenv
30
- exec /bin/bash <<EOT
31
- # use syslog for logging
32
- exec >/dev/kmsg 2>&1
33
- # pull in system rbenv
34
- source /etc/profile.d/rbenv.sh
35
-
36
- cd /opt/theclymb/current
37
- exec bin/sidekiq -e production -C config/sidekiq.yml -P tmp/pids/sidekiq.pid
38
- EOT
39
- end script