good_job 1.2.1 → 1.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +131 -1
  3. data/README.md +321 -160
  4. data/engine/app/controllers/good_job/active_jobs_controller.rb +8 -0
  5. data/engine/app/controllers/good_job/base_controller.rb +5 -0
  6. data/engine/app/controllers/good_job/dashboards_controller.rb +50 -0
  7. data/engine/app/helpers/good_job/application_helper.rb +4 -0
  8. data/engine/app/views/assets/_style.css.erb +16 -0
  9. data/engine/app/views/good_job/active_jobs/show.html.erb +1 -0
  10. data/engine/app/views/good_job/dashboards/index.html.erb +19 -0
  11. data/engine/app/views/layouts/good_job/base.html.erb +61 -0
  12. data/engine/app/views/shared/_chart.erb +51 -0
  13. data/engine/app/views/shared/_jobs_table.erb +26 -0
  14. data/engine/app/views/vendor/bootstrap/_bootstrap-native.js.erb +1662 -0
  15. data/engine/app/views/vendor/bootstrap/_bootstrap.css.erb +10258 -0
  16. data/engine/app/views/vendor/chartist/_chartist.css.erb +613 -0
  17. data/engine/app/views/vendor/chartist/_chartist.js.erb +4516 -0
  18. data/engine/config/routes.rb +4 -0
  19. data/engine/lib/good_job/engine.rb +5 -0
  20. data/lib/active_job/queue_adapters/good_job_adapter.rb +3 -2
  21. data/lib/generators/good_job/install_generator.rb +8 -0
  22. data/lib/good_job.rb +41 -25
  23. data/lib/good_job/adapter.rb +44 -4
  24. data/lib/good_job/cli.rb +66 -13
  25. data/lib/good_job/configuration.rb +61 -2
  26. data/lib/good_job/job.rb +128 -37
  27. data/lib/good_job/lockable.rb +125 -14
  28. data/lib/good_job/log_subscriber.rb +70 -6
  29. data/lib/good_job/multi_scheduler.rb +6 -0
  30. data/lib/good_job/notifier.rb +64 -27
  31. data/lib/good_job/performer.rb +38 -0
  32. data/lib/good_job/railtie.rb +1 -0
  33. data/lib/good_job/scheduler.rb +49 -40
  34. data/lib/good_job/version.rb +2 -1
  35. metadata +163 -7
  36. data/lib/good_job/pg_locks.rb +0 -21
@@ -0,0 +1,4 @@
1
+ GoodJob::Engine.routes.draw do
2
+ root to: 'dashboards#index'
3
+ resources :active_jobs, only: :show
4
+ end
@@ -0,0 +1,5 @@
1
+ module GoodJob
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace GoodJob
4
+ end
5
+ end
@@ -1,5 +1,6 @@
1
- module ActiveJob
2
- module QueueAdapters
1
+ module ActiveJob # :nodoc:
2
+ module QueueAdapters # :nodoc:
3
+ # See {GoodJob::Adapter} for details.
3
4
  class GoodJobAdapter < GoodJob::Adapter
4
5
  def initialize(execution_mode: nil, max_threads: nil, poll_interval: nil, scheduler: nil, inline: false)
5
6
  configuration = GoodJob::Configuration.new({ execution_mode: execution_mode }, env: ENV)
@@ -2,6 +2,13 @@ require 'rails/generators'
2
2
  require 'rails/generators/active_record'
3
3
 
4
4
  module GoodJob
5
+ #
6
+ # Implements the Rails generator used for setting up GoodJob in a Rails
7
+ # application. Run it with +bin/rails g good_job:install+ in your console.
8
+ #
9
+ # This generator is primarily dedicated to stubbing out a migration that adds
10
+ # a table to hold GoodJob's queued jobs in your database.
11
+ #
5
12
  class InstallGenerator < Rails::Generators::Base
6
13
  include Rails::Generators::Migration
7
14
 
@@ -11,6 +18,7 @@ module GoodJob
11
18
 
12
19
  source_paths << File.join(File.dirname(__FILE__), "templates")
13
20
 
21
+ # Generates the actual migration file and places it on disk.
14
22
  def create_migration_file
15
23
  migration_template 'migration.rb.erb', 'db/migrate/create_good_jobs.rb', migration_version: migration_version
