mirror of
https://github.com/mperham/sidekiq.git
synced 2022-11-09 13:52:34 -05:00
Update Web UI, add new Busy tab with process heartbeat and job info
This commit is contained in:
parent
ee7e181bd6
commit
ff9db33666
10 changed files with 80 additions and 47 deletions
|
@ -11,6 +11,8 @@ Please see [Upgrading.md](Upgrading.md) for more comprehensive upgrade notes.
|
|||
exposing these jobs.
|
||||
- **Process Heartbeat** - each Sidekiq process will ping Redis every 5
|
||||
seconds to give an accurate summary of the Sidekiq population at work.
|
||||
- The Workers tab is now renamed to Busy and contains a list of live
|
||||
Sidekiq processes with a heartbeat.
|
||||
- **Remove official support for Ruby 1.9** Things still might work but
|
||||
I no longer actively test on it.
|
||||
- **Remove built-in support for Redis-to-Go**.
|
||||
|
@ -23,6 +25,8 @@ Please see [Upgrading.md](Upgrading.md) for more comprehensive upgrade notes.
|
|||
version to pick up Sidekiq support.
|
||||
- Remove deprecated Sidekiq::Client.registered\_\* APIs
|
||||
- Remove deprecated support for the old Sidekiq::Worker#retries\_exhausted method.
|
||||
- Remove usage of the term 'Worker' in the UI for clarity. Users would call both threads and
|
||||
processes 'workers'. Instead, use "Thread", "Process" or "Job".
|
||||
|
||||
2.17.7
|
||||
-----------
|
||||
|
|
|
@ -470,8 +470,8 @@ module Sidekiq
|
|||
live = ProcessSet.new.map {|x| /\A#{x['hostname']}:#{x['process_id']}-/ }
|
||||
msgs = Sidekiq.redis do |conn|
|
||||
workers = conn.smembers("workers")
|
||||
to_rem = workers.delete_if {|w| !live.any? {|identity| w =~ identity } }
|
||||
conn.srem('workers', *to_rem) unless to_rem.empty?
|
||||
to_rem = workers.reject {|w| live.any? {|identity| w =~ identity } }
|
||||
conn.srem('workers', to_rem) unless to_rem.empty?
|
||||
|
||||
workers.empty? ? {} : conn.mapped_mget(*workers.map {|w| "worker:#{w}" })
|
||||
end
|
||||
|
|
|
@ -58,6 +58,7 @@ module Sidekiq
|
|||
manager.heartbeat({
|
||||
'key' => "#{hostname}:#{$$}",
|
||||
'hostname' => hostname,
|
||||
'started_at' => Time.now.to_f,
|
||||
'pid' => $$,
|
||||
'process_id' => process_id,
|
||||
'tag' => tag.strip,
|
||||
|
|
|
@ -20,7 +20,7 @@ module Sidekiq
|
|||
|
||||
DEFAULT_TABS = {
|
||||
"Dashboard" => '',
|
||||
"Workers" => 'workers',
|
||||
"Busy" => 'busy',
|
||||
"Queues" => 'queues',
|
||||
"Retries" => 'retries',
|
||||
"Scheduled" => 'scheduled',
|
||||
|
@ -38,8 +38,8 @@ module Sidekiq
|
|||
alias_method :tabs, :custom_tabs
|
||||
end
|
||||
|
||||
get "/workers" do
|
||||
erb :workers
|
||||
get "/busy" do
|
||||
erb :busy
|
||||
end
|
||||
|
||||
get "/queues" do
|
||||
|
|
|
@ -363,12 +363,12 @@ class TestApi < Sidekiq::Test
|
|||
assert false
|
||||
end
|
||||
|
||||
pdata = { 'pid' => $$, 'hostname' => hostname, 'process_id' => process_id, 'key' => "#{hostname}:#{$$}", 'at' => Time.now.to_f }
|
||||
pdata = { 'pid' => $$, 'hostname' => hostname, 'process_id' => process_id, 'key' => "#{hostname}:#{$$}", 'at' => Time.now.to_f, 'started_at' => Time.now.to_i }
|
||||
Sidekiq.redis do |conn|
|
||||
conn.hset('processes', pdata['key'], Sidekiq.dump_json(pdata))
|
||||
end
|
||||
|
||||
s = "worker:#{hostname}:#{process_id}-12345"
|
||||
s = "#{hostname}:#{process_id}-12345"
|
||||
data = Sidekiq.dump_json({ 'payload' => {}, 'queue' => 'default', 'run_at' => Time.now.to_i })
|
||||
Sidekiq.redis do |c|
|
||||
c.multi do
|
||||
|
@ -384,6 +384,7 @@ class TestApi < Sidekiq::Test
|
|||
assert_equal Time.now.year, Time.at(y['run_at']).year
|
||||
end
|
||||
|
||||
assert_equal 1, w.size
|
||||
s = "#{hostname}:#{process_id}-12346"
|
||||
data = Sidekiq.dump_json({ 'payload' => {}, 'queue' => 'default', 'run_at' => (Time.now.to_i - 2*60*60) })
|
||||
Sidekiq.redis do |c|
|
||||
|
|
|
@ -30,13 +30,14 @@ class TestWeb < Sidekiq::Test
|
|||
|
||||
it 'can display workers' do
|
||||
Sidekiq.redis do |conn|
|
||||
conn.hset('processes', 'foo:1234', Sidekiq.dump_json('key' => 'foo:1234', 'hostname' => 'foo', 'process_id' => '1234', 'started_at' => Time.now.to_f, 'at' => Time.now.to_f))
|
||||
identity = 'foo:1234-123abc:default'
|
||||
conn.sadd('workers', identity)
|
||||
hash = {:queue => 'critical', :payload => { 'class' => WebWorker.name, 'args' => [1,'abc'] }, :run_at => Time.now.to_i }
|
||||
conn.setex("worker:#{identity}", 10, Sidekiq.dump_json(hash))
|
||||
end
|
||||
|
||||
get '/workers'
|
||||
get '/busy'
|
||||
assert_equal 200, last_response.status
|
||||
assert_match /status-active/, last_response.body
|
||||
assert_match /critical/, last_response.body
|
||||
|
@ -286,7 +287,7 @@ class TestWeb < Sidekiq::Test
|
|||
conn.setex("worker:#{identity}", 10, Sidekiq.dump_json(hash))
|
||||
end
|
||||
|
||||
get '/workers'
|
||||
get '/busy'
|
||||
assert_equal 200, last_response.status
|
||||
assert_match /FailWorker/, last_response.body
|
||||
assert last_response.body.include?( "<a>hello</a>" )
|
||||
|
|
|
@ -64,3 +64,7 @@ en: # <---- change this to your locale code
|
|||
DeadJobs: Dead Jobs
|
||||
NoDeadJobsFound: No dead jobs were found
|
||||
Dead: Dead
|
||||
Processes: Processes
|
||||
Thread: Thread
|
||||
Threads: Threads
|
||||
Jobs: Jobs
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
<table class="workers table table-hover table-bordered table-striped table-white">
|
||||
<thead>
|
||||
<th><%= t('Worker') %></th>
|
||||
<th><%= t('Queue') %></th>
|
||||
<th><%= t('Class') %></th>
|
||||
<th><%= t('Arguments') %></th>
|
||||
<th><%= t('Started') %></th>
|
||||
</thead>
|
||||
<% workers.each_with_index do |(worker, msg), index| %>
|
||||
<tr>
|
||||
<td><%= worker %></td>
|
||||
<td>
|
||||
<a href="<%= root_path %>queues/<%= msg['queue'] %>"><%= msg['queue'] %></a>
|
||||
</td>
|
||||
<td><%= msg['payload']['class'] %></td>
|
||||
<td>
|
||||
<div class="args"><%= display_args(msg['payload']['args']) %></div>
|
||||
</td>
|
||||
<td><%= relative_time(Time.at(msg['run_at'])) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
60
web/views/busy.erb
Normal file
60
web/views/busy.erb
Normal file
|
@ -0,0 +1,60 @@
|
|||
<div class="row header">
|
||||
<div class="col-sm-7">
|
||||
<h3><%= t('Processes') %></h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="processes table table-hover table-bordered table-striped table-white">
|
||||
<thead>
|
||||
<th><%= t('Name') %></th>
|
||||
<th><%= t('Started') %></th>
|
||||
<th><%= t('Threads') %></th>
|
||||
<th><%= t('Busy') %></th>
|
||||
</thead>
|
||||
<% Sidekiq::ProcessSet.new.each_with_index do |process, index| %>
|
||||
<tr>
|
||||
<td><%= process['key'] %></td>
|
||||
<td><%= relative_time(Time.at(process['started_at'])) %></td>
|
||||
<td><%= process['concurrency'] %></td>
|
||||
<td><%= process['busy'] %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
|
||||
<div class="row header">
|
||||
<div class="col-sm-7">
|
||||
<h3><%= t('Jobs') %></h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="workers table table-hover table-bordered table-striped table-white">
|
||||
<thead>
|
||||
<th><%= t('Thread') %></th>
|
||||
<th><%= t('Queue') %></th>
|
||||
<th><%= t('Class') %></th>
|
||||
<th><%= t('Arguments') %></th>
|
||||
<th><%= t('Started') %></th>
|
||||
</thead>
|
||||
<% workers.each_with_index do |(thread, msg), index| %>
|
||||
<tr>
|
||||
<td><%= thread %></td>
|
||||
<td>
|
||||
<a href="<%= root_path %>queues/<%= msg['queue'] %>"><%= msg['queue'] %></a>
|
||||
</td>
|
||||
<td><%= msg['payload']['class'] %></td>
|
||||
<td>
|
||||
<div class="args"><%= display_args(msg['payload']['args']) %></div>
|
||||
</td>
|
||||
<td><%= relative_time(Time.at(msg['run_at'])) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
<% if workers_size > 0 %>
|
||||
<div class="row">
|
||||
<div class="col-sm-2 pull-right">
|
||||
<form action="<%= root_path %>reset" method="post">
|
||||
<button class="btn btn-primary btn-block" type="submit"><%= t('ClearWorkerList') %></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
|
@ -1,16 +0,0 @@
|
|||
<div class="row header">
|
||||
<div class="col-sm-7">
|
||||
<h3><%= t('Workers') %></h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= erb :_workers %>
|
||||
<% if workers_size > 0 %>
|
||||
<div class="row">
|
||||
<div class="col-sm-2 pull-right">
|
||||
<form action="<%= root_path %>reset" method="post">
|
||||
<button class="btn btn-primary btn-block" type="submit"><%= t('ClearWorkerList') %></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
Loading…
Add table
Reference in a new issue