sidekiq-throttled 0.6.7 → 0.7.0
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/.gitignore +1 -0
- data/CHANGES.md +7 -0
- data/Gemfile +2 -0
- data/README.md +33 -0
- data/gemfiles/sidekiq_4.0.gemfile +2 -0
- data/gemfiles/sidekiq_4.1.gemfile +2 -0
- data/gemfiles/sidekiq_4.2.gemfile +2 -0
- data/lib/sidekiq/throttled.rb +0 -15
- data/lib/sidekiq/throttled/patches/queue.rb +18 -0
- data/lib/sidekiq/throttled/queues_pauser.rb +12 -0
- data/lib/sidekiq/throttled/version.rb +1 -1
- data/lib/sidekiq/throttled/web.rb +51 -4
- data/lib/sidekiq/throttled/web/queues.html.erb +49 -0
- data/lib/sidekiq/throttled/web/{index.html.erb → throttled.html.erb} +14 -20
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc5eb064ad2211b8e21d3a5936b953d68174545a
|
4
|
+
data.tar.gz: 90107848a47f41d73d2646d82a8a6c5c013cad20
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4471f6d39fa2e29071f6b66fa256e257040c61192b8110e6ef1bc15fd15e93e5b7318250b0f5c76259974c407278490069b9e6ed541f83ab0ce83218ffaf957
|
7
|
+
data.tar.gz: 4f53ef0e1b5c7cf1a2ba0a1c973525aa4a4ef0cb40809b08435d5d7403cee52664cf685ee0c8b61711573763913e89cc74c09136d65d2b173a560caf4c580dbe
|
data/.gitignore
CHANGED
data/CHANGES.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## 0.7.0 (2017-03-22)
|
2
|
+
|
3
|
+
* Expose pause/resume queues hidden feature to UI. This was available via API
|
4
|
+
since v0.6.0 and today it's finally got it's UI.
|
5
|
+
([@ixti])
|
6
|
+
|
7
|
+
|
1
8
|
## 0.6.7 (2017-03-21)
|
2
9
|
|
3
10
|
* Fix fetcher causing workers starvation upon low concurrency thresholds.
|
data/Gemfile
CHANGED
@@ -10,12 +10,14 @@ gem "rubocop", "~> 0.47.0", :require => false
|
|
10
10
|
gem "sidekiq"
|
11
11
|
|
12
12
|
group :development do
|
13
|
+
gem "byebug"
|
13
14
|
gem "guard", :require => false
|
14
15
|
gem "guard-rspec", :require => false
|
15
16
|
gem "guard-rubocop", :require => false
|
16
17
|
end
|
17
18
|
|
18
19
|
group :test do
|
20
|
+
gem "capybara"
|
19
21
|
gem "coveralls", :require => false
|
20
22
|
gem "rack-test"
|
21
23
|
gem "simplecov", ">= 0.9"
|
data/README.md
CHANGED
@@ -117,6 +117,39 @@ if you are using dynamic limit/period options. Otherwise you risk getting into
|
|
117
117
|
some trouble.
|
118
118
|
|
119
119
|
|
120
|
+
## Enhanced Queues list
|
121
|
+
|
122
|
+
This gem provides ability to pause/resume queues from processing by workers.
|
123
|
+
So you may simply pause particular queue without need to stop and reconfigure
|
124
|
+
workers by simply pushing a button on sidekiq web UI.
|
125
|
+
|
126
|
+
By default we add *Enhanced Queues* tab with this functionality. But if you
|
127
|
+
want you can override default *Queues* tab completely (notice that page will
|
128
|
+
still be available using it's URL, but tab will be pointing enhanced version).
|
129
|
+
To do so, just call `Sidekiq::Throttled::Web.enhance_queues_tab!` somewhere
|
130
|
+
in your initializer/bootstrap code. If you are using rails, you might want to
|
131
|
+
add it right into your `config/routes.rb` file:
|
132
|
+
|
133
|
+
``` ruby
|
134
|
+
# file config/routes.rb
|
135
|
+
|
136
|
+
require "sidekiq/web"
|
137
|
+
require "sidekiq/throttled/web"
|
138
|
+
|
139
|
+
Rails.application.routes.draw do
|
140
|
+
# ...
|
141
|
+
|
142
|
+
# Replace Sidekiq Queues with enhanced version!
|
143
|
+
Sidekiq::Throttled::Web.enhance_queues_tab!
|
144
|
+
|
145
|
+
# Mount Sidekiq Web UI to `/sidekiq` endpoint
|
146
|
+
mount Sidekiq::Web => "/sidekiq"
|
147
|
+
|
148
|
+
# ...
|
149
|
+
end
|
150
|
+
```
|
151
|
+
|
152
|
+
|
120
153
|
## Supported Ruby Versions
|
121
154
|
|
122
155
|
This library aims to support and is [tested against][travis] the following Ruby
|
@@ -10,12 +10,14 @@ gem "rubocop", "~> 0.47.0", :require => false
|
|
10
10
|
gem "sidekiq", "~> 4.0.0"
|
11
11
|
|
12
12
|
group :development do
|
13
|
+
gem "byebug"
|
13
14
|
gem "guard", :require => false
|
14
15
|
gem "guard-rspec", :require => false
|
15
16
|
gem "guard-rubocop", :require => false
|
16
17
|
end
|
17
18
|
|
18
19
|
group :test do
|
20
|
+
gem "capybara"
|
19
21
|
gem "coveralls", :require => false
|
20
22
|
gem "rack-test"
|
21
23
|
gem "simplecov", ">= 0.9"
|
@@ -10,12 +10,14 @@ gem "rubocop", "~> 0.47.0", :require => false
|
|
10
10
|
gem "sidekiq", "~> 4.1.0"
|
11
11
|
|
12
12
|
group :development do
|
13
|
+
gem "byebug"
|
13
14
|
gem "guard", :require => false
|
14
15
|
gem "guard-rspec", :require => false
|
15
16
|
gem "guard-rubocop", :require => false
|
16
17
|
end
|
17
18
|
|
18
19
|
group :test do
|
20
|
+
gem "capybara"
|
19
21
|
gem "coveralls", :require => false
|
20
22
|
gem "rack-test"
|
21
23
|
gem "simplecov", ">= 0.9"
|
@@ -10,12 +10,14 @@ gem "rubocop", "~> 0.47.0", :require => false
|
|
10
10
|
gem "sidekiq", "~> 4.2.0"
|
11
11
|
|
12
12
|
group :development do
|
13
|
+
gem "byebug"
|
13
14
|
gem "guard", :require => false
|
14
15
|
gem "guard-rspec", :require => false
|
15
16
|
gem "guard-rubocop", :require => false
|
16
17
|
end
|
17
18
|
|
18
19
|
group :test do
|
20
|
+
gem "capybara"
|
19
21
|
gem "coveralls", :require => false
|
20
22
|
gem "rack-test"
|
21
23
|
gem "simplecov", ">= 0.9"
|
data/lib/sidekiq/throttled.rb
CHANGED
@@ -58,21 +58,6 @@ module Sidekiq
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
# (see QueuesPauser#pause!)
|
62
|
-
def pause!(queue)
|
63
|
-
QueuesPauser.instance.pause!(queue)
|
64
|
-
end
|
65
|
-
|
66
|
-
# (see QueuesPauser#resume!)
|
67
|
-
def resume!(queue)
|
68
|
-
QueuesPauser.instance.resume!(queue)
|
69
|
-
end
|
70
|
-
|
71
|
-
# (see QueuesPauser#paused_queues)
|
72
|
-
def paused_queues
|
73
|
-
QueuesPauser.instance.paused_queues
|
74
|
-
end
|
75
|
-
|
76
61
|
# Tells whenever job is throttled or not.
|
77
62
|
#
|
78
63
|
# @param [String] message Job's JSON payload
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sidekiq
|
4
|
+
module Throttled
|
5
|
+
module Patches
|
6
|
+
module Queue
|
7
|
+
def paused?
|
8
|
+
QueuesPauser.instance.paused? name
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.apply!
|
12
|
+
require "sidekiq/api"
|
13
|
+
::Sidekiq::Queue.send(:prepend, self)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require "set"
|
4
4
|
require "singleton"
|
5
5
|
|
6
|
+
require "sidekiq/throttled/patches/queue"
|
6
7
|
require "sidekiq/throttled/communicator"
|
7
8
|
require "sidekiq/throttled/queue_name"
|
8
9
|
|
@@ -45,6 +46,8 @@ module Sidekiq
|
|
45
46
|
# @private
|
46
47
|
# @return [void]
|
47
48
|
def setup!
|
49
|
+
Patches::Queue.apply!
|
50
|
+
|
48
51
|
Sidekiq.configure_server do
|
49
52
|
@communicator.receive PAUSE_MESSAGE do |queue|
|
50
53
|
@paused_queues << QueueName.expand(queue)
|
@@ -88,6 +91,15 @@ module Sidekiq
|
|
88
91
|
end
|
89
92
|
end
|
90
93
|
|
94
|
+
# Checks if given `queue` is paused.
|
95
|
+
#
|
96
|
+
# @param queue [#to_s]
|
97
|
+
# @return [Boolean]
|
98
|
+
def paused?(queue)
|
99
|
+
queue = QueueName.normalize queue.to_s
|
100
|
+
Sidekiq.redis { |conn| conn.sismember(PAUSED_QUEUES, queue) }
|
101
|
+
end
|
102
|
+
|
91
103
|
# Resumes given `queue`.
|
92
104
|
#
|
93
105
|
# @param [#to_s] queue
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
# stdlib
|
3
4
|
require "pathname"
|
4
5
|
|
@@ -13,19 +14,64 @@ require "sidekiq/throttled/web/stats"
|
|
13
14
|
module Sidekiq
|
14
15
|
module Throttled
|
15
16
|
# Provides Sidekiq tab to monitor and reset throttled stats.
|
16
|
-
#
|
17
|
-
# @private
|
18
17
|
module Web
|
18
|
+
VIEWS = Pathname.new(__dir__).join("web")
|
19
|
+
THROTTLED_TPL = VIEWS.join("throttled.html.erb").read.freeze
|
20
|
+
QUEUES_TPL = VIEWS.join("queues.html.erb").read.freeze
|
21
|
+
|
19
22
|
class << self
|
23
|
+
# Replace default Queues tab with enhanced one.
|
24
|
+
def enhance_queues_tab!
|
25
|
+
Sidekiq::Web::DEFAULT_TABS["Queues"] = "enhanced-queues"
|
26
|
+
Sidekiq::Web.tabs.delete("Enhanced Queues")
|
27
|
+
end
|
28
|
+
|
29
|
+
# Restore original Queues tab.
|
30
|
+
#
|
31
|
+
# @api There's next to absolutely no value in this method for real
|
32
|
+
# users. The only it's purpose is to restore virgin state in specs.
|
33
|
+
def restore_queues_tab!
|
34
|
+
Sidekiq::Web::DEFAULT_TABS["Queues"] = "queues"
|
35
|
+
Sidekiq::Web.tabs["Enhanced Queues"] = "enhanced-queues"
|
36
|
+
end
|
37
|
+
|
38
|
+
# @api private
|
20
39
|
def registered(app)
|
21
|
-
|
22
|
-
app
|
40
|
+
register_throttled_tab app
|
41
|
+
register_enhanced_queues_tab app
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def register_throttled_tab(app)
|
47
|
+
app.get("/throttled") { erb THROTTLED_TPL.dup }
|
23
48
|
|
24
49
|
app.delete("/throttled/:id") do
|
25
50
|
Registry.get(params[:id], &:reset!)
|
26
51
|
redirect "#{root_path}throttled"
|
27
52
|
end
|
28
53
|
end
|
54
|
+
|
55
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
56
|
+
def register_enhanced_queues_tab(app)
|
57
|
+
pauser = QueuesPauser.instance
|
58
|
+
|
59
|
+
app.get("/enhanced-queues") do
|
60
|
+
@queues = Sidekiq::Queue.all
|
61
|
+
erb QUEUES_TPL.dup
|
62
|
+
end
|
63
|
+
|
64
|
+
app.post("/enhanced-queues/:name") do
|
65
|
+
case params[:action]
|
66
|
+
when "delete" then Sidekiq::Queue.new(params[:name]).clear
|
67
|
+
when "pause" then pauser.pause!(params[:name])
|
68
|
+
else pauser.resume!(params[:name])
|
69
|
+
end
|
70
|
+
|
71
|
+
redirect "#{root_path}enhanced-queues"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
29
75
|
end
|
30
76
|
end
|
31
77
|
end
|
@@ -33,3 +79,4 @@ end
|
|
33
79
|
|
34
80
|
Sidekiq::Web.register Sidekiq::Throttled::Web
|
35
81
|
Sidekiq::Web.tabs["Throttled"] = "throttled"
|
82
|
+
Sidekiq::Web.tabs["Enhanced Queues"] = "enhanced-queues"
|
@@ -0,0 +1,49 @@
|
|
1
|
+
<h3><%= t('Queues') %></h3>
|
2
|
+
|
3
|
+
<div class="table_container">
|
4
|
+
<table class="queues table table-hover table-bordered table-striped table-white">
|
5
|
+
<thead>
|
6
|
+
<th><%= t('Queue') %></th>
|
7
|
+
<th><%= t('Size') %></th>
|
8
|
+
<th><%= t('Actions') %></th>
|
9
|
+
</thead>
|
10
|
+
<% @queues.each do |queue| %>
|
11
|
+
<tr>
|
12
|
+
<td>
|
13
|
+
<a href="<%= root_path %>queues/<%= CGI.escape(queue.name) %>"><%= queue.name %></a>
|
14
|
+
</td>
|
15
|
+
<td><%= number_with_delimiter(queue.size) %> </td>
|
16
|
+
<td width="20%">
|
17
|
+
<form action="<%=root_path %>enhanced-queues/<%= CGI.escape(queue.name) %>" method="post" style="display:inline">
|
18
|
+
<%= csrf_tag %>
|
19
|
+
<% if queue.paused? %>
|
20
|
+
<button class="btn btn-primary btn-pauser-resume btn-xs" type="submit" name="action" value="resume">Resume</button>
|
21
|
+
<% else %>
|
22
|
+
<button class="btn btn-danger btn-pauser-pause btn-xs" type="submit" name="action" value="pause">Pause</button>
|
23
|
+
<% end %>
|
24
|
+
|
25
|
+
<button class="btn btn-danger btn-xs" type="submit" name="action" value="delete" data-confirm="<%= t('AreYouSureDeleteQueue', :queue => h(queue.name)) %>"><%= t('Delete') %></button>
|
26
|
+
</form>
|
27
|
+
</td>
|
28
|
+
</tr>
|
29
|
+
<% end %>
|
30
|
+
</table>
|
31
|
+
</div>
|
32
|
+
|
33
|
+
<style>
|
34
|
+
.btn-pauser-pause {
|
35
|
+
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #b13e00), color-stop(100%, #983500));
|
36
|
+
background-image: -webkit-linear-gradient(#b13e00, #983500);
|
37
|
+
background-image: -moz-linear-gradient(#b13e00, #983500);
|
38
|
+
background-image: -o-linear-gradient(#b13e00, #983500);
|
39
|
+
background-image: linear-gradient(#b13e00, #983500);
|
40
|
+
}
|
41
|
+
|
42
|
+
.btn-pauser-resume {
|
43
|
+
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #00b13e), color-stop(100%, #009835));
|
44
|
+
background-image: -webkit-linear-gradient(#00b13e, #009835);
|
45
|
+
background-image: -moz-linear-gradient(#00b13e, #009835);
|
46
|
+
background-image: -o-linear-gradient(#00b13e, #009835);
|
47
|
+
background-image: linear-gradient(#00b13e, #009835);
|
48
|
+
}
|
49
|
+
</style>
|
@@ -1,21 +1,15 @@
|
|
1
|
-
<
|
2
|
-
<div class="row header">
|
3
|
-
<div class="col-sm-8 pull-left">
|
4
|
-
<h3>Throttled</h3>
|
5
|
-
</div>
|
6
|
-
</div>
|
7
|
-
</div>
|
1
|
+
<h3>Throttled</h3>
|
8
2
|
|
9
|
-
<
|
10
|
-
<
|
11
|
-
<
|
12
|
-
<
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
3
|
+
<div class="table_container">
|
4
|
+
<table class="table table-hover table-bordered table-striped table-white">
|
5
|
+
<thead>
|
6
|
+
<tr>
|
7
|
+
<th>Name</th>
|
8
|
+
<th style="text-align:center;">Concurrency</th>
|
9
|
+
<th style="text-align:center;">Threshold</th>
|
10
|
+
<th style="text-align:center;">Actions</th>
|
11
|
+
</tr>
|
12
|
+
</thead>
|
19
13
|
<% Sidekiq::Throttled::Registry.each_with_static_keys do |name, strategy| %>
|
20
14
|
<tr>
|
21
15
|
<td style="vertical-align:middle;"><%= name %></td>
|
@@ -26,7 +20,7 @@
|
|
26
20
|
<%= Sidekiq::Throttled::Web::Stats.new(strategy.threshold).to_html %>
|
27
21
|
</td>
|
28
22
|
<td style="vertical-align:middle;text-align:center;">
|
29
|
-
<form action="<%= root_path %>throttled/<%= name %>" method="
|
23
|
+
<form action="<%= root_path %>throttled/<%= CGI.escape name %>" method="post">
|
30
24
|
<%= csrf_tag %>
|
31
25
|
<input type="hidden" name="_method" value="delete" />
|
32
26
|
<button class="btn btn-danger" type="submit">Reset</button>
|
@@ -34,5 +28,5 @@
|
|
34
28
|
</td>
|
35
29
|
</tr>
|
36
30
|
<% end %>
|
37
|
-
</
|
38
|
-
</
|
31
|
+
</table>
|
32
|
+
</div>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-throttled
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexey V Zapparov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sidekiq
|
@@ -71,6 +71,7 @@ files:
|
|
71
71
|
- lib/sidekiq/throttled/fetch.rb
|
72
72
|
- lib/sidekiq/throttled/fetch/unit_of_work.rb
|
73
73
|
- lib/sidekiq/throttled/middleware.rb
|
74
|
+
- lib/sidekiq/throttled/patches/queue.rb
|
74
75
|
- lib/sidekiq/throttled/queue_name.rb
|
75
76
|
- lib/sidekiq/throttled/queues_pauser.rb
|
76
77
|
- lib/sidekiq/throttled/registry.rb
|
@@ -83,8 +84,9 @@ files:
|
|
83
84
|
- lib/sidekiq/throttled/testing.rb
|
84
85
|
- lib/sidekiq/throttled/version.rb
|
85
86
|
- lib/sidekiq/throttled/web.rb
|
86
|
-
- lib/sidekiq/throttled/web/
|
87
|
+
- lib/sidekiq/throttled/web/queues.html.erb
|
87
88
|
- lib/sidekiq/throttled/web/stats.rb
|
89
|
+
- lib/sidekiq/throttled/web/throttled.html.erb
|
88
90
|
- lib/sidekiq/throttled/worker.rb
|
89
91
|
- sidekiq-throttled.gemspec
|
90
92
|
homepage: https://github.com/sensortower/sidekiq-throttled
|
@@ -107,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
109
|
version: '0'
|
108
110
|
requirements: []
|
109
111
|
rubyforge_project:
|
110
|
-
rubygems_version: 2.
|
112
|
+
rubygems_version: 2.6.8
|
111
113
|
signing_key:
|
112
114
|
specification_version: 4
|
113
115
|
summary: Concurrency and threshold throttling for Sidekiq.
|