sidekiq-throttled 0.18.0 → 1.0.0.alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/{README.md → README.adoc} +95 -114
- data/lib/sidekiq/throttled/basic_fetch.rb +55 -0
- data/lib/sidekiq/throttled/fetch.rb +3 -87
- data/lib/sidekiq/throttled/job.rb +1 -1
- data/lib/sidekiq/throttled/middleware.rb +3 -1
- data/lib/sidekiq/throttled/registry.rb +2 -5
- data/lib/sidekiq/throttled/strategy/concurrency.rb +2 -4
- data/lib/sidekiq/throttled/strategy/threshold.rb +2 -4
- data/lib/sidekiq/throttled/strategy.rb +10 -10
- data/lib/sidekiq/throttled/strategy_collection.rb +1 -1
- data/lib/sidekiq/throttled/version.rb +1 -1
- data/lib/sidekiq/throttled/web.rb +2 -45
- data/lib/sidekiq/throttled/worker.rb +1 -1
- data/lib/sidekiq/throttled.rb +16 -50
- metadata +17 -77
- data/.coveralls.yml +0 -1
- data/.github/dependabot.yml +0 -12
- data/.github/workflows/ci.yml +0 -52
- data/.gitignore +0 -12
- data/.rspec +0 -5
- data/.rubocop.yml +0 -20
- data/.rubocop_todo.yml +0 -68
- data/.travis.yml +0 -37
- data/.yardopts +0 -1
- data/Appraisals +0 -9
- data/CHANGES.md +0 -318
- data/Gemfile +0 -34
- data/Guardfile +0 -25
- data/Rakefile +0 -27
- data/gemfiles/sidekiq_6.4.gemfile +0 -33
- data/gemfiles/sidekiq_6.5.gemfile +0 -33
- data/lib/sidekiq/throttled/communicator/callbacks.rb +0 -72
- data/lib/sidekiq/throttled/communicator/exception_handler.rb +0 -25
- data/lib/sidekiq/throttled/communicator/listener.rb +0 -109
- data/lib/sidekiq/throttled/communicator.rb +0 -116
- data/lib/sidekiq/throttled/expirable_list.rb +0 -70
- data/lib/sidekiq/throttled/fetch/unit_of_work.rb +0 -83
- data/lib/sidekiq/throttled/patches/queue.rb +0 -18
- data/lib/sidekiq/throttled/queue_name.rb +0 -46
- data/lib/sidekiq/throttled/queues_pauser.rb +0 -152
- data/lib/sidekiq/throttled/testing.rb +0 -12
- data/lib/sidekiq/throttled/utils.rb +0 -19
- data/lib/sidekiq/throttled/web/queues.html.erb +0 -49
- data/lib/sidekiq/throttled/web/summary_fix.js +0 -10
- data/lib/sidekiq/throttled/web/summary_fix.rb +0 -35
- data/rubocop/layout.yml +0 -24
- data/rubocop/lint.yml +0 -41
- data/rubocop/metrics.yml +0 -4
- data/rubocop/performance.yml +0 -25
- data/rubocop/rspec.yml +0 -3
- data/rubocop/style.yml +0 -84
- data/sidekiq-throttled.gemspec +0 -36
- /data/{LICENSE.md → LICENSE} +0 -0
data/CHANGES.md
DELETED
@@ -1,318 +0,0 @@
|
|
1
|
-
## 0.18.0 (2023-04-10)
|
2
|
-
|
3
|
-
* Fix redis-prescription dependency usage
|
4
|
-
|
5
|
-
## 0.17.0 (2022-09-14)
|
6
|
-
|
7
|
-
* [#13](https://github.com/ixti/sidekiq-throttled/pull/13)
|
8
|
-
Fix redis-4.8+ deprecation warnings
|
9
|
-
|
10
|
-
* [#8](https://github.com/ixti/sidekiq-throttled/pull/8)
|
11
|
-
Drop Sidekiq < 6.4 support
|
12
|
-
|
13
|
-
## 0.16.2 (2022-07-19)
|
14
|
-
|
15
|
-
* [#5](https://github.com/ixti/sidekiq-throttled/issues/5)
|
16
|
-
[#6](https://github.com/ixti/sidekiq-throttled/pull/6)
|
17
|
-
Add Sidekiq 6.5+ support
|
18
|
-
|
19
|
-
## 0.16.1 (2022-06-14)
|
20
|
-
|
21
|
-
* [#2](https://github.com/ixti/sidekiq-throttled/pull/2)
|
22
|
-
Support custom ActiveJob adapters.
|
23
|
-
([@longkt90])
|
24
|
-
|
25
|
-
* [#107](https://github.com/sensortower/sidekiq-throttled/pull/107)
|
26
|
-
Log error when key sufix extraction fails.
|
27
|
-
([@pjungwir])
|
28
|
-
|
29
|
-
## 0.16.0 (2022-06-13)
|
30
|
-
|
31
|
-
* Drop Ruby 2.6 support.
|
32
|
-
|
33
|
-
* Drop Sidekiq 5.X support.
|
34
|
-
|
35
|
-
* [#121](https://github.com/sensortower/sidekiq-throttled/pull/121)
|
36
|
-
Sidekiq 6.5 compatibility.
|
37
|
-
([@hieuk09])
|
38
|
-
|
39
|
-
* [#116](https://github.com/sensortower/sidekiq-throttled/pull/116)
|
40
|
-
Unwrap ActiveJob JobWrapper
|
41
|
-
([@holstvoogd])
|
42
|
-
|
43
|
-
* [#115](https://github.com/sensortower/sidekiq-throttled/pull/115)
|
44
|
-
Fix Redis 4.6 deprecation warnings.
|
45
|
-
([@dbackeus])
|
46
|
-
|
47
|
-
* [#113](https://github.com/sensortower/sidekiq-throttled/pull/113)
|
48
|
-
Add Ruby 3.1 to CI.
|
49
|
-
([@petergoldstein])
|
50
|
-
|
51
|
-
* [#103](https://github.com/sensortower/sidekiq-throttled/pull/103)
|
52
|
-
Rename Sidekiq::Throttled::Worker to Sidekiq::Throttled::Job, and alias it
|
53
|
-
as Sidekiq::Throttled::Worker.
|
54
|
-
([@CHTJonas])
|
55
|
-
|
56
|
-
## 0.15.0 (2021-12-16)
|
57
|
-
|
58
|
-
* [#102](https://github.com/sensortower/sidekiq-throttled/pull/102)
|
59
|
-
Support Ruby 3.0 and Sidekiq 6.2+.
|
60
|
-
([@ybiquitous])
|
61
|
-
|
62
|
-
* [#97](https://github.com/sensortower/sidekiq-throttled/pull/97)
|
63
|
-
Fix kwargs usage in strategy collection.
|
64
|
-
([@baptistejub])
|
65
|
-
|
66
|
-
## 0.14.0 (2021-09-21)
|
67
|
-
|
68
|
-
* [#98](https://github.com/sensortower/sidekiq-throttled/pull/98)
|
69
|
-
Remove warning for strategy override.
|
70
|
-
([@mattiagiuffrida-st])
|
71
|
-
|
72
|
-
* [#65](https://github.com/sensortower/sidekiq-throttled/pull/65)
|
73
|
-
Support composite (multi-key) strategies.
|
74
|
-
([@holyketzer])
|
75
|
-
|
76
|
-
* [#89](https://github.com/sensortower/sidekiq-throttled/pull/89),
|
77
|
-
[#96](https://github.com/sensortower/sidekiq-throttled/pull/96), and
|
78
|
-
[#93](https://github.com/sensortower/sidekiq-throttled/pull/93)
|
79
|
-
Improve documentation.
|
80
|
-
([@hubertjakubiak], [@khaile], and [@kylerippey])
|
81
|
-
|
82
|
-
## 0.13.0 (2020-07-28)
|
83
|
-
|
84
|
-
* [#85](https://github.com/sensortower/sidekiq-throttled/pull/85)
|
85
|
-
Add Sidekiq 6.1+ support.
|
86
|
-
([@hmaack])
|
87
|
-
|
88
|
-
## 0.12.0 (2020-06-22)
|
89
|
-
|
90
|
-
* [#80](https://github.com/sensortower/sidekiq-throttled/pull/80)
|
91
|
-
Allow override cooldown timeout of queues with throttled jobs.
|
92
|
-
([@vaot])
|
93
|
-
|
94
|
-
* [#76](https://github.com/sensortower/sidekiq-throttled/pull/76)
|
95
|
-
Fix warnings on Ruby 2.7
|
96
|
-
([@lenon])
|
97
|
-
|
98
|
-
|
99
|
-
## 0.11.0 (2019-08-24)
|
100
|
-
|
101
|
-
* [#59](https://github.com/sensortower/sidekiq-throttled/pull/59)
|
102
|
-
Add throttling observer.
|
103
|
-
([@ogins57])
|
104
|
-
|
105
|
-
|
106
|
-
## 0.10.0 (2019-06-22)
|
107
|
-
|
108
|
-
* [#60](https://github.com/sensortower/sidekiq-throttled/pull/60)
|
109
|
-
Skip throttling check in redis if limit is 0.
|
110
|
-
([@mstruve])
|
111
|
-
|
112
|
-
* [#58](https://github.com/sensortower/sidekiq-throttled/pull/58)
|
113
|
-
Improve documentation bout TTL.
|
114
|
-
([@ziaulrehman40])
|
115
|
-
|
116
|
-
* Improve reliability of paused queues, by resyncing list of paused queues
|
117
|
-
on schedule.
|
118
|
-
([@ixti])
|
119
|
-
|
120
|
-
|
121
|
-
## 0.9.0 (2018-09-11)
|
122
|
-
|
123
|
-
* Add support of Sidekiq 5.2.x
|
124
|
-
([@ixti])
|
125
|
-
|
126
|
-
* Drop support of Sidekiq 4.x
|
127
|
-
([@ixti])
|
128
|
-
|
129
|
-
* Add concurrent-ruby as dependency which is no longer a dependency of
|
130
|
-
Sidekiq as 5.2+ version.
|
131
|
-
([@ixti])
|
132
|
-
|
133
|
-
|
134
|
-
## 0.8.2 (2018-02-14)
|
135
|
-
|
136
|
-
* Extract redis LUA scripts stored procedures runner to redis-prescription gem.
|
137
|
-
([@ixti])
|
138
|
-
|
139
|
-
* Switch to Concurrent.monotonic_time to expire elements of ExpirableList.
|
140
|
-
([@ixti])
|
141
|
-
|
142
|
-
|
143
|
-
## 0.8.1 (2017-11-02)
|
144
|
-
|
145
|
-
* Preload job class constant prior trying to get it's throttling strategy.
|
146
|
-
([@ixti])
|
147
|
-
|
148
|
-
|
149
|
-
## 0.8.0 (2017-10-11)
|
150
|
-
|
151
|
-
* Refactor concurrency throttling internals to use sorted sets in order to avoid
|
152
|
-
starvation in case when finalize! was not called (OOM / redis issues).
|
153
|
-
([@ixti])
|
154
|
-
|
155
|
-
|
156
|
-
## 0.7.3 (2017-06-26)
|
157
|
-
|
158
|
-
* [#34](https://github.com/sensortower/sidekiq-throttled/issues/34)
|
159
|
-
Fix reset button for sidekiq `>= 4.2`.
|
160
|
-
([@ixti])
|
161
|
-
|
162
|
-
|
163
|
-
## 0.7.2 (2017-04-02)
|
164
|
-
|
165
|
-
* Fix summary bar fixer on sidekiq 4.2+.
|
166
|
-
([@ixti])
|
167
|
-
|
168
|
-
* Fix regexp used to fix summay bar queues link when ui was enhanced.
|
169
|
-
([@ixti])
|
170
|
-
|
171
|
-
|
172
|
-
## 0.7.1 (2017-03-30)
|
173
|
-
|
174
|
-
* Fix summary bar queues link when queue ui was enhanced.
|
175
|
-
([@ixti])
|
176
|
-
|
177
|
-
* [#31](https://github.com/sensortower/sidekiq-throttled/pull/31)
|
178
|
-
[#30](https://github.com/sensortower/sidekiq-throttled/issues/30)
|
179
|
-
Do not throttle if limit is `nil`.
|
180
|
-
([@ixti])
|
181
|
-
|
182
|
-
|
183
|
-
## 0.7.0 (2017-03-22)
|
184
|
-
|
185
|
-
* Expose pause/resume queues hidden feature to UI. This was available via API
|
186
|
-
since v0.6.0 and today it's finally got it's UI.
|
187
|
-
([@ixti])
|
188
|
-
|
189
|
-
|
190
|
-
## 0.6.7 (2017-03-21)
|
191
|
-
|
192
|
-
* Fix fetcher causing workers starvation upon low concurrency thresholds.
|
193
|
-
([@ixti])
|
194
|
-
|
195
|
-
|
196
|
-
## 0.6.6 (2016-10-16)
|
197
|
-
|
198
|
-
* [#24](https://github.com/sensortower/sidekiq-throttled/pull/24)
|
199
|
-
Fix dynamic `:key_suffix` issue.
|
200
|
-
([@iporsut])
|
201
|
-
|
202
|
-
|
203
|
-
## 0.6.5 (2016-09-04)
|
204
|
-
|
205
|
-
* Fix concurrency throttling when redis-namespace is used.
|
206
|
-
([@ixti])
|
207
|
-
|
208
|
-
|
209
|
-
## 0.6.4 (2016-09-02)
|
210
|
-
|
211
|
-
* Rename UnitOfWork throttled requeue to `#requeue_throttled`.
|
212
|
-
([@ixti])
|
213
|
-
|
214
|
-
|
215
|
-
## 0.6.3 (2016-09-02)
|
216
|
-
|
217
|
-
* Enrich internal API to allow better extensibility.
|
218
|
-
([@ixti])
|
219
|
-
|
220
|
-
|
221
|
-
## 0.6.2 (2016-09-01)
|
222
|
-
|
223
|
-
* Add `Fetch.bulk_requeue` used by Sidekiq upon termination.
|
224
|
-
([@ixti])
|
225
|
-
|
226
|
-
|
227
|
-
## 0.6.1 (2016-08-30)
|
228
|
-
|
229
|
-
* Trivial internal API change: extracted queues list builder of `Fetch` into
|
230
|
-
dedicated internal method, allowing to enhance it with extra custom filters.
|
231
|
-
([@ixti])
|
232
|
-
|
233
|
-
|
234
|
-
## 0.6.0 (2016-08-27)
|
235
|
-
|
236
|
-
* [#21](https://github.com/sensortower/sidekiq-throttled/pull/21)
|
237
|
-
Allow pause/unpause queues.
|
238
|
-
([@ixti])
|
239
|
-
|
240
|
-
|
241
|
-
## 0.5.0 (2016-08-18)
|
242
|
-
|
243
|
-
* Drop Sidekiq 3.x support.
|
244
|
-
([@ixti])
|
245
|
-
|
246
|
-
|
247
|
-
## 0.4.1 (2016-08-18)
|
248
|
-
|
249
|
-
* [#15](https://github.com/sensortower/sidekiq-throttled/pull/15)
|
250
|
-
Fix throttled web UI on older versions of sidekiq.
|
251
|
-
([@palanglung])
|
252
|
-
|
253
|
-
|
254
|
-
## 0.4.0 (2016-05-17)
|
255
|
-
|
256
|
-
* [#14](https://github.com/sensortower/sidekiq-throttled/pull/14)
|
257
|
-
Support dynamic configuration of limits and periods.
|
258
|
-
([@azach], [@ixti])
|
259
|
-
|
260
|
-
|
261
|
-
## 0.3.2 (2016-05-16)
|
262
|
-
|
263
|
-
* [#13](https://github.com/sensortower/sidekiq-throttled/issues/13)
|
264
|
-
Fix throttled BasicFetch with strictly ordered queues on sidekiq 4.
|
265
|
-
([@palanglung], [@ixti])
|
266
|
-
|
267
|
-
|
268
|
-
## 0.3.1 (2016-05-15)
|
269
|
-
|
270
|
-
* Precalculate LUA script digests to reduce bandwidth upon nodes reload
|
271
|
-
_(which might (and might not) happen if you run thousands of nodes)_.
|
272
|
-
([@ixti])
|
273
|
-
|
274
|
-
|
275
|
-
## 0.3.0 (2016-05-02)
|
276
|
-
|
277
|
-
* [#1](https://github.com/sensortower/sidekiq-throttled/issues/1):
|
278
|
-
Add Sidekiq 4.0 support.
|
279
|
-
([@ixti])
|
280
|
-
|
281
|
-
|
282
|
-
## 0.2.0 (2016-02-29)
|
283
|
-
|
284
|
-
* [#6](https://github.com/sensortower/sidekiq-throttled/pull/6):
|
285
|
-
Add dynamic key suffix functionality.
|
286
|
-
([@fhwang])
|
287
|
-
|
288
|
-
|
289
|
-
## 0.1.0 (2015-11-03)
|
290
|
-
|
291
|
-
* Initial release.
|
292
|
-
|
293
|
-
|
294
|
-
[@ixti]: https://github.com/ixti
|
295
|
-
[@fhwang]: https://github.com/fhwang
|
296
|
-
[@palanglung]: https://github.com/palanglung
|
297
|
-
[@azach]: https://github.com/azach
|
298
|
-
[@iporsut]: https://github.com/iporsut
|
299
|
-
[@mstruve]: https://github.com/mstruve
|
300
|
-
[@ziaulrehman40]: https://github.com/ziaulrehman40
|
301
|
-
[@ogins57]: https://github.com/ogins57
|
302
|
-
[@lenon]: https://github.com/lenon
|
303
|
-
[@vaot]: https://github.com/vaot
|
304
|
-
[@hmaack]: https://github.com/hmaack
|
305
|
-
[@holyketzer]: https://github.com/holyketzer
|
306
|
-
[@hubertjakubiak]: https://github.com/hubertjakubiak
|
307
|
-
[@kylerippey]: https://github.com/kylerippey
|
308
|
-
[@khaile]: https://github.com/khaile
|
309
|
-
[@mattiagiuffrida-st]: https://github.com/mattiagiuffrida-st
|
310
|
-
[@baptistejub]: https://github.com/baptistejub
|
311
|
-
[@ybiquitous]: https://github.com/ybiquitous
|
312
|
-
[@hieuk09]: https://github.com/hieuk09
|
313
|
-
[@petergoldstein]: https://github.com/petergoldstein
|
314
|
-
[@dbackeus]: https://github.com/dbackeus
|
315
|
-
[@holstvoogd]: https://github.com/holstvoogd
|
316
|
-
[@CHTJonas]: https://github.com/CHTJonas
|
317
|
-
[@pjungwir]: https://github.com/pjungwir
|
318
|
-
[@longkt90]: https://github.com/longkt90
|
data/Gemfile
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "appraisal"
|
6
|
-
gem "rake"
|
7
|
-
gem "rspec"
|
8
|
-
gem "sidekiq"
|
9
|
-
|
10
|
-
group :development do
|
11
|
-
gem "byebug"
|
12
|
-
gem "guard", :require => false
|
13
|
-
gem "guard-rspec", :require => false
|
14
|
-
gem "guard-rubocop", :require => false
|
15
|
-
end
|
16
|
-
|
17
|
-
group :test do
|
18
|
-
gem "apparition"
|
19
|
-
gem "capybara"
|
20
|
-
gem "puma"
|
21
|
-
gem "rack-test"
|
22
|
-
gem "sinatra"
|
23
|
-
gem "timecop"
|
24
|
-
end
|
25
|
-
|
26
|
-
group :lint do
|
27
|
-
gem "rubocop", :require => false
|
28
|
-
gem "rubocop-performance", :require => false
|
29
|
-
gem "rubocop-rake", :require => false
|
30
|
-
gem "rubocop-rspec", :require => false
|
31
|
-
end
|
32
|
-
|
33
|
-
# Specify your gem's dependencies in sidekiq-throttled.gemspec
|
34
|
-
gemspec
|
data/Guardfile
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
group :red_green_refactor, :halt_on_fail => true do
|
4
|
-
guard :rspec, :cmd => "bundle exec rspec --no-profile" do
|
5
|
-
require "guard/rspec/dsl"
|
6
|
-
dsl = Guard::RSpec::Dsl.new(self)
|
7
|
-
|
8
|
-
# Feel free to open issues for suggestions and improvements
|
9
|
-
|
10
|
-
# RSpec files
|
11
|
-
rspec = dsl.rspec
|
12
|
-
watch(rspec.spec_helper) { rspec.spec_dir }
|
13
|
-
watch(rspec.spec_support) { rspec.spec_dir }
|
14
|
-
watch(rspec.spec_files)
|
15
|
-
|
16
|
-
# Ruby files
|
17
|
-
ruby = dsl.ruby
|
18
|
-
dsl.watch_spec_files_for(ruby.lib_files)
|
19
|
-
end
|
20
|
-
|
21
|
-
guard :rubocop, :all_on_start => false do
|
22
|
-
watch(%r{.+\.rb$})
|
23
|
-
watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
|
24
|
-
end
|
25
|
-
end
|
data/Rakefile
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "bundler/gem_tasks"
|
4
|
-
|
5
|
-
require "rspec/core/rake_task"
|
6
|
-
RSpec::Core::RakeTask.new(:spec)
|
7
|
-
|
8
|
-
desc "Run RuboCop"
|
9
|
-
task :rubocop do
|
10
|
-
require "rubocop"
|
11
|
-
result = RuboCop::CLI.new.run([])
|
12
|
-
abort("RuboCop failed!") if result.nonzero?
|
13
|
-
end
|
14
|
-
|
15
|
-
namespace :rubocop do
|
16
|
-
desc "Auto-correct RuboCop offenses"
|
17
|
-
task :autocorrect do
|
18
|
-
require "rubocop"
|
19
|
-
result = RuboCop::CLI.new.run(["--auto-correct"])
|
20
|
-
abort("RuboCop failed!") if result.nonzero?
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
default_suite = ENV["CI"] ? :spec : %i[spec rubocop]
|
25
|
-
named_suites = { "rubocop" => :rubocop, "rspec" => :spec }
|
26
|
-
|
27
|
-
task :default => named_suites.fetch(ENV.fetch("SUITE", nil), default_suite)
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "appraisal"
|
6
|
-
gem "rake"
|
7
|
-
gem "rspec"
|
8
|
-
gem "sidekiq", "~> 6.4.0"
|
9
|
-
|
10
|
-
group :development do
|
11
|
-
gem "byebug"
|
12
|
-
gem "guard", require: false
|
13
|
-
gem "guard-rspec", require: false
|
14
|
-
gem "guard-rubocop", require: false
|
15
|
-
end
|
16
|
-
|
17
|
-
group :test do
|
18
|
-
gem "apparition"
|
19
|
-
gem "capybara"
|
20
|
-
gem "puma"
|
21
|
-
gem "rack-test"
|
22
|
-
gem "sinatra"
|
23
|
-
gem "timecop"
|
24
|
-
end
|
25
|
-
|
26
|
-
group :lint do
|
27
|
-
gem "rubocop", require: false
|
28
|
-
gem "rubocop-performance", require: false
|
29
|
-
gem "rubocop-rake", require: false
|
30
|
-
gem "rubocop-rspec", require: false
|
31
|
-
end
|
32
|
-
|
33
|
-
gemspec path: "../"
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "appraisal"
|
6
|
-
gem "rake"
|
7
|
-
gem "rspec"
|
8
|
-
gem "sidekiq", "~> 6.5.0"
|
9
|
-
|
10
|
-
group :development do
|
11
|
-
gem "byebug"
|
12
|
-
gem "guard", require: false
|
13
|
-
gem "guard-rspec", require: false
|
14
|
-
gem "guard-rubocop", require: false
|
15
|
-
end
|
16
|
-
|
17
|
-
group :test do
|
18
|
-
gem "apparition"
|
19
|
-
gem "capybara"
|
20
|
-
gem "puma"
|
21
|
-
gem "rack-test"
|
22
|
-
gem "sinatra"
|
23
|
-
gem "timecop"
|
24
|
-
end
|
25
|
-
|
26
|
-
group :lint do
|
27
|
-
gem "rubocop", require: false
|
28
|
-
gem "rubocop-performance", require: false
|
29
|
-
gem "rubocop-rake", require: false
|
30
|
-
gem "rubocop-rspec", require: false
|
31
|
-
end
|
32
|
-
|
33
|
-
gemspec path: "../"
|
@@ -1,72 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "fiber"
|
4
|
-
|
5
|
-
require "sidekiq/throttled/communicator/exception_handler"
|
6
|
-
|
7
|
-
module Sidekiq
|
8
|
-
module Throttled
|
9
|
-
class Communicator
|
10
|
-
# Callbacks registry and runner. Runs registered callbacks in dedicated
|
11
|
-
# Fiber solving issue with ConnectionPool and Redis client in subscriber
|
12
|
-
# mode.
|
13
|
-
#
|
14
|
-
# Once Redis entered subscriber mode `#subscribe` method, it can't be used
|
15
|
-
# for any command but pub/sub or quit, making it impossible to use for
|
16
|
-
# anything else. ConnectionPool binds reserved client to Thread, thus
|
17
|
-
# nested `#with` calls inside same thread result into a same connection.
|
18
|
-
# That makes it impossible to issue any normal Redis commands from
|
19
|
-
# within listener Thread.
|
20
|
-
#
|
21
|
-
# @private
|
22
|
-
class Callbacks
|
23
|
-
include ExceptionHandler
|
24
|
-
|
25
|
-
# Initializes callbacks registry.
|
26
|
-
def initialize
|
27
|
-
@mutex = Mutex.new
|
28
|
-
@handlers = Hash.new { |h, k| h[k] = [] }
|
29
|
-
end
|
30
|
-
|
31
|
-
# Registers handler of given event.
|
32
|
-
#
|
33
|
-
# @example
|
34
|
-
#
|
35
|
-
# callbacks.on "and out comes wolves" do |who|
|
36
|
-
# puts "#{who} let the dogs out?!"
|
37
|
-
# end
|
38
|
-
#
|
39
|
-
# @param [#to_s] event
|
40
|
-
# @raise [ArgumentError] if no handler block given
|
41
|
-
# @yield [*args] Runs given block upon `event`
|
42
|
-
# @yieldreturn [void]
|
43
|
-
# @return [self]
|
44
|
-
def on(event, &handler)
|
45
|
-
raise ArgumentError, "No block given" unless handler
|
46
|
-
|
47
|
-
@mutex.synchronize { @handlers[event.to_s] << handler }
|
48
|
-
self
|
49
|
-
end
|
50
|
-
|
51
|
-
# Runs event handlers with given args.
|
52
|
-
#
|
53
|
-
# @param [#to_s] event
|
54
|
-
# @param [Object] payload
|
55
|
-
# @return [void]
|
56
|
-
def run(event, payload = nil)
|
57
|
-
@mutex.synchronize do
|
58
|
-
fiber = Fiber.new do
|
59
|
-
@handlers[event.to_s].each do |callback|
|
60
|
-
callback.call(payload)
|
61
|
-
rescue => e
|
62
|
-
handle_exception(e, :context => "sidekiq:throttled")
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
fiber.resume
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "sidekiq"
|
4
|
-
require "sidekiq/version"
|
5
|
-
|
6
|
-
module Sidekiq
|
7
|
-
module Throttled
|
8
|
-
class Communicator
|
9
|
-
if Sidekiq::VERSION >= "6.5.0"
|
10
|
-
module ExceptionHandler
|
11
|
-
def handle_exception(*args)
|
12
|
-
Sidekiq.handle_exception(*args)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
# NOTE: `Sidekiq.default_error_handler` is private API
|
17
|
-
Sidekiq.error_handlers << Sidekiq.method(:default_error_handler)
|
18
|
-
else
|
19
|
-
require "sidekiq/exception_handler"
|
20
|
-
|
21
|
-
ExceptionHandler = ::Sidekiq::ExceptionHandler
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,109 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "sidekiq/throttled/communicator/exception_handler"
|
4
|
-
|
5
|
-
module Sidekiq
|
6
|
-
module Throttled
|
7
|
-
class Communicator
|
8
|
-
# Redis subscription listener thread.
|
9
|
-
#
|
10
|
-
# @private
|
11
|
-
class Listener < Thread
|
12
|
-
include ExceptionHandler
|
13
|
-
|
14
|
-
# Starts listener thread.
|
15
|
-
#
|
16
|
-
# @param [String] channel Redis pub/sub channel to listen
|
17
|
-
# @param [Callbacks] callbacks Message callbacks registry
|
18
|
-
def initialize(channel, callbacks)
|
19
|
-
@channel = channel
|
20
|
-
@callbacks = callbacks
|
21
|
-
@terminated = false
|
22
|
-
@subscribed = false
|
23
|
-
|
24
|
-
super { listen until @terminated }
|
25
|
-
end
|
26
|
-
|
27
|
-
# Whenever underlying redis client subscribed to pub/sup channel.
|
28
|
-
#
|
29
|
-
# @return [Boolean]
|
30
|
-
def ready?
|
31
|
-
@subscribed
|
32
|
-
end
|
33
|
-
|
34
|
-
# Whenever main loop is still running.
|
35
|
-
#
|
36
|
-
# @return [Boolean]
|
37
|
-
def listening?
|
38
|
-
!@terminated
|
39
|
-
end
|
40
|
-
|
41
|
-
# Stops listener.
|
42
|
-
#
|
43
|
-
# @return [void]
|
44
|
-
def stop
|
45
|
-
# Raising exception while client is in subscription mode makes
|
46
|
-
# redis close connection and thus causing ConnectionPool reopen
|
47
|
-
# it (normal mode). Otherwise subscription mode client will be
|
48
|
-
# pushed back to ConnectionPool causing problems.
|
49
|
-
raise Sidekiq::Shutdown
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
# Wraps {#subscribe} with exception handlers:
|
55
|
-
#
|
56
|
-
# - `Sidekiq::Shutdown` exception marks listener as stopped and returns
|
57
|
-
# making `while` loop of listener thread terminate.
|
58
|
-
#
|
59
|
-
# - `StandardError` got recorded to the log and swallowed,
|
60
|
-
# making `while` loop of the listener thread restart.
|
61
|
-
#
|
62
|
-
# - `Exception` is recorded to the log and re-raised.
|
63
|
-
#
|
64
|
-
# @return [void]
|
65
|
-
def listen # rubocop:disable Metrics/MethodLength
|
66
|
-
subscribe
|
67
|
-
rescue Sidekiq::Shutdown
|
68
|
-
@terminated = true
|
69
|
-
@subscribed = false
|
70
|
-
rescue StandardError => e # rubocop:disable Style/RescueStandardError
|
71
|
-
@subscribed = false
|
72
|
-
handle_exception(e, { :context => "sidekiq:throttled" })
|
73
|
-
sleep 1
|
74
|
-
rescue Exception => e # rubocop:disable Lint/RescueException
|
75
|
-
@terminated = true
|
76
|
-
@subscribed = false
|
77
|
-
handle_exception(e, { :context => "sidekiq:throttled" })
|
78
|
-
raise
|
79
|
-
end
|
80
|
-
|
81
|
-
# Subscribes to channel and triggers all registerd handlers for
|
82
|
-
# received messages.
|
83
|
-
#
|
84
|
-
# @note Puts thread's Redis connection to subscription mode and
|
85
|
-
# locks thread.
|
86
|
-
#
|
87
|
-
# @see http://redis.io/topics/pubsub
|
88
|
-
# @see http://redis.io/commands/subscribe
|
89
|
-
# @see Callbacks#run
|
90
|
-
# @return [void]
|
91
|
-
def subscribe # rubocop:disable Metrics/MethodLength
|
92
|
-
Sidekiq.redis do |conn|
|
93
|
-
conn.subscribe @channel do |on|
|
94
|
-
on.subscribe do
|
95
|
-
@subscribed = true
|
96
|
-
@callbacks.run("ready")
|
97
|
-
end
|
98
|
-
|
99
|
-
on.message do |_channel, data|
|
100
|
-
message, payload = Marshal.load(data) # rubocop:disable Security/MarshalLoad:
|
101
|
-
@callbacks.run("message:#{message}", payload)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|