sidekiq 2.13.1 → 2.14.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.
- data/Changes.md +12 -1
- data/Contributing.md +3 -0
- data/Gemfile +1 -16
- data/Pro-Changes.md +18 -0
- data/lib/sidekiq/api.rb +2 -2
- data/lib/sidekiq/cli.rb +7 -4
- data/lib/sidekiq/client.rb +1 -1
- data/lib/sidekiq/exception_handler.rb +14 -14
- data/lib/sidekiq/middleware/server/retry_jobs.rb +1 -1
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web.rb +31 -24
- data/sidekiq.gemspec +1 -2
- data/web/views/_job_info.erb +76 -0
- data/web/views/_nav.erb +23 -0
- data/web/views/_paging.erb +25 -0
- data/web/views/_status.erb +4 -0
- data/web/views/_summary.erb +26 -0
- data/web/views/_workers.erb +29 -0
- data/web/views/dashboard.erb +59 -0
- data/web/views/index.erb +16 -0
- data/web/views/layout.erb +73 -0
- data/web/views/queue.erb +38 -0
- data/web/views/queues.erb +22 -0
- data/web/views/retries.erb +57 -0
- data/web/views/retry.erb +30 -0
- data/web/views/scheduled.erb +48 -0
- data/web/views/scheduled_job_info.erb +7 -0
- metadata +19 -35
- data/web/views/_job_info.slim +0 -51
- data/web/views/_nav.slim +0 -16
- data/web/views/_paging.slim +0 -15
- data/web/views/_status.slim +0 -3
- data/web/views/_summary.slim +0 -19
- data/web/views/_workers.slim +0 -21
- data/web/views/dashboard.slim +0 -46
- data/web/views/index.slim +0 -10
- data/web/views/layout.slim +0 -50
- data/web/views/queue.slim +0 -27
- data/web/views/queues.slim +0 -15
- data/web/views/retries.slim +0 -41
- data/web/views/retry.slim +0 -21
- data/web/views/scheduled.slim +0 -33
- data/web/views/scheduled_job_info.slim +0 -6
data/Changes.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
2.14.0
|
2
|
+
-----------
|
3
|
+
|
4
|
+
- Removed slim gem dependency, Web UI now uses ERB [Locke23rus, #1120]
|
5
|
+
- Fix more race conditions in Web UI actions
|
6
|
+
- Don't reset Job enqueued\_at when retrying
|
7
|
+
- Timestamp tooltips in the Web UI should use UTC
|
8
|
+
- Fix invalid usage of handle\_exception causing issues in Airbrake
|
9
|
+
[#1134]
|
10
|
+
|
11
|
+
|
1
12
|
2.13.1
|
2
13
|
-----------
|
3
14
|
|
@@ -12,7 +23,7 @@
|
|
12
23
|
```ruby
|
13
24
|
Sidekiq.configure_server do |config|
|
14
25
|
config.server_middleware do |chain|
|
15
|
-
chain.add Sidekiq::
|
26
|
+
chain.add Sidekiq::Middleware::Server::RetryJobs, :max_retries => 10
|
16
27
|
end
|
17
28
|
end
|
18
29
|
```
|
data/Contributing.md
CHANGED
data/Gemfile
CHANGED
@@ -1,17 +1,2 @@
|
|
1
|
-
source '
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
gemspec
|
3
|
-
|
4
|
-
gem 'slim', '1.1.0' # earliest verson supported
|
5
|
-
|
6
|
-
gem 'sqlite3', :platform => :mri
|
7
|
-
|
8
|
-
group :test do
|
9
|
-
gem 'simplecov', :require => false
|
10
|
-
gem 'minitest-emoji', :require => false
|
11
|
-
end
|
12
|
-
|
13
|
-
group :development do
|
14
|
-
gem 'pry', :platform => :mri
|
15
|
-
gem 'shotgun'
|
16
|
-
gem 'rack', '~> 1.4.0'
|
17
|
-
end
|
data/Pro-Changes.md
CHANGED
@@ -3,6 +3,24 @@ Sidekiq Pro Changelog
|
|
3
3
|
|
4
4
|
Please see http://sidekiq.org/pro for more details and how to buy.
|
5
5
|
|
6
|
+
1.2.3
|
7
|
+
-----------
|
8
|
+
|
9
|
+
- Pro now requires Sidekiq 2.14.0
|
10
|
+
- Fix bad exception handling in batch callbacks [#1134]
|
11
|
+
- Convert Batch UI to ERB
|
12
|
+
|
13
|
+
1.2.2
|
14
|
+
-----------
|
15
|
+
|
16
|
+
- Problem with reliable fetch which could lead to lost jobs when Sidekiq
|
17
|
+
is shut down normally. Thanks to MikaelAmborn for the report. [#1109]
|
18
|
+
|
19
|
+
1.2.1
|
20
|
+
-----------
|
21
|
+
|
22
|
+
- Forgot to push paging code necessary for `delete_job` performance.
|
23
|
+
|
6
24
|
1.2.0
|
7
25
|
-----------
|
8
26
|
|
data/lib/sidekiq/api.rb
CHANGED
@@ -175,7 +175,7 @@ module Sidekiq
|
|
175
175
|
end
|
176
176
|
|
177
177
|
def enqueued_at
|
178
|
-
Time.at(@item['enqueued_at'] || 0)
|
178
|
+
Time.at(@item['enqueued_at'] || 0).utc
|
179
179
|
end
|
180
180
|
|
181
181
|
def queue
|
@@ -210,7 +210,7 @@ module Sidekiq
|
|
210
210
|
end
|
211
211
|
|
212
212
|
def at
|
213
|
-
Time.at(score)
|
213
|
+
Time.at(score).utc
|
214
214
|
end
|
215
215
|
|
216
216
|
def delete
|
data/lib/sidekiq/cli.rb
CHANGED
@@ -9,10 +9,13 @@ require 'sidekiq'
|
|
9
9
|
require 'sidekiq/util'
|
10
10
|
|
11
11
|
module Sidekiq
|
12
|
-
#
|
13
|
-
#
|
12
|
+
# We are shutting down Sidekiq but what about workers that
|
13
|
+
# are working on some long job? This error is
|
14
|
+
# raised in workers that have not finished within the hard
|
15
|
+
# timeout limit. This is needed to rollback db transactions,
|
14
16
|
# otherwise Ruby's Thread#kill will commit. See #377.
|
15
|
-
|
17
|
+
# DO NOT RESCUE THIS ERROR.
|
18
|
+
class Shutdown < Interrupt; end
|
16
19
|
|
17
20
|
class CLI
|
18
21
|
include Util
|
@@ -105,7 +108,7 @@ module Sidekiq
|
|
105
108
|
when 'USR2'
|
106
109
|
if Sidekiq.options[:logfile]
|
107
110
|
Sidekiq.logger.info "Received USR2, reopening log file"
|
108
|
-
|
111
|
+
initialize_logger
|
109
112
|
end
|
110
113
|
when 'TTIN'
|
111
114
|
Thread.list.each do |thread|
|
data/lib/sidekiq/client.rb
CHANGED
@@ -1,39 +1,39 @@
|
|
1
1
|
module Sidekiq
|
2
2
|
module ExceptionHandler
|
3
3
|
|
4
|
-
def handle_exception(ex,
|
5
|
-
Sidekiq.logger.warn
|
4
|
+
def handle_exception(ex, ctxHash)
|
5
|
+
Sidekiq.logger.warn ctxHash
|
6
6
|
Sidekiq.logger.warn ex
|
7
7
|
Sidekiq.logger.warn ex.backtrace.join("\n")
|
8
8
|
# This list of services is getting a bit ridiculous.
|
9
9
|
# For future error services, please add your own
|
10
10
|
# middleware like BugSnag does:
|
11
11
|
# https://github.com/bugsnag/bugsnag-ruby/blob/master/lib/bugsnag/sidekiq.rb
|
12
|
-
send_to_airbrake(
|
13
|
-
send_to_honeybadger(
|
14
|
-
send_to_exceptional(
|
15
|
-
send_to_exception_notifier(
|
12
|
+
send_to_airbrake(ctxHash, ex) if defined?(::Airbrake)
|
13
|
+
send_to_honeybadger(ctxHash, ex) if defined?(::Honeybadger)
|
14
|
+
send_to_exceptional(ctxHash, ex) if defined?(::Exceptional)
|
15
|
+
send_to_exception_notifier(ctxHash, ex) if defined?(::ExceptionNotifier)
|
16
16
|
end
|
17
17
|
|
18
18
|
private
|
19
19
|
|
20
|
-
def send_to_airbrake(
|
21
|
-
::Airbrake.notify_or_ignore(ex, :parameters =>
|
20
|
+
def send_to_airbrake(hash, ex)
|
21
|
+
::Airbrake.notify_or_ignore(ex, :parameters => hash)
|
22
22
|
end
|
23
23
|
|
24
|
-
def send_to_honeybadger(
|
25
|
-
::Honeybadger.notify_or_ignore(ex, :parameters =>
|
24
|
+
def send_to_honeybadger(hash, ex)
|
25
|
+
::Honeybadger.notify_or_ignore(ex, :parameters => hash)
|
26
26
|
end
|
27
27
|
|
28
|
-
def send_to_exceptional(
|
28
|
+
def send_to_exceptional(hash, ex)
|
29
29
|
if ::Exceptional::Config.should_send_to_api?
|
30
|
-
::Exceptional.context(
|
30
|
+
::Exceptional.context(hash)
|
31
31
|
::Exceptional::Remote.error(::Exceptional::ExceptionData.new(ex))
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
def send_to_exception_notifier(
|
36
|
-
::ExceptionNotifier.notify_exception(ex, :data => {:message =>
|
35
|
+
def send_to_exception_notifier(hash, ex)
|
36
|
+
::ExceptionNotifier.notify_exception(ex, :data => {:message => hash})
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
data/lib/sidekiq/version.rb
CHANGED
data/lib/sidekiq/web.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
+
require 'erb'
|
1
2
|
require 'yaml'
|
2
3
|
require 'sinatra/base'
|
3
|
-
require 'slim'
|
4
|
-
|
5
|
-
raise "The Sidekiq Web UI requires slim 1.1.0 or greater. You have slim v#{Slim::VERSION}" if Gem::Version.new(Slim::VERSION) < Gem::Version.new('1.1.0')
|
6
4
|
|
7
5
|
require 'sidekiq'
|
8
6
|
require 'sidekiq/api'
|
@@ -16,7 +14,6 @@ module Sidekiq
|
|
16
14
|
set :public_folder, Proc.new { "#{root}/assets" }
|
17
15
|
set :views, Proc.new { "#{root}/views" }
|
18
16
|
set :locales, Proc.new { "#{root}/locales" }
|
19
|
-
set :slim, :pretty => true
|
20
17
|
|
21
18
|
helpers do
|
22
19
|
def strings
|
@@ -161,15 +158,19 @@ module Sidekiq
|
|
161
158
|
def redis_keys
|
162
159
|
["redis_stats", "uptime_in_days", "connected_clients", "used_memory_human", "used_memory_peak_human"]
|
163
160
|
end
|
161
|
+
|
162
|
+
def h(text)
|
163
|
+
ERB::Util.h(text)
|
164
|
+
end
|
164
165
|
end
|
165
166
|
|
166
167
|
get "/workers" do
|
167
|
-
|
168
|
+
erb :index
|
168
169
|
end
|
169
170
|
|
170
171
|
get "/queues" do
|
171
172
|
@queues = Sidekiq::Queue.all
|
172
|
-
|
173
|
+
erb :queues
|
173
174
|
end
|
174
175
|
|
175
176
|
get "/queues/:name" do
|
@@ -178,7 +179,7 @@ module Sidekiq
|
|
178
179
|
@name = params[:name]
|
179
180
|
(@current_page, @total_size, @messages) = page("queue:#{@name}", params[:page], @count)
|
180
181
|
@messages = @messages.map {|msg| Sidekiq.load_json(msg) }
|
181
|
-
|
182
|
+
erb :queue
|
182
183
|
end
|
183
184
|
|
184
185
|
post "/reset" do
|
@@ -200,14 +201,14 @@ module Sidekiq
|
|
200
201
|
@count = (params[:count] || 25).to_i
|
201
202
|
(@current_page, @total_size, @retries) = page("retry", params[:page], @count)
|
202
203
|
@retries = @retries.map {|msg, score| [Sidekiq.load_json(msg), score] }
|
203
|
-
|
204
|
+
erb :retries
|
204
205
|
end
|
205
206
|
|
206
207
|
get "/retries/:key" do
|
207
208
|
halt 404 unless params['key']
|
208
209
|
@retry = Sidekiq::RetrySet.new.fetch(*parse_params(params['key'])).first
|
209
210
|
redirect "#{root_path}retries" if @retry.nil?
|
210
|
-
|
211
|
+
erb :retry
|
211
212
|
end
|
212
213
|
|
213
214
|
post '/retries' do
|
@@ -238,10 +239,12 @@ module Sidekiq
|
|
238
239
|
post "/retries/:key" do
|
239
240
|
halt 404 unless params['key']
|
240
241
|
job = Sidekiq::RetrySet.new.fetch(*parse_params(params['key'])).first
|
241
|
-
if
|
242
|
-
|
243
|
-
|
244
|
-
|
242
|
+
if job
|
243
|
+
if params['retry']
|
244
|
+
job.retry
|
245
|
+
elsif params['delete']
|
246
|
+
job.delete
|
247
|
+
end
|
245
248
|
end
|
246
249
|
redirect "#{root_path}retries"
|
247
250
|
end
|
@@ -250,14 +253,14 @@ module Sidekiq
|
|
250
253
|
@count = (params[:count] || 25).to_i
|
251
254
|
(@current_page, @total_size, @scheduled) = page("schedule", params[:page], @count)
|
252
255
|
@scheduled = @scheduled.map {|msg, score| [Sidekiq.load_json(msg), score] }
|
253
|
-
|
256
|
+
erb :scheduled
|
254
257
|
end
|
255
258
|
|
256
259
|
get "/scheduled/:key" do
|
257
260
|
halt 404 unless params['key']
|
258
261
|
@job = Sidekiq::ScheduledSet.new.fetch(*parse_params(params['key'])).first
|
259
262
|
redirect "#{root_path}scheduled" if @job.nil?
|
260
|
-
|
263
|
+
erb :scheduled_job_info
|
261
264
|
end
|
262
265
|
|
263
266
|
post '/scheduled' do
|
@@ -265,10 +268,12 @@ module Sidekiq
|
|
265
268
|
|
266
269
|
params['key'].each do |key|
|
267
270
|
job = Sidekiq::ScheduledSet.new.fetch(*parse_params(key)).first
|
268
|
-
if
|
269
|
-
|
270
|
-
|
271
|
-
|
271
|
+
if job
|
272
|
+
if params['delete']
|
273
|
+
job.delete
|
274
|
+
elsif params['add_to_queue']
|
275
|
+
job.add_to_queue
|
276
|
+
end
|
272
277
|
end
|
273
278
|
end
|
274
279
|
redirect "#{root_path}scheduled"
|
@@ -277,10 +282,12 @@ module Sidekiq
|
|
277
282
|
post "/scheduled/:key" do
|
278
283
|
halt 404 unless params['key']
|
279
284
|
job = Sidekiq::ScheduledSet.new.fetch(*parse_params(params['key'])).first
|
280
|
-
if
|
281
|
-
|
282
|
-
|
283
|
-
|
285
|
+
if job
|
286
|
+
if params['add_to_queue']
|
287
|
+
job.add_to_queue
|
288
|
+
elsif params['delete']
|
289
|
+
job.delete
|
290
|
+
end
|
284
291
|
end
|
285
292
|
redirect "#{root_path}scheduled"
|
286
293
|
end
|
@@ -290,7 +297,7 @@ module Sidekiq
|
|
290
297
|
stats_history = Sidekiq::Stats::History.new((params[:days] || 30).to_i)
|
291
298
|
@processed_history = stats_history.processed
|
292
299
|
@failed_history = stats_history.failed
|
293
|
-
|
300
|
+
erb :dashboard
|
294
301
|
end
|
295
302
|
|
296
303
|
get '/dashboard/stats' do
|
data/sidekiq.gemspec
CHANGED
@@ -14,13 +14,12 @@ Gem::Specification.new do |gem|
|
|
14
14
|
gem.name = "sidekiq"
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = Sidekiq::VERSION
|
17
|
-
gem.add_dependency 'redis', '>= 3.0'
|
17
|
+
gem.add_dependency 'redis', '>= 3.0.4'
|
18
18
|
gem.add_dependency 'redis-namespace'
|
19
19
|
gem.add_dependency 'connection_pool', '>= 1.0.0'
|
20
20
|
gem.add_dependency 'celluloid', '>= 0.14.1'
|
21
21
|
gem.add_dependency 'json'
|
22
22
|
gem.add_development_dependency 'sinatra'
|
23
|
-
gem.add_development_dependency 'slim', '>= 1.1.0'
|
24
23
|
gem.add_development_dependency 'minitest', '~> 5'
|
25
24
|
gem.add_development_dependency 'rake'
|
26
25
|
gem.add_development_dependency 'actionmailer'
|
@@ -0,0 +1,76 @@
|
|
1
|
+
<header>
|
2
|
+
<h3><%= t('Job') %></h3>
|
3
|
+
</header>
|
4
|
+
|
5
|
+
<table class="table table-bordered table-striped">
|
6
|
+
<tbody>
|
7
|
+
<tr>
|
8
|
+
<th><%= t('Queue') %></th>
|
9
|
+
<td>
|
10
|
+
<a href="<%= root_path %>queues/<%= job['queue'] %>"><%= job['queue'] %></a>
|
11
|
+
</td>
|
12
|
+
</tr>
|
13
|
+
<tr>
|
14
|
+
<th><%= t('Class') %></th>
|
15
|
+
<td>
|
16
|
+
<code><%= job['class'] %></code>
|
17
|
+
</td>
|
18
|
+
</tr>
|
19
|
+
<tr>
|
20
|
+
<th><%= t('Arguments') %></th>
|
21
|
+
<td>
|
22
|
+
<code>
|
23
|
+
<!-- We don't want to truncate any job arguments when viewing a single job's status page -->
|
24
|
+
<div class="args-extended"><%= display_args(job['args'], nil) %></div>
|
25
|
+
</code>
|
26
|
+
</td>
|
27
|
+
</tr>
|
28
|
+
<tr>
|
29
|
+
<th>JID</th>
|
30
|
+
<td>
|
31
|
+
<code><%= job.jid %></code>
|
32
|
+
</td>
|
33
|
+
</tr>
|
34
|
+
<tr>
|
35
|
+
<th><%= t('Enqueued') %></th>
|
36
|
+
<td><%= relative_time(job.enqueued_at) %></td>
|
37
|
+
</tr>
|
38
|
+
<% unless retry_extra_items(job).empty? %>
|
39
|
+
<tr>
|
40
|
+
<th><%= t('Extras') %></th>
|
41
|
+
<td>
|
42
|
+
<code>
|
43
|
+
<%= retry_extra_items(job).inspect %>
|
44
|
+
</code>
|
45
|
+
</td>
|
46
|
+
</tr>
|
47
|
+
<% end %>
|
48
|
+
<% if type == :retry %>
|
49
|
+
<% if job['retry_count'] && job['retry_count'] > 0 %>
|
50
|
+
<tr>
|
51
|
+
<th><%= t('RetryCount') %></th>
|
52
|
+
<td><%= job['retry_count'] %></td>
|
53
|
+
</tr>
|
54
|
+
<tr>
|
55
|
+
<th><%= t('LastRetry') %></th>
|
56
|
+
<td><%= relative_time(job['retried_at'].is_a?(Numeric) ? Time.at(job['retried_at']) : Time.parse(job['retried_at'])) %></td>
|
57
|
+
</tr>
|
58
|
+
<% else %>
|
59
|
+
<tr>
|
60
|
+
<th><%= t('OriginallyFailed') %></th>
|
61
|
+
<td><%= relative_time(job['failed_at'].is_a?(Numeric) ? Time.at(job['failed_at']) : Time.parse(job['failed_at'])) %></td>
|
62
|
+
</tr>
|
63
|
+
<% end %>
|
64
|
+
<tr>
|
65
|
+
<th><%= t('NextRetry') %></th>
|
66
|
+
<td><%= relative_time(job.at) %></td>
|
67
|
+
</tr>
|
68
|
+
<% end %>
|
69
|
+
<% if type == :scheduled %>
|
70
|
+
<tr>
|
71
|
+
<th><%= t('Scheduled') %></th>
|
72
|
+
<td><%= relative_time(job.at) %></td>
|
73
|
+
</tr>
|
74
|
+
<% end %>
|
75
|
+
</tbody>
|
76
|
+
</table>
|
data/web/views/_nav.erb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
<div class="navbar-inner">
|
2
|
+
<div class="container">
|
3
|
+
<a class="brand" href="<%= root_path %>"><%= Sidekiq::NAME %></a>
|
4
|
+
<ul class="nav">
|
5
|
+
<% tabs.each do |title, url| %>
|
6
|
+
<% if url == '' %>
|
7
|
+
<li class="<%= current_path == url ? 'active' : '' %>">
|
8
|
+
<a href="<%= root_path %><%= url %>"><%= t(title) %></a>
|
9
|
+
</li>
|
10
|
+
<% else %>
|
11
|
+
<li class="<%= current_path.start_with?(url) ? 'active' : '' %>">
|
12
|
+
<a href="<%= root_path %><%= url %>"><%= t(title) %></a>
|
13
|
+
</li>
|
14
|
+
<% end %>
|
15
|
+
<% end %>
|
16
|
+
<% custom_tabs.each do |title, url| %>
|
17
|
+
<li class="<%= current_path.start_with?(url) ? 'active' : '' %>">
|
18
|
+
<a href="<%= root_path %><%= url %>"><%= t(title) %></a>
|
19
|
+
</li>
|
20
|
+
<% end %>
|
21
|
+
</ul>
|
22
|
+
</div>
|
23
|
+
</div>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<% if @total_size > @count %>
|
2
|
+
<div class="pagination pagination-right">
|
3
|
+
<ul>
|
4
|
+
<li class="<%= 'disabled' if @current_page == 1 %>">
|
5
|
+
<a href="<%= url %>?page=1">«</a>
|
6
|
+
</li>
|
7
|
+
<% if @current_page > 1 %>
|
8
|
+
<li>
|
9
|
+
<a href="<%= url %>?page=<%= @current_page - 1 %>"><%= @current_page - 1 %></a>
|
10
|
+
</li>
|
11
|
+
<% end %>
|
12
|
+
<li class="disabled">
|
13
|
+
<a href="<%= url %>?page=<%= @current_page %>"><%= @current_page %></a>
|
14
|
+
</li>
|
15
|
+
<% if @total_size > @current_page * @count %>
|
16
|
+
<li>
|
17
|
+
<a href="<%= url %>?page=<%= @current_page + 1 %>"><%= @current_page + 1 %></a>
|
18
|
+
</li>
|
19
|
+
<% end %>
|
20
|
+
<li class="<%= 'disabled' if @total_size <= @current_page * @count %>">
|
21
|
+
<a href="<%= url %>?page=<%= (@total_size.to_f / @count).ceil %>">»</a>
|
22
|
+
</li>
|
23
|
+
</ul>
|
24
|
+
</div>
|
25
|
+
<% end %>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<ul class="unstyled summary row">
|
2
|
+
<li class="processed span2">
|
3
|
+
<span class="count"><%= number_with_delimiter(stats.processed) %></span>
|
4
|
+
<span class="desc"><%= t('Processed') %></span>
|
5
|
+
</li>
|
6
|
+
<li class="failed span2">
|
7
|
+
<span class="count"><%= number_with_delimiter(stats.failed) %></span>
|
8
|
+
<span class="desc"><%= t('Failed') %></span>
|
9
|
+
</li>
|
10
|
+
<li class="busy span2">
|
11
|
+
<span class="count"><%= number_with_delimiter(workers_size) %></span>
|
12
|
+
<span class="desc"><%= t('Busy') %></span>
|
13
|
+
</li>
|
14
|
+
<li class="scheduled span2">
|
15
|
+
<span class="count"><%= number_with_delimiter(stats.scheduled_size) %></span>
|
16
|
+
<span class="desc"><%= t('Scheduled') %></span>
|
17
|
+
</li>
|
18
|
+
<li class="retries span2">
|
19
|
+
<span class="count"><%= number_with_delimiter(stats.retry_size) %></span>
|
20
|
+
<span class="desc"><%= t('Retries') %></span>
|
21
|
+
</li>
|
22
|
+
<li class="enqueued span2">
|
23
|
+
<span class="count"><%= number_with_delimiter(stats.enqueued) %></span>
|
24
|
+
<span class="desc"><%= t('Enqueued') %></span>
|
25
|
+
</li>
|
26
|
+
</ul>
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<table class="workers table table-hover table-bordered table-striped table-white">
|
2
|
+
<thead>
|
3
|
+
<th><%= t('Worker') %></th>
|
4
|
+
<th><%= t('Queue') %></th>
|
5
|
+
<th><%= t('Class') %></th>
|
6
|
+
<th><%= t('Arguments') %></th>
|
7
|
+
<th><%= t('Started') %></th>
|
8
|
+
</thead>
|
9
|
+
<% workers.each_with_index do |(worker, msg), index| %>
|
10
|
+
<tr>
|
11
|
+
<td><%= worker %></td>
|
12
|
+
<td>
|
13
|
+
<a href="<%= root_path %>queues/<%= msg['queue'] %>">= msg['queue'] %></a>
|
14
|
+
</td>
|
15
|
+
|
16
|
+
<td><%= msg['payload']['class'] %></td>
|
17
|
+
<td>
|
18
|
+
<% if msg['payload']['args'].to_s.size > 100 %>
|
19
|
+
<%= msg['payload']['args'].inspect[0..100] + "... " %>
|
20
|
+
<button data-toggle="collapse" data-target="#worker_<%= index %>" class="btn btn-mini"><%= t('ShowAll') %></button>
|
21
|
+
<div class="toggle" id="worker_<%= index %>" style="display: none;max-width: 750px;"><%= msg['payload']['args'] %></div>
|
22
|
+
<% else %>
|
23
|
+
<%= msg['payload']['args'] %>
|
24
|
+
<% end %>
|
25
|
+
</td>
|
26
|
+
<td><%= relative_time(msg['run_at'].is_a?(Numeric) ? Time.at(msg['run_at']) : Time.parse(msg['run_at'])) %></td>
|
27
|
+
</tr>
|
28
|
+
<% end %>
|
29
|
+
</table>
|
@@ -0,0 +1,59 @@
|
|
1
|
+
<script type="text/javascript" src="<%= root_path %>javascripts/dashboard.js"></script>
|
2
|
+
|
3
|
+
<h3>
|
4
|
+
<%= t('Dashboard') %>
|
5
|
+
<span class="beacon">
|
6
|
+
<span class="ring"></span>
|
7
|
+
<span class="dot"></span>
|
8
|
+
</span>
|
9
|
+
</h3>
|
10
|
+
|
11
|
+
<h5></h5>
|
12
|
+
<div id="realtime"></div>
|
13
|
+
|
14
|
+
<h5>
|
15
|
+
<span class="history-heading"><%= t('History') %></span>
|
16
|
+
<a href="<%= root_path %>?days=7" class="history-graph <%= "active" if params[:days] == "7" %>"><%= t('OneWeek') %></a>
|
17
|
+
<a href="<%= root_path %>" class="history-graph <%= "active" if params[:days].nil? || params[:days] == "30" %>" ><%= t('OneMonth') %></a>
|
18
|
+
<a href="<%= root_path %>?days=90" class="history-graph <%= "active" if params[:days] == "90" %>"><%= t('ThreeMonths') %></a>
|
19
|
+
<a href="<%= root_path %>?days=180" class="history-graph <%= "active" if params[:days] == "180" %>"><%= t('SixMonths') %></a>
|
20
|
+
</h5>
|
21
|
+
<div id="history" data-processed="<%= h Sidekiq.dump_json(@processed_history) %>" data-failed="<%= h Sidekiq.dump_json(@failed_history) %>" data-update-url="<%= root_path %>dashboard/stats"></div>
|
22
|
+
|
23
|
+
<br/>
|
24
|
+
<h5>Redis</h5>
|
25
|
+
|
26
|
+
<% if @redis_info.fetch("redis_version", nil) %>
|
27
|
+
<div class="stat">
|
28
|
+
<h3 class="redis_version"><%= @redis_info.fetch("redis_version") %></h3>
|
29
|
+
<p><%= t('Version') %></p>
|
30
|
+
</div>
|
31
|
+
<% end %>
|
32
|
+
|
33
|
+
<% if @redis_info.fetch("uptime_in_days", nil) %>
|
34
|
+
<div class="stat">
|
35
|
+
<h3 class="uptime_in_days"><%= @redis_info.fetch("uptime_in_days") %></h3>
|
36
|
+
<p><%= t('Uptime') %></p>
|
37
|
+
</div>
|
38
|
+
<% end %>
|
39
|
+
|
40
|
+
<% if @redis_info.fetch("connected_clients", nil) %>
|
41
|
+
<div class="stat">
|
42
|
+
<h3 class="connected_clients"><%= @redis_info.fetch("connected_clients") %></h3>
|
43
|
+
<p><%= t('Connections') %></p>
|
44
|
+
</div>
|
45
|
+
<% end %>
|
46
|
+
|
47
|
+
<% if @redis_info.fetch("used_memory_human", nil) %>
|
48
|
+
<div class="stat">
|
49
|
+
<h3 class="used_memory_human"><%= @redis_info.fetch("used_memory_human") %></h3>
|
50
|
+
<p><%= t('MemoryUsage') %></p>
|
51
|
+
</div>
|
52
|
+
<% end %>
|
53
|
+
|
54
|
+
<% if @redis_info.fetch("used_memory_peak_human", nil) %>
|
55
|
+
<div class="stat">
|
56
|
+
<h3 class="used_memory_peak_human"><%= @redis_info.fetch("used_memory_peak_human") %></h3>
|
57
|
+
<p><%= @redis_info.fetch("used_memory_peak_human") %></p>
|
58
|
+
</div>
|
59
|
+
<% end %>
|
data/web/views/index.erb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
<div class="row header">
|
2
|
+
<div class="span7">
|
3
|
+
<h3><%= t('Workers') %></h3>
|
4
|
+
</div>
|
5
|
+
</div>
|
6
|
+
|
7
|
+
<%= erb :_workers %>
|
8
|
+
<% if workers_size > 0 %>
|
9
|
+
<div class="row">
|
10
|
+
<div class="span2 pull-right">
|
11
|
+
<form action="<%= root_path %>reset" method="post">
|
12
|
+
<button class="btn btn-primary btn-block" type="submit"><%= t('ClearWorkerList') %></button>
|
13
|
+
</form>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
<% end %>
|