Class: GoodJob::CronManager

Inherits:
Object
  • Object
show all
Defined in:
lib/good_job/cron_manager.rb

Overview

CronManagers enqueue jobs on a repeating schedule.

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cron_entries = [], start_on_initialize: false, executor: Concurrent.global_io_executor) ⇒ CronManager

Returns a new instance of CronManager.

Parameters:

  • cron_entries (Array<CronEntry>) (defaults to: [])
  • start_on_initialize (Boolean) (defaults to: false)


34
35
36
37
38
39
40
41
42
# File 'lib/good_job/cron_manager.rb', line 34

def initialize(cron_entries = [], start_on_initialize: false, executor: Concurrent.global_io_executor)
  @executor = executor
  @running = false
  @cron_entries = cron_entries
  @tasks = Concurrent::Hash.new

  start if start_on_initialize
  self.class.instances << self
end

Class Attribute Details

.instancesArray<GoodJob::CronManager>? (readonly)

List of all instantiated CronManagers in the current process.

Returns:



16
# File 'lib/good_job/cron_manager.rb', line 16

cattr_reader :instances, default: Concurrent::Array.new, instance_reader: false

Instance Attribute Details

#cron_entriesHash (readonly)

Execution configuration to be scheduled

Returns:

  • (Hash)


30
31
32
# File 'lib/good_job/cron_manager.rb', line 30

def cron_entries
  @cron_entries
end

Class Method Details

.task_observer(time, output, thread_error) ⇒ Object

Task observer for cron task

Parameters:

  • time (Time)
  • output (Object)
  • thread_error (Exception)


22
23
24
25
26
# File 'lib/good_job/cron_manager.rb', line 22

def self.task_observer(time, output, thread_error) # rubocop:disable Lint/UnusedMethodArgument
  return if thread_error.is_a? Concurrent::CancelledOperationError

  GoodJob._on_thread_error(thread_error) if thread_error
end

Instance Method Details

#create_task(cron_entry, previously_at: nil) ⇒ Object

Enqueues a scheduled task

Parameters:

  • cron_entry (CronEntry)

    the CronEntry object to schedule

  • previously_at (Date, Time, ActiveSupport::TimeWithZone, nil) (defaults to: nil)

    the last, in-memory, scheduled time the cron task was intended to run



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/good_job/cron_manager.rb', line 84

def create_task(cron_entry, previously_at: nil)
  cron_at = cron_entry.next_at(previously_at: previously_at)
  delay = [(cron_at - Time.current).to_f, 0].max
  future = Concurrent::ScheduledTask.new(delay, args: [self, cron_entry, cron_at], executor: @executor) do |thr_scheduler, thr_cron_entry, thr_cron_at|
    # Re-schedule the next cron task before executing the current task
    thr_scheduler.create_task(thr_cron_entry, previously_at: thr_cron_at)

    Rails.application.executor.wrap do
      cron_entry.enqueue(thr_cron_at) if thr_cron_entry.enabled?
    end
  end

  @tasks[cron_entry.key] = future
  future.add_observer(self.class, :task_observer)
  future.execute
end

#restart(timeout: nil) ⇒ Object

Stop and restart

Parameters:

  • timeout (Numeric, nil) (defaults to: nil)

    Unused but retained for compatibility



64
65
66
67
# File 'lib/good_job/cron_manager.rb', line 64

def restart(timeout: nil) # rubocop:disable Lint/UnusedMethodArgument
  shutdown
  start
end

#running?Boolean?

Tests whether the manager is running.

Returns:

  • (Boolean, nil)


71
72
73
# File 'lib/good_job/cron_manager.rb', line 71

def running?
  @running
end

#shutdown(timeout: nil) ⇒ Object

Stop/cancel any scheduled tasks

Parameters:

  • timeout (Numeric, nil) (defaults to: nil)

    Unused but retained for compatibility



56
57
58
59
60
# File 'lib/good_job/cron_manager.rb', line 56

def shutdown(timeout: nil) # rubocop:disable Lint/UnusedMethodArgument
  @running = false
  @tasks.each_value(&:cancel)
  @tasks.clear
end

#shutdown?Boolean?

Tests whether the manager is shutdown.

Returns:

  • (Boolean, nil)


77
78
79
# File 'lib/good_job/cron_manager.rb', line 77

def shutdown?
  !running?
end

#startObject

Schedule tasks that will enqueue jobs based on their schedule



45
46
47
48
49
50
51
52
# File 'lib/good_job/cron_manager.rb', line 45

def start
  ActiveSupport::Notifications.instrument("cron_manager_start.good_job", cron_entries: cron_entries) do
    @running = true
    cron_entries.each do |cron_entry|
      create_task(cron_entry)
    end
  end
end