16
24
  end
@@ -1,19 +1,18 @@
1
1
  require "rails"
2
- require 'good_job/railtie'
3
2
 
4
- require 'good_job/configuration'
5
- require 'good_job/log_subscriber'
6
- require 'good_job/lockable'
7
- require 'good_job/job'
8
- require 'good_job/scheduler'
9
- require 'good_job/multi_scheduler'
10
- require 'good_job/adapter'
11
- require 'good_job/pg_locks'
12
- require 'good_job/performer'
13
- require 'good_job/current_execution'
14
- require 'good_job/notifier'
3
+ require "active_job"
4
+ require "active_job/queue_adapters"
15
5
 
16
- require 'active_job/queue_adapters/good_job_adapter'
6
+ require "zeitwerk"
7
+
8
+ loader = Zeitwerk::Loader.for_gem
9
+ loader.inflector.inflect(
10
+ 'cli' => "CLI"
11
+ )
12
+ loader.push_dir(File.join(__dir__, ["generators"]))
13
+ loader.setup
14
+
15
+ require "good_job/railtie"
17
16
 
18
17
  # GoodJob is a multithreaded, Postgres-based, ActiveJob backend for Ruby on Rails.
19
18
  #
@@ -21,48 +20,65 @@ require 'active_job/queue_adapters/good_job_adapter'
21
20
  module GoodJob
22
21
  # @!attribute [rw] logger
23
22
  # @!scope class
24
- # The logger used by GoodJob
23
+ # The logger used by GoodJob (default: +Rails.logger+).
24
+ # Use this to redirect logs to a special location or file.
25
25
  # @return [Logger]
26
- mattr_accessor :logger, default: ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDOUT))
26
+ # @example Output GoodJob logs to a file:
27
+ # GoodJob.logger = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new("log/my_logs.log"))
28
+ mattr_accessor :logger, default: ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new($stdout))
27
29
 
28
30
  # @!attribute [rw] preserve_job_records
29
31
  # @!scope class
30
- # Whether to preserve job records in the database after they have finished for inspection
32
+ # Whether to preserve job records in the database after they have finished (default: +false+).
33
+ # By default, GoodJob deletes job records after the job is completed successfully.
34
+ # If you want to preserve jobs for latter inspection, set this to +true+.
35
+ # If you want to preserve only jobs that finished with error for latter inspection, set this to +:on_unhandled_error+.
36
+ # If +true+, you will need to clean out jobs using the +good_job cleanup_preserved_jobs+ CLI command.
31
37
  # @return [Boolean]
32
38
  mattr_accessor :preserve_job_records, default: false
33
39
 
34
40
  # @!attribute [rw] reperform_jobs_on_standard_error
35
41
  # @!scope class
36
- # Whether to re-perform a job when a type of +StandardError+ is raised and bubbles up to the GoodJob backend
42
+ # Whether to re-perform a job when a type of +StandardError+ is raised to GoodJob (default: +true+).
43
+ # If +true+, causes jobs to be re-queued and retried if they raise an instance of +StandardError+.
44
+ # If +false+, jobs will be discarded or marked as finished if they raise an instance of +StandardError+.
45
+ # Instances of +Exception+, like +SIGINT+, will *always* be retried, regardless of this attribute's value.
37
46
  # @return [Boolean]
38
47
  mattr_accessor :reperform_jobs_on_standard_error, default: true
39
48
 
40
49
  # @!attribute [rw] on_thread_error
41
50
  # @!scope class
42
- # Called when a thread raises an error
51
+ # This callable will be called when an exception reaches GoodJob (default: +nil+).
52
+ # It can be useful for logging errors to bug tracking services, like Sentry or Airbrake.
43
53
  # @example Send errors to Sentry
44
54
  # # config/initializers/good_job.rb
45
- #
46
- # # With Sentry (or Bugsnag, Airbrake, Honeybadger, etc.)
47
55
  # GoodJob.on_thread_error = -> (exception) { Raven.capture_exception(exception) }
48
56
  # @return [#call, nil]
49
57
  mattr_accessor :on_thread_error, default: nil
50
58
 
