sidekiq-throttled 0.6.7 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ec534fed2e493758df139b6245cf1f9e657c2e18
4
- data.tar.gz: 3de82b6c63e63e59a7c14c47683b9a9bff3dd912
3
+ metadata.gz: cc5eb064ad2211b8e21d3a5936b953d68174545a
4
+ data.tar.gz: 90107848a47f41d73d2646d82a8a6c5c013cad20
5
5
  SHA512:
6
- metadata.gz: cb31fced1ceae5050599471b39cbe8eedd7285bab72b77923fc471e4104eb1fdb85b7631622917ce423d3440abf06953123f289ce9d1917d1a33446beb39f3d2
7
- data.tar.gz: eb34237d9b64bb9c3cc4b6a9d33dc79d439b7990e84a59d63a999361eed857eda4cdf100831fd6e1e1f944d118d7dda504c98980d7bc33aaeafe0c01af3bcefd
6
+ metadata.gz: f4471f6d39fa2e29071f6b66fa256e257040c61192b8110e6ef1bc15fd15e93e5b7318250b0f5c76259974c407278490069b9e6ed541f83ab0ce83218ffaf957
7
+ data.tar.gz: 4f53ef0e1b5c7cf1a2ba0a1c973525aa4a4ef0cb40809b08435d5d7403cee52664cf685ee0c8b61711573763913e89cc74c09136d65d2b173a560caf4c580dbe
data/.gitignore CHANGED
@@ -8,3 +8,4 @@
8
8
  /pkg/
9
9
  /spec/reports/
10
10
  /tmp/
11
+ .byebug_history
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"
@@ -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
@@ -3,6 +3,6 @@
3
3
  module Sidekiq
4
4
  module Throttled
5
5
  # Gem version
6
- VERSION = "0.6.7"
6
+ VERSION = "0.7.0"
7
7
  end
8
8
  end
@@ -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
- template = Pathname.new(__FILE__).join("../web/index.html.erb").read
22
- app.get("/throttled") { erb template.dup }
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
- <div class="col-sm-12">
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
- <table class="table table-hover table-bordered table-striped table-white">
10
- <thead>
11
- <tr>
12
- <th>Name</th>
13
- <th style="text-align:center;">Concurrency</th>
14
- <th style="text-align:center;">Threshold</th>
15
- <th></th>
16
- </tr>
17
- </thead>
18
- <tbody>
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="POST">
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
- </tbody>
38
- </table>
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.6.7
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-20 00:00:00.000000000 Z
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/index.html.erb
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.4.5.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.