Module: GoodJob

Defined in:
lib/good_job.rb,
lib/good_job/cli.rb,
lib/good_job/job.rb,
lib/good_job/daemon.rb,
lib/good_job/poller.rb,
lib/good_job/adapter.rb,
lib/good_job/railtie.rb,
lib/good_job/version.rb,
lib/good_job/lockable.rb,
lib/good_job/notifier.rb,
lib/good_job/scheduler.rb,
lib/good_job/cron_manager.rb,
lib/good_job/configuration.rb,
lib/good_job/job_performer.rb,
lib/good_job/log_subscriber.rb,
lib/good_job/multi_scheduler.rb,
lib/good_job/execution_result.rb,
lib/good_job/current_execution.rb,
lib/good_job/active_job_extensions.rb,
lib/generators/good_job/update_generator.rb,
lib/generators/good_job/install_generator.rb,
lib/good_job/active_job_extensions/concurrency.rb

Overview

:nodoc:

Defined Under Namespace

Modules: ActiveJobExtensions, CurrentExecution, Lockable Classes: Adapter, CLI, Configuration, CronManager, Daemon, ExecutionResult, InstallGenerator, Job, JobPerformer, LogSubscriber, MultiScheduler, Notifier, Poller, Railtie, Scheduler, UpdateGenerator

Constant Summary collapse

VERSION =

GoodJob gem version.

'2.0.4'

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.active_record_parent_classActiveRecord::Base

The ActiveRecord parent class inherited by GoodJob::Job (default: ActiveRecord::Base). Use this when using multiple databases or other custom ActiveRecord configuration.

Examples:

Change the base class:

GoodJob.active_record_parent_class = "CustomApplicationRecord"

Returns:

  • (ActiveRecord::Base)


28
# File 'lib/good_job.rb', line 28

mattr_accessor :active_record_parent_class, default: "ActiveRecord::Base"

.loggerLogger?

The logger used by GoodJob (default: Rails.logger). Use this to redirect logs to a special location or file.

Examples:

Output GoodJob logs to a file:

GoodJob.logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new("log/my_logs.log"))

Returns:

  • (Logger, nil)


37
# File 'lib/good_job.rb', line 37

mattr_accessor :logger, default: ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new($stdout))

.on_thread_errorProc?

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.

Examples:

Send errors to Sentry

# config/initializers/good_job.rb
GoodJob.on_thread_error = -> (exception) { Raven.capture_exception(exception) }

Returns:

  • (Proc, nil)


67
# File 'lib/good_job.rb', line 67

mattr_accessor :on_thread_error, default: nil

.preserve_job_recordsBoolean?

Whether to preserve job records in the database after they have finished (default: false). By default, GoodJob deletes job records after the job is completed successfully. 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 true, you will need to clean out jobs using the good_job cleanup_preserved_jobs CLI command or by using Goodjob.cleanup_preserved_jobs.

Returns:

  • (Boolean, nil)


48
# File 'lib/good_job.rb', line 48

mattr_accessor :preserve_job_records, default: false

.retry_on_unhandled_errorBoolean?

Whether to re-perform a job when a type of StandardError is raised to GoodJob (default: true). 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.

Returns:

  • (Boolean, nil)


57
# File 'lib/good_job.rb', line 57

mattr_accessor :retry_on_unhandled_error, default: true

Class Method Details

._executablesObject



138
139
140
141
142
143
144
145
# File 'lib/good_job.rb', line 138

def self._executables
  [].concat(
    CronManager.instances,
    Notifier.instances,
    Poller.instances,
    Scheduler.instances
  )
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)

Parameters:

  • executables (Array<Notifier, Poller, Scheduler, MultiScheduler, CronManager>)

    Objects to shut down.

  • method_name (:symbol) (defaults to: :shutdown)

    Method to call, e.g. :shutdown or :restart.

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


107
108
109
110
111
112
113
114
115
116
# File 'lib/good_job.rb', line 107

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) ⇒ Integer

Deletes preserved job records. By default, GoodJob deletes 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 delete old records and preserve space in your database.

Returns:

  • (Integer)

    Number of jobs that were deleted.



127
128
129
130
131
132
133
134
135
136
# File 'lib/good_job.rb', line 127

def self.cleanup_preserved_jobs(older_than: nil)
  older_than ||= GoodJob::Configuration.new({}).cleanup_preserved_jobs_before_seconds_ago
  timestamp = Time.current - older_than

  ActiveSupport::Notifications.instrument("cleanup_preserved_jobs.good_job", { older_than: older_than, timestamp: timestamp }) do |payload|
    deleted_records_count = GoodJob::Job.finished(timestamp).delete_all

    payload[:deleted_records_count] = deleted_records_count
  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.

Parameters:

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

    Seconds to wait for active threads to finish.



98
99
100
# File 'lib/good_job.rb', line 98

def self.restart(timeout: -1)
  _shutdown_all(_executables, :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.

Parameters:

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

    Seconds to wait for actively executing jobs to finish

    • nil, the scheduler will trigger a shutdown but not wait for it to complete.

    • -1, the scheduler will wait until the shutdown is complete.

    • 0, the scheduler will immediately shutdown and stop any active tasks.

    • 1.., the scheduler will wait that many seconds before stopping any remaining active tasks.

  • wait (Boolean)

    whether to wait for shutdown



81
82
83
# File 'lib/good_job.rb', line 81

def self.shutdown(timeout: -1)
  _shutdown_all(_executables, timeout: timeout)
end

.shutdown?Boolean

Tests whether jobs have stopped executing.

Returns:

  • (Boolean)

    whether background threads are shut down



87
88
89
# File 'lib/good_job.rb', line 87

def self.shutdown?
  _executables.all?(&:shutdown?)
end