lib/good_job/adapter.rb in good_job-2.7.1 vs lib/good_job/adapter.rb in good_job-2.7.2
- old
+ new
@@ -2,10 +2,16 @@
module GoodJob
#
# ActiveJob Adapter.
#
class Adapter
+ # @!attribute [r] instances
+ # @!scope class
+ # List of all instantiated Adapters in the current process.
+ # @return [Array<GoodJob::Adapter>, nil]
+ cattr_reader :instances, default: [], instance_reader: false
+
# @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.
@@ -18,30 +24,24 @@
# - +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+.
- def initialize(execution_mode: nil, queues: nil, max_threads: nil, poll_interval: nil)
+ # @param start_async_on_initialize [Boolean] whether to start the async scheduler when the adapter is initialized.
+ def initialize(execution_mode: nil, queues: nil, max_threads: nil, poll_interval: nil, start_async_on_initialize: Rails.application.initialized?)
@configuration = GoodJob::Configuration.new(
{
execution_mode: execution_mode,
queues: queues,
max_threads: max_threads,
poll_interval: poll_interval,
}
)
@configuration.validate!
+ self.class.instances << self
- if execute_async? # rubocop:disable Style/GuardClause
- @notifier = GoodJob::Notifier.new
- @poller = GoodJob::Poller.new(poll_interval: @configuration.poll_interval)
- @scheduler = GoodJob::Scheduler.from_configuration(@configuration, warm_cache_on_initialize: Rails.application.initialized?)
- @notifier.recipients << [@scheduler, :create_thread]
- @poller.recipients << [@scheduler, :create_thread]
-
- @cron_manager = GoodJob::CronManager.new(@configuration.cron_entries, start_on_initialize: Rails.application.initialized?) if @configuration.enable_cron?
- end
+ start_async if start_async_on_initialize
end
# 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+
@@ -72,11 +72,11 @@
raise result.unhandled_error if result.unhandled_error
else
job_state = { queue_name: execution.queue_name }
job_state[:scheduled_at] = execution.scheduled_at if execution.scheduled_at
- executed_locally = execute_async? && @scheduler.create_thread(job_state)
+ executed_locally = execute_async? && @scheduler&.create_thread(job_state)
Notifier.notify(job_state) unless executed_locally
end
execution
end
@@ -95,10 +95,11 @@
timeout
end
executables = [@notifier, @poller, @scheduler].compact
GoodJob._shutdown_all(executables, timeout: timeout)
+ @_async_started = false
end
# Whether in +:async+ execution mode.
# @return [Boolean]
def execute_async?
@@ -115,9 +116,31 @@
# Whether in +:inline+ execution mode.
# @return [Boolean]
def execute_inline?
@configuration.execution_mode == :inline
+ end
+
+ # Start async executors
+ # @return void
+ def start_async
+ return unless execute_async?
+
+ @notifier = GoodJob::Notifier.new
+ @poller = GoodJob::Poller.new(poll_interval: @configuration.poll_interval)
+ @scheduler = GoodJob::Scheduler.from_configuration(@configuration, warm_cache_on_initialize: true)
+ @notifier.recipients << [@scheduler, :create_thread]
+ @poller.recipients << [@scheduler, :create_thread]
+
+ @cron_manager = GoodJob::CronManager.new(@configuration.cron_entries, start_on_initialize: true) if @configuration.enable_cron?
+
+ @_async_started = true
+ end
+
+ # Whether the async executors are running
+ # @return [Boolean]
+ def async_started?
+ @_async_started
end
private
# Whether running in a web server process.