lib/good_job/job.rb in good_job-1.6.0 vs lib/good_job/job.rb in good_job-1.7.0
- old
+ new
@@ -70,10 +70,16 @@
# @!method priority_ordered
# @!scope class
# @return [ActiveRecord::Relation]
scope :priority_ordered, -> { order('priority DESC NULLS LAST') }
+ # Order jobs by scheduled (unscheduled or soonest 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.
# However, if you have changed {GoodJob.preserve_job_records}, this may
# find completed Jobs.
@@ -143,9 +149,26 @@
result, error = good_job.perform
end
[good_job, result, error] if good_job
+ end
+
+ # Fetches the scheduled execution time of the next eligible Job(s).
+ # @return [Array<(DateTime)>]
+ def self.next_scheduled_at(after: nil, limit: 100, now_limit: nil)
+ query = advisory_unlocked.unfinished.schedule_ordered
+
+ after ||= Time.current
+ after_query = query.where('scheduled_at > ?', after).or query.where(scheduled_at: nil).where('created_at > ?', after)
+ after_at = after_query.limit(limit).pluck(:scheduled_at, :created_at).map { |timestamps| timestamps.compact.first }
+
+ if now_limit&.positive?
+ now_query = query.where('scheduled_at < ?', Time.current).or query.where(scheduled_at: nil)
+ now_at = now_query.limit(now_limit).pluck(:scheduled_at, :created_at).map { |timestamps| timestamps.compact.first }
+ end
+
+ Array(now_at) + after_at
end
# Places an ActiveJob job on a queue by creating a new {Job} record.
# @param active_job [ActiveJob::Base]
# The job to enqueue.