sidekiq 3.5.4 → 7.2.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 (228) hide show
  1. checksums.yaml +5 -5
  2. data/Changes.md +992 -6
  3. data/LICENSE.txt +9 -0
  4. data/README.md +52 -43
  5. data/bin/sidekiq +22 -4
  6. data/bin/sidekiqload +209 -115
  7. data/bin/sidekiqmon +11 -0
  8. data/lib/generators/sidekiq/job_generator.rb +57 -0
  9. data/lib/generators/sidekiq/templates/{worker.rb.erb → job.rb.erb} +2 -2
  10. data/lib/generators/sidekiq/templates/job_spec.rb.erb +6 -0
  11. data/lib/generators/sidekiq/templates/job_test.rb.erb +8 -0
  12. data/lib/sidekiq/api.rb +633 -295
  13. data/lib/sidekiq/capsule.rb +127 -0
  14. data/lib/sidekiq/cli.rb +270 -248
  15. data/lib/sidekiq/client.rb +139 -108
  16. data/lib/sidekiq/component.rb +68 -0
  17. data/lib/sidekiq/config.rb +287 -0
  18. data/lib/sidekiq/deploy.rb +62 -0
  19. data/lib/sidekiq/embedded.rb +61 -0
  20. data/lib/sidekiq/fetch.rb +53 -121
  21. data/lib/sidekiq/job.rb +374 -0
  22. data/lib/sidekiq/job_logger.rb +51 -0
  23. data/lib/sidekiq/job_retry.rb +301 -0
  24. data/lib/sidekiq/job_util.rb +107 -0
  25. data/lib/sidekiq/launcher.rb +241 -69
  26. data/lib/sidekiq/logger.rb +131 -0
  27. data/lib/sidekiq/manager.rb +88 -190
  28. data/lib/sidekiq/metrics/query.rb +155 -0
  29. data/lib/sidekiq/metrics/shared.rb +95 -0
  30. data/lib/sidekiq/metrics/tracking.rb +136 -0
  31. data/lib/sidekiq/middleware/chain.rb +114 -56
  32. data/lib/sidekiq/middleware/current_attributes.rb +95 -0
  33. data/lib/sidekiq/middleware/i18n.rb +8 -7
  34. data/lib/sidekiq/middleware/modules.rb +21 -0
  35. data/lib/sidekiq/monitor.rb +146 -0
  36. data/lib/sidekiq/paginator.rb +29 -16
  37. data/lib/sidekiq/processor.rb +238 -118
  38. data/lib/sidekiq/rails.rb +57 -27
  39. data/lib/sidekiq/redis_client_adapter.rb +111 -0
  40. data/lib/sidekiq/redis_connection.rb +49 -50
  41. data/lib/sidekiq/ring_buffer.rb +29 -0
  42. data/lib/sidekiq/scheduled.rb +173 -52
  43. data/lib/sidekiq/sd_notify.rb +149 -0
  44. data/lib/sidekiq/systemd.rb +24 -0
  45. data/lib/sidekiq/testing/inline.rb +7 -5
  46. data/lib/sidekiq/testing.rb +197 -65
  47. data/lib/sidekiq/transaction_aware_client.rb +44 -0
  48. data/lib/sidekiq/version.rb +4 -1
  49. data/lib/sidekiq/web/action.rb +93 -0
  50. data/lib/sidekiq/web/application.rb +463 -0
  51. data/lib/sidekiq/web/csrf_protection.rb +180 -0
  52. data/lib/sidekiq/web/helpers.rb +364 -0
  53. data/lib/sidekiq/web/router.rb +104 -0
  54. data/lib/sidekiq/web.rb +113 -216
  55. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  56. data/lib/sidekiq.rb +99 -142
  57. data/sidekiq.gemspec +26 -23
  58. data/web/assets/images/apple-touch-icon.png +0 -0
  59. data/web/assets/javascripts/application.js +163 -74
  60. data/web/assets/javascripts/base-charts.js +106 -0
  61. data/web/assets/javascripts/chart.min.js +13 -0
  62. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  63. data/web/assets/javascripts/dashboard-charts.js +182 -0
  64. data/web/assets/javascripts/dashboard.js +37 -280
  65. data/web/assets/javascripts/metrics.js +298 -0
  66. data/web/assets/stylesheets/application-dark.css +147 -0
  67. data/web/assets/stylesheets/application-rtl.css +153 -0
  68. data/web/assets/stylesheets/application.css +181 -198
  69. data/web/assets/stylesheets/bootstrap-rtl.min.css +9 -0
  70. data/web/assets/stylesheets/bootstrap.css +4 -8
  71. data/web/locales/ar.yml +87 -0
  72. data/web/locales/cs.yml +62 -52
  73. data/web/locales/da.yml +60 -53
  74. data/web/locales/de.yml +65 -53
  75. data/web/locales/el.yml +43 -24
  76. data/web/locales/en.yml +86 -62
  77. data/web/locales/es.yml +70 -53
  78. data/web/locales/fa.yml +80 -0
  79. data/web/locales/fr.yml +86 -56
  80. data/web/locales/gd.yml +99 -0
  81. data/web/locales/he.yml +80 -0
  82. data/web/locales/hi.yml +59 -59
  83. data/web/locales/it.yml +53 -53
  84. data/web/locales/ja.yml +78 -56
  85. data/web/locales/ko.yml +52 -52
  86. data/web/locales/lt.yml +83 -0
  87. data/web/locales/nb.yml +61 -61
  88. data/web/locales/nl.yml +52 -52
  89. data/web/locales/pl.yml +45 -45
  90. data/web/locales/pt-br.yml +83 -55
  91. data/web/locales/pt.yml +51 -51
  92. data/web/locales/ru.yml +68 -60
  93. data/web/locales/sv.yml +53 -53
  94. data/web/locales/ta.yml +60 -60
  95. data/web/locales/uk.yml +62 -61
  96. data/web/locales/ur.yml +80 -0
  97. data/web/locales/vi.yml +83 -0
  98. data/web/locales/zh-cn.yml +43 -16
  99. data/web/locales/zh-tw.yml +42 -8
  100. data/web/views/_footer.erb +10 -9
  101. data/web/views/_job_info.erb +26 -5
  102. data/web/views/_metrics_period_select.erb +12 -0
  103. data/web/views/_nav.erb +6 -20
  104. data/web/views/_paging.erb +3 -1
  105. data/web/views/_poll_link.erb +3 -6
  106. data/web/views/_summary.erb +7 -7
  107. data/web/views/busy.erb +87 -28
  108. data/web/views/dashboard.erb +51 -21
  109. data/web/views/dead.erb +4 -4
  110. data/web/views/filtering.erb +7 -0
  111. data/web/views/layout.erb +15 -5
  112. data/web/views/metrics.erb +91 -0
  113. data/web/views/metrics_for_job.erb +59 -0
  114. data/web/views/morgue.erb +25 -22
  115. data/web/views/queue.erb +35 -25
  116. data/web/views/queues.erb +23 -7
  117. data/web/views/retries.erb +28 -23
  118. data/web/views/retry.erb +5 -5
  119. data/web/views/scheduled.erb +19 -17
  120. data/web/views/scheduled_job_info.erb +1 -1
  121. metadata +86 -268
  122. data/.gitignore +0 -12
  123. data/.travis.yml +0 -16
  124. data/3.0-Upgrade.md +0 -70
  125. data/COMM-LICENSE +0 -95
  126. data/Contributing.md +0 -32
  127. data/Ent-Changes.md +0 -39
  128. data/Gemfile +0 -27
  129. data/LICENSE +0 -9
  130. data/Pro-2.0-Upgrade.md +0 -138
  131. data/Pro-Changes.md +0 -454
  132. data/Rakefile +0 -9
  133. data/bin/sidekiqctl +0 -93
  134. data/lib/generators/sidekiq/templates/worker_spec.rb.erb +0 -6
  135. data/lib/generators/sidekiq/templates/worker_test.rb.erb +0 -8
  136. data/lib/generators/sidekiq/worker_generator.rb +0 -49
  137. data/lib/sidekiq/actor.rb +0 -39
  138. data/lib/sidekiq/core_ext.rb +0 -105
  139. data/lib/sidekiq/exception_handler.rb +0 -30
  140. data/lib/sidekiq/extensions/action_mailer.rb +0 -56
  141. data/lib/sidekiq/extensions/active_record.rb +0 -39
  142. data/lib/sidekiq/extensions/class_methods.rb +0 -39
  143. data/lib/sidekiq/extensions/generic_proxy.rb +0 -24
  144. data/lib/sidekiq/logging.rb +0 -104
  145. data/lib/sidekiq/middleware/server/active_record.rb +0 -13
  146. data/lib/sidekiq/middleware/server/logging.rb +0 -40
  147. data/lib/sidekiq/middleware/server/retry_jobs.rb +0 -206
  148. data/lib/sidekiq/util.rb +0 -68
  149. data/lib/sidekiq/web_helpers.rb +0 -249
  150. data/lib/sidekiq/worker.rb +0 -103
  151. data/test/config.yml +0 -9
  152. data/test/env_based_config.yml +0 -11
  153. data/test/fake_env.rb +0 -0
  154. data/test/fixtures/en.yml +0 -2
  155. data/test/helper.rb +0 -49
  156. data/test/test_api.rb +0 -493
  157. data/test/test_cli.rb +0 -335
  158. data/test/test_client.rb +0 -194
  159. data/test/test_exception_handler.rb +0 -55
  160. data/test/test_extensions.rb +0 -126
  161. data/test/test_fetch.rb +0 -104
  162. data/test/test_logging.rb +0 -34
  163. data/test/test_manager.rb +0 -168
  164. data/test/test_middleware.rb +0 -159
  165. data/test/test_processor.rb +0 -237
  166. data/test/test_rails.rb +0 -21
  167. data/test/test_redis_connection.rb +0 -126
  168. data/test/test_retry.rb +0 -325
  169. data/test/test_scheduled.rb +0 -114
  170. data/test/test_scheduling.rb +0 -49
  171. data/test/test_sidekiq.rb +0 -99
  172. data/test/test_testing.rb +0 -142
  173. data/test/test_testing_fake.rb +0 -268
  174. data/test/test_testing_inline.rb +0 -93
  175. data/test/test_util.rb +0 -16
  176. data/test/test_web.rb +0 -608
  177. data/test/test_web_helpers.rb +0 -53
  178. data/web/assets/images/bootstrap/glyphicons-halflings-white.png +0 -0
  179. data/web/assets/images/bootstrap/glyphicons-halflings.png +0 -0
  180. data/web/assets/images/status/active.png +0 -0
  181. data/web/assets/images/status/idle.png +0 -0
  182. data/web/assets/javascripts/locales/README.md +0 -27
  183. data/web/assets/javascripts/locales/jquery.timeago.ar.js +0 -96
  184. data/web/assets/javascripts/locales/jquery.timeago.bg.js +0 -18
  185. data/web/assets/javascripts/locales/jquery.timeago.bs.js +0 -49
  186. data/web/assets/javascripts/locales/jquery.timeago.ca.js +0 -18
  187. data/web/assets/javascripts/locales/jquery.timeago.cs.js +0 -18
  188. data/web/assets/javascripts/locales/jquery.timeago.cy.js +0 -20
  189. data/web/assets/javascripts/locales/jquery.timeago.da.js +0 -18
  190. data/web/assets/javascripts/locales/jquery.timeago.de.js +0 -18
  191. data/web/assets/javascripts/locales/jquery.timeago.el.js +0 -18
  192. data/web/assets/javascripts/locales/jquery.timeago.en-short.js +0 -20
  193. data/web/assets/javascripts/locales/jquery.timeago.en.js +0 -20
  194. data/web/assets/javascripts/locales/jquery.timeago.es.js +0 -18
  195. data/web/assets/javascripts/locales/jquery.timeago.et.js +0 -18
  196. data/web/assets/javascripts/locales/jquery.timeago.fa.js +0 -22
  197. data/web/assets/javascripts/locales/jquery.timeago.fi.js +0 -28
  198. data/web/assets/javascripts/locales/jquery.timeago.fr-short.js +0 -16
  199. data/web/assets/javascripts/locales/jquery.timeago.fr.js +0 -17
  200. data/web/assets/javascripts/locales/jquery.timeago.he.js +0 -18
  201. data/web/assets/javascripts/locales/jquery.timeago.hr.js +0 -49
  202. data/web/assets/javascripts/locales/jquery.timeago.hu.js +0 -18
  203. data/web/assets/javascripts/locales/jquery.timeago.hy.js +0 -18
  204. data/web/assets/javascripts/locales/jquery.timeago.id.js +0 -18
  205. data/web/assets/javascripts/locales/jquery.timeago.it.js +0 -16
  206. data/web/assets/javascripts/locales/jquery.timeago.ja.js +0 -19
  207. data/web/assets/javascripts/locales/jquery.timeago.ko.js +0 -17
  208. data/web/assets/javascripts/locales/jquery.timeago.lt.js +0 -20
  209. data/web/assets/javascripts/locales/jquery.timeago.mk.js +0 -20
  210. data/web/assets/javascripts/locales/jquery.timeago.nl.js +0 -20
  211. data/web/assets/javascripts/locales/jquery.timeago.no.js +0 -18
  212. data/web/assets/javascripts/locales/jquery.timeago.pl.js +0 -31
  213. data/web/assets/javascripts/locales/jquery.timeago.pt-br.js +0 -16
  214. data/web/assets/javascripts/locales/jquery.timeago.pt.js +0 -16
  215. data/web/assets/javascripts/locales/jquery.timeago.ro.js +0 -18
  216. data/web/assets/javascripts/locales/jquery.timeago.rs.js +0 -49
  217. data/web/assets/javascripts/locales/jquery.timeago.ru.js +0 -34
  218. data/web/assets/javascripts/locales/jquery.timeago.sk.js +0 -18
  219. data/web/assets/javascripts/locales/jquery.timeago.sl.js +0 -44
  220. data/web/assets/javascripts/locales/jquery.timeago.sv.js +0 -18
  221. data/web/assets/javascripts/locales/jquery.timeago.th.js +0 -20
  222. data/web/assets/javascripts/locales/jquery.timeago.tr.js +0 -16
  223. data/web/assets/javascripts/locales/jquery.timeago.uk.js +0 -34
  224. data/web/assets/javascripts/locales/jquery.timeago.uz.js +0 -19
  225. data/web/assets/javascripts/locales/jquery.timeago.zh-cn.js +0 -20
  226. data/web/assets/javascripts/locales/jquery.timeago.zh-tw.js +0 -20
  227. data/web/views/_poll_js.erb +0 -5
  228. /data/web/assets/images/{status-sd8051fd480.png → status.png} +0 -0