51
- # Shuts down all execution pools
59
+ # Stop executing jobs.
60
+ # GoodJob does its work in pools of background threads.
61
+ # When forking processes you should shut down these background threads before forking, and restart them after forking.
62
+ # For example, you should use +shutdown+ and +restart+ when using async execution mode with Puma.
63
+ # See the {file:README.md#executing-jobs-async--in-process} for more explanation and examples.
52
64
  # @param wait [Boolean] whether to wait for shutdown
53
65
  # @return [void]
54
66
  def self.shutdown(wait: true)
55
- Notifier.instances.each { |adapter| adapter.shutdown(wait: wait) }
67
+ Notifier.instances.each { |notifier| notifier.shutdown(wait: wait) }
56
68
  Scheduler.instances.each { |scheduler| scheduler.shutdown(wait: wait) }
57
69
  end
58
70
 
59
- # Tests if execution pools are shut down
60
- # @return [Boolean] whether execution pools are shut down
71
+ # Tests whether jobs have stopped executing.
72
+ # @return [Boolean] whether background threads are shut down
61
73
  def self.shutdown?
62
74
  Notifier.instances.all?(&:shutdown?) && Scheduler.instances.all?(&:shutdown?)
63
75
  end
64
76
 
65
- # Restarts all execution pools
77
+ # Stops and restarts executing jobs.
78
+ # GoodJob does its work in pools of background threads.
79
+ # When forking processes you should shut down these background threads before forking, and restart them after forking.
80
+ # For example, you should use +shutdown+ and +restart+ when using async execution mode with Puma.
81
+ # See the {file:README.md#executing-jobs-async--in-process} for more explanation and examples.
66
82
  # @return [void]
67
83
  def self.restart
68
84
  Notifier.instances.each(&:restart)
@@ -1,7 +1,28 @@
1
1
  module GoodJob
2
+ #
3
+ # ActiveJob Adapter.
4
+ #
2
5
  class Adapter
6
+ # Valid execution modes.
3
7
  EXECUTION_MODES = [:async, :external, :inline].freeze
4
8
 
9
+ # @param execution_mode [nil, Symbol] specifies how and where jobs should be executed. You can also set this with the environment variable +GOOD_JOB_EXECUTION_MODE+.
10
+ #
11
+ # - +:inline+ executes jobs immediately in whatever process queued them (usually the web server process). This should only be used in test and development environments.
12
+ # - +: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.
13
+ # - +: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.
14
+ #
15
+ # The default value depends on the Rails environment:
16
+ #
17
+ # - +development+ and +test+: +:inline+
18
+ # - +production+ and all other environments: +:external+
19
+ #
20
+ # @param max_threads [nil, Integer] 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+.
21
+ # @param queues [nil, String] 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 +"*"+.
22
+ # @param poll_interval [nil, Integer] 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+.
23
+ # @param scheduler [nil, Scheduler] (deprecated) a scheduler to be managed by the adapter
24
+ # @param notifier [nil, Notifier] (deprecated) a notifier to be managed by the adapter
25
+ # @param inline [nil, Boolean] (deprecated) whether to run in inline execution mode
5
26
  def initialize(execution_mode: nil, queues: nil, max_threads: nil, poll_interval: nil, scheduler: nil, notifier: nil, inline: false)
6
27
  if inline && execution_mode.nil?
7
28
  ActiveSupport::Deprecation.warn('GoodJob::Adapter#new(inline: true) is deprecated; use GoodJob::Adapter.new(execution_mode: :inline) instead')
@@ -9,10 +30,12 @@ module GoodJob
9
30
  end
10
31
 
11
32
  configuration = GoodJob::Configuration.new(
12
- execution_mode: execution_mode,
13
- queues: queues,
14
- max_threads: max_threads,
15
- poll_interval: poll_interval
33
+ {
34
+ execution_mode: execution_mode,
35
+ queues: queues,
36
+ max_threads: max_threads,
37
+ poll_interval: poll_interval,
38
+ }
16
39
  )
17
40
 
18
41
  @execution_mode = configuration.execution_mode
@@ -25,10 +48,19 @@ module GoodJob
25
48
  end
26
49
  end
27
50
 
51
+ # Enqueues the ActiveJob job to be performed.
52
+ # For use by Rails; you should generally not call this directly.
53
+ # @param active_job [ActiveJob::Base] the job to be enqueued from +#perform_later+
54
+ # @return [GoodJob::Job]
28
55
  def enqueue(active_job)
