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.