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.