Class: GoodJob::Adapter

Inherits:
Object
  • Object
show all
Defined in:
lib/good_job/adapter.rb

Overview

ActiveJob Adapter.

Constant Summary collapse

EXECUTION_MODES =

Valid execution modes.

[:async, :external, :inline].freeze

Instance Method Summary collapse

Constructor Details

#initialize(execution_mode: nil, queues: nil, max_threads: nil, poll_interval: nil, scheduler: nil, notifier: nil, inline: false) ⇒ Adapter

Returns a new instance of Adapter.

Parameters:

  • execution_mode (nil, Symbol) (defaults to: 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 causes the adapter to execute you jobs in separate threads in whatever process queued them (usually the web process). This is akin to running the command-line tool’s code inside your web server. It can be more economical for small workloads (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.

    The default value depends on the Rails environment:

    • development and test: :inline

    • production and all other environments: :external

  • max_threads (nil, Integer) (defaults to: 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.

  • queues (nil, String) (defaults to: nil)

    determines which queues to execute jobs from when execution_mode is set to :async. See README for more details on the format of this string. You can also set this with the environment variable GOOD_JOB_QUEUES. Defaults to “*”.

  • poll_interval (nil, Integer) (defaults to: 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.

  • scheduler (nil, Scheduler) (defaults to: nil)

    (deprecated) a scheduler to be managed by the adapter

  • notifier (nil, Notifier) (defaults to: nil)

    (deprecated) a notifier to be managed by the adapter

  • inline (nil, Boolean) (defaults to: false)

    (deprecated) whether to run in inline execution mode

Raises:

  • (ArgumentError)


26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/good_job/adapter.rb', line 26

def initialize(execution_mode: nil, queues: nil, max_threads: nil, poll_interval: nil, scheduler: nil, notifier: nil, inline: false)
  if inline && execution_mode.nil?
    ActiveSupport::Deprecation.warn('GoodJob::Adapter#new(inline: true) is deprecated; use GoodJob::Adapter.new(execution_mode: :inline) instead')
    execution_mode = :inline
  end

  configuration = GoodJob::Configuration.new(
    {
      execution_mode: execution_mode,
      queues: queues,
      max_threads: max_threads,
      poll_interval: poll_interval,
    }
  )

  @execution_mode = configuration.execution_mode
  raise ArgumentError, "execution_mode: must be one of #{EXECUTION_MODES.join(', ')}." unless EXECUTION_MODES.include?(@execution_mode)

  if @execution_mode == :async # rubocop:disable Style/GuardClause
    @notifier = notifier || GoodJob::Notifier.new
    @poller = GoodJob::Poller.new(poll_interval: configuration.poll_interval)
    @scheduler = scheduler || GoodJob::Scheduler.from_configuration(configuration)
    @notifier.recipients << [@scheduler, :create_thread]
    @poller.recipients << [@scheduler, :create_thread]
  end
end

Instance Method Details

#enqueue(active_job) ⇒ GoodJob::Job

Enqueues the ActiveJob job to be performed. For use by Rails; you should generally not call this directly.

Parameters:

  • active_job (ActiveJob::Base)

    the job to be enqueued from #perform_later

Returns:



57
58
59
# File 'lib/good_job/adapter.rb', line 57

def enqueue(active_job)
  enqueue_at(active_job, nil)
end

#enqueue_at(active_job, timestamp) ⇒ GoodJob::Job

Enqueues an ActiveJob job to be run at a specific time. For use by Rails; you should generally not call this directly.

Parameters:

  • active_job (ActiveJob::Base)

    the job to be enqueued from #perform_later

  • timestamp (Integer)

    the epoch time to perform the job

Returns:



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/good_job/adapter.rb', line 66

def enqueue_at(active_job, timestamp)
  good_job = GoodJob::Job.enqueue(
    active_job,
    scheduled_at: timestamp ? Time.zone.at(timestamp) : nil,
    create_with_advisory_lock: execute_inline?
  )

  if execute_inline?
    begin
      good_job.perform
    ensure
      good_job.advisory_unlock
    end
  end

  executed_locally = execute_async? && @scheduler.create_thread(queue_name: good_job.queue_name)
  Notifier.notify(queue_name: good_job.queue_name) unless executed_locally

  good_job
end

#execute_async?Boolean

Whether in :async execution mode.

Returns:

  • (Boolean)


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

def execute_async?
  @execution_mode == :async
end

#execute_externally?Boolean

Whether in :external execution mode.

Returns:

  • (Boolean)


103
104
105
# File 'lib/good_job/adapter.rb', line 103

def execute_externally?
  @execution_mode == :external
end

#execute_inline?Boolean

Whether in :inline execution mode.

Returns:

  • (Boolean)


108
109
110
# File 'lib/good_job/adapter.rb', line 108

def execute_inline?
  @execution_mode == :inline
end

#inline?Boolean

(deprecated) Whether in :inline execution mode.

Returns:

  • (Boolean)


113
114
115
116
# File 'lib/good_job/adapter.rb', line 113

def inline?
  ActiveSupport::Deprecation.warn('GoodJob::Adapter::inline? is deprecated; use GoodJob::Adapter::execute_inline? instead')
  execute_inline?
end

#shutdown(wait: true) ⇒ void

This method returns an undefined value.

Gracefully stop processing jobs. Waits for termination by default.

Parameters:

  • wait (Boolean) (defaults to: true)

    Whether to wait for shut down.



91
92
93
94
95
# File 'lib/good_job/adapter.rb', line 91

def shutdown(wait: true)
  @notifier&.shutdown(wait: wait)
  @poller&.shutdown(wait: wait)
  @scheduler&.shutdown(wait: wait)
end