sidekiq 2.15.1 → 4.2.10

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 (187) hide show
  1. checksums.yaml +7 -0
  2. data/.github/contributing.md +32 -0
  3. data/.github/issue_template.md +9 -0
  4. data/.gitignore +1 -0
  5. data/.travis.yml +16 -17
  6. data/3.0-Upgrade.md +70 -0
  7. data/4.0-Upgrade.md +53 -0
  8. data/COMM-LICENSE +56 -44
  9. data/Changes.md +644 -1
  10. data/Ent-Changes.md +173 -0
  11. data/Gemfile +27 -0
  12. data/LICENSE +1 -1
  13. data/Pro-2.0-Upgrade.md +138 -0
  14. data/Pro-3.0-Upgrade.md +44 -0
  15. data/Pro-Changes.md +457 -3
  16. data/README.md +46 -29
  17. data/Rakefile +6 -3
  18. data/bin/sidekiq +4 -0
  19. data/bin/sidekiqctl +41 -20
  20. data/bin/sidekiqload +154 -0
  21. data/code_of_conduct.md +50 -0
  22. data/lib/generators/sidekiq/templates/worker.rb.erb +9 -0
  23. data/lib/generators/sidekiq/templates/worker_spec.rb.erb +6 -0
  24. data/lib/generators/sidekiq/templates/worker_test.rb.erb +8 -0
  25. data/lib/generators/sidekiq/worker_generator.rb +49 -0
  26. data/lib/sidekiq.rb +141 -29
  27. data/lib/sidekiq/api.rb +540 -106
  28. data/lib/sidekiq/cli.rb +131 -71
  29. data/lib/sidekiq/client.rb +168 -96
  30. data/lib/sidekiq/core_ext.rb +36 -8
  31. data/lib/sidekiq/exception_handler.rb +20 -28
  32. data/lib/sidekiq/extensions/action_mailer.rb +25 -5
  33. data/lib/sidekiq/extensions/active_record.rb +8 -4
  34. data/lib/sidekiq/extensions/class_methods.rb +9 -5
  35. data/lib/sidekiq/extensions/generic_proxy.rb +1 -0
  36. data/lib/sidekiq/fetch.rb +45 -101
  37. data/lib/sidekiq/launcher.rb +144 -30
  38. data/lib/sidekiq/logging.rb +69 -12
  39. data/lib/sidekiq/manager.rb +90 -140
  40. data/lib/sidekiq/middleware/chain.rb +18 -5
  41. data/lib/sidekiq/middleware/i18n.rb +9 -2
  42. data/lib/sidekiq/middleware/server/active_record.rb +1 -1
  43. data/lib/sidekiq/middleware/server/logging.rb +11 -11
  44. data/lib/sidekiq/middleware/server/retry_jobs.rb +98 -44
  45. data/lib/sidekiq/paginator.rb +20 -8
  46. data/lib/sidekiq/processor.rb +157 -96
  47. data/lib/sidekiq/rails.rb +109 -5
  48. data/lib/sidekiq/redis_connection.rb +70 -24
  49. data/lib/sidekiq/scheduled.rb +122 -50
  50. data/lib/sidekiq/testing.rb +171 -31
  51. data/lib/sidekiq/testing/inline.rb +1 -0
  52. data/lib/sidekiq/util.rb +31 -5
  53. data/lib/sidekiq/version.rb +2 -1
  54. data/lib/sidekiq/web.rb +136 -263
  55. data/lib/sidekiq/web/action.rb +93 -0
  56. data/lib/sidekiq/web/application.rb +336 -0
  57. data/lib/sidekiq/web/helpers.rb +278 -0
  58. data/lib/sidekiq/web/router.rb +100 -0
  59. data/lib/sidekiq/worker.rb +40 -7
  60. data/sidekiq.gemspec +18 -14
  61. data/web/assets/images/favicon.ico +0 -0
  62. data/web/assets/images/{status-sd8051fd480.png → status.png} +0 -0
  63. data/web/assets/javascripts/application.js +67 -19
  64. data/web/assets/javascripts/dashboard.js +138 -29
  65. data/web/assets/stylesheets/application.css +267 -406
  66. data/web/assets/stylesheets/bootstrap.css +4 -8
  67. data/web/locales/cs.yml +78 -0
  68. data/web/locales/da.yml +9 -1
  69. data/web/locales/de.yml +18 -9
  70. data/web/locales/el.yml +68 -0
  71. data/web/locales/en.yml +19 -4
  72. data/web/locales/es.yml +10 -1
  73. data/web/locales/fa.yml +79 -0
  74. data/web/locales/fr.yml +50 -32
  75. data/web/locales/hi.yml +75 -0
  76. data/web/locales/it.yml +27 -18
  77. data/web/locales/ja.yml +27 -12
  78. data/web/locales/ko.yml +8 -3
  79. data/web/locales/{no.yml → nb.yml} +19 -5
  80. data/web/locales/nl.yml +8 -3
  81. data/web/locales/pl.yml +0 -1
  82. data/web/locales/pt-br.yml +11 -4
  83. data/web/locales/pt.yml +8 -1
  84. data/web/locales/ru.yml +39 -21
  85. data/web/locales/sv.yml +68 -0
  86. data/web/locales/ta.yml +75 -0
  87. data/web/locales/uk.yml +76 -0
  88. data/web/locales/zh-cn.yml +68 -0
  89. data/web/locales/zh-tw.yml +68 -0
  90. data/web/views/_footer.erb +17 -0
  91. data/web/views/_job_info.erb +72 -60
  92. data/web/views/_nav.erb +58 -25
  93. data/web/views/_paging.erb +5 -5
  94. data/web/views/_poll_link.erb +7 -0
  95. data/web/views/_summary.erb +20 -14
  96. data/web/views/busy.erb +94 -0
  97. data/web/views/dashboard.erb +34 -21
  98. data/web/views/dead.erb +34 -0
  99. data/web/views/layout.erb +8 -30
  100. data/web/views/morgue.erb +75 -0
  101. data/web/views/queue.erb +37 -30
  102. data/web/views/queues.erb +26 -20
  103. data/web/views/retries.erb +60 -47
  104. data/web/views/retry.erb +23 -19
  105. data/web/views/scheduled.erb +39 -35
  106. data/web/views/scheduled_job_info.erb +2 -1
  107. metadata +152 -195
  108. data/Contributing.md +0 -29
  109. data/config.ru +0 -18
  110. data/lib/sidekiq/actor.rb +0 -7
  111. data/lib/sidekiq/capistrano.rb +0 -54
  112. data/lib/sidekiq/yaml_patch.rb +0 -21
  113. data/test/config.yml +0 -11
  114. data/test/env_based_config.yml +0 -11
  115. data/test/fake_env.rb +0 -0
  116. data/test/helper.rb +0 -42
  117. data/test/test_api.rb +0 -341
  118. data/test/test_cli.rb +0 -326
  119. data/test/test_client.rb +0 -211
  120. data/test/test_exception_handler.rb +0 -124
  121. data/test/test_extensions.rb +0 -105
  122. data/test/test_fetch.rb +0 -44
  123. data/test/test_manager.rb +0 -83
  124. data/test/test_middleware.rb +0 -135
  125. data/test/test_processor.rb +0 -160
  126. data/test/test_redis_connection.rb +0 -97
  127. data/test/test_retry.rb +0 -306
  128. data/test/test_scheduled.rb +0 -86
  129. data/test/test_scheduling.rb +0 -47
  130. data/test/test_sidekiq.rb +0 -37
  131. data/test/test_testing.rb +0 -82
  132. data/test/test_testing_fake.rb +0 -265
  133. data/test/test_testing_inline.rb +0 -92
  134. data/test/test_util.rb +0 -18
  135. data/test/test_web.rb +0 -372
  136. data/web/assets/images/bootstrap/glyphicons-halflings-white.png +0 -0
  137. data/web/assets/images/bootstrap/glyphicons-halflings.png +0 -0
  138. data/web/assets/images/status/active.png +0 -0
  139. data/web/assets/images/status/idle.png +0 -0
  140. data/web/assets/javascripts/locales/README.md +0 -27
  141. data/web/assets/javascripts/locales/jquery.timeago.ar.js +0 -96
  142. data/web/assets/javascripts/locales/jquery.timeago.bg.js +0 -18
  143. data/web/assets/javascripts/locales/jquery.timeago.bs.js +0 -49
  144. data/web/assets/javascripts/locales/jquery.timeago.ca.js +0 -18
  145. data/web/assets/javascripts/locales/jquery.timeago.cy.js +0 -20
  146. data/web/assets/javascripts/locales/jquery.timeago.cz.js +0 -18
  147. data/web/assets/javascripts/locales/jquery.timeago.da.js +0 -18
  148. data/web/assets/javascripts/locales/jquery.timeago.de.js +0 -18
  149. data/web/assets/javascripts/locales/jquery.timeago.el.js +0 -18
  150. data/web/assets/javascripts/locales/jquery.timeago.en-short.js +0 -20
  151. data/web/assets/javascripts/locales/jquery.timeago.en.js +0 -20
  152. data/web/assets/javascripts/locales/jquery.timeago.es.js +0 -18
  153. data/web/assets/javascripts/locales/jquery.timeago.et.js +0 -18
  154. data/web/assets/javascripts/locales/jquery.timeago.fa.js +0 -22
  155. data/web/assets/javascripts/locales/jquery.timeago.fi.js +0 -28
  156. data/web/assets/javascripts/locales/jquery.timeago.fr-short.js +0 -16
  157. data/web/assets/javascripts/locales/jquery.timeago.fr.js +0 -17
  158. data/web/assets/javascripts/locales/jquery.timeago.he.js +0 -18
  159. data/web/assets/javascripts/locales/jquery.timeago.hr.js +0 -49
  160. data/web/assets/javascripts/locales/jquery.timeago.hu.js +0 -18
  161. data/web/assets/javascripts/locales/jquery.timeago.hy.js +0 -18
  162. data/web/assets/javascripts/locales/jquery.timeago.id.js +0 -18
  163. data/web/assets/javascripts/locales/jquery.timeago.it.js +0 -16
  164. data/web/assets/javascripts/locales/jquery.timeago.ja.js +0 -19
  165. data/web/assets/javascripts/locales/jquery.timeago.ko.js +0 -17
  166. data/web/assets/javascripts/locales/jquery.timeago.lt.js +0 -20
  167. data/web/assets/javascripts/locales/jquery.timeago.mk.js +0 -20
  168. data/web/assets/javascripts/locales/jquery.timeago.nl.js +0 -20
  169. data/web/assets/javascripts/locales/jquery.timeago.no.js +0 -18
  170. data/web/assets/javascripts/locales/jquery.timeago.pl.js +0 -31
  171. data/web/assets/javascripts/locales/jquery.timeago.pt-br.js +0 -16
  172. data/web/assets/javascripts/locales/jquery.timeago.pt.js +0 -16
  173. data/web/assets/javascripts/locales/jquery.timeago.ro.js +0 -18
  174. data/web/assets/javascripts/locales/jquery.timeago.rs.js +0 -49
  175. data/web/assets/javascripts/locales/jquery.timeago.ru.js +0 -34
  176. data/web/assets/javascripts/locales/jquery.timeago.sk.js +0 -18
  177. data/web/assets/javascripts/locales/jquery.timeago.sl.js +0 -44
  178. data/web/assets/javascripts/locales/jquery.timeago.sv.js +0 -18
  179. data/web/assets/javascripts/locales/jquery.timeago.th.js +0 -20
  180. data/web/assets/javascripts/locales/jquery.timeago.tr.js +0 -16
  181. data/web/assets/javascripts/locales/jquery.timeago.uk.js +0 -34
  182. data/web/assets/javascripts/locales/jquery.timeago.uz.js +0 -19
  183. data/web/assets/javascripts/locales/jquery.timeago.zh-CN.js +0 -20
  184. data/web/assets/javascripts/locales/jquery.timeago.zh-TW.js +0 -20
  185. data/web/views/_poll.erb +0 -14
  186. data/web/views/_workers.erb +0 -29
  187. data/web/views/index.erb +0 -16
