Skip to content

Commit

Permalink
Adds elapsed time and ETA tracking (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
aussiDavid authored Feb 18, 2023
1 parent 7d3d19a commit 5b8d6d4
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 3 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ Sidekiq::Status::at job_id #=> 5
Sidekiq::Status::total job_id #=> 100
Sidekiq::Status::message job_id #=> "Almost done"
Sidekiq::Status::pct_complete job_id #=> 5
Sidekiq::Status::working_at job_id #=> 2718
Sidekiq::Status::update_time job_id #=> 2819
```

### Unscheduling
Expand Down
15 changes: 15 additions & 0 deletions lib/sidekiq-status.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,21 @@ def pct_complete(job_id)
get(job_id, :pct_complete).to_i
end

def working_at(job_id)
(get(job_id, :working_at) || Time.now).to_i
end

def update_time(job_id)
(get(job_id, :update_time) || Time.now).to_i
end

def eta(job_id)
at = at(job_id)
return nil if at.zero?

(Time.now.to_i - working_at(job_id)).to_f / at * (total(job_id) - at)
end

def message(job_id)
get(job_id, :message)
end
Expand Down
19 changes: 18 additions & 1 deletion lib/sidekiq-status/web.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module Web

DEFAULT_PER_PAGE_OPTS = [25, 50, 100].freeze
DEFAULT_PER_PAGE = 25
COMMON_STATUS_HASH_KEYS = %w(update_time jid status worker args label pct_complete total at message)
COMMON_STATUS_HASH_KEYS = %w(update_time jid status worker args label pct_complete total at message working_at elapsed eta)

class << self
def per_page_opts= arr
Expand Down Expand Up @@ -48,6 +48,8 @@ def sidekiq_status_template(name)
def add_details_to_status(status)
status['label'] = status_label(status['status'])
status["pct_complete"] ||= pct_complete(status)
status["elapsed"] ||= elapsed(status).to_s
status["eta"] ||= eta(status).to_s
status["custom"] = process_custom_data(status)
return status
end
Expand All @@ -61,6 +63,19 @@ def pct_complete(status)
Sidekiq::Status::pct_complete(status['jid']) || 0
end

def elapsed(status)
case status['status']
when 'complete'
Sidekiq::Status.update_time(status['jid']) - Sidekiq::Status.working_at(status['jid'])
when 'working', 'retrying'
Time.now.to_i - Sidekiq::Status.working_at(status['jid'])
end
end

def eta(status)
Sidekiq::Status.eta(status['jid']) if status['status'] == 'working'
end

def status_label(status)
case status
when 'complete'
Expand Down Expand Up @@ -122,6 +137,8 @@ def has_sort_by?(value)
{id: "status", name: "Status", class: nil, url: nil},
{id: "update_time", name: "Last Updated", class: nil, url: nil},
{id: "pct_complete", name: "Progress", class: nil, url: nil},
{id: "elapsed", name: "Time Elapsed", class: nil, url: nil},
{id: "eta", name: "ETA", class: nil, url: nil},
]

@headers.each do |h|
Expand Down
9 changes: 7 additions & 2 deletions lib/sidekiq-status/worker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,20 @@ def retrieve(name)
def at(num, message = nil)
@_status_total = 100 if @_status_total.nil?
pct_complete = ((num / @_status_total.to_f) * 100).to_i rescue 0
store(at: num, total: @_status_total, pct_complete: pct_complete, message: message)
store(at: num, total: @_status_total, pct_complete: pct_complete, message: message, working_at: working_at)
end

# Sets total number of tasks
# @param Fixnum total number of tasks
# @return [String]
def total(num)
@_status_total = num
store(total: num)
store(total: num, working_at: working_at)
end

private

def working_at
@working_at ||= Time.now.to_i
end
end
18 changes: 18 additions & 0 deletions spec/lib/sidekiq-status/worker_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,22 @@
expect(subject.expiration).to eq(:val)
end
end

describe ".at" do
subject { StubJob.new }

it "records when the worker has started" do
expect { subject.at(0) }.to(change { subject.retrieve('working_at') })
end

context "when setting the total for the worker" do
it "records when the worker has started" do
expect { subject.total(100) }.to(change { subject.retrieve('working_at') })
end
end

it "records when the worker last worked" do
expect { subject.at(0) }.to(change { subject.retrieve('update_time') })
end
end
end
26 changes: 26 additions & 0 deletions web/views/status.erb
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,32 @@
</div>
</div>

<div class="row">
<div class="col-sm-2">
<strong>Elapsed Time</strong>
</div>
<div class="col-sm-10">
<p>
<% if @status["elapsed"] %>
<%= ChronicDuration.output(@status["elapsed"].to_i, :weeks => true, :units => 2) %>
<% end %>
</p>
</div>
</div>

<div class="row">
<div class="col-sm-2">
<strong>ETA</strong>
</div>
<div class="col-sm-10">
<p>
<% if @status["eta"] %>
<%= ChronicDuration.output(@status["eta"].to_i, :weeks => true, :units => 2) %>
<% end %>
</p>
</div>
</div>

<% if @status["custom"].any? %>
<hr>
<% @status["custom"].each do |key, val| %>
Expand Down
10 changes: 10 additions & 0 deletions web/views/statuses.erb
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,16 @@ function setPerPage(select){
<% end %>
</div>
</td>
<td style='text-align: center; white-space: nowrap;'>
<% if container["elapsed"] %>
<%= ChronicDuration.output(container["elapsed"].to_i, :weeks => true, :units => 2) %>
<% end %>
</td>
<td style='text-align: center; white-space: nowrap;'>
<% if container["eta"] %>
<%= ChronicDuration.output(container["eta"].to_i, :weeks => true, :units => 2) %>
<% end %>
</td>
<td>
<div class="actions">
<form action="statuses" method="post">
Expand Down

0 comments on commit 5b8d6d4

Please sign in to comment.