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/capsule_tracker.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/charts/good_job/base_chart.rb,
app/models/good_job/cron_entry.rb,
lib/good_job/interrupted_error.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/models/good_job/job/lockable.rb,
app/helpers/good_job/icons_helper.rb,
lib/good_job/adapter/inline_buffer.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,
app/charts/good_job/performance_show_chart.rb,
app/controllers/good_job/pauses_controller.rb,
lib/good_job/active_job_extensions/batches.rb,
app/charts/good_job/performance_index_chart.rb,
app/controllers/good_job/batches_controller.rb,
app/controllers/good_job/cleaner_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/performance_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, BaseChart, BaseFilter, BaseRecord, Batch, BatchRecord, BatchesController, BatchesFilter, CLI, Capsule, CapsuleTracker, CleanerController, CleanupTracker, Configuration, CronEntriesController, CronEntry, CronManager, Daemon, DiscreteExecution, Engine, Execution, ExecutionResult, FrontendsController, I18nConfig, InstallGenerator, InterruptError, InterruptedError, Job, JobPerformer, JobsController, JobsFilter, LogSubscriber, MetricsController, MultiScheduler, Notifier, PausesController, PerformanceController, PerformanceIndexChart, PerformanceShowChart, 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.
'4.18.0'- 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::Job(default:ActiveRecord::Base). -
.capsule ⇒ GoodJob::Capsule?
Global/default execution capsule for GoodJob.
-
.configuration ⇒ GoodJob::Configuration?
Global configuration object for GoodJob.
-
.handled_exceptions ⇒ Array<Class, String>
Exception classes that GoodJob will rescue during job execution (default:
[StandardError]). -
.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 handled (rescued) error 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,, after: []) ⇒ void
Sends
#shutdownor#restartto executable objects (Notifier, Poller, Scheduler, MultiScheduler, CronManager, SharedExecutor). -
.cleanup_preserved_jobs(older_than: nil, in_batches_of: 1_000, include_discarded: GoodJob.configuration.cleanup_discarded_jobs?) ⇒ Integer
Destroys preserved job and batch records.
-
.cli? ⇒ Boolean
Whether this process was initialized via the GoodJob executable (‘$ good_job`).
-
.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.
-
.handled_exception_classes ⇒ Array<Class>
Resolved exception classes from GoodJob.handled_exceptions.
-
.migrated? ⇒ Boolean
Whether all GoodJob migrations have been applied.
-
.pause(queue: nil, job_class: nil) ⇒ void
Pause job execution for a given queue or job class.
-
.paused(type = nil) ⇒ Hash
Get a list of all paused queues and job classes.
-
.paused?(queue: nil, job_class: nil, label: nil) ⇒ Boolean
Check if job execution is paused for a given queue or job class.
-
.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.
-
.unpause(queue: nil, job_class: nil, label: nil) ⇒ void
Unpause job execution for a given queue or job class.
-
.v4_ready? ⇒ Boolean
Tests whether GoodJob can be safely upgraded to v4.
Class Attribute Details
.active_record_parent_class ⇒ ActiveRecord::Base
The ActiveRecord parent class inherited by GoodJob::Job (default: ActiveRecord::Base). Use this when using multiple databases or other custom ActiveRecord configuration.
68 |
# File 'lib/good_job.rb', line 68 mattr_accessor :active_record_parent_class, default: nil |
.capsule ⇒ GoodJob::Capsule?
Global/default execution capsule for GoodJob.
137 |
# File 'lib/good_job.rb', line 137 mattr_accessor :capsule, default: GoodJob::Capsule.new(configuration: configuration) |
.configuration ⇒ GoodJob::Configuration?
Global configuration object for GoodJob.
131 |
# File 'lib/good_job.rb', line 131 mattr_accessor :configuration, default: GoodJob::Configuration.new({}) |
.handled_exceptions ⇒ Array<Class, String>
Exception classes that GoodJob will rescue during job execution (default: [StandardError]). Accepts class objects or strings that will be constantized at runtime. Exceptions not in this list will propagate and crash the executing thread.
109 |
# File 'lib/good_job.rb', line 109 mattr_accessor :handled_exceptions, default: [StandardError, NotImplementedError] |
.logger ⇒ Logger?
The logger used by GoodJob (default: Rails.logger). Use this to redirect logs to a special location or file.
77 |
# File 'lib/good_job.rb', line 77 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.
125 |
# File 'lib/good_job.rb', line 125 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 want to preserve jobs based on the error event, set this to a lambda that takes the error_event argument. 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.
90 |
# File 'lib/good_job.rb', line 90 mattr_accessor :preserve_job_records, default: true |
.retry_on_unhandled_error ⇒ Boolean?
Whether to re-perform a job when a handled (rescued) error is raised to GoodJob (default: false). If true, causes jobs to be re-queued and retried if they raise an instance of a handled exception. If false, jobs will be discarded or marked as finished if they raise an instance of a handled exception.
99 |
# File 'lib/good_job.rb', line 99 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
142 143 144 |
# File 'lib/good_job.rb', line 142 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,, after: []) ⇒ void
This method returns an undefined value.
Sends #shutdown or #restart to executable objects (Notifier, Poller, Scheduler, MultiScheduler, CronManager, SharedExecutor)
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/good_job.rb', line 200 def self._shutdown_all(executables, method_name = :shutdown, timeout: -1, after: []) 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 return unless after.any? && !timeout.nil? if stop_at after.each { |executable| executable.shutdown(timeout: [stop_at - Time.current, 0].max) } else after.each { |executable| executable.shutdown(timeout: timeout) } end end |
.cleanup_preserved_jobs(older_than: nil, in_batches_of: 1_000, include_discarded: GoodJob.configuration.cleanup_discarded_jobs?) ⇒ 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.
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/good_job.rb', line 228 def self.cleanup_preserved_jobs(older_than: nil, in_batches_of: 1_000, include_discarded: GoodJob.configuration.cleanup_discarded_jobs?) older_than ||= GoodJob.configuration.cleanup_preserved_jobs_before_seconds_ago = Time.current - older_than ActiveSupport::Notifications.instrument("cleanup_preserved_jobs.good_job", { older_than: older_than, timestamp: }) do |payload| deleted_jobs_count = 0 deleted_batches_count = 0 deleted_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 break if GoodJob.current_thread_shutting_down? active_job_ids = jobs_query.pluck(:active_job_id) break if active_job_ids.empty? deleted_executions = GoodJob::Execution.where(active_job_id: active_job_ids).delete_all deleted_executions_count += deleted_executions deleted_jobs = GoodJob::Job.where(active_job_id: active_job_ids).delete_all deleted_jobs_count += deleted_jobs end batches_query = GoodJob::BatchRecord.finished_before().limit(in_batches_of) batches_query = batches_query.succeeded unless include_discarded loop do break if GoodJob.current_thread_shutting_down? deleted = batches_query.delete_all break if deleted.zero? deleted_batches_count += deleted end payload[:destroyed_batches_count] = deleted_batches_count payload[:destroyed_executions_count] = deleted_executions_count payload[:destroyed_jobs_count] = deleted_jobs_count destroyed_records_count = deleted_batches_count + deleted_executions_count + deleted_jobs_count payload[:destroyed_records_count] = destroyed_records_count destroyed_records_count end end |
.cli? ⇒ Boolean
Whether this process was initialized via the GoodJob executable (‘$ good_job`)
355 356 357 |
# File 'lib/good_job.rb', line 355 def self.cli? GoodJob::CLI.within_exe? end |
.configure_active_record(&block) ⇒ void
This method returns an undefined value.
Custom Active Record configuration that is class_eval’ed into GoodJob::BaseRecord
154 155 156 |
# File 'lib/good_job.rb', line 154 def self.configure_active_record(&block) self._active_record_configuration = block end |
.deprecator ⇒ ActiveSupport::Deprecation
Deprecator for providing deprecation warnings.
306 307 308 309 310 311 |
# File 'lib/good_job.rb', line 306 def self.deprecator @_deprecator ||= begin next_major_version = GEM_VERSION.segments[0] + 1 ActiveSupport::Deprecation.new("#{next_major_version}.0", "GoodJob") end end |
.handled_exception_classes ⇒ Array<Class>
Resolved exception classes from handled_exceptions.
113 114 115 |
# File 'lib/good_job.rb', line 113 def self.handled_exception_classes handled_exceptions.map { |e| e.is_a?(String) ? e.constantize : e } end |
.migrated? ⇒ Boolean
Whether all GoodJob migrations have been applied. For use in tests/CI to validate GoodJob is up-to-date.
316 317 318 319 |
# File 'lib/good_job.rb', line 316 def self.migrated? GoodJob::Job.lock_type_migrated? && GoodJob::Job.connection.index_name_exists?(:good_jobs, "index_good_jobs_on_queue_name_priority_scheduled_at_unfinished") end |
.pause(queue: nil, job_class: nil) ⇒ void
This method returns an undefined value.
Pause job execution for a given queue or job class.
325 326 327 |
# File 'lib/good_job.rb', line 325 def self.pause(queue: nil, job_class: nil) GoodJob::Setting.pause(queue: queue, job_class: job_class) end |
.paused(type = nil) ⇒ Hash
Get a list of all paused queues and job classes
349 350 351 |
# File 'lib/good_job.rb', line 349 def self.paused(type = nil) GoodJob::Setting.paused(type) end |
.paused?(queue: nil, job_class: nil, label: nil) ⇒ Boolean
Check if job execution is paused for a given queue or job class.
343 344 345 |
# File 'lib/good_job.rb', line 343 def self.paused?(queue: nil, job_class: nil, label: nil) GoodJob::Setting.paused?(queue: queue, job_class: job_class, label: label) 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.
280 281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/good_job.rb', line 280 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.
188 189 190 191 192 |
# File 'lib/good_job.rb', line 188 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.
171 172 173 |
# File 'lib/good_job.rb', line 171 def self.shutdown(timeout: -1) _shutdown_all(Capsule.instances, timeout: timeout) end |
.shutdown? ⇒ Boolean
Tests whether jobs have stopped executing.
177 178 179 |
# File 'lib/good_job.rb', line 177 def self.shutdown? Capsule.instances.all?(&:shutdown?) end |
.unpause(queue: nil, job_class: nil, label: nil) ⇒ void
This method returns an undefined value.
Unpause job execution for a given queue or job class.
334 335 336 |
# File 'lib/good_job.rb', line 334 def self.unpause(queue: nil, job_class: nil, label: nil) GoodJob::Setting.unpause(queue: queue, job_class: job_class, label: label) end |
.v4_ready? ⇒ Boolean
Tests whether GoodJob can be safely upgraded to v4
296 297 298 299 300 301 302 |
# File 'lib/good_job.rb', line 296 def self.v4_ready? GoodJob.deprecator.warn(<<~MSG) Calling `GoodJob.v4_ready?` is deprecated and will be removed in GoodJob v5. If you are reading this deprecation you are already on v4. MSG true end |