From 167388f2f77150d77530a30177fdf101760600c7 Mon Sep 17 00:00:00 2001 From: Uepsilon Date: Wed, 28 May 2014 15:56:08 +0200 Subject: [PATCH 1/4] adds duration to job --- lib/resque/plugins/status.rb | 20 ++++++++++++++++---- lib/resque/plugins/status/hash.rb | 28 ++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/lib/resque/plugins/status.rb b/lib/resque/plugins/status.rb index 2089d61..5940cd2 100644 --- a/lib/resque/plugins/status.rb +++ b/lib/resque/plugins/status.rb @@ -157,7 +157,10 @@ def initialize(uuid, options = {}) # If an error occurs within the job's work, it will set the status as failed and # re-raise the error. def safe_perform! - set_status({'status' => STATUS_WORKING}) + set_status({ + 'status' => STATUS_WORKING, + 'started_at' => Time.now.to_i + }) perform if status && status.failed? on_failure(status.message) if respond_to?(:on_failure) @@ -219,26 +222,35 @@ def at(num, total, *messages) # Resque::Plugins::Status::Hash.kill() def tick(*messages) kill! if should_kill? - set_status({'status' => STATUS_WORKING}, *messages) + + status_options = {'status' => STATUS_WORKING} + status_options.merge!('started_at' => Time.now.to_i) unless status.working? + + set_status(status_options, *messages) end # set the status to 'failed' passing along any additional messages def failed(*messages) - set_status({'status' => STATUS_FAILED}, *messages) + set_status({ + 'status' => STATUS_FAILED, + 'finished_at' => Time.now.to_i, + }, *messages) end # set the status to 'completed' passing along any addional messages def completed(*messages) set_status({ 'status' => STATUS_COMPLETED, + 'finished_at' => Time.now.to_i, 'message' => "Completed at #{Time.now}" - }, *messages) + }, *messages) end # kill the current job, setting the status to 'killed' and raising Killed def kill! set_status({ 'status' => STATUS_KILLED, + 'finished_at' => Time.now.to_i, 'message' => "Killed at #{Time.now}" }) raise Killed diff --git a/lib/resque/plugins/status/hash.rb b/lib/resque/plugins/status/hash.rb index bb5ae89..72706d0 100644 --- a/lib/resque/plugins/status/hash.rb +++ b/lib/resque/plugins/status/hash.rb @@ -205,6 +205,10 @@ class << self hash_accessor :num hash_accessor :total + #adds start- & end-time for processing + hash_accessor :started_at + hash_accessor :finished_at + # Create a new Resque::Plugins::Status::Hash object. If multiple arguments are passed # it is assumed the first argument is the UUID and the rest are status objects. # All arguments are subsequentily merged in order. Strings are assumed to @@ -242,6 +246,30 @@ def time time? ? Time.at(self['time']) : nil end + # Returns the duration the job took to be performed or to current time + # when it's not done yet + # format can be given to format time + def duration(format = "%H:%M:%S") + duration = nil + if completed? or failed? + duration = self['finished_at'] - self['started_at'] + elsif working? + duration = Time.now.to_i - self['started_at'] + end + + Time.at(duration).utc.strftime(format) + end + + # Returns the time when the perform was called + def started_at + started_at? ? Time.at(self['started_at']) : nil + end + + # Returns the time when the processing was completed / failed + def finished_at + finished_at? ? Time.at(self['finished_at']) : nil + end + Resque::Plugins::Status::STATUSES.each do |status| define_method("#{status}?") do self['status'] === status From 502140a77273aeb8dc0eccd7be30c7f480a01d82 Mon Sep 17 00:00:00 2001 From: Uepsilon Date: Wed, 28 May 2014 15:58:34 +0200 Subject: [PATCH 2/4] fixes issue when duration is not calculable --- lib/resque/plugins/status/hash.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resque/plugins/status/hash.rb b/lib/resque/plugins/status/hash.rb index 72706d0..cee8cc6 100644 --- a/lib/resque/plugins/status/hash.rb +++ b/lib/resque/plugins/status/hash.rb @@ -257,7 +257,7 @@ def duration(format = "%H:%M:%S") duration = Time.now.to_i - self['started_at'] end - Time.at(duration).utc.strftime(format) + duration.nil? ? nil : Time.at(duration).utc.strftime(format) end # Returns the time when the perform was called From 355fdb61b6544a8b0c086362910760b1179db867 Mon Sep 17 00:00:00 2001 From: Uepsilon Date: Wed, 28 May 2014 16:40:54 +0200 Subject: [PATCH 3/4] adds output of duration, started_at and finished_at to server --- lib/resque/server/views/status.erb | 3 ++- lib/resque/server/views/statuses.erb | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/resque/server/views/status.erb b/lib/resque/server/views/status.erb index e6a54da..f38acfa 100644 --- a/lib/resque/server/views/status.erb +++ b/lib/resque/server/views/status.erb @@ -53,6 +53,7 @@ .attr('class', '') .addClass('status-progress-bar status-' + json.status); } + if (json.time) { $status.find('.status-time').text(new Date(json.time * 1000).toString()) } @@ -76,7 +77,7 @@ }; function printValue(key, value) { - if (/(^|_)time$/.test(key) && typeof value == 'number') { + if (/(^|_)(time|started_at|finished_at)$/.test(key) && typeof value == 'number') { var time = new Date(); time.setTime(value * 1000); return time.toUTCString(); diff --git a/lib/resque/server/views/statuses.erb b/lib/resque/server/views/statuses.erb index b30378b..0b9287f 100644 --- a/lib/resque/server/views/statuses.erb +++ b/lib/resque/server/views/statuses.erb @@ -21,6 +21,7 @@ Last Updated % Complete Message + Duration Kill <% unless @statuses.empty? %> @@ -35,6 +36,7 @@
<%= status.pct_complete ? "#{status.pct_complete}%" : '' %>
<%= status.message %> + <%= status.duration %> <% if status.killable? %>Kill<% end %> <% end %> From f073c70fbc3413497eeed8ee3e2af41862bd0a46 Mon Sep 17 00:00:00 2001 From: Uepsilon Date: Wed, 28 May 2014 17:25:25 +0200 Subject: [PATCH 4/4] now displays duration for killed jobs --- lib/resque/plugins/status/hash.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resque/plugins/status/hash.rb b/lib/resque/plugins/status/hash.rb index cee8cc6..272b02f 100644 --- a/lib/resque/plugins/status/hash.rb +++ b/lib/resque/plugins/status/hash.rb @@ -251,7 +251,7 @@ def time # format can be given to format time def duration(format = "%H:%M:%S") duration = nil - if completed? or failed? + if completed? or failed? or killed? duration = self['finished_at'] - self['started_at'] elsif working? duration = Time.now.to_i - self['started_at']