@@ -1,29 +0,0 @@
1
- # Contributing
2
-
3
- First of all, thank you for even opening this file up! I hope you find
4
- it worthwhile to help out with Sidekiq.
5
-
6
- ## Issues
7
-
8
- When opening an issue, please include a **backtrace** with your error.
9
-
10
- ## Code
11
-
12
- If you're interested in helping or contributing to Sidekiq, here's
13
- some known areas which need improvement:
14
-
15
- * The Web UI and sidekiq.org website could always use more polish. If you have an eye for design and an idea for improvement, please open an issue and let us know.
16
- * The Sidekiq API has a serious issue: deleting elements and iterating
17
- at the same time is broken, see #866, #1060.
18
- * Make normal testing and inline testing dynamic: #1053
19
- * Your brilliant idea which I haven't listed!
20
-
21
- It's always best to open an issue before investing a lot of time into a
22
- fix or new functionality. Functionality must meet my design goals and
23
- vision for the project to be accepted; I would be happy to discuss how
24
- your idea can best fit into Sidekiq.
25
-
26
-
27
- ## Sponsorship
28
-
29
- If you've got more money than time and want to sponsor Sidekiq's continued support, your company can buy [Sidekiq Pro](http://sidekiq.org/pro). You get great functionality, I continue to fix bugs and enhance Sidekiq for years to come.
data/config.ru DELETED
@@ -1,18 +0,0 @@
1
- require 'sidekiq'
2
-
3
- Sidekiq.configure_client do |config|
4
- config.redis = { :size => 1 }
5
- end
6
-
7
- #Sidekiq.redis {|conn| conn.flushdb }
8
- #10.times do |idx|
9
- #Sidekiq::Client.push('class' => 'HardWorker', 'args' => ['foo', 0.1, idx])
10
- #end
11
-
12
- #Sidekiq.redis { |conn| conn.zadd('retry', Time.now.utc.to_f + 3000, MultiJson.encode({
13
- #'class' => 'HardWorker', 'args' => ['foo', 0.1, Time.now.to_f],
14
- #'queue' => 'default', 'error_message' => 'No such method', 'error_class' => 'NoMethodError',
15
- #'failed_at' => Time.now.utc, 'retry_count' => 0 })) }
16
-
17
- require 'sidekiq/web'
18
- run Sidekiq::Web
@@ -1,7 +0,0 @@
1
- module Sidekiq
2
- module Actor
3
- def self.included(klass)
4
- klass.send(:include, Celluloid)
5
- end
6
- end
7
- end
@@ -1,54 +0,0 @@
1
- Capistrano::Configuration.instance.load do
2
-
3
- _cset(:sidekiq_default_hooks) { true }
4
- _cset(:sidekiq_cmd) { "#{fetch(:bundle_cmd, "bundle")} exec sidekiq" }
5
- _cset(:sidekiqctl_cmd) { "#{fetch(:bundle_cmd, "bundle")} exec sidekiqctl" }
6
- _cset(:sidekiq_timeout) { 10 }
7
- _cset(:sidekiq_role) { :app }
8
- _cset(:sidekiq_pid) { "#{current_path}/tmp/pids/sidekiq.pid" }
9
- _cset(:sidekiq_processes) { 1 }
10
-
11
- if fetch(:sidekiq_default_hooks)
12
- before "deploy:update_code", "sidekiq:quiet"
13
- after "deploy:stop", "sidekiq:stop"
14
- after "deploy:start", "sidekiq:start"
15
- before "deploy:restart", "sidekiq:restart"
16
- end
17
-
18
- namespace :sidekiq do
19
- def for_each_process(&block)
20
- fetch(:sidekiq_processes).times do |idx|
21
- yield((idx == 0 ? "#{fetch(:sidekiq_pid)}" : "#{fetch(:sidekiq_pid)}-#{idx}"), idx)
22
- end
23
- end
24
-
25
- desc "Quiet sidekiq (stop accepting new work)"
26
- task :quiet, :roles => lambda { fetch(:sidekiq_role) }, :on_no_matching_servers => :continue do
27
- for_each_process do |pid_file, idx|
28
- run "if [ -d #{current_path} ] && [ -f #{pid_file} ] && kill -0 `cat #{pid_file}`> /dev/null 2>&1; then cd #{current_path} && #{fetch(:sidekiqctl_cmd)} quiet #{pid_file} ; else echo 'Sidekiq is not running'; fi"
29
- end
30
- end
31
-
32
- desc "Stop sidekiq"
33
- task :stop, :roles => lambda { fetch(:sidekiq_role) }, :on_no_matching_servers => :continue do
34
- for_each_process do |pid_file, idx|
35
- run "if [ -d #{current_path} ] && [ -f #{pid_file} ] && kill -0 `cat #{pid_file}`> /dev/null 2>&1; then cd #{current_path} && #{fetch(:sidekiqctl_cmd)} stop #{pid_file} #{fetch :sidekiq_timeout} ; else echo 'Sidekiq is not running'; fi"
36
- end
37
- end
38
-
39
- desc "Start sidekiq"
40
- task :start, :roles => lambda { fetch(:sidekiq_role) }, :on_no_matching_servers => :continue do
41
- rails_env = fetch(:rails_env, "production")
42
- for_each_process do |pid_file, idx|
43
- run "cd #{current_path} ; nohup #{fetch(:sidekiq_cmd)} -e #{rails_env} -C #{current_path}/config/sidekiq.yml -i #{idx} -P #{pid_file} >> #{current_path}/log/sidekiq.log 2>&1 &", :pty => false
44
- end
45
- end
46
-
47
- desc "Restart sidekiq"
48
- task :restart, :roles => lambda { fetch(:sidekiq_role) }, :on_no_matching_servers => :continue do
49
- stop
50
- start
51
- end
52
-
53
- end
54
- end
@@ -1,21 +0,0 @@
1
- # YAML marshalling of instances can fail in some circumstances,
2
- # e.g. when the instance has a handle to a Proc. This monkeypatch limits
3
- # the YAML serialization to just AR's internal @attributes hash.
4
- # The paperclip gem litters AR instances with Procs, for instance.
5
- #
6
- # Courtesy of @ryanlecompte https://gist.github.com/007b88ae90372d1a3321
7
- #
8
-
9
- if defined?(::ActiveRecord)
10
- class ActiveRecord::Base
11
- yaml_as "tag:ruby.yaml.org,2002:ActiveRecord"
12
-
13
- def self.yaml_new(klass, tag, val)
14
- klass.unscoped.find(val['attributes'][klass.primary_key])
15
- end
16
-
17
- def to_yaml_properties
18
- ['@attributes']
19
- end
20
- end
21
- end
@@ -1,11 +0,0 @@
1
- ---
2
- :verbose: false
3
- :environment: xzibit
4
- :require: ./test/fake_env.rb
5
- :pidfile: /tmp/sidekiq-config-test.pid
6
- :logfile: /tmp/sidekiq.log
7
- :namespace: sidekiq
8
- :concurrency: 50
9
- :queues:
10
- - [<%="very_"%>often, 2]
11
- - [seldom, 1]
@@ -1,11 +0,0 @@
1
- ---
2
- :pidfile: /tmp/sidekiq-config-test.pid
3
- :concurrency: 50
4
- staging:
5
- :verbose: false
6
- :require: ./test/fake_env.rb
7
- :logfile: /tmp/sidekiq.log
8
- :concurrency: 5
9
- :queues:
10
- - [<%="very_"%>often, 2]
11
- - [seldom, 1]
File without changes
@@ -1,42 +0,0 @@
1
- $TESTING = true
2
- require 'coveralls'
3
- Coveralls.wear! do
4
- add_filter "/test/"
5
- end
6
-
7
- ENV['RACK_ENV'] = ENV['RAILS_ENV'] = 'test'
8
- if ENV.has_key?("SIMPLECOV")
9
- require 'simplecov'
10
- SimpleCov.start do
11
- add_filter "/test/"
12
- end
13
- end
14
-
15
- begin
16
- require 'pry'
17
- rescue LoadError
18
- end
19
-
20
- require 'minitest/autorun'
21
- require 'minitest/pride'
22
-
23
- require 'celluloid/autostart'
24
- require 'sidekiq'
25
- require 'sidekiq/util'
26
- Sidekiq.logger.level = Logger::ERROR
27
-
28
- Sidekiq::Test = MiniTest::Unit::TestCase
29
-
30
- require 'sidekiq/redis_connection'
31
- redis_url = ENV['REDIS_URL'] || 'redis://localhost/15'
32
- REDIS = Sidekiq::RedisConnection.create(:url => redis_url, :namespace => 'testy')
33
-
34
- Sidekiq.configure_client do |config|
35
- config.redis = { :url => redis_url, :namespace => 'testy' }
36
- end
37
-
38
- Celluloid.class_eval do
39
- def self.shutdown
40
- $stderr.puts "Celluloid shutdown disabled"
41
- end
42
- end
@@ -1,341 +0,0 @@
1
- require 'helper'
2
-
3
- class TestApi < Sidekiq::Test
4
- describe "stats" do
5
- before do
6
- Sidekiq.redis {|c| c.flushdb }
7
- end
8
-
9
- describe "processed" do
10
- it "is initially zero" do
11
- s = Sidekiq::Stats.new
12
- assert_equal 0, s.processed
13
- end
14
-
15
- it "returns number of processed jobs" do
16
- Sidekiq.redis { |conn| conn.set("stat:processed", 5) }
17
- s = Sidekiq::Stats.new
18
- assert_equal 5, s.processed
19
- end
20
- end
21
-
22
- describe "failed" do
23
- it "is initially zero" do
24
- s = Sidekiq::Stats.new
25
- assert_equal 0, s.processed
26
- end
27
-
28
- it "returns number of failed jobs" do
29
- Sidekiq.redis { |conn| conn.set("stat:failed", 5) }
30
- s = Sidekiq::Stats.new
31
- assert_equal 5, s.failed
32
- end
33
- end
34
-
35
- describe "reset" do
36
- it 'can reset stats' do
37
- Sidekiq.redis do |conn|
38
- conn.set('stat:processed', 5)
39
- conn.set('stat:failed', 10)
40
- Sidekiq::Stats.new.reset
41
- assert_equal '0', conn.get('stat:processed')
42
- assert_equal '0', conn.get('stat:failed')
43
- end
44
- end
45
- end
46
-
47
- describe "queues" do
48
- it "is initially empty" do
49
- s = Sidekiq::Stats.new
50
- assert_equal 0, s.queues.size
51
- end
52
-
53
- it "returns a hash of queue and size in order" do
54
- Sidekiq.redis do |conn|
55
- conn.rpush 'queue:foo', '{}'
56
- conn.sadd 'queues', 'foo'
57
-
58
- 3.times { conn.rpush 'queue:bar', '{}' }
59
- conn.sadd 'queues', 'bar'
60
- end
61
-
62
- s = Sidekiq::Stats.new
63
- assert_equal ({ "foo" => 1, "bar" => 3 }), s.queues
64
- assert_equal "bar", s.queues.first.first
65
- end
66
- end
67
-
68
- describe "enqueued" do
69
- it "is initially empty" do
70
- s = Sidekiq::Stats.new
71
- assert_equal 0, s.enqueued
72
- end
73
-
74
- it "returns total enqueued jobs" do
75
- Sidekiq.redis do |conn|
76
- conn.rpush 'queue:foo', '{}'
77
- conn.sadd 'queues', 'foo'
78
-
79
- 3.times { conn.rpush 'queue:bar', '{}' }
80
- conn.sadd 'queues', 'bar'
81
- end
82
-
83
- s = Sidekiq::Stats.new
84
- assert_equal 4, s.enqueued
85
- end
86
- end
87
-
88
- describe "over time" do
89
- describe "processed" do
90
- it 'retrieves hash of dates' do
91
- Sidekiq.redis do |c|
92
- c.incrby("stat:processed:2012-12-24", 4)
93
- c.incrby("stat:processed:2012-12-25", 1)
94
- c.incrby("stat:processed:2012-12-26", 6)
95
- c.incrby("stat:processed:2012-12-27", 2)
96
- end
97
- Time.stub(:now, Time.parse("2012-12-26 1:00:00 -0500")) do
98
- s = Sidekiq::Stats::History.new(2)
99
- assert_equal ({ "2012-12-26" => 6, "2012-12-25" => 1 }), s.processed
100
-
101
- s = Sidekiq::Stats::History.new(3)
102
- assert_equal ({ "2012-12-26" => 6, "2012-12-25" => 1, "2012-12-24" => 4 }), s.processed
103
-
104
- s = Sidekiq::Stats::History.new(2, Date.parse("2012-12-25"))
105
- assert_equal ({ "2012-12-25" => 1, "2012-12-24" => 4 }), s.processed
106
- end
107
- end
108
- end
109
-
110
- describe "failed" do
111
- it 'retrieves hash of dates' do
112
- Sidekiq.redis do |c|
113
- c.incrby("stat:failed:2012-12-24", 4)
114
- c.incrby("stat:failed:2012-12-25", 1)
115
- c.incrby("stat:failed:2012-12-26", 6)
116
- c.incrby("stat:failed:2012-12-27", 2)
117
- end
118
- Time.stub(:now, Time.parse("2012-12-26 1:00:00 -0500")) do
119
- s = Sidekiq::Stats::History.new(2)
120
- assert_equal ({ "2012-12-26" => 6, "2012-12-25" => 1 }), s.failed
121
-
122
- s = Sidekiq::Stats::History.new(3)
123
- assert_equal ({ "2012-12-26" => 6, "2012-12-25" => 1, "2012-12-24" => 4 }), s.failed
124
-
125
- s = Sidekiq::Stats::History.new(2, Date.parse("2012-12-25"))
126
- assert_equal ({ "2012-12-25" => 1, "2012-12-24" => 4 }), s.failed
127
- end
128
- end
129
- end
130
- end
131
- end
132
-
133
- describe 'with an empty database' do
134
- before do
135
- Sidekiq.redis {|c| c.flushdb }
136
- end
137
-
138
- it 'shows queue as empty' do
139
- q = Sidekiq::Queue.new
140
- assert_equal 0, q.size
141
- assert_equal 0, q.latency
142
- end
143
-
144
- class ApiWorker
145
- include Sidekiq::Worker
146
- end
147
-
148
- it 'can enumerate jobs' do
149
- q = Sidekiq::Queue.new
150
- Time.stub(:now, Time.new(2012, 12, 26)) do
151
- ApiWorker.perform_async(1, 'mike')
152
- assert_equal ['TestApi::ApiWorker'], q.map(&:klass)
153
-
154
- job = q.first
155
- assert_equal 24, job.jid.size
156
- assert_equal [1, 'mike'], job.args
157
- assert_equal Time.new(2012, 12, 26), job.enqueued_at
158
-
159
- end
160
-
161
- assert q.latency > 10_000_000
162
-
163
- q = Sidekiq::Queue.new('other')
164
- assert_equal 0, q.size
165
- end
166
-
167
- it 'can delete jobs' do
168
- q = Sidekiq::Queue.new
169
- ApiWorker.perform_async(1, 'mike')
170
- assert_equal 1, q.size
171
- assert_equal [true], q.map(&:delete)
172
- assert_equal 0, q.size
173
- end
174
-
175
- it "can move scheduled job to queue" do
176
- job_id = ApiWorker.perform_in(100, 1, 'jason')
177
- job = Sidekiq::ScheduledSet.new.find_job(job_id)
178
- q = Sidekiq::Queue.new
179
- job.add_to_queue
180
- queued_job = q.find_job(job_id)
181
- refute_nil queued_job
182
- assert_equal queued_job.jid, job_id
183
- job = Sidekiq::ScheduledSet.new.find_job(job_id)
184
- assert_nil job
185
- end
186
-
187
- it 'can find job by id in sorted sets' do
188
- job_id = ApiWorker.perform_in(100, 1, 'jason')
189
- job = Sidekiq::ScheduledSet.new.find_job(job_id)
190
- refute_nil job
191
- assert_equal job_id, job.jid
192
- assert_in_delta job.latency, 0.0, 0.01
193
- end
194
-
195
- it 'can find job by id in queues' do
196
- q = Sidekiq::Queue.new
197
- job_id = ApiWorker.perform_async(1, 'jason')
198
- job = q.find_job(job_id)
199
- refute_nil job
200
- assert_equal job_id, job.jid
201
- end
202
-
203
- it 'can clear a queue' do
204
- q = Sidekiq::Queue.new
205
- 2.times { ApiWorker.perform_async(1, 'mike') }
206
- q.clear
207
-
208
- Sidekiq.redis do |conn|
209
- refute conn.smembers('queues').include?('foo')
210
- refute conn.exists('queues:foo')
211
- end
212
- end
213
-
214
- it 'can fetch by score' do
215
- same_time = Time.now.to_f
216
- add_retry('bob1', same_time)
217
- add_retry('bob2', same_time)
218
- r = Sidekiq::RetrySet.new
219
- assert_equal 2, r.fetch(same_time).size
220
- end
221
-
222
- it 'can fetch by score and jid' do
223
- same_time = Time.now.to_f
224
- add_retry('bob1', same_time)
225
- add_retry('bob2', same_time)
226
- r = Sidekiq::RetrySet.new
227
- # jobs = r.fetch(same_time)
228
- # puts jobs[1].jid
229
- assert_equal 1, r.fetch(same_time, 'bob1').size
230
- end
231
-
232
- it 'shows empty retries' do
233
- r = Sidekiq::RetrySet.new
234
- assert_equal 0, r.size
235
- end
236
-
237
- it 'can enumerate retries' do
238
- add_retry
239
-
240
- r = Sidekiq::RetrySet.new
241
- assert_equal 1, r.size
242
- array = r.to_a
243
- assert_equal 1, array.size
244
-
245
- retri = array.first
246
- assert_equal 'ApiWorker', retri.klass
247
- assert_equal 'default', retri.queue
248
- assert_equal 'bob', retri.jid
249
- assert_in_delta Time.now.to_f, retri.at.to_f, 0.01
250
- end
251
-
252
- it 'can delete multiple retries from score' do
253
- same_time = Time.now.to_f
254
- add_retry('bob1', same_time)
255
- add_retry('bob2', same_time)
256
- r = Sidekiq::RetrySet.new
257
- assert_equal 2, r.size
258
- Sidekiq::RetrySet.new.delete(same_time)
259
- assert_equal 0, r.size
260
- end
261
-
262
- it 'can delete a single retry from score and jid' do
263
- same_time = Time.now.to_f
264
- add_retry('bob1', same_time)
265
- add_retry('bob2', same_time)
266
- r = Sidekiq::RetrySet.new
267
- assert_equal 2, r.size
268
- Sidekiq::RetrySet.new.delete(same_time, 'bob1')
269
- assert_equal 1, r.size
270
- end
271
-
272
- it 'can retry a retry' do
273
- add_retry
274
- r = Sidekiq::RetrySet.new
275
- assert_equal 1, r.size
276
- r.first.retry
277
- assert_equal 0, r.size
278
- assert_equal 1, Sidekiq::Queue.new('default').size
279
- job = Sidekiq::Queue.new('default').first
280
- assert_equal 'bob', job.jid
281
- assert_equal 1, job['retry_count']
282
- end
283
-
284
- it 'can clear retries' do
285
- add_retry
286
- add_retry('test')
287
- r = Sidekiq::RetrySet.new
288
- assert_equal 2, r.size
289
- r.clear
290
- assert_equal 0, r.size
291
- end
292
-
293
- it 'can enumerate workers' do
294
- w = Sidekiq::Workers.new
295
- assert_equal 0, w.size
296
- w.each do
297
- assert false
298
- end
299
-
300
- s = '12345'
301
- data = Sidekiq.dump_json({ 'payload' => {}, 'queue' => 'default', 'run_at' => Time.now.to_i })
302
- Sidekiq.redis do |c|
303
- c.multi do
304
- c.sadd('workers', s)
305
- c.set("worker:#{s}", data)
306
- c.set("worker:#{s}:started", Time.now.to_s)
307
- end
308
- end
309
-
310
- assert_equal 1, w.size
311
- w.each do |x, y, z|
312
- assert_equal s, x
313
- assert_equal 'default', y['queue']
314
- assert_equal Time.now.year, DateTime.parse(z).year
315
- end
316
- end
317
-
318
- it 'can reschedule jobs' do
319
- add_retry('foo1')
320
- add_retry('foo2')
321
-
322
- retries = Sidekiq::RetrySet.new
323
- assert_equal 2, retries.size
324
- refute(retries.map { |r| r.score > (Time.now.to_f + 9) }.any?)
325
-
326
- retries.each do |retri|
327
- retri.reschedule(Time.now.to_f + 10) if retri.jid == 'foo2'
328
- end
329
-
330
- assert_equal 2, retries.size
331
- assert(retries.map { |r| r.score > (Time.now.to_f + 9) }.any?)
332
- end
333
-
334
- def add_retry(jid = 'bob', at = Time.now.to_f)
335
- payload = Sidekiq.dump_json('class' => 'ApiWorker', 'args' => [1, 'mike'], 'queue' => 'default', 'jid' => jid, 'retry_count' => 2, 'failed_at' => Time.now.utc)
336
- Sidekiq.redis do |conn|
337
- conn.zadd('retry', at.to_s, payload)
338
- end
339
- end
340
- end
341
- end