Module: GoodJob
- Includes:
- ActiveSupport::Deprecation::DeprecatedConstantAccessor, Dependencies, ThreadStatus
- Defined in:
- lib/good_job.rb,
lib/good_job/cli.rb,
lib/good_job/bulk.rb,
lib/good_job/daemon.rb,
lib/good_job/engine.rb,
lib/good_job/poller.rb,
lib/good_job/adapter.rb,
lib/good_job/capsule.rb,
lib/good_job/version.rb,
lib/good_job/callable.rb,
lib/good_job/notifier.rb,
lib/good_job/scheduler.rb,
lib/good_job/sd_notify.rb,
app/models/good_job/job.rb,
app/models/good_job/batch.rb,
lib/good_job/cron_manager.rb,
lib/good_job/dependencies.rb,
lib/good_job/probe_server.rb,
lib/good_job/configuration.rb,
lib/good_job/job_performer.rb,
lib/good_job/thread_status.rb,
app/models/good_job/process.rb,
app/models/good_job/setting.rb,
lib/good_job/current_thread.rb,
lib/good_job/log_subscriber.rb,
lib/good_job/cleanup_tracker.rb,
lib/good_job/interrupt_error.rb,
lib/good_job/multi_scheduler.rb,
lib/good_job/shared_executor.rb,
lib/good_job/systemd_service.rb,
app/models/good_job/execution.rb,
app/models/good_job/cron_entry.rb,
app/models/good_job/base_record.rb,
app/models/good_job/i18n_config.rb,
app/filters/good_job/base_filter.rb,
app/filters/good_job/jobs_filter.rb,
app/models/good_job/batch_record.rb,
app/helpers/good_job/icons_helper.rb,
app/models/good_job/base_execution.rb,
lib/good_job/job_performer/metrics.rb,
app/filters/good_job/batches_filter.rb,
lib/good_job/overridable_connection.rb,
app/models/good_job/execution_result.rb,
app/models/good_job/discrete_execution.rb,
app/helpers/good_job/application_helper.rb,
app/models/concerns/good_job/filterable.rb,
app/models/concerns/good_job/reportable.rb,
lib/good_job/notifier/process_heartbeat.rb,
lib/good_job/probe_server/not_found_app.rb,
app/controllers/good_job/jobs_controller.rb,
lib/generators/good_job/update_generator.rb,
lib/good_job/probe_server/simple_handler.rb,
app/models/concerns/good_job/error_events.rb,
lib/generators/good_job/install_generator.rb,
lib/good_job/active_job_extensions/labels.rb,
lib/good_job/probe_server/webrick_handler.rb,
lib/good_job/active_job_extensions/batches.rb,
app/controllers/good_job/batches_controller.rb,
app/controllers/good_job/metrics_controller.rb,
app/charts/good_job/scheduled_by_queue_chart.rb,
app/controllers/good_job/frontends_controller.rb,
app/controllers/good_job/processes_controller.rb,
app/models/concerns/good_job/advisory_lockable.rb,
app/models/good_job/active_record_parent_class.rb,
lib/good_job/active_job_extensions/concurrency.rb,
app/controllers/good_job/application_controller.rb,
app/controllers/good_job/cron_entries_controller.rb,
lib/good_job/probe_server/healthcheck_middleware.rb,
lib/good_job/active_job_extensions/notify_options.rb,
lib/good_job/active_job_extensions/interrupt_errors.rb
Overview
:nodoc:
Defined Under Namespace
Modules: ActiveJobExtensions, AdvisoryLockable, ApplicationHelper, Bulk, Callable, CurrentThread, Dependencies, ErrorEvents, Filterable, IconsHelper, OverridableConnection, Reportable, SdNotify, ThreadStatus Classes: Adapter, ApplicationController, BaseExecution, BaseFilter, BaseRecord, Batch, BatchRecord, BatchesController, BatchesFilter, CLI, Capsule, CleanupTracker, Configuration, CronEntriesController, CronEntry, CronManager, Daemon, DiscreteExecution, Engine, Execution, ExecutionResult, FrontendsController, I18nConfig, InstallGenerator, InterruptError, Job, JobPerformer, JobsController, JobsFilter, LogSubscriber, MetricsController, MultiScheduler, Notifier, Poller, ProbeServer, Process, ProcessesController, ScheduledByQueueChart, Scheduler, Setting, SharedExecutor, SystemdService, UpdateGenerator
Constant Summary collapse
- NONE =
Default, null, blank value placeholder.
Module.new.freeze
- DEFAULT_LOGGER =
Default logger for GoodJob; overridden by Rails.logger in Railtie.
ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new($stdout))
- VERSION =
GoodJob gem version.
'3.28.2'
- GEM_VERSION =
GoodJob version as Gem::Version object
Gem::Version.new(VERSION)
- ActiveRecordParentClass =
if GoodJob.active_record_parent_class Object.const_get(GoodJob.active_record_parent_class) else ActiveRecord::Base end
Class Attribute Summary collapse
-
.active_record_parent_class ⇒ ActiveRecord::Base
The ActiveRecord parent class inherited by
GoodJob::Execution
(default:ActiveRecord::Base
). -
.capsule ⇒ GoodJob::Capsule?
Global/default execution capsule for GoodJob.
-
.configuration ⇒ GoodJob::Configuration?
Global configuration object for GoodJob.
-
.logger ⇒ Logger?
The logger used by GoodJob (default:
Rails.logger
). -
.on_thread_error ⇒ Proc?
This callable will be called when an exception reaches GoodJob (default:
nil
). -
.preserve_job_records ⇒ Boolean, ...
Whether to preserve job records in the database after they have finished (default:
true
). -
.retry_on_unhandled_error ⇒ Boolean?
Whether to re-perform a job when a type of
StandardError
is raised to GoodJob (default:false
).
Class Method Summary collapse
-
._on_thread_error(exception) ⇒ void
Called with exception when a GoodJob thread raises an exception.
-
._shutdown_all(executables, method_name = :shutdown, timeout: -1)) ⇒ void
Sends
#shutdown
or#restart
to executable objects (Notifier, Poller, Scheduler, MultiScheduler, CronManager). -
.cleanup_preserved_jobs(older_than: nil, in_batches_of: 1_000) ⇒ Integer
Destroys preserved job and batch records.
-
.configure_active_record(&block) ⇒ void
Custom Active Record configuration that is class_eval’ed into
GoodJob::BaseRecord
. -
.deprecator ⇒ ActiveSupport::Deprecation
Deprecator for providing deprecation warnings.
-
.migrated? ⇒ Boolean
Whether all GoodJob migrations have been applied.
-
.perform_inline(queue_string = "*", limit: nil) ⇒ void
Perform all queued jobs in the current thread.
-
.restart(timeout: -1)) ⇒ void
Stops and restarts executing jobs.
-
.shutdown(timeout: -1)) ⇒ void
Stop executing jobs.
-
.shutdown? ⇒ Boolean
Tests whether jobs have stopped executing.
Class Attribute Details
.active_record_parent_class ⇒ ActiveRecord::Base
The ActiveRecord parent class inherited by GoodJob::Execution
(default: ActiveRecord::Base
). Use this when using multiple databases or other custom ActiveRecord configuration.
65 |
# File 'lib/good_job.rb', line 65 mattr_accessor :active_record_parent_class, default: nil |
.capsule ⇒ GoodJob::Capsule?
Global/default execution capsule for GoodJob.
115 |
# File 'lib/good_job.rb', line 115 mattr_accessor :capsule, default: GoodJob::Capsule.new(configuration: configuration) |
.configuration ⇒ GoodJob::Configuration?
Global configuration object for GoodJob.
109 |
# File 'lib/good_job.rb', line 109 mattr_accessor :configuration, default: GoodJob::Configuration.new({}) |
.logger ⇒ Logger?
The logger used by GoodJob (default: Rails.logger
). Use this to redirect logs to a special location or file.
74 |
# File 'lib/good_job.rb', line 74 mattr_accessor :logger, default: DEFAULT_LOGGER |
.on_thread_error ⇒ Proc?
This callable will be called when an exception reaches GoodJob (default: nil
). It can be useful for logging errors to bug tracking services, like Sentry or Airbrake.
103 |
# File 'lib/good_job.rb', line 103 mattr_accessor :on_thread_error, default: nil |
.preserve_job_records ⇒ Boolean, ...
Whether to preserve job records in the database after they have finished (default: true
). If you want to preserve jobs for latter inspection, set this to true
. If you want to preserve only jobs that finished with error for latter inspection, set this to :on_unhandled_error
. If you do not want to preserve jobs, set this to false
. When using GoodJob’s cron functionality, job records will be preserved for a brief time to prevent duplicate jobs.
84 |
# File 'lib/good_job.rb', line 84 mattr_accessor :preserve_job_records, default: true |
.retry_on_unhandled_error ⇒ Boolean?
Whether to re-perform a job when a type of StandardError
is raised to GoodJob (default: false
). If true
, causes jobs to be re-queued and retried if they raise an instance of StandardError
. If false
, jobs will be discarded or marked as finished if they raise an instance of StandardError
. Instances of Exception
, like SIGINT
, will always be retried, regardless of this attribute’s value.
93 |
# File 'lib/good_job.rb', line 93 mattr_accessor :retry_on_unhandled_error, default: false |
Class Method Details
._on_thread_error(exception) ⇒ void
This method returns an undefined value.
Called with exception when a GoodJob thread raises an exception
120 121 122 |
# File 'lib/good_job.rb', line 120 def self._on_thread_error(exception) on_thread_error.call(exception) if on_thread_error.respond_to?(:call) end |
._shutdown_all(executables, method_name = :shutdown, timeout: -1)) ⇒ void
This method returns an undefined value.
Sends #shutdown
or #restart
to executable objects (Notifier, Poller, Scheduler, MultiScheduler, CronManager)
176 177 178 179 180 181 182 183 184 185 |
# File 'lib/good_job.rb', line 176 def self._shutdown_all(executables, method_name = :shutdown, timeout: -1) if timeout.is_a?(Numeric) && timeout.positive? executables.each { |executable| executable.send(method_name, timeout: nil) } stop_at = Time.current + timeout executables.each { |executable| executable.send(method_name, timeout: [stop_at - Time.current, 0].max) } else executables.each { |executable| executable.send(method_name, timeout: timeout) } end end |
.cleanup_preserved_jobs(older_than: nil, in_batches_of: 1_000) ⇒ Integer
Destroys preserved job and batch records. By default, GoodJob destroys job records when the job is performed and this method is not necessary. However, when ‘GoodJob.preserve_job_records = true`, the jobs will be preserved in the database. This is useful when wanting to analyze or inspect job performance. If you are preserving job records this way, use this method regularly to destroy old records and preserve space in your database.
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/good_job.rb', line 196 def self.cleanup_preserved_jobs(older_than: nil, in_batches_of: 1_000) older_than ||= GoodJob.configuration.cleanup_preserved_jobs_before_seconds_ago = Time.current - older_than include_discarded = GoodJob.configuration.cleanup_discarded_jobs? ActiveSupport::Notifications.instrument("cleanup_preserved_jobs.good_job", { older_than: older_than, timestamp: }) do |payload| deleted_executions_count = 0 deleted_batches_count = 0 deleted_discrete_executions_count = 0 jobs_query = GoodJob::Job.finished_before().order(finished_at: :asc).limit(in_batches_of) jobs_query = jobs_query.succeeded unless include_discarded loop do active_job_ids = jobs_query.pluck(:active_job_id) break if active_job_ids.empty? if GoodJob::Execution.discrete_support? deleted_discrete_executions = GoodJob::DiscreteExecution.where(active_job_id: active_job_ids).delete_all deleted_discrete_executions_count += deleted_discrete_executions end deleted_executions = GoodJob::Execution.where(active_job_id: active_job_ids).delete_all deleted_executions_count += deleted_executions end if GoodJob::BatchRecord.migrated? batches_query = GoodJob::BatchRecord.finished_before().limit(in_batches_of) batches_query = batches_query.succeeded unless include_discarded loop do deleted = batches_query.delete_all break if deleted.zero? deleted_batches_count += deleted end end payload[:destroyed_batches_count] = deleted_batches_count payload[:destroyed_discrete_executions_count] = deleted_discrete_executions_count payload[:destroyed_executions_count] = deleted_executions_count destroyed_records_count = deleted_batches_count + deleted_discrete_executions_count + deleted_executions_count payload[:destroyed_records_count] = destroyed_records_count destroyed_records_count end end |
.configure_active_record(&block) ⇒ void
This method returns an undefined value.
Custom Active Record configuration that is class_eval’ed into GoodJob::BaseRecord
132 133 134 |
# File 'lib/good_job.rb', line 132 def self.configure_active_record(&block) self._active_record_configuration = block end |
.deprecator ⇒ ActiveSupport::Deprecation
Deprecator for providing deprecation warnings.
265 266 267 268 269 270 |
# File 'lib/good_job.rb', line 265 def self.deprecator @_deprecator ||= begin next_major_version = GEM_VERSION.segments[0] + 1 ActiveSupport::Deprecation.new("#{next_major_version}.0", "GoodJob") end end |
.migrated? ⇒ Boolean
Whether all GoodJob migrations have been applied. For use in tests/CI to validate GoodJob is up-to-date.
278 279 280 281 282 |
# File 'lib/good_job.rb', line 278 def self.migrated? # Always update with the most recent migration check GoodJob::Execution.reset_column_information GoodJob::Execution.candidate_lookup_index_migrated? end |
.perform_inline(queue_string = "*", limit: nil) ⇒ void
This method returns an undefined value.
Perform all queued jobs in the current thread. This is primarily intended for usage in a test environment. Unhandled job errors will be raised.
249 250 251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/good_job.rb', line 249 def self.perform_inline(queue_string = "*", limit: nil) job_performer = JobPerformer.new(queue_string) iteration = 0 loop do break if limit && iteration >= limit result = Rails.application.executor.wrap { job_performer.next } break unless result raise result.unhandled_error if result.unhandled_error iteration += 1 end end |
.restart(timeout: -1)) ⇒ void
This method returns an undefined value.
Stops and restarts executing jobs. GoodJob does its work in pools of background threads. When forking processes you should shut down these background threads before forking, and restart them after forking. For example, you should use shutdown
and restart
when using async execution mode with Puma. See the README for more explanation and examples.
165 166 167 168 169 |
# File 'lib/good_job.rb', line 165 def self.restart(timeout: -1) return if configuration.execution_mode != :async && configuration.in_webserver? _shutdown_all(Capsule.instances, :restart, timeout: timeout) end |
.shutdown(timeout: -1)) ⇒ void
This method returns an undefined value.
Stop executing jobs. GoodJob does its work in pools of background threads. When forking processes you should shut down these background threads before forking, and restart them after forking. For example, you should use shutdown
and restart
when using async execution mode with Puma. See the README for more explanation and examples.
148 149 150 |
# File 'lib/good_job.rb', line 148 def self.shutdown(timeout: -1) _shutdown_all(Capsule.instances, timeout: timeout) end |