Module: Gouda::Scheduler
- Defined in:
- lib/gouda/scheduler.rb
Defined Under Namespace
Classes: Entry
Class Method Summary collapse
-
.build_scheduler_entries_list!(cron_table_hash = nil) ⇒ Object
Takes in a Hash formatted with cron entries in the format similar to good_job, and builds a table of scheduler entries.
-
.enqueue_next_scheduled_workload_for(finished_workload) ⇒ Object
Once a workload has finished (doesn’t matter whether it raised an exception or completed successfully), it is going to be passed to this method to enqueue the next scheduled workload.
-
.entries ⇒ Object
Returns the list of entries of the scheduler which are currently known.
-
.upsert_workloads_from_entries_list! ⇒ Object
Will upsert (‘INSERT … ON CONFLICT UPDATE`) workloads for all entries which are in the scheduler entries table (the table needs to be read or hydrated first using `build_scheduler_entries_list!`).
Class Method Details
.build_scheduler_entries_list!(cron_table_hash = nil) ⇒ Object
Takes in a Hash formatted with cron entries in the format similar to good_job, and builds a table of scheduler entries. A scheduler entry references a particular job class name, the set of arguments to be passed to the job when performing it, and either the interval to repeat the job after or a cron pattern. This method does not insert the actual Workloads into the database but just builds the table of the entries. That table gets consulted when workloads finish to determine whether the workload that just ran was scheduled or ad-hoc, and whether the subsequent workload has to be enqueued.
If no table is given the method will attempt to read the table from Rails application config from ‘[:gouda]`.
The table is a Hash of entries, and the keys are the names of the workload to be enqueued - those keys are also used to ensure scheduled workloads only get scheduled once.
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/gouda/scheduler.rb', line 82 def self.build_scheduler_entries_list!(cron_table_hash = nil) Gouda.logger.info "Updating scheduled workload entries..." if cron_table_hash.blank? config_from_rails = Rails.application.config.try(:gouda) cron_table_hash = if config_from_rails.present? config_from_rails.dig(:cron).to_h if config_from_rails.dig(:enable_cron) elsif Gouda.config.enable_cron Gouda.config.cron end return unless cron_table_hash end defaults = {cron: nil, interval_seconds: nil, kwargs: nil, args: nil} @cron_table = cron_table_hash.map do |(name, cron_entry_params)| # `class` is a reserved keyword and a method that exists on every Ruby object so... cron_entry_params[:job_class] ||= cron_entry_params.delete(:class) params_with_defaults = defaults.merge(cron_entry_params) Entry.new(name: name, **params_with_defaults) end end |
.enqueue_next_scheduled_workload_for(finished_workload) ⇒ Object
Once a workload has finished (doesn’t matter whether it raised an exception or completed successfully), it is going to be passed to this method to enqueue the next scheduled workload
111 112 113 114 115 116 117 118 119 |
# File 'lib/gouda/scheduler.rb', line 111 def self.enqueue_next_scheduled_workload_for(finished_workload) return unless finished_workload.scheduler_key timer_table = @cron_table.to_a.index_by(&:scheduler_key) timer_entry = timer_table[finished_workload.scheduler_key] return unless timer_entry Gouda.enqueue_jobs_via_their_adapters([timer_entry.build_active_job]) end |
.entries ⇒ Object
Returns the list of entries of the scheduler which are currently known. Normally the scheduler will hold the list of entries loaded from the Rails config.
125 126 127 |
# File 'lib/gouda/scheduler.rb', line 125 def self.entries @cron_table || [] end |
.upsert_workloads_from_entries_list! ⇒ Object
Will upsert (‘INSERT … ON CONFLICT UPDATE`) workloads for all entries which are in the scheduler entries table (the table needs to be read or hydrated first using `build_scheduler_entries_list!`). This is done in a transaction. Any workloads which have been previously inserted from the scheduled entries, but no longer have a corresponding scheduler entry, will be deleted from the database. If there already are workloads with the corresponding scheduler key they will not be touched and will be performed with their previously-defined arguments.
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/gouda/scheduler.rb', line 137 def self.upsert_workloads_from_entries_list! table_entries = @cron_table || [] # Remove any cron keyed workloads which no longer match config-wise known_keys = table_entries.map(&:scheduler_key).uniq Gouda::Workload.transaction do Gouda::Workload.where.not(scheduler_key: known_keys).delete_all # Insert the next iteration for every "next" entry in the crontab. active_jobs_to_enqueue = table_entries.filter_map(&:build_active_job) Gouda.logger.info "#{active_jobs_to_enqueue.size} job(s) to enqueue from the scheduler." enqjobs = Gouda.enqueue_jobs_via_their_adapters(active_jobs_to_enqueue) Gouda.logger.info "#{enqjobs.size} scheduled job(s) enqueued." end end |