lib/good_job/execution.rb in good_job-2.14.4 vs lib/good_job/execution.rb in good_job-2.15.0
- old
+ new
@@ -86,19 +86,19 @@
# @!method priority_ordered
# @!scope class
# @return [ActiveRecord::Relation]
scope :priority_ordered, -> { order('priority DESC NULLS LAST') }
- # Order jobs by scheduled (unscheduled or soonest first).
+ # Order jobs by scheduled or created (oldest first).
# @!method schedule_ordered
# @!scope class
# @return [ActiveRecord::Relation]
scope :schedule_ordered, -> { order(Arel.sql('COALESCE(scheduled_at, created_at) ASC')) }
# Get Jobs were completed before the given timestamp. If no timestamp is
# provided, get all jobs that have been completed. By default, GoodJob
- # deletes jobs after they are completed and this will find no jobs.
+ # destroys jobs after they are completed and this will find no jobs.
# However, if you have changed {GoodJob.preserve_job_records}, this may
# find completed Jobs.
# @!method finished(timestamp = nil)
# @!scope class
# @param timestamp (Float)
@@ -268,9 +268,68 @@
def active_job
ActiveJob::Base.deserialize(active_job_data).tap do |aj|
aj.send(:deserialize_arguments_if_needed)
end
+ end
+
+ # There are 3 buckets of non-overlapping statuses:
+ # 1. The job will be executed
+ # - queued: The job will execute immediately when an execution thread becomes available.
+ # - scheduled: The job is scheduled to execute in the future.
+ # - retried: The job previously errored on execution and will be re-executed in the future.
+ # 2. The job is being executed
+ # - running: the job is actively being executed by an execution thread
+ # 3. The job will not execute
+ # - finished: The job executed successfully
+ # - discarded: The job previously errored on execution and will not be re-executed in the future.
+ #
+ # @return [Symbol]
+ def status
+ if finished_at.present?
+ if error.present?
+ :discarded
+ else
+ :finished
+ end
+ elsif (scheduled_at || created_at) > DateTime.current
+ if serialized_params.fetch('executions', 0) > 1
+ :retried
+ else
+ :scheduled
+ end
+ elsif running?
+ :running
+ else
+ :queued
+ end
+ end
+
+ def running?
+ performed_at? && !finished_at?
+ end
+
+ def number
+ serialized_params.fetch('executions', 0) + 1
+ end
+
+ # The last relevant timestamp for this execution
+ def last_status_at
+ finished_at || performed_at || scheduled_at || created_at
+ end
+
+ # Time between when this job was expected to run and when it started running
+ def queue_latency
+ now = Time.zone.now
+ expected_start = scheduled_at || created_at
+ actual_start = performed_at || now
+
+ actual_start - expected_start unless expected_start >= now
+ end
+
+ # Time between when this job started and finished
+ def runtime_latency
+ (finished_at || Time.zone.now) - performed_at if performed_at
end
private
def active_job_data