mirror of
https://github.com/mperham/sidekiq.git
synced 2022-11-09 13:52:34 -05:00
Merge branch 'feature/arg-scroll' of git://github.com/jonhyman/sidekiq into jonhyman-feature/arg-scroll
This commit is contained in:
commit
8ef73772c1
9 changed files with 132 additions and 52 deletions
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
- Make Sidekiq::Middleware::Chain Enumerable
|
- Make Sidekiq::Middleware::Chain Enumerable
|
||||||
- Make summary bar and graphs responsive [manishval] [#1025]
|
- Make summary bar and graphs responsive [manishval] [#1025]
|
||||||
|
- Adds a job status page for scheduled jobs [jonhyman]
|
||||||
|
|
||||||
2.13.0
|
2.13.0
|
||||||
-----------
|
-----------
|
||||||
|
|
|
@ -105,10 +105,10 @@ module Sidekiq
|
||||||
[score.to_f, jid]
|
[score.to_f, jid]
|
||||||
end
|
end
|
||||||
|
|
||||||
def display_args(args, count=100)
|
def display_args(args, truncate_after_chars = 2000)
|
||||||
args.map do |arg|
|
args.map do |arg|
|
||||||
a = arg.inspect
|
a = arg.inspect
|
||||||
a.size > count ? "#{a[0..count]}..." : a
|
truncate_after_chars && a.size > truncate_after_chars ? "#{a[0..truncate_after_chars]}..." : a
|
||||||
end.join(", ")
|
end.join(", ")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -247,6 +247,13 @@ module Sidekiq
|
||||||
slim :scheduled
|
slim :scheduled
|
||||||
end
|
end
|
||||||
|
|
||||||
|
get "/scheduled/:key" do
|
||||||
|
halt 404 unless params['key']
|
||||||
|
@job = Sidekiq::ScheduledSet.new.fetch(*parse_params(params['key'])).first
|
||||||
|
redirect "#{root_path}scheduled" if @job.nil?
|
||||||
|
slim :scheduled_job_info
|
||||||
|
end
|
||||||
|
|
||||||
post '/scheduled' do
|
post '/scheduled' do
|
||||||
halt 404 unless params['key']
|
halt 404 unless params['key']
|
||||||
|
|
||||||
|
@ -261,6 +268,17 @@ module Sidekiq
|
||||||
redirect "#{root_path}scheduled"
|
redirect "#{root_path}scheduled"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
post "/scheduled/:key" do
|
||||||
|
halt 404 unless params['key']
|
||||||
|
job = Sidekiq::ScheduledSet.new.fetch(*parse_params(params['key'])).first
|
||||||
|
if params['add_to_queue']
|
||||||
|
job.add_to_queue
|
||||||
|
elsif params['delete']
|
||||||
|
job.delete
|
||||||
|
end
|
||||||
|
redirect "#{root_path}scheduled"
|
||||||
|
end
|
||||||
|
|
||||||
get '/' do
|
get '/' do
|
||||||
@redis_info = Sidekiq.redis { |conn| conn.info }.select{ |k, v| redis_keys.include? k }
|
@redis_info = Sidekiq.redis { |conn| conn.info }.select{ |k, v| redis_keys.include? k }
|
||||||
stats_history = Sidekiq::Stats::History.new((params[:days] || 30).to_i)
|
stats_history = Sidekiq::Stats::History.new((params[:days] || 30).to_i)
|
||||||
|
|
|
@ -130,7 +130,7 @@ class TestWeb < Minitest::Test
|
||||||
|
|
||||||
it 'can display a single retry' do
|
it 'can display a single retry' do
|
||||||
params = add_retry
|
params = add_retry
|
||||||
get '/retries/2c4c17969825a384a92f023b'
|
get '/retries/0-shouldntexist'
|
||||||
assert_equal 302, last_response.status
|
assert_equal 302, last_response.status
|
||||||
get "/retries/#{job_params(*params)}"
|
get "/retries/#{job_params(*params)}"
|
||||||
assert_equal 200, last_response.status
|
assert_equal 200, last_response.status
|
||||||
|
@ -138,7 +138,7 @@ class TestWeb < Minitest::Test
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'handles missing retry' do
|
it 'handles missing retry' do
|
||||||
get "/retries/2c4c17969825a384a92f023b"
|
get "/retries/0-shouldntexist"
|
||||||
assert_equal 302, last_response.status
|
assert_equal 302, last_response.status
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -187,6 +187,42 @@ class TestWeb < Minitest::Test
|
||||||
assert_match /HardWorker/, last_response.body
|
assert_match /HardWorker/, last_response.body
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'can display a single scheduled job' do
|
||||||
|
params = add_scheduled
|
||||||
|
get '/scheduled/0-shouldntexist'
|
||||||
|
assert_equal 302, last_response.status
|
||||||
|
get "/scheduled/#{job_params(*params)}"
|
||||||
|
assert_equal 200, last_response.status
|
||||||
|
assert_match /HardWorker/, last_response.body
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'handles missing scheduled job' do
|
||||||
|
get "/scheduled/0-shouldntexist"
|
||||||
|
assert_equal 302, last_response.status
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can add to queue a single scheduled job' do
|
||||||
|
params = add_scheduled
|
||||||
|
post "/scheduled/#{job_params(*params)}", 'add_to_queue' => true
|
||||||
|
assert_equal 302, last_response.status
|
||||||
|
assert_equal 'http://example.org/scheduled', last_response.header['Location']
|
||||||
|
|
||||||
|
get '/queues/default'
|
||||||
|
assert_equal 200, last_response.status
|
||||||
|
assert_match /#{params.first['args'][2]}/, last_response.body
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can delete a single scheduled job' do
|
||||||
|
params = add_scheduled
|
||||||
|
post "/scheduled/#{job_params(*params)}", 'delete' => 'Delete'
|
||||||
|
assert_equal 302, last_response.status
|
||||||
|
assert_equal 'http://example.org/scheduled', last_response.header['Location']
|
||||||
|
|
||||||
|
get "/scheduled"
|
||||||
|
assert_equal 200, last_response.status
|
||||||
|
refute_match /#{params.first['args'][2]}/, last_response.body
|
||||||
|
end
|
||||||
|
|
||||||
it 'can delete scheduled' do
|
it 'can delete scheduled' do
|
||||||
params = add_scheduled
|
params = add_scheduled
|
||||||
Sidekiq.redis do |conn|
|
Sidekiq.redis do |conn|
|
||||||
|
|
|
@ -844,4 +844,12 @@ img.smallogo {
|
||||||
.rickshaw_legend li:active {
|
.rickshaw_legend li:active {
|
||||||
background: rgba(255, 255, 255, 0.2);
|
background: rgba(255, 255, 255, 0.2);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
.args {
|
||||||
|
overflow: scroll;
|
||||||
|
max-height: 100px;
|
||||||
|
}
|
||||||
|
.args-extended {
|
||||||
|
overflow: scroll;
|
||||||
|
max-height: 500px;
|
||||||
|
}
|
||||||
|
|
51
web/views/_job_info.slim
Normal file
51
web/views/_job_info.slim
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
header
|
||||||
|
h3 = t('Job')
|
||||||
|
|
||||||
|
table class="table table-bordered table-striped"
|
||||||
|
tbody
|
||||||
|
tr
|
||||||
|
th = t('Queue')
|
||||||
|
td
|
||||||
|
a href="#{root_path}queues/#{job['queue']}" #{job['queue']}
|
||||||
|
tr
|
||||||
|
th = t('Class')
|
||||||
|
td
|
||||||
|
code= job['class']
|
||||||
|
tr
|
||||||
|
th = t('Arguments')
|
||||||
|
td
|
||||||
|
code
|
||||||
|
// We don't want to truncate any job arguments when viewing a single job's status page
|
||||||
|
div.args-extended=display_args(job['args'], nil)
|
||||||
|
tr
|
||||||
|
th JID
|
||||||
|
td
|
||||||
|
code= job.jid
|
||||||
|
tr
|
||||||
|
th = t('Enqueued')
|
||||||
|
td== relative_time(job.enqueued_at)
|
||||||
|
- unless retry_extra_items(job).empty?
|
||||||
|
tr
|
||||||
|
th = t('Extras')
|
||||||
|
td
|
||||||
|
code
|
||||||
|
= retry_extra_items(job).inspect
|
||||||
|
- if type == :retry
|
||||||
|
- if job['retry_count'] && job['retry_count'] > 0
|
||||||
|
tr
|
||||||
|
th = t('RetryCount')
|
||||||
|
td= job['retry_count']
|
||||||
|
tr
|
||||||
|
th = t('LastRetry')
|
||||||
|
td== relative_time(job['retried_at'].is_a?(Numeric) ? Time.at(job['retried_at']) : Time.parse(job['retried_at']))
|
||||||
|
- else
|
||||||
|
tr
|
||||||
|
th = t('OriginallyFailed')
|
||||||
|
td== relative_time(job['failed_at'].is_a?(Numeric) ? Time.at(job['failed_at']) : Time.parse(job['failed_at']))
|
||||||
|
tr
|
||||||
|
th = t('NextRetry')
|
||||||
|
td== relative_time(job.at)
|
||||||
|
- if type == :scheduled
|
||||||
|
tr
|
||||||
|
th = t('Scheduled')
|
||||||
|
td== relative_time(job.at)
|
|
@ -27,7 +27,8 @@ header.row
|
||||||
td
|
td
|
||||||
a href="#{root_path}queues/#{msg['queue']}" #{msg['queue']}
|
a href="#{root_path}queues/#{msg['queue']}" #{msg['queue']}
|
||||||
td= msg['class']
|
td= msg['class']
|
||||||
td= display_args(msg['args'])
|
td
|
||||||
|
div.args=display_args(msg['args'])
|
||||||
input.btn.btn-primary.btn-small.pull-left type="submit" name="retry" value="#{t('RetryNow')}"
|
input.btn.btn-primary.btn-small.pull-left type="submit" name="retry" value="#{t('RetryNow')}"
|
||||||
input.btn.btn-danger.btn-small.pull-left type="submit" name="delete" value="#{t('Delete')}"
|
input.btn.btn-danger.btn-small.pull-left type="submit" name="delete" value="#{t('Delete')}"
|
||||||
|
|
||||||
|
|
|
@ -1,47 +1,4 @@
|
||||||
header
|
== slim :_job_info, :locals => {:job => @retry, :type => :retry}
|
||||||
h3 = t('Job')
|
|
||||||
|
|
||||||
table class="retry table table-bordered table-striped"
|
|
||||||
tbody
|
|
||||||
tr
|
|
||||||
th = t('Queue')
|
|
||||||
td
|
|
||||||
a href="#{root_path}queues/#{@retry['queue']}" #{@retry['queue']}
|
|
||||||
tr
|
|
||||||
th = t('Class')
|
|
||||||
td
|
|
||||||
code= @retry['class']
|
|
||||||
tr
|
|
||||||
th = t('Arguments')
|
|
||||||
td
|
|
||||||
code= display_args(@retry['args'], 1000)
|
|
||||||
tr
|
|
||||||
th JID
|
|
||||||
td
|
|
||||||
code= @retry.jid
|
|
||||||
tr
|
|
||||||
th = t('Enqueued')
|
|
||||||
td== relative_time(@retry.enqueued_at)
|
|
||||||
- unless retry_extra_items(@retry).empty?
|
|
||||||
tr
|
|
||||||
th = t('Extras')
|
|
||||||
td
|
|
||||||
code
|
|
||||||
= retry_extra_items(@retry).inspect
|
|
||||||
- if @retry['retry_count'] > 0
|
|
||||||
tr
|
|
||||||
th = t('RetryCount')
|
|
||||||
td= @retry['retry_count']
|
|
||||||
tr
|
|
||||||
th = t('LastRetry')
|
|
||||||
td== relative_time(@retry['retried_at'].is_a?(Numeric) ? Time.at(@retry['retried_at']) : Time.parse(@retry['retried_at']))
|
|
||||||
- else
|
|
||||||
tr
|
|
||||||
th = t('OriginallyFailed')
|
|
||||||
td== relative_time(@retry['failed_at'].is_a?(Numeric) ? Time.at(@retry['failed_at']) : Time.parse(@retry['failed_at']))
|
|
||||||
tr
|
|
||||||
th = t('NextRetry')
|
|
||||||
td== relative_time(@retry.at)
|
|
||||||
|
|
||||||
h3 = t('Error')
|
h3 = t('Error')
|
||||||
table class="error table table-bordered table-striped"
|
table class="error table table-bordered table-striped"
|
||||||
|
|
|
@ -20,11 +20,13 @@ header.row
|
||||||
tr
|
tr
|
||||||
td
|
td
|
||||||
input type='checkbox' name='key[]' value='#{job_params(msg, score)}'
|
input type='checkbox' name='key[]' value='#{job_params(msg, score)}'
|
||||||
td== relative_time(Time.at(score))
|
td
|
||||||
|
a href="#{root_path}scheduled/#{job_params(msg, score)}"== relative_time(Time.at(score))
|
||||||
td
|
td
|
||||||
a href="#{root_path}queues/#{msg['queue']}" #{msg['queue']}
|
a href="#{root_path}queues/#{msg['queue']}" #{msg['queue']}
|
||||||
td= msg['class']
|
td= msg['class']
|
||||||
td= display_args(msg['args'])
|
td
|
||||||
|
div.args=display_args(msg['args'])
|
||||||
input.btn.btn-danger.pull-right type="submit" name="delete" value="#{t('Delete')}"
|
input.btn.btn-danger.pull-right type="submit" name="delete" value="#{t('Delete')}"
|
||||||
input.btn.btn-danger.pull-right type="submit" name="add_to_queue" value="#{t('AddToQueue')}"
|
input.btn.btn-danger.pull-right type="submit" name="add_to_queue" value="#{t('AddToQueue')}"
|
||||||
- else
|
- else
|
||||||
|
|
6
web/views/scheduled_job_info.slim
Normal file
6
web/views/scheduled_job_info.slim
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
== slim :_job_info, :locals => {:job => @job, :type => :scheduled}
|
||||||
|
|
||||||
|
form.form-horizontal action="#{root_path}scheduled/#{job_params(@job, @job.score)}" method="post"
|
||||||
|
a.btn href="#{root_path}scheduled" = t('GoBack')
|
||||||
|
input.btn.btn-primary type="submit" name="add_to_queue" value="#{t('AddToQueue')}"
|
||||||
|
input.btn.btn-danger type="submit" name="delete" value="#{t('Delete')}"
|
Loading…
Add table
Reference in a new issue