data/test/test_api.rb DELETED
@@ -1,493 +0,0 @@
1
- require_relative 'helper'
2
-
3
- class TestApi < Sidekiq::Test
4
-
5
- describe "stats" do
6
-
7
- it "is initially zero" do
8
- Sidekiq.redis {|c| c.flushdb }
9
- s = Sidekiq::Stats.new
10
- assert_equal 0, s.processed
11
- assert_equal 0, s.failed
12
- assert_equal 0, s.enqueued
13
- end
14
-
15
- describe "processed" do
16
- it "returns number of processed jobs" do
17
- Sidekiq.redis { |conn| conn.set("stat:processed", 5) }
18
- s = Sidekiq::Stats.new
19
- assert_equal 5, s.processed
20
- end
21
- end
22
-
23
- describe "failed" do
24
- it "returns number of failed jobs" do
25
- Sidekiq.redis { |conn| conn.set("stat:failed", 5) }
26
- s = Sidekiq::Stats.new
27
- assert_equal 5, s.failed
28
- end
29
- end
30
-
31
- describe "reset" do
32
- before do
33
- Sidekiq.redis do |conn|
34
- conn.set('stat:processed', 5)
35
- conn.set('stat:failed', 10)
36
- end
37
- end
38
-
39
- it 'will reset all stats by default' do
40
- Sidekiq::Stats.new.reset
41
- s = Sidekiq::Stats.new
42
- assert_equal 0, s.failed
43
- assert_equal 0, s.processed
44
- end
45
-
46
- it 'can reset individual stats' do
47
- Sidekiq::Stats.new.reset('failed')
48
- s = Sidekiq::Stats.new
49
- assert_equal 0, s.failed
50
- assert_equal 5, s.processed
51
- end
52
-
53
- it 'can accept anything that responds to #to_s' do
54
- Sidekiq::Stats.new.reset(:failed)
55
- s = Sidekiq::Stats.new
56
- assert_equal 0, s.failed
57
- assert_equal 5, s.processed
58
- end
59
-
60
- it 'ignores anything other than "failed" or "processed"' do
61
- Sidekiq::Stats.new.reset((1..10).to_a, ['failed'])
62
- s = Sidekiq::Stats.new
63
- assert_equal 0, s.failed
64
- assert_equal 5, s.processed
65
- end
66
- end
67
-
68
- describe "queues" do
69
- before do
70
- Sidekiq.redis {|c| c.flushdb }
71
- end
72
-
73
- it "is initially empty" do
74
- s = Sidekiq::Stats::Queues.new
75
- assert_equal 0, s.lengths.size
76
- end
77
-
78
- it "returns a hash of queue and size in order" do
79
- Sidekiq.redis do |conn|
80
- conn.rpush 'queue:foo', '{}'
81
- conn.sadd 'queues', 'foo'
82
-
83
- 3.times { conn.rpush 'queue:bar', '{}' }
84
- conn.sadd 'queues', 'bar'
85
- end
86
-
87
- s = Sidekiq::Stats::Queues.new
88
- assert_equal ({ "foo" => 1, "bar" => 3 }), s.lengths
89
- assert_equal "bar", s.lengths.first.first
90
-
91
- assert_equal Sidekiq::Stats.new.queues, Sidekiq::Stats::Queues.new.lengths
92
- end
93
- end
94
-
95
- describe "enqueued" do
96
- it "returns total enqueued jobs" do
97
- Sidekiq.redis do |conn|
98
- conn.flushdb
99
- conn.rpush 'queue:foo', '{}'
100
- conn.sadd 'queues', 'foo'
101
-
102
- 3.times { conn.rpush 'queue:bar', '{}' }
103
- conn.sadd 'queues', 'bar'
104
- end
105
-
106
- s = Sidekiq::Stats.new
107
- assert_equal 4, s.enqueued
108
- end
109
- end
110
-
111
- describe "over time" do
112
- before do
113
- @before = DateTime::DATE_FORMATS[:default]
114
- DateTime::DATE_FORMATS[:default] = "%d/%m/%Y %H:%M:%S"
115
- end
116
-
117
- after do
118
- DateTime::DATE_FORMATS[:default] = @before
119
- end
120
-
121
- describe "processed" do
122
- it 'retrieves hash of dates' do
123
- Sidekiq.redis do |c|
124
- c.incrby("stat:processed:2012-12-24", 4)
125
- c.incrby("stat:processed:2012-12-25", 1)
126
- c.incrby("stat:processed:2012-12-26", 6)
127
- c.incrby("stat:processed:2012-12-27", 2)
128
- end
129
- Time.stub(:now, Time.parse("2012-12-26 1:00:00 -0500")) do
130
- s = Sidekiq::Stats::History.new(2)
131
- assert_equal({ "2012-12-26" => 6, "2012-12-25" => 1 }, s.processed)
132
-
133
- s = Sidekiq::Stats::History.new(3)
134
- assert_equal({ "2012-12-26" => 6, "2012-12-25" => 1, "2012-12-24" => 4 }, s.processed)
135
-
136
- s = Sidekiq::Stats::History.new(2, Date.parse("2012-12-25"))
137
- assert_equal({ "2012-12-25" => 1, "2012-12-24" => 4 }, s.processed)
138
- end
139
- end
140
- end
141
-
142
- describe "failed" do
143
- it 'retrieves hash of dates' do
144
- Sidekiq.redis do |c|
145
- c.incrby("stat:failed:2012-12-24", 4)
146
- c.incrby("stat:failed:2012-12-25", 1)
147
- c.incrby("stat:failed:2012-12-26", 6)
148
- c.incrby("stat:failed:2012-12-27", 2)
149
- end
150
- Time.stub(:now, Time.parse("2012-12-26 1:00:00 -0500")) do
151
- s = Sidekiq::Stats::History.new(2)
152
- assert_equal ({ "2012-12-26" => 6, "2012-12-25" => 1 }), s.failed
153
-
154
- s = Sidekiq::Stats::History.new(3)
155
- assert_equal ({ "2012-12-26" => 6, "2012-12-25" => 1, "2012-12-24" => 4 }), s.failed
156
-
157
- s = Sidekiq::Stats::History.new(2, Date.parse("2012-12-25"))
158
- assert_equal ({ "2012-12-25" => 1, "2012-12-24" => 4 }), s.failed
159
- end
160
- end
161
- end
162
- end
163
- end
164
-
165
- describe 'with an empty database' do
166
- before do
167
- Sidekiq.redis {|c| c.flushdb }
168
- end
169
-
170
- it 'shows queue as empty' do
171
- q = Sidekiq::Queue.new
172
- assert_equal 0, q.size
173
- assert_equal 0, q.latency
174
- end
175
-
176
- class ApiWorker
177
- include Sidekiq::Worker
178
- end
179
-
180
- it 'can enumerate jobs' do
181
- q = Sidekiq::Queue.new
182
- Time.stub(:now, Time.new(2012, 12, 26)) do
183
- ApiWorker.perform_async(1, 'mike')
184
- assert_equal ['TestApi::ApiWorker'], q.map(&:klass)
185
-
186
- job = q.first
187
- assert_equal 24, job.jid.size
188
- assert_equal [1, 'mike'], job.args
189
- assert_equal Time.new(2012, 12, 26), job.enqueued_at
190
- end
191
-
192
- assert q.latency > 10_000_000
193
-
194
- q = Sidekiq::Queue.new('other')
195
- assert_equal 0, q.size
196
- end
197
-
198
- it 'has no enqueued_at time for jobs enqueued in the future' do
199
- job_id = ApiWorker.perform_in(100, 1, 'foo')
200
- job = Sidekiq::ScheduledSet.new.find_job(job_id)
201
- assert_nil job.enqueued_at
202
- end
203
-
204
- it 'unwraps delayed jobs' do
205
- Sidekiq::Queue.delay.foo(1,2,3)
206
- q = Sidekiq::Queue.new
207
- x = q.first
208
- assert_equal "Sidekiq::Queue.foo", x.display_class
209
- assert_equal [1,2,3], x.display_args
210
- end
211
-
212
- it 'can delete jobs' do
213
- q = Sidekiq::Queue.new
214
- ApiWorker.perform_async(1, 'mike')
215
- assert_equal 1, q.size
216
-
217
- x = q.first
218
- assert_equal "TestApi::ApiWorker", x.display_class
219
- assert_equal [1,'mike'], x.display_args
220
-
221
- assert_equal [true], q.map(&:delete)
222
- assert_equal 0, q.size
223
- end
224
-
225
- it "can move scheduled job to queue" do
226
- remain_id = ApiWorker.perform_in(100, 1, 'jason')
227
- job_id = ApiWorker.perform_in(100, 1, 'jason')
228
- job = Sidekiq::ScheduledSet.new.find_job(job_id)
229
- q = Sidekiq::Queue.new
230
- job.add_to_queue
231
- queued_job = q.find_job(job_id)
232
- refute_nil queued_job
233
- assert_equal queued_job.jid, job_id
234
- assert_nil Sidekiq::ScheduledSet.new.find_job(job_id)
235
- refute_nil Sidekiq::ScheduledSet.new.find_job(remain_id)
236
- end
237
-
238
- it "handles multiple scheduled jobs when moving to queue" do
239
- jids = Sidekiq::Client.push_bulk('class' => ApiWorker,
240
- 'args' => [[1, 'jason'], [2, 'jason']],
241
- 'at' => Time.now.to_f)
242
- assert_equal 2, jids.size
243
- (remain_id, job_id) = jids
244
- job = Sidekiq::ScheduledSet.new.find_job(job_id)
245
- q = Sidekiq::Queue.new
246
- job.add_to_queue
247
- queued_job = q.find_job(job_id)
248
- refute_nil queued_job
249
- assert_equal queued_job.jid, job_id
250
- assert_nil Sidekiq::ScheduledSet.new.find_job(job_id)
251
- refute_nil Sidekiq::ScheduledSet.new.find_job(remain_id)
252
- end
253
-
254
- it 'can find job by id in sorted sets' do
255
- job_id = ApiWorker.perform_in(100, 1, 'jason')
256
- job = Sidekiq::ScheduledSet.new.find_job(job_id)
257
- refute_nil job
258
- assert_equal job_id, job.jid
259
- assert_in_delta job.latency, 0.0, 0.1
260
- end
261
-
262
- it 'can remove jobs when iterating over a sorted set' do
263
- # scheduled jobs must be greater than SortedSet#each underlying page size
264
- 51.times do
265
- ApiWorker.perform_in(100, 'aaron')
266
- end
267
- set = Sidekiq::ScheduledSet.new
268
- set.map(&:delete)
269
- assert_equal set.size, 0
270
- end
271
-
272
- it 'can remove jobs when iterating over a queue' do
273
- # initial queue size must be greater than Queue#each underlying page size
274
- 51.times do
275
- ApiWorker.perform_async(1, 'aaron')
276
- end
277
- q = Sidekiq::Queue.new
278
- q.map(&:delete)
279
- assert_equal q.size, 0
280
- end
281
-
282
- it 'can find job by id in queues' do
283
- q = Sidekiq::Queue.new
284
- job_id = ApiWorker.perform_async(1, 'jason')
285
- job = q.find_job(job_id)
286
- refute_nil job
287
- assert_equal job_id, job.jid
288
- end
289
-
290
- it 'can clear a queue' do
291
- q = Sidekiq::Queue.new
292
- 2.times { ApiWorker.perform_async(1, 'mike') }
293
- q.clear
294
-
295
- Sidekiq.redis do |conn|
296
- refute conn.smembers('queues').include?('foo')
297
- refute conn.exists('queue:foo')
298
- end
299
- end
300
-
301
- it 'can fetch by score' do
302
- same_time = Time.now.to_f
303
- add_retry('bob1', same_time)
304
- add_retry('bob2', same_time)
305
- r = Sidekiq::RetrySet.new
306
- assert_equal 2, r.fetch(same_time).size
307
- end
308
-
309
- it 'can fetch by score and jid' do
310
- same_time = Time.now.to_f
311
- add_retry('bob1', same_time)
312
- add_retry('bob2', same_time)
313
- r = Sidekiq::RetrySet.new
314
- assert_equal 1, r.fetch(same_time, 'bob1').size
315
- end
316
-
317
- it 'shows empty retries' do
318
- r = Sidekiq::RetrySet.new
319
- assert_equal 0, r.size
320
- end
321
-
322
- it 'can enumerate retries' do
323
- add_retry
324
-
325
- r = Sidekiq::RetrySet.new
326
- assert_equal 1, r.size
327
- array = r.to_a
328
- assert_equal 1, array.size
329
-
330
- retri = array.first
331
- assert_equal 'ApiWorker', retri.klass
332
- assert_equal 'default', retri.queue
333
- assert_equal 'bob', retri.jid
334
- assert_in_delta Time.now.to_f, retri.at.to_f, 0.02
335
- end
336
-
337
- it 'requires a jid to delete an entry' do
338
- start_time = Time.now.to_f
339
- add_retry('bob2', Time.now.to_f)
340
- assert_raises(ArgumentError) do
341
- Sidekiq::RetrySet.new.delete(start_time)
342
- end
343
- end
344
-
345
- it 'can delete a single retry from score and jid' do
346
- same_time = Time.now.to_f
347
- add_retry('bob1', same_time)
348
- add_retry('bob2', same_time)
349
- r = Sidekiq::RetrySet.new
350
- assert_equal 2, r.size
351
- Sidekiq::RetrySet.new.delete(same_time, 'bob1')
352
- assert_equal 1, r.size
353
- end
354
-
355
- it 'can retry a retry' do
356
- add_retry
357
- r = Sidekiq::RetrySet.new
358
- assert_equal 1, r.size
359
- r.first.retry
360
- assert_equal 0, r.size
361
- assert_equal 1, Sidekiq::Queue.new('default').size
362
- job = Sidekiq::Queue.new('default').first
363
- assert_equal 'bob', job.jid
364
- assert_equal 1, job['retry_count']
365
- end
366
-
367
- it 'can clear retries' do
368
- add_retry
369
- add_retry('test')
370
- r = Sidekiq::RetrySet.new
371
- assert_equal 2, r.size
372
- r.clear
373
- assert_equal 0, r.size
374
- end
375
-
376
- it 'can enumerate processes' do
377
- identity_string = "identity_string"
378
- odata = {
379
- 'pid' => 123,
380
- 'hostname' => Socket.gethostname,
381
- 'key' => identity_string,
382
- 'identity' => identity_string,
383
- 'started_at' => Time.now.to_f - 15,
384
- }
385
-
386
- time = Time.now.to_f
387
- Sidekiq.redis do |conn|
388
- conn.multi do
389
- conn.sadd('processes', odata['key'])
390
- conn.hmset(odata['key'], 'info', Sidekiq.dump_json(odata), 'busy', 10, 'beat', time)
391
- conn.sadd('processes', 'fake:pid')
392
- end
393
- end
394
-
395
- ps = Sidekiq::ProcessSet.new.to_a
396
- assert_equal 1, ps.size
397
- data = ps.first
398
- assert_equal 10, data['busy']
399
- assert_equal time, data['beat']
400
- assert_equal 123, data['pid']
401
- data.quiet!
402
- data.stop!
403
- signals_string = "#{odata['key']}-signals"
404
- assert_equal "TERM", Sidekiq.redis{|c| c.lpop(signals_string) }
405
- assert_equal "USR1", Sidekiq.redis{|c| c.lpop(signals_string) }
406
- end
407
-
408
- it 'can enumerate workers' do
409
- w = Sidekiq::Workers.new
410
- assert_equal 0, w.size
411
- w.each do
412
- assert false
413
- end
414
-
415
- hn = Socket.gethostname
416
- key = "#{hn}:#{$$}"
417
- pdata = { 'pid' => $$, 'hostname' => hn, 'started_at' => Time.now.to_i }
418
- Sidekiq.redis do |conn|
419
- conn.sadd('processes', key)
420
- conn.hmset(key, 'info', Sidekiq.dump_json(pdata), 'busy', 0, 'beat', Time.now.to_f)
421
- end
422
-
423
- s = "#{key}:workers"
424
- data = Sidekiq.dump_json({ 'payload' => {}, 'queue' => 'default', 'run_at' => Time.now.to_i })
425
- Sidekiq.redis do |c|
426
- c.hmset(s, '1234', data)
427
- end
428
-
429
- w.each do |p, x, y|
430
- assert_equal key, p
431
- assert_equal "1234", x
432
- assert_equal 'default', y['queue']
433
- assert_equal Time.now.year, Time.at(y['run_at']).year
434
- end
435
-
436
- s = "#{key}:workers"
437
- data = Sidekiq.dump_json({ 'payload' => {}, 'queue' => 'default', 'run_at' => (Time.now.to_i - 2*60*60) })
438
- Sidekiq.redis do |c|
439
- c.multi do
440
- c.hmset(s, '5678', data)
441
- c.hmset("b#{s}", '5678', data)
442
- end
443
- end
444
-
445
- assert_equal ['1234', '5678'], w.map { |_, tid, _| tid }
446
- end
447
-
448
- it 'can reschedule jobs' do
449
- add_retry('foo1')
450
- add_retry('foo2')
451
-
452
- retries = Sidekiq::RetrySet.new
453
- assert_equal 2, retries.size
454
- refute(retries.map { |r| r.score > (Time.now.to_f + 9) }.any?)
455
-
456
- retries.each do |retri|
457
- retri.reschedule(Time.now.to_f + 10) if retri.jid == 'foo2'
458
- end
459
-
460
- assert_equal 2, retries.size
461
- assert(retries.map { |r| r.score > (Time.now.to_f + 9) }.any?)
462
- end
463
-
464
- it 'prunes processes which have died' do
465
- data = { 'pid' => rand(10_000), 'hostname' => "app#{rand(1_000)}", 'started_at' => Time.now.to_f }
466
- key = "#{data['hostname']}:#{data['pid']}"
467
- Sidekiq.redis do |conn|
468
- conn.sadd('processes', key)
469
- conn.hmset(key, 'info', Sidekiq.dump_json(data), 'busy', 0, 'beat', Time.now.to_f)
470
- end
471
-
472
- ps = Sidekiq::ProcessSet.new
473
- assert_equal 1, ps.size
474
- assert_equal 1, ps.to_a.size
475
-
476
- Sidekiq.redis do |conn|
477
- conn.sadd('processes', "bar:987")
478
- conn.sadd('processes', "bar:986")
479
- end
480
-
481
- ps = Sidekiq::ProcessSet.new
482
- assert_equal 1, ps.size
483
- assert_equal 1, ps.to_a.size
484
- end
485
-
486
- def add_retry(jid = 'bob', at = Time.now.to_f)
487
- payload = Sidekiq.dump_json('class' => 'ApiWorker', 'args' => [1, 'mike'], 'queue' => 'default', 'jid' => jid, 'retry_count' => 2, 'failed_at' => Time.now.to_f)
488
- Sidekiq.redis do |conn|
489
- conn.zadd('retry', at.to_s, payload)
490
- end
491
- end
492
- end
493
- end