29
56
  enqueue_at(active_job, nil)
30
57
  end
31
58
 
59
+ # Enqueues an ActiveJob job to be run at a specific time.
60
+ # For use by Rails; you should generally not call this directly.
61
+ # @param active_job [ActiveJob::Base] the job to be enqueued from +#perform_later+
62
+ # @param timestamp [Integer] the epoch time to perform the job
63
+ # @return [GoodJob::Job]
32
64
  def enqueue_at(active_job, timestamp)
33
65
  good_job = GoodJob::Job.enqueue(
34
66
  active_job,
@@ -50,23 +82,31 @@ module GoodJob
50
82
  good_job
51
83
  end
52
84
 
85
+ # Gracefully stop processing jobs.
86
+ # Waits for termination by default.
87
+ # @param wait [Boolean] Whether to wait for shut down.
88
+ # @return [void]
53
89
  def shutdown(wait: true)
54
90
  @notifier&.shutdown(wait: wait)
55
91
  @scheduler&.shutdown(wait: wait)
56
92
  end
57
93
 
94
+ # Whether in +:async+ execution mode.
58
95
  def execute_async?
59
96
  @execution_mode == :async
60
97
  end
61
98
 
99
+ # Whether in +:external+ execution mode.
62
100
  def execute_externally?
63
101
  @execution_mode == :external
64
102
  end
65
103
 
104
+ # Whether in +:inline+ execution mode.
66
105
  def execute_inline?
67
106
  @execution_mode == :inline
68
107
  end
69
108
 
109
+ # (deprecated) Whether in +:inline+ execution mode.
70
110
  def inline?
71
111
  ActiveSupport::Deprecation.warn('GoodJob::Adapter::inline? is deprecated; use GoodJob::Adapter::execute_inline? instead')
72
112
  execute_inline?
@@ -1,20 +1,48 @@
1
1
  require 'thor'
2
2
 
3
3
  module GoodJob
4
+ #
5
+ # Implements the +good_job+ command-line tool, which executes jobs and
6
+ # provides other utilities. The actual entry point is in +exe/good_job+, but
7
+ # it just sets up and calls this class.
8
+ #
9
+ # The +good_job+ command-line tool is based on Thor, a CLI framework for
10
+ # Ruby. For more on general usage, see http://whatisthor.com/ and
11
+ # https://github.com/erikhuda/thor/wiki.
12
+ #
4
13
  class CLI < Thor
14
+ # Path to the local Rails application's environment configuration.
15
+ # Requiring this loads the application's configuration and classes.
5
16
  RAILS_ENVIRONMENT_RB = File.expand_path("config/environment.rb")
6
17
 
7
- desc :start, "Start job worker"
18
+ # @!macro thor.desc
19
+ # @!method $1
20
+ # @return [void]
21
+ # The +good_job $1+ command. $2
22
+ desc :start, "Executes queued jobs."
23
+ long_desc <<~DESCRIPTION
24
+ Executes queued jobs.
25
+
26
+ All options can be configured with environment variables.
27
+ See option descriptions for the matching environment variable name.
28
+
29
+ == Configuring queues
30
+ \x5Separate multiple queues with commas; exclude queues with a leading minus;
31
+ separate isolated execution pools with semicolons and threads with colons.
32
+
33
+ DESCRIPTION
8
34
  method_option :max_threads,
9
35
  type: :numeric,
10
- desc: "Maximum number of threads to use for working jobs (default: ActiveRecord::Base.connection_pool.size)"
36
+ banner: 'COUNT',
37
+ desc: "Maximum number of threads to use for working jobs. (env var: GOOD_JOB_MAX_THREADS, default: 5)"
11
38
  method_option :queues,
12
39
  type: :string,
13
- banner: "queue1,queue2(;queue3,queue4:5;-queue1,queue2)",
14
- desc: "Queues to work from. Separate multiple queues with commas; exclude queues with a leading minus; separate isolated execution pools with semicolons and threads with colons (default: *)"
40
+ banner: "QUEUE_LIST",
41
+ desc: "Queues to work from. (env var: GOOD_JOB_QUEUES, default: *)"
15
42
  method_option :poll_interval,
16
43
  type: :numeric,
17
- desc: "Interval between polls for available jobs in seconds (default: 1)"
44
+ banner: 'SECONDS',
45
+ desc: "Interval between polls for available jobs in seconds (env var: GOOD_JOB_POLL_INTERVAL, default: 1)"
18
46
  def start
19
47
  set_up_application!
20
48
 
@@ -39,17 +67,37 @@ module GoodJob
39
67
 
40
68
  default_task :start
41
69
 
42
- desc :cleanup_preserved_jobs, "Delete preserved job records"
70
+ # @!macro thor.desc
71
+ desc :cleanup_preserved_jobs, "Deletes preserved job records."
72
+ long_desc <<~DESCRIPTION
73
+ Deletes preserved job records.
74
+
75
+ By default, GoodJob deletes job records when the job is performed and this
76
+ command is not necessary.
77
+
78
+ However, when `GoodJob.preserve_job_records = true`, the jobs will be
79
+ preserved in the database. This is useful when wanting to analyze or
80
+ inspect job performance.
81
+
82
+ If you are preserving job records this way, use this command regularly
83
+ to delete old records and preserve space in your database.
84
+
85
+ DESCRIPTION
43
86
  method_option :before_seconds_ago,
44
87
  type: :numeric,
45
- default: 24 * 60 * 60,
46
- desc: "Delete records finished more than this many seconds ago"
47
-
88
+ banner: 'SECONDS',
89
+ desc: "Delete records finished more than this many seconds ago (env var: GOOD_JOB_CLEANUP_PRESERVED_JOBS_BEFORE_SECONDS_AGO, default: 86400)"
48
90
  def cleanup_preserved_jobs
49
91
  set_up_application!
50
92
 
51
- timestamp = Time.current - options[:before_seconds_ago]
52
- ActiveSupport::Notifications.instrument("cleanup_preserved_jobs.good_job", { before_seconds_ago: options[:before_seconds_ago], timestamp: timestamp }) do |payload|
93
+ configuration = GoodJob::Configuration.new(options)
94
+
95
+ timestamp = Time.current - configuration.cleanup_preserved_jobs_before_seconds_ago
96
+
97
+ ActiveSupport::Notifications.instrument(
98
+ "cleanup_preserved_jobs.good_job",
99
+ { before_seconds_ago: configuration.cleanup_preserved_jobs_before_seconds_ago, timestamp: timestamp }
100
+ ) do |payload|
53
101
  deleted_records_count = GoodJob::Job.finished(timestamp).delete_all
54
102
 
55
103
  payload[:deleted_records_count] = deleted_records_count
@@ -57,11 +105,16 @@ module GoodJob
57
105
  end
58
106
 
59
107
  no_commands do
108
+ # Load the current Rails application and configuration that the good_job
109
+ # command-line tool should be working within.
110
+ #
111
+ # GoodJob components that need access to constants, classes, etc. from
112
+ # Rails or from the application can be set up here.
60
113
  def set_up_application!
61
114
  require RAILS_ENVIRONMENT_RB
62
- return unless defined?(GOOD_JOB_LOG_TO_STDOUT) && GOOD_JOB_LOG_TO_STDOUT && !ActiveSupport::Logger.logger_outputs_to?(GoodJob.logger, STDOUT)
115
+ return unless defined?(GOOD_JOB_LOG_TO_STDOUT) && GOOD_JOB_LOG_TO_STDOUT && !ActiveSupport::Logger.logger_outputs_to?(GoodJob.logger, $stdout)
63
116
 
64
- GoodJob::LogSubscriber.loggers << ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDOUT))
117
+ GoodJob::LogSubscriber.loggers << ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new($stdout))
65
118
  GoodJob::LogSubscriber.reset_logger
