sidekiq 3.4.1 → 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.

Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/4.0-Upgrade.md +50 -0
  3. data/COMM-LICENSE +55 -45
  4. data/Changes.md +73 -1
  5. data/Ent-Changes.md +66 -0
  6. data/Gemfile +7 -1
  7. data/Pro-2.0-Upgrade.md +2 -2
  8. data/Pro-3.0-Upgrade.md +46 -0
  9. data/Pro-Changes.md +65 -2
  10. data/README.md +8 -9
  11. data/bin/sidekiq +5 -0
  12. data/bin/sidekiqctl +8 -2
  13. data/bin/sidekiqload +167 -0
  14. data/lib/sidekiq/api.rb +29 -31
  15. data/lib/sidekiq/cli.rb +41 -42
  16. data/lib/sidekiq/client.rb +5 -10
  17. data/lib/sidekiq/fetch.rb +35 -111
  18. data/lib/sidekiq/launcher.rb +102 -42
  19. data/lib/sidekiq/manager.rb +78 -180
  20. data/lib/sidekiq/middleware/server/logging.rb +10 -5
  21. data/lib/sidekiq/middleware/server/retry_jobs.rb +5 -5
  22. data/lib/sidekiq/processor.rb +126 -97
  23. data/lib/sidekiq/redis_connection.rb +23 -5
  24. data/lib/sidekiq/scheduled.rb +47 -26
  25. data/lib/sidekiq/testing.rb +96 -17
  26. data/lib/sidekiq/util.rb +20 -0
  27. data/lib/sidekiq/version.rb +1 -1
  28. data/lib/sidekiq/web.rb +17 -1
  29. data/lib/sidekiq/web_helpers.rb +26 -4
  30. data/lib/sidekiq/worker.rb +14 -0
  31. data/lib/sidekiq.rb +37 -14
  32. data/sidekiq.gemspec +11 -11
  33. data/test/helper.rb +45 -10
  34. data/test/test_actors.rb +137 -0
  35. data/test/test_api.rb +388 -388
  36. data/test/test_cli.rb +29 -59
  37. data/test/test_client.rb +60 -135
  38. data/test/test_extensions.rb +29 -23
  39. data/test/test_fetch.rb +2 -57
  40. data/test/test_launcher.rb +80 -0
  41. data/test/test_logging.rb +1 -1
  42. data/test/test_manager.rb +16 -131
  43. data/test/test_middleware.rb +3 -5
  44. data/test/test_processor.rb +110 -76
  45. data/test/test_rails.rb +21 -0
  46. data/test/test_redis_connection.rb +0 -1
  47. data/test/test_retry.rb +114 -162
  48. data/test/test_scheduled.rb +11 -17
  49. data/test/test_scheduling.rb +20 -42
  50. data/test/test_sidekiq.rb +46 -16
  51. data/test/test_testing.rb +80 -20
  52. data/test/test_testing_fake.rb +68 -8
  53. data/test/test_testing_inline.rb +3 -3
  54. data/test/test_util.rb +16 -0
  55. data/test/test_web.rb +17 -3
  56. data/test/test_web_helpers.rb +3 -2
  57. data/web/assets/images/favicon.ico +0 -0
  58. data/web/assets/javascripts/application.js +6 -1
  59. data/web/assets/javascripts/dashboard.js +2 -8
  60. data/web/assets/javascripts/locales/jquery.timeago.pt-br.js +14 -14
  61. data/web/assets/stylesheets/application.css +33 -56
  62. data/web/locales/de.yml +1 -1
  63. data/web/locales/en.yml +1 -0
  64. data/web/locales/{no.yml → nb.yml} +10 -2
  65. data/web/locales/uk.yml +76 -0
  66. data/web/views/_footer.erb +2 -7
  67. data/web/views/_job_info.erb +1 -1
  68. data/web/views/_nav.erb +2 -2
  69. data/web/views/_poll_js.erb +5 -0
  70. data/web/views/{_poll.erb → _poll_link.erb} +0 -3
  71. data/web/views/busy.erb +2 -1
  72. data/web/views/dead.erb +1 -0
  73. data/web/views/layout.erb +2 -0
  74. data/web/views/morgue.erb +3 -0
  75. data/web/views/queue.erb +1 -0
  76. data/web/views/queues.erb +1 -0
  77. data/web/views/retries.erb +3 -0
  78. data/web/views/retry.erb +1 -0
  79. data/web/views/scheduled.erb +1 -0
  80. data/web/views/scheduled_job_info.erb +1 -0
  81. metadata +81 -47
  82. data/lib/sidekiq/actor.rb +0 -39
  83. data/test/test_worker_generator.rb +0 -17
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
 
@@ -33,7 +32,7 @@ are untested but might work fine. MRI 1.9 is no longer supported.
33
32
 
34
33
  All Rails releases starting from 3.2 are officially supported.
35
34
 
36
- Redis 2.4 or greater is required.
35
+ Redis 2.8 or greater is required.
37
36
 
38
37
 
39
38
  Installation
@@ -45,7 +44,7 @@ Installation
45
44
  Getting Started
46
45
  -----------------
47
46
 
48
- See the [sidekiq home page](http://sidekiq.org) for the simple 3-step process.
47
+ See the [Getting Started wiki page](https://github.com/mperham/sidekiq/wiki/Getting-Started) and follow the simple setup process.
49
48
  You can watch [Railscast #366](http://railscasts.com/episodes/366-sidekiq) to see Sidekiq in action. If you do everything right, you should see this:
50
49
 
51
50
  ![Web UI](https://github.com/mperham/sidekiq/raw/master/examples/web-ui.png)
@@ -54,10 +53,10 @@ You can watch [Railscast #366](http://railscasts.com/episodes/366-sidekiq) to se
54
53
  Want to Upgrade?
55
54
  -------------------
56
55
 
57
- I also sell Sidekiq Pro, an extension to Sidekiq which provides more
58
- features, a commercial-friendly license and allows you to support high
56
+ I also sell Sidekiq Pro and Sidekiq Enterprise, extensions to Sidekiq which provide more
57
+ features, a commercial-friendly license and allow you to support high
59
58
  quality open source development all at the same time. Please see the
60
- [Sidekiq Pro](http://sidekiq.org/pro) homepage for more detail.
59
+ [Sidekiq](http://sidekiq.org/) homepage for more detail.
61
60
 
62
61
 
63
62
  More Information
@@ -67,7 +66,7 @@ Please see the [sidekiq wiki](https://github.com/mperham/sidekiq/wiki) for the o
67
66
  [mperham/sidekiq on Gitter](https://gitter.im/mperham/sidekiq) is dedicated to this project,
68
67
  but bug reports or feature requests suggestions should still go through [issues on Github](https://github.com/mperham/sidekiq/issues). Release announcements are made to the [@sidekiq](https://twitter.com/sidekiq) Twitter account.
69
68
 
70
- You may also find useful a [Google Group](https://groups.google.com/forum/#!forum/sidekiq) dedicated to Sidekiq discussion and [a Sidekiq tag](https://stackoverflow.com/questions/tagged/sidekiq) on Stack Overflow.
69
+ You may also find useful a [Reddit area](https://reddit.com/r/sidekiq) dedicated to Sidekiq discussion and [a Sidekiq tag](https://stackoverflow.com/questions/tagged/sidekiq) on Stack Overflow.
71
70
 
72
71
 
73
72
  Problems?
@@ -76,14 +75,14 @@ Problems?
76
75
  **Please do not directly email any Sidekiq committers with questions or problems.** A community is best served when discussions are held in public.
77
76
 
78
77
  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, chat in Gitter, or open a new issue.
79
- 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.
78
+ StackOverflow or Reddit is the preferred place to ask questions on usage. If you are encountering what you think is a bug, please open an issue.
80
79
 
81
80
 
82
81
  Thanks
83
82
  -----------------
84
83
 
85
84
  Sidekiq stays fast by using the [JProfiler java profiler](http://www.ej-technologies.com/products/jprofiler/overview.html) to find and fix
86
- performance problems on JRuby. Unfortunately MRI does not have good profile tooling.
85
+ performance problems on JRuby. Unfortunately MRI does not have good multithreaded profiling tools.
87
86
 
88
87
 
89
88
  License
data/bin/sidekiq CHANGED
@@ -1,5 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ # Quiet some warnings we see when running in warning mode:
4
+ # RUBYOPT=-w bundle exec sidekiq
5
+ $TESTING = false
6
+ $CELLULOID_DEBUG = false
7
+
3
8
  require_relative '../lib/sidekiq/cli'
4
9
 
5
10
  begin
data/bin/sidekiqctl CHANGED
@@ -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
data/bin/sidekiqload ADDED
@@ -0,0 +1,167 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Quiet some warnings we see when running in warning mode:
4
+ # RUBYOPT=-w bundle exec sidekiq
5
+ $TESTING = false
6
+
7
+ #require 'ruby-prof'
8
+ Bundler.require(:default)
9
+
10
+ require_relative '../lib/sidekiq/cli'
11
+ require_relative '../lib/sidekiq/launcher'
12
+
13
+ include Sidekiq::Util
14
+
15
+ # brew tap shopify/shopify
16
+ # brew install toxiproxy
17
+ # gem install toxiproxy
18
+ require 'toxiproxy'
19
+ # simulate a non-localhost network for realer-world conditions.
20
+ # adding 1ms of network latency has an ENORMOUS impact on benchmarks
21
+ Toxiproxy.populate([{
22
+ "name": "redis",
23
+ "listen": "127.0.0.1:6380",
24
+ "upstream": "127.0.0.1:6379"
25
+ }])
26
+
27
+
28
+ Sidekiq.configure_server do |config|
29
+ config.redis = { db: 13, port: 6380 }
30
+ #config.redis = { db: 13 }
31
+ config.options[:queues] << 'default'
32
+ config.logger.level = Logger::ERROR
33
+ config.average_scheduled_poll_interval = 2
34
+ config.reliable! if defined?(Sidekiq::Pro)
35
+ end
36
+
37
+ class LoadWorker
38
+ include Sidekiq::Worker
39
+ sidekiq_options retry: 1
40
+ sidekiq_retry_in do |x|
41
+ 1
42
+ end
43
+
44
+ def perform(idx)
45
+ #raise idx.to_s if idx % 100 == 1
46
+ end
47
+ end
48
+
49
+ # brew tap shopify/shopify
50
+ # brew install toxiproxy
51
+ # gem install toxiproxy
52
+ require 'toxiproxy'
53
+ # simulate a non-localhost network for realer-world conditions.
54
+ # adding 1ms of network latency has an ENORMOUS impact on benchmarks
55
+ Toxiproxy.populate([{
56
+ "name": "redis",
57
+ "listen": "127.0.0.1:6380",
58
+ "upstream": "127.0.0.1:6379"
59
+ }])
60
+
61
+ self_read, self_write = IO.pipe
62
+ %w(INT TERM USR1 USR2 TTIN).each do |sig|
63
+ begin
64
+ trap sig do
65
+ self_write.puts(sig)
66
+ end
67
+ rescue ArgumentError
68
+ puts "Signal #{sig} not supported"
69
+ end
70
+ end
71
+
72
+ Sidekiq.redis {|c| c.flushdb}
73
+ def handle_signal(launcher, sig)
74
+ Sidekiq.logger.debug "Got #{sig} signal"
75
+ case sig
76
+ when 'INT'
77
+ # Handle Ctrl-C in JRuby like MRI
78
+ # http://jira.codehaus.org/browse/JRUBY-4637
79
+ raise Interrupt
80
+ when 'TERM'
81
+ # Heroku sends TERM and then waits 10 seconds for process to exit.
82
+ raise Interrupt
83
+ when 'USR1'
84
+ Sidekiq.logger.info "Received USR1, no longer accepting new work"
85
+ launcher.quiet
86
+ when 'USR2'
87
+ if Sidekiq.options[:logfile]
88
+ Sidekiq.logger.info "Received USR2, reopening log file"
89
+ Sidekiq::Logging.reopen_logs
90
+ end
91
+ when 'TTIN'
92
+ Thread.list.each do |thread|
93
+ Sidekiq.logger.warn "Thread TID-#{thread.object_id.to_s(36)} #{thread['label']}"
94
+ if thread.backtrace
95
+ Sidekiq.logger.warn thread.backtrace.join("\n")
96
+ else
97
+ Sidekiq.logger.warn "<no backtrace available>"
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ def Process.rss
104
+ `ps -o rss= -p #{Process.pid}`.chomp.to_i
105
+ end
106
+
107
+ iter = 10
108
+ count = 10_000
109
+
110
+ iter.times do
111
+ arr = Array.new(count) do
112
+ []
113
+ end
114
+ count.times do |idx|
115
+ arr[idx][0] = idx
116
+ end
117
+ Sidekiq::Client.push_bulk('class' => LoadWorker, 'args' => arr)
118
+ end
119
+ Sidekiq.logger.error "Created #{count*iter} jobs"
120
+
121
+ Monitoring = Thread.new do
122
+ watchdog("monitor thread") do
123
+ while true
124
+ sleep 2
125
+ qsize, retries = Sidekiq.redis do |conn|
126
+ conn.pipelined do
127
+ conn.llen "queue:default"
128
+ conn.zcard "retry"
129
+ end
130
+ end.map(&:to_i)
131
+ total = qsize + retries
132
+ #GC.start
133
+ Sidekiq.logger.error("RSS: #{Process.rss} Pending: #{total}")
134
+ if total == 0
135
+ Sidekiq.logger.error("Done")
136
+ exit(0)
137
+ end
138
+ end
139
+ end
140
+ end
141
+
142
+ begin
143
+ #RubyProf::exclude_threads = [ Monitoring ]
144
+ #RubyProf.start
145
+ fire_event(:startup)
146
+ Sidekiq.logger.error "Simulating 1ms of latency between Sidekiq and redis"
147
+ Toxiproxy[:redis].downstream(:latency, latency: 1).apply do
148
+ launcher = Sidekiq::Launcher.new(Sidekiq.options)
149
+ launcher.run
150
+
151
+ while readable_io = IO.select([self_read])
152
+ signal = readable_io.first[0].gets.strip
153
+ handle_signal(launcher, signal)
154
+ end
155
+ end
156
+ rescue SystemExit => e
157
+ #Sidekiq.logger.error("Profiling...")
158
+ #result = RubyProf.stop
159
+ #printer = RubyProf::GraphHtmlPrinter.new(result)
160
+ #printer.print(File.new("output.html", "w"), :min_percent => 1)
161
+ # normal
162
+ rescue => e
163
+ raise e if $DEBUG
164
+ STDERR.puts e.message
165
+ STDERR.puts e.backtrace.join("\n")
166
+ exit 1
167
+ end
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
- keys << "stat:#{stat}:#{date}"
163
- dates << date
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].to_s] = value ? value.to_i : 0
170
+ stat_hash[dates[idx]] = value ? value.to_i : 0
170
171
  end
171
172
  end
172
173
 
@@ -224,7 +225,7 @@ module Sidekiq
224
225
  page = 0
225
226
  page_size = 50
226
227
 
227
- loop do
228
+ while true do
228
229
  range_start = page * page_size - deleted_size
229
230
  range_end = page * page_size - deleted_size + (page_size - 1)
230
231
  entries = Sidekiq.redis do |conn|
@@ -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)
@@ -312,7 +312,7 @@ module Sidekiq
312
312
  end
313
313
 
314
314
  def enqueued_at
315
- Time.at(@item['enqueued_at'] || 0).utc
315
+ @item['enqueued_at'] ? Time.at(@item['enqueued_at']).utc : nil
316
316
  end
317
317
 
318
318
  def created_at
@@ -369,11 +369,15 @@ module Sidekiq
369
369
  end
370
370
 
371
371
  def delete
372
- @parent.delete(score, jid)
372
+ if @value
373
+ @parent.delete_by_value(@parent.name, @value)
374
+ else
375
+ @parent.delete_by_jid(score, jid)
376
+ end
373
377
  end
374
378
 
375
379
  def reschedule(at)
376
- @parent.delete(score, jid)
380
+ delete
377
381
  @parent.schedule(at, item)
378
382
  end
379
383
 
@@ -484,7 +488,7 @@ module Sidekiq
484
488
  page = -1
485
489
  page_size = 50
486
490
 
487
- loop do
491
+ while true do
488
492
  range_start = page * page_size + offset_size
489
493
  range_end = page * page_size + offset_size + (page_size - 1)
490
494
  elements = Sidekiq.redis do |conn|
@@ -519,36 +523,30 @@ module Sidekiq
519
523
  self.detect { |j| j.jid == jid }
520
524
  end
521
525
 
522
- def delete(score, jid = nil)
523
- if jid
524
- elements = Sidekiq.redis do |conn|
525
- conn.zrangebyscore(name, score, score)
526
- end
526
+ def delete_by_value(name, value)
527
+ Sidekiq.redis do |conn|
528
+ ret = conn.zrem(name, value)
529
+ @_size -= 1 if ret
530
+ ret
531
+ end
532
+ end
527
533
 
528
- elements_with_jid = elements.map do |element|
534
+ def delete_by_jid(score, jid)
535
+ Sidekiq.redis do |conn|
536
+ elements = conn.zrangebyscore(name, score, score)
537
+ elements.each do |element|
529
538
  message = Sidekiq.load_json(element)
530
-
531
539
  if message["jid"] == jid
532
- _, @_size = Sidekiq.redis do |conn|
533
- conn.multi do
534
- conn.zrem(name, element)
535
- conn.zcard name
536
- end
537
- end
538
- end
539
- end
540
- elements_with_jid.count != 0
541
- else
542
- count, @_size = Sidekiq.redis do |conn|
543
- conn.multi do
544
- conn.zremrangebyscore(name, score, score)
545
- conn.zcard name
540
+ ret = conn.zrem(name, element)
541
+ @_size -= 1 if ret
542
+ break ret
546
543
  end
544
+ false
547
545
  end
548
- count != 0
549
546
  end
550
547
  end
551
548
 
549
+ alias_method :delete, :delete_by_jid
552
550
  end
553
551
 
554
552
  ##
data/lib/sidekiq/cli.rb CHANGED
@@ -11,18 +11,18 @@ require 'sidekiq'
11
11
  require 'sidekiq/util'
12
12
 
13
13
  module Sidekiq
14
- # We are shutting down Sidekiq but what about workers that
15
- # are working on some long job? This error is
16
- # raised in workers that have not finished within the hard
17
- # timeout limit. This is needed to rollback db transactions,
18
- # otherwise Ruby's Thread#kill will commit. See #377.
19
- # DO NOT RESCUE THIS ERROR.
20
- class Shutdown < Interrupt; end
21
-
22
14
  class CLI
23
15
  include Util
24
16
  include Singleton unless $TESTING
25
17
 
18
+ PROCTITLES = [
19
+ proc { 'sidekiq'.freeze },
20
+ proc { Sidekiq::VERSION },
21
+ proc { |me, data| data['tag'] },
22
+ proc { |me, data| "[#{Processor::WORKER_STATE.size} of #{data['concurrency']} busy]" },
23
+ proc { |me, data| "stopping" if me.stopping? },
24
+ ]
25
+
26
26
  # Used for CLI testing
27
27
  attr_accessor :code
28
28
  attr_accessor :launcher
@@ -40,7 +40,6 @@ module Sidekiq
40
40
  validate!
41
41
  daemonize
42
42
  write_pid
43
- load_celluloid
44
43
  end
45
44
 
46
45
  # Code within this method is not tested because it alters
@@ -64,15 +63,23 @@ module Sidekiq
64
63
 
65
64
  logger.info "Running in #{RUBY_DESCRIPTION}"
66
65
  logger.info Sidekiq::LICENSE
67
- logger.info "Upgrade to Sidekiq Pro for more features and support: http://sidekiq.org/pro" unless defined?(::Sidekiq::Pro)
68
-
69
- fire_event(:startup)
66
+ logger.info "Upgrade to Sidekiq Pro for more features and support: http://sidekiq.org" unless defined?(::Sidekiq::Pro)
70
67
 
71
68
  Sidekiq.redis do |conn|
72
69
  # touch the connection pool so it is created before we
73
- # launch the actors.
70
+ # fire startup and start multithreading.
71
+ ver = conn.info['redis_version']
72
+ raise "You are using Redis v#{ver}, Sidekiq requires Redis v2.8.0 or greater" if ver < '2.8'
74
73
  end
75
74
 
75
+ # Before this point, the process is initializing with just the main thread.
76
+ # Starting here the process will now have multiple threads running.
77
+ fire_event(:startup)
78
+
79
+ logger.debug {
80
+ "Middleware: #{Sidekiq.server_middleware.map(&:klass).join(', ')}"
81
+ }
82
+
76
83
  if !options[:daemon]
77
84
  logger.info 'Starting processing, hit Ctrl-C to stop'
78
85
  end
@@ -90,26 +97,28 @@ module Sidekiq
90
97
  rescue Interrupt
91
98
  logger.info 'Shutting down'
92
99
  launcher.stop
93
- fire_event(:shutdown, true)
94
100
  # Explicitly exit so busy Processor threads can't block
95
101
  # process shutdown.
102
+ logger.info "Bye!"
96
103
  exit(0)
97
104
  end
98
105
  end
99
106
 
100
107
  def self.banner
101
- %q{ s
102
- ss
103
- sss sss ss
104
- s sss s ssss sss ____ _ _ _ _
105
- s sssss ssss / ___|(_) __| | ___| | _(_) __ _
106
- s sss \___ \| |/ _` |/ _ \ |/ / |/ _` |
107
- s sssss s ___) | | (_| | __/ <| | (_| |
108
- ss s s |____/|_|\__,_|\___|_|\_\_|\__, |
109
- s s s |_|
110
- s s
111
- sss
112
- sss }
108
+ %q{
109
+ m,
110
+ `$b
111
+ .ss, $$: .,d$
112
+ `$$P,d$P' .,md$P"'
113
+ ,$$$$$bmmd$$$P^'
114
+ .d$$$$$$$$$$P'
115
+ $$^' `"^$$$' ____ _ _ _ _
116
+ $: ,$$: / ___|(_) __| | ___| | _(_) __ _
117
+ `b :$$ \___ \| |/ _` |/ _ \ |/ / |/ _` |
118
+ $$: ___) | | (_| | __/ <| | (_| |
119
+ $$ |____/|_|\__,_|\___|_|\_\_|\__, |
120
+ .d$$ |_|
121
+ }
113
122
  end
114
123
 
115
124
  def handle_signal(sig)
@@ -124,8 +133,7 @@ module Sidekiq
124
133
  raise Interrupt
125
134
  when 'USR1'
126
135
  Sidekiq.logger.info "Received USR1, no longer accepting new work"
127
- launcher.manager.async.stop
128
- fire_event(:quiet, true)
136
+ launcher.quiet
129
137
  when 'USR2'
130
138
  if Sidekiq.options[:logfile]
131
139
  Sidekiq.logger.info "Received USR2, reopening log file"
@@ -154,19 +162,6 @@ module Sidekiq
154
162
  end
155
163
  end
156
164
 
157
- def load_celluloid
158
- raise "Celluloid cannot be required until here, or it will break Sidekiq's daemonization" if defined?(::Celluloid) && options[:daemon]
159
-
160
- # Celluloid can't be loaded until after we've daemonized
161
- # because it spins up threads and creates locks which get
162
- # into a very bad state if forked.
163
- require 'celluloid/autostart'
164
- Celluloid.logger = (options[:verbose] ? Sidekiq.logger : nil)
165
-
166
- require 'sidekiq/manager'
167
- require 'sidekiq/scheduled'
168
- end
169
-
170
165
  def daemonize
171
166
  return unless options[:daemon]
172
167
 
@@ -340,7 +335,11 @@ module Sidekiq
340
335
  die 1
341
336
  end
342
337
  @parser.parse!(argv)
343
- opts[:config_file] ||= 'config/sidekiq.yml' if File.exist?('config/sidekiq.yml')
338
+
339
+ %w[config/sidekiq.yml config/sidekiq.yml.erb].each do |filename|
340
+ opts[:config_file] ||= filename if File.exist?(filename)
341
+ end
342
+
344
343
  opts
345
344
  end
346
345
 
@@ -119,16 +119,12 @@ module Sidekiq
119
119
 
120
120
  class << self
121
121
 
122
- def default
123
- @default ||= new
124
- end
125
-
126
122
  def push(item)
127
- default.push(item)
123
+ new.push(item)
128
124
  end
129
125
 
130
126
  def push_bulk(items)
131
- default.push_bulk(items)
127
+ new.push_bulk(items)
132
128
  end
133
129
 
134
130
  # Resque compatibility helpers. Note all helpers
@@ -210,10 +206,9 @@ module Sidekiq
210
206
  end
211
207
 
212
208
  def normalize_item(item)
213
- raise(ArgumentError, "Message must be a Hash of the form: { 'class' => SomeWorker, 'args' => ['bob', 1, :foo => 'bar'] }") unless item.is_a?(Hash)
214
- raise(ArgumentError, "Message must include a class and set of arguments: #{item.inspect}") if !item['class'] || !item['args']
215
- raise(ArgumentError, "Message args must be an Array") unless item['args'].is_a?(Array)
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)
209
+ 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)
210
+ raise(ArgumentError, "Job args must be an Array") unless item['args'].is_a?(Array)
211
+ 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
212
 
218
213
  normalized_hash(item['class'.freeze])
219
214
  .each{ |key, value| item[key] = value if item[key].nil? }