class GoodJob::Adapter

ActiveJob Adapter.

Public Class Methods

new(execution_mode: nil, queues: nil, max_threads: nil, poll_interval: nil) click to toggle source

@param execution_mode [Symbol, nil] specifies how and where jobs should be executed. You can also set this with the environment variable GOOD_JOB_EXECUTION_MODE.

- +:inline+ executes jobs immediately in whatever process queued them (usually the web server process). This should only be used in test and development environments.
- +:external+ causes the adapter to enqueue jobs, but not execute them. When using this option (the default for production environments), you'll need to use the command-line tool to actually execute your jobs.
- +:async+ (or +:async_server+) executes jobs in separate threads within the Rails web server process (`bundle exec rails server`). It can be more economical for small workloads because you don't need a separate machine or environment for running your jobs, but if your web server is under heavy load or your jobs require a lot of resources, you should choose +:external+ instead.
  When not in the Rails web server, jobs will execute in +:external+ mode to ensure jobs are not executed within `rails console`, `rails db:migrate`, `rails assets:prepare`, etc.
- +:async_all+ executes jobs in any Rails process.

The default value depends on the Rails environment:

- +development+ and +test+: +:inline+
- +production+ and all other environments: +:external+

@param max_threads [Integer, nil] sets the number of threads per scheduler to use when execution_mode is set to :async. The queues parameter can specify a number of threads for each group of queues which will override this value. You can also set this with the environment variable GOOD_JOB_MAX_THREADS. Defaults to 5. @param queues [String, nil] determines which queues to execute jobs from when execution_mode is set to :async. See {file:README.md#optimize-queues-threads-and-processes} for more details on the format of this string. You can also set this with the environment variable GOOD_JOB_QUEUES. Defaults to +“*”+. @param poll_interval [Integer, nil] sets the number of seconds between polls for jobs when execution_mode is set to :async. You can also set this with the environment variable GOOD_JOB_POLL_INTERVAL. Defaults to 1.

   # File lib/good_job/adapter.rb
23 def initialize(execution_mode: nil, queues: nil, max_threads: nil, poll_interval: nil)
24   @configuration = GoodJob::Configuration.new(
25     {
26       execution_mode: execution_mode,
27       queues: queues,
28       max_threads: max_threads,
29       poll_interval: poll_interval,
30     }
31   )
32   @configuration.validate!
33 
34   if execute_async? # rubocop:disable Style/GuardClause
35     @notifier = GoodJob::Notifier.new
36     @poller = GoodJob::Poller.new(poll_interval: @configuration.poll_interval)
37     @scheduler = GoodJob::Scheduler.from_configuration(@configuration, warm_cache_on_initialize: Rails.application.initialized?)
38     @notifier.recipients << [@scheduler, :create_thread]
39     @poller.recipients << [@scheduler, :create_thread]
40 
41     @cron_manager = GoodJob::CronManager.new(@configuration.cron, start_on_initialize: Rails.application.initialized?) if @configuration.enable_cron?
42   end
43 end

Public Instance Methods

enqueue(active_job) click to toggle source

Enqueues the ActiveJob job to be performed. For use by Rails; you should generally not call this directly. @param active_job [ActiveJob::Base] the job to be enqueued from #perform_later @return [GoodJob::Job]

   # File lib/good_job/adapter.rb
49 def enqueue(active_job)
50   enqueue_at(active_job, nil)
51 end
enqueue_at(active_job, timestamp) click to toggle source

Enqueues an ActiveJob job to be run at a specific time. For use by Rails; you should generally not call this directly. @param active_job [ActiveJob::Base] the job to be enqueued from #perform_later @param timestamp [Integer, nil] the epoch time to perform the job @return [GoodJob::Job]

   # File lib/good_job/adapter.rb
58 def enqueue_at(active_job, timestamp)
59   good_job = GoodJob::Job.enqueue(
60     active_job,
61     scheduled_at: timestamp ? Time.zone.at(timestamp) : nil,
62     create_with_advisory_lock: execute_inline?
63   )
64 
65   if execute_inline?
66     begin
67       good_job.perform
68     ensure
69       good_job.advisory_unlock
70     end
71   else
72     job_state = { queue_name: good_job.queue_name }
73     job_state[:scheduled_at] = good_job.scheduled_at if good_job.scheduled_at
74 
75     executed_locally = execute_async? && @scheduler.create_thread(job_state)
76     Notifier.notify(job_state) unless executed_locally
77   end
78 
79   good_job
80 end
execute_async?() click to toggle source

Whether in :async execution mode. @return [Boolean]

    # File lib/good_job/adapter.rb
102 def execute_async?
103   @configuration.execution_mode == :async_all ||
104     @configuration.execution_mode.in?([:async, :async_server]) && in_server_process?
105 end
execute_externally?() click to toggle source

Whether in :external execution mode. @return [Boolean]

    # File lib/good_job/adapter.rb
109 def execute_externally?
110   @configuration.execution_mode == :external ||
111     @configuration.execution_mode.in?([:async, :async_server]) && !in_server_process?
112 end
execute_inline?() click to toggle source

Whether in :inline execution mode. @return [Boolean]

    # File lib/good_job/adapter.rb
116 def execute_inline?
117   @configuration.execution_mode == :inline
118 end
shutdown(timeout: :default) click to toggle source

Shut down the thread pool executors. @param timeout [nil, Numeric, Symbol] Seconds to wait for active threads.

* +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 threads.
* A positive number will wait that many seconds before stopping any remaining active threads.

@return [void]

   # File lib/good_job/adapter.rb
89 def shutdown(timeout: :default)
90   timeout = if timeout == :default
91               @configuration.shutdown_timeout
92             else
93               timeout
94             end
95 
96   executables = [@notifier, @poller, @scheduler].compact
97   GoodJob._shutdown_all(executables, timeout: timeout)
98 end

Private Instance Methods

in_server_process?() click to toggle source

Whether running in a web server process. @return [Boolean, nil]

    # File lib/good_job/adapter.rb
124 def in_server_process?
125   return @_in_server_process if defined? @_in_server_process
126 
127   @_in_server_process = Rails.const_defined?('Server') ||
128                         caller.grep(%r{config.ru}).any? || # EXAMPLE: config.ru:3:in `block in <main>' OR config.ru:3:in `new_from_string'
129                         caller.grep(%{/rack/handler/}).any? || # EXAMPLE: iodine-0.7.44/lib/rack/handler/iodine.rb:13:in `start'
130                         (Concurrent.on_jruby? && caller.grep(%r{jruby/rack/rails_booter}).any?) # EXAMPLE: uri:classloader:/jruby/rack/rails_booter.rb:83:in `load_environment'
131 end