66
119
  end
67
120
  end
@@ -1,12 +1,47 @@
1
1
  module GoodJob
2
+ #
3
+ # +GoodJob::Configuration+ provides normalized configuration information to
4
+ # the rest of GoodJob. It combines environment information with explicitly
5
+ # set options to get the final values for each option.
6
+ #
2
7
  class Configuration
8
+ # Default number of threads to use per {Scheduler}
9
+ DEFAULT_MAX_THREADS = 5
10
+ # Default number of seconds between polls for jobs
11
+ DEFAULT_POLL_INTERVAL = 1
12
+ # Default number of seconds to preserve jobs for {CLI#cleanup_preserved_jobs}
13
+ DEFAULT_CLEANUP_PRESERVED_JOBS_BEFORE_SECONDS_AGO = 24 * 60 * 60
14
+
15
+ # @!attribute [r] options
16
+ # The options that were explicitly set when initializing +Configuration+.
17
+ # @return [Hash]
18
+ #
19
+ # @!attribute [r] env
20
+ # The environment from which to read GoodJob's environment variables. By
21
+ # default, this is the current process's environment, but it can be set
22
+ # to something else in {#initialize}.
23
+ # @return [Hash]
3
24
  attr_reader :options, :env
4
25
 
26
+ # @param options [Hash] Any explicitly specified configuration options to
27
+ # use. Keys are symbols that match the various methods on this class.
28
+ # @param env [Hash] A +Hash+ from which to read environment variables that
29
+ # might specify additional configuration values.
5
30
  def initialize(options, env: ENV)
6
31
  @options = options
7
32
  @env = env
8
33
  end
9
34
 
35
+ # Specifies how and where jobs should be executed. See {Adapter#initialize}
36
+ # for more details on possible values.
37
+ #
38
+ # When running inside a Rails app, you may want to use
39
+ # {#rails_execution_mode}, which takes the current Rails environment into
40
+ # account when determining the final value.
41
+ #
42
+ # @param default [Symbol]
43
+ # Value to use if none was specified in the configuration.
44
+ # @return [Symbol]
10
45
  def execution_mode(default: :external)
11
46
  if options[:execution_mode]
12
47
  options[:execution_mode]
@@ -17,6 +52,9 @@ module GoodJob
17
52
  end
18
53
  end
19
54
 
55
+ # Like {#execution_mode}, but takes the current Rails environment into
56
+ # account (e.g. in the +test+ environment, it falls back to +:inline+).
57
+ # @return [Symbol]
20
58
  def rails_execution_mode
21
59
  if execution_mode(default: nil)
22
60
  execution_mode
@@ -29,26 +67,47 @@ module GoodJob
29
67
  end
30
68
  end
31
69
 
70
+ # Indicates the number of threads to use per {Scheduler}. Note that
71
+ # {#queue_string} may provide more specific thread counts to use with
72
+ # individual schedulers.
73
+ # @return [Integer]
32
74
  def max_threads
33
75
  (
34
76
  options[:max_threads] ||
35
77
  env['GOOD_JOB_MAX_THREADS'] ||
36
78
  env['RAILS_MAX_THREADS'] ||
37
- ActiveRecord::Base.connection_pool.size
79
+ DEFAULT_MAX_THREADS
38
80
  ).to_i
39
81
  end
40
82
 
83
+ # Describes which queues to execute jobs from and how those queues should
84
+ # be grouped into {Scheduler} instances. See
85
+ # {file:README.md#optimize-queues-threads-and-processes} for more details
86
+ # on the format of this string.
87
+ # @return [String]
41
88
  def queue_string
42
89
  options[:queues] ||
43
90
  env['GOOD_JOB_QUEUES'] ||
44
91
  '*'
45
92
  end
46
93
 
94
+ # The number of seconds between polls for jobs. GoodJob will execute jobs
95
+ # on queues continuously until a queue is empty, at which point it will
96
+ # poll (using this interval) for new queued jobs to execute.
97
+ # @return [Integer]
47
98
  def poll_interval
48
99
  (
49
100
  options[:poll_interval] ||
50
101
  env['GOOD_JOB_POLL_INTERVAL'] ||
51
- 1
102
+ DEFAULT_POLL_INTERVAL
103
+ ).to_i
104
+ end
105
+
106
+ def cleanup_preserved_jobs_before_seconds_ago
107
+ (
108
+ options[:before_seconds_ago] ||
109
+ env['GOOD_JOB_CLEANUP_PRESERVED_JOBS_BEFORE_SECONDS_AGO'] ||
110
+ DEFAULT_CLEANUP_PRESERVED_JOBS_BEFORE_SECONDS_AGO
52
111
  ).to_i
53
112
  end
54
113
  end