good_job 1.4.1 → 1.5.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ac71f85784bd491d995252ed498d55642ee511a402ad093cc056fd2e062a437b
4
- data.tar.gz: 33f1a9ebf6952f3140046338bb616a4a81c469b4099f526e56d15b9aa1f8951d
3
+ metadata.gz: 89ef994e63adf5fe8dcbcdd230d9669d21c2cb6d9c62da622c8d8a197fcb3cef
4
+ data.tar.gz: 6ed6d2cc6f75c5b4dc6976f3e360a5aeb27e3488fbd8035d086058b40d693025
5
5
  SHA512:
6
- metadata.gz: 1660dd44eca81ce42cbdb917253dfb340d5e5a4b371275f51eb919fc5aacb3485c6bbd87164d49d07547682efe311fb1a41bce35599ab5d45b8bd669d1e840c2
7
- data.tar.gz: 1c2994d95046ea9f692539dffcb0bfa33d81daed73886a2fef7ab9c9c6063b4085c17f8cc7ed93bcfab999ca25ffef1db31fa82344e3a31a6dcbdc3a84c966ed
6
+ metadata.gz: f8d856f3797236bffecfffe5bcb58599aa0b2f843962fe09032eb0606d432d1f379dd564d00e29512bd6e3ca0c26c261401eed4b45806f21c660d9cd1a9a4838
7
+ data.tar.gz: cd223dc763e1bb56d746f957aec29403ed78b6d89619fd4d4b23148d2f78a86c452e29e48249cf408cc4fff7c0ee564eb7032d9b02b24239a2d0215f40df5194
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [v1.5.0](https://github.com/bensheldon/good_job/tree/v1.5.0) (2021-01-17)
4
+
5
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v1.4.1...v1.5.0)
6
+
7
+ **Implemented enhancements:**
8
+
9
+ - Create Web UI Dashboard [\#50](https://github.com/bensheldon/good_job/issues/50)
10
+
11
+ **Closed issues:**
12
+
13
+ - JRuby Support [\#160](https://github.com/bensheldon/good_job/issues/160)
14
+
15
+ **Merged pull requests:**
16
+
17
+ - Update bundler version to 2.2.5 [\#200](https://github.com/bensheldon/good_job/pull/200) ([bensheldon](https://github.com/bensheldon))
18
+ - Configure GoodJob via `Rails.application.config` instead of recommending `GoodJob::Adapter.new` [\#199](https://github.com/bensheldon/good_job/pull/199) ([bensheldon](https://github.com/bensheldon))
19
+ - Update GH Test Matrix with minimum & latest JRuby version [\#197](https://github.com/bensheldon/good_job/pull/197) ([tedhexaflow](https://github.com/tedhexaflow))
20
+ - Fix JRuby version number [\#193](https://github.com/bensheldon/good_job/pull/193) ([tedhexaflow](https://github.com/tedhexaflow))
21
+
3
22
  ## [v1.4.1](https://github.com/bensheldon/good_job/tree/v1.4.1) (2021-01-09)
4
23
 
5
24
  [Full Changelog](https://github.com/bensheldon/good_job/compare/v1.4.0...v1.4.1)
@@ -22,6 +41,7 @@
22
41
 
23
42
  **Implemented enhancements:**
24
43
 
44
+ - Format serialized params to ease reading [\#170](https://github.com/bensheldon/good_job/pull/170) ([morgoth](https://github.com/morgoth))
25
45
  - Add JRuby support [\#167](https://github.com/bensheldon/good_job/pull/167) ([bensheldon](https://github.com/bensheldon))
26
46
 
27
47
  ## [v1.3.6](https://github.com/bensheldon/good_job/tree/v1.3.6) (2020-12-30)
@@ -97,7 +117,6 @@
97
117
  **Implemented enhancements:**
98
118
 
99
119
  - Extract polling from scheduler into Polling object [\#128](https://github.com/bensheldon/good_job/issues/128)
100
- - Format serialized params to ease reading [\#170](https://github.com/bensheldon/good_job/pull/170) ([morgoth](https://github.com/morgoth))
101
120
 
102
121
  **Fixed bugs:**
103
122
 
@@ -508,7 +527,6 @@
508
527
  - Add pg gem as explicit dependency [\#13](https://github.com/bensheldon/good_job/pull/13) ([bensheldon](https://github.com/bensheldon))
509
528
  - Bump nokogiri from 1.10.7 to 1.10.9 [\#12](https://github.com/bensheldon/good_job/pull/12) ([dependabot[bot]](https://github.com/apps/dependabot))
510
529
  - Add Appraisal with tests for Rails 5.1, 5.2, 6.0 [\#11](https://github.com/bensheldon/good_job/pull/11) ([bensheldon](https://github.com/bensheldon))
511
- - Use Rails.logger and ActiveSupport::Notifications for logging instead of puts [\#10](https://github.com/bensheldon/good_job/pull/10) ([bensheldon](https://github.com/bensheldon))
512
530
 
513
531
  ## [v0.2.0](https://github.com/bensheldon/good_job/tree/v0.2.0) (2020-03-06)
514
532
 
@@ -516,6 +534,7 @@
516
534
 
517
535
  **Merged pull requests:**
518
536
 
537
+ - Use Rails.logger and ActiveSupport::Notifications for logging instead of puts [\#10](https://github.com/bensheldon/good_job/pull/10) ([bensheldon](https://github.com/bensheldon))
519
538
  - Remove minitest files [\#9](https://github.com/bensheldon/good_job/pull/9) ([bensheldon](https://github.com/bensheldon))
520
539
  - Use scheduled\_at and priority for scheduling [\#8](https://github.com/bensheldon/good_job/pull/8) ([bensheldon](https://github.com/bensheldon))
521
540
  - Create Github Action workflow for PRs and Issues [\#7](https://github.com/bensheldon/good_job/pull/7) ([bensheldon](https://github.com/bensheldon))
data/README.md CHANGED
@@ -35,8 +35,8 @@ For more of the story of GoodJob, read the [introductory blog post](https://isla
35
35
  - [Command-line options](#command-line-options)
36
36
  - [`good_job start`](#good_job-start)
37
37
  - [`good_job cleanup_preserved_jobs`](#good_job-cleanup_preserved_jobs)
38
- - [Adapter options](#adapter-options)
39
- - [Global options](#global-options)
38
+ - [Configuration options](#configuration-options)
39
+ - [Global options](#global-options)pter
40
40
  - [Dashboard](#dashboard)
41
41
  - [Go deeper](#go-deeper)
42
42
  - [Exceptions, retries, and reliability](#exceptions-retries-and-reliability)
@@ -127,7 +127,7 @@ For more of the story of GoodJob, read the [introductory blog post](https://isla
127
127
  ## Compatibility
128
128
 
129
129
  - **Ruby on Rails:** 5.2+
130
- - **Ruby:** MRI 2.5+. JRuby 9.13+ (_JRuby's `activerecord-jdbcpostgresql-adapter` gem does not support Postgres LISTEN/NOTIFY)._
130
+ - **Ruby:** MRI 2.5+. JRuby 9.2.13+ (_JRuby's `activerecord-jdbcpostgresql-adapter` gem does not support Postgres LISTEN/NOTIFY)._
131
131
  - **Postgres:** 9.6+
132
132
 
133
133
  ## Configuration
@@ -189,9 +189,31 @@ If you are preserving job records this way, use this command regularly
189
189
  to delete old records and preserve space in your database.
190
190
  ```
191
191
 
192
- ### Adapter options
192
+ ### Configuration options
193
193
 
194
- To use GoodJob, you can set `config.active_job.queue_adapter` to a `:good_job` or to an instance of `GoodJob::Adapter`, which you can configure with several options:
194
+ To use GoodJob, you can set `config.active_job.queue_adapter` to a `:good_job`.
195
+
196
+ Additional configuration can be provided via `config.good_job.OPTION = ...` for example:
197
+
198
+ ```ruby
199
+ # config/application.rb
200
+
201
+ config.active_job.queue_adapter = :good_job
202
+
203
+ # Configure options individually...
204
+ config.good_job.execution_mode = :async
205
+ config.good_job.max_threads = 5
206
+ config.good_job.poll_interval = 30 # seconds
207
+
208
+ # ...or all at once.
209
+ config.good_job = {
210
+ execution_mode: :async,
211
+ max_threads: 5,
212
+ poll_interval: 30,
213
+ }
214
+ ```
215
+
216
+ Available configuration options are:
195
217
 
196
218
  - `execution_mode` (symbol) specifies how and where jobs should be executed. You can also set this with the environment variable `GOOD_JOB_EXECUTION_MODE`. It can be any one of:
197
219
  - `:inline` executes jobs immediately in whatever process queued them (usually the web server process). This should only be used in test and development environments.
@@ -201,17 +223,21 @@ To use GoodJob, you can set `config.active_job.queue_adapter` to a `:good_job` o
201
223
  - `queues` (string) determines which queues to execute jobs from when `execution_mode` is set to `:async`. See the description of `good_job start` for more details on the format of this string. You can also set this with the environment variable `GOOD_JOB_QUEUES`.
202
224
  - `poll_interval` (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`.
203
225
 
204
- Using the symbol instead of explicitly configuring the options above (i.e. setting `config.active_job.queue_adapter = :good_job`) is equivalent to:
226
+ By default, GoodJob configures the following execution modes per environment:
205
227
 
206
228
  ```ruby
229
+
207
230
  # config/environments/development.rb
208
- config.active_job.queue_adapter = GoodJob::Adapter.new(execution_mode: :inline)
231
+ config.active_job.queue_adapter = :good_job
232
+ config.good_job.execution_mode = :inline
209
233
 
210
234
  # config/environments/test.rb
211
- config.active_job.queue_adapter = GoodJob::Adapter.new(execution_mode: :inline)
235
+ config.active_job.queue_adapter = :good_job
236
+ config.good_job.execution_mode = :inline
212
237
 
213
238
  # config/environments/production.rb
214
- config.active_job.queue_adapter = GoodJob::Adapter.new(execution_mode: :external)
239
+ config.active_job.queue_adapter = :good_job
240
+ config.good_job.execution_mode = :external
215
241
  ```
216
242
 
217
243
  ### Global options
@@ -442,14 +468,24 @@ pool: <%= [ENV.fetch("RAILS_MAX_THREADS", 5).to_i, ENV.fetch("GOOD_JOB_MAX_THREA
442
468
 
443
469
  GoodJob can execute jobs "async" in the same process as the webserver (e.g. `bin/rail s`). GoodJob's async execution mode offers benefits of economy by not requiring a separate job worker process, but with the tradeoff of increased complexity. Async mode can be configured in two ways:
444
470
 
445
- - Directly configure the ActiveJob adapter:
471
+ - Via Rails configuration:
446
472
 
447
473
  ```ruby
448
474
  # config/environments/production.rb
449
- config.active_job.queue_adapter = GoodJob::Adapter.new(execution_mode: :async, max_threads: 4, poll_interval: 30)
475
+ config.active_job.queue_adapter = :good_job
476
+
477
+ # To change the execution mode
478
+ config.good_job.execution_mode = :async
479
+
480
+ # Or with more configuration
481
+ config.good_job = {
482
+ execution_mode: :async,
483
+ max_threads: 4,
484
+ poll_interval: 30
485
+ }
450
486
  ```
451
487
 
452
- - Or, when using `...queue_adapter = :good_job`, via environment variables:
488
+ - Or, with environment variables:
453
489
 
454
490
  ```bash
455
491
  $ GOOD_JOB_EXECUTION_MODE=async GOOD_JOB_MAX_THREADS=4 GOOD_JOB_POLL_INTERVAL=30 bin/rails server
@@ -2,9 +2,9 @@ module ActiveJob # :nodoc:
2
2
  module QueueAdapters # :nodoc:
3
3
  # See {GoodJob::Adapter} for details.
4
4
  class GoodJobAdapter < GoodJob::Adapter
5
- def initialize(execution_mode: nil, max_threads: nil, poll_interval: nil, scheduler: nil, inline: false)
6
- configuration = GoodJob::Configuration.new({ execution_mode: execution_mode }, env: ENV)
7
- super(execution_mode: configuration.rails_execution_mode, max_threads: max_threads, poll_interval: poll_interval, scheduler: scheduler, inline: inline)
5
+ def initialize(**options)
6
+ configuration = GoodJob::Configuration.new(options, env: ENV)
7
+ super(**options.merge(execution_mode: configuration.rails_execution_mode))
8
8
  end
9
9
  end
10
10
  end
@@ -20,13 +20,22 @@ module GoodJob
20
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
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
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
26
- def initialize(execution_mode: nil, queues: nil, max_threads: nil, poll_interval: nil, scheduler: nil, notifier: nil, inline: false)
27
- if inline && execution_mode.nil?
28
- ActiveSupport::Deprecation.warn('GoodJob::Adapter#new(inline: true) is deprecated; use GoodJob::Adapter.new(execution_mode: :inline) instead')
29
- execution_mode = :inline
23
+ def initialize(execution_mode: nil, queues: nil, max_threads: nil, poll_interval: nil)
24
+ if caller[0..4].find { |c| c.include?("/config/application.rb") || c.include?("/config/environments/") }
25
+ ActiveSupport::Deprecation.warn(<<~DEPRECATION)
26
+ GoodJob no longer recommends creating a GoodJob::Adapter instance:
27
+
28
+ config.active_job.queue_adapter = GoodJob::Adapter.new...
29
+
30
+ Instead, configure GoodJob through configuration:
31
+
32
+ config.active_job.queue_adapter = :good_job
33
+ config.good_job.execution_mode = :#{execution_mode}
34
+ config.good_job.max_threads = #{max_threads}
35
+ config.good_job.poll_interval = #{poll_interval}
36
+ # etc...
37
+
38
+ DEPRECATION
30
39
  end
31
40
 
32
41
  configuration = GoodJob::Configuration.new(
@@ -42,9 +51,9 @@ module GoodJob
42
51
  raise ArgumentError, "execution_mode: must be one of #{EXECUTION_MODES.join(', ')}." unless EXECUTION_MODES.include?(@execution_mode)
43
52
 
44
53
  if @execution_mode == :async # rubocop:disable Style/GuardClause
45
- @notifier = notifier || GoodJob::Notifier.new
54
+ @notifier = GoodJob::Notifier.new
46
55
  @poller = GoodJob::Poller.new(poll_interval: configuration.poll_interval)
47
- @scheduler = scheduler || GoodJob::Scheduler.from_configuration(configuration)
56
+ @scheduler = GoodJob::Scheduler.from_configuration(configuration)
48
57
  @notifier.recipients << [@scheduler, :create_thread]
49
58
  @poller.recipients << [@scheduler, :create_thread]
50
59
  end
@@ -108,11 +117,5 @@ module GoodJob
108
117
  def execute_inline?
109
118
  @execution_mode == :inline
110
119
  end
111
-
112
- # (deprecated) Whether in +:inline+ execution mode.
113
- def inline?
114
- ActiveSupport::Deprecation.warn('GoodJob::Adapter::inline? is deprecated; use GoodJob::Adapter::execute_inline? instead')
115
- execute_inline?
116
- end
117
120
  end
118
121
  end
@@ -45,6 +45,8 @@ module GoodJob
45
45
  def execution_mode(default: :external)
46
46
  if options[:execution_mode]
47
47
  options[:execution_mode]
48
+ elsif rails_config[:execution_mode]
49
+ rails_config[:execution_mode]
48
50
  elsif env['GOOD_JOB_EXECUTION_MODE'].present?
49
51
  env['GOOD_JOB_EXECUTION_MODE'].to_sym
50
52
  else
@@ -72,6 +74,7 @@ module GoodJob
72
74
  def max_threads
73
75
  (
74
76
  options[:max_threads] ||
77
+ rails_config[:max_threads] ||
75
78
  env['GOOD_JOB_MAX_THREADS'] ||
76
79
  env['RAILS_MAX_THREADS'] ||
77
80
  DEFAULT_MAX_THREADS
@@ -85,6 +88,7 @@ module GoodJob
85
88
  # @return [String]
86
89
  def queue_string
87
90
  options[:queues] ||
91
+ rails_config[:queues] ||
88
92
  env['GOOD_JOB_QUEUES'] ||
89
93
  '*'
90
94
  end
@@ -96,6 +100,7 @@ module GoodJob
96
100
  def poll_interval
97
101
  (
98
102
  options[:poll_interval] ||
103
+ rails_config[:poll_interval] ||
99
104
  env['GOOD_JOB_POLL_INTERVAL'] ||
100
105
  DEFAULT_POLL_INTERVAL
101
106
  ).to_i
@@ -107,9 +112,16 @@ module GoodJob
107
112
  def cleanup_preserved_jobs_before_seconds_ago
108
113
  (
109
114
  options[:before_seconds_ago] ||
115
+ rails_config[:cleanup_preserved_jobs_before_seconds_ago] ||
110
116
  env['GOOD_JOB_CLEANUP_PRESERVED_JOBS_BEFORE_SECONDS_AGO'] ||
111
117
  DEFAULT_CLEANUP_PRESERVED_JOBS_BEFORE_SECONDS_AGO
112
118
  ).to_i
113
119
  end
120
+
121
+ private
122
+
123
+ def rails_config
124
+ Rails.application.config.good_job
125
+ end
114
126
  end
115
127
  end
@@ -0,0 +1,63 @@
1
+ require 'concurrent/delay'
2
+
3
+ module GoodJob
4
+ #
5
+ # JobPerformer queries the database for jobs and performs them on behalf of a
6
+ # {Scheduler}. It mainly functions as glue between a {Scheduler} and the jobs
7
+ # it should be executing.
8
+ #
9
+ # The JobPerformer must be safe to execute across multiple threads.
10
+ #
11
+ class JobPerformer
12
+ # @param queue_string [String] Queues to execute jobs from
13
+ def initialize(queue_string)
14
+ @queue_string = queue_string
15
+
16
+ @job_query = Concurrent::Delay.new { GoodJob::Job.queue_string(queue_string) }
17
+ @parsed_queues = Concurrent::Delay.new { GoodJob::Job.queue_parser(queue_string) }
18
+ end
19
+
20
+ # A meaningful name to identify the performer in logs and for debugging.
21
+ # @return [String] The queues from which Jobs are worked
22
+ def name
23
+ @queue_string
24
+ end
25
+
26
+ # Perform the next eligible job
27
+ # @return [nil, Object] Returns job result or +nil+ if no job was found
28
+ def next
29
+ job_query.perform_with_advisory_lock
30
+ end
31
+
32
+ # Tests whether this performer should be used in GoodJob's current state.
33
+ #
34
+ # For example, state will be a LISTEN/NOTIFY message that is passed down
35
+ # from the Notifier to the Scheduler. The Scheduler is able to ask
36
+ # its performer "does this message relate to you?", and if not, ignore it
37
+ # to minimize thread wake-ups, database queries, and thundering herds.
38
+ #
39
+ # @return [Boolean] whether the performer's {#next} method should be
40
+ # called in the current state.
41
+ def next?(state = {})
42
+ if parsed_queues[:exclude]
43
+ parsed_queues[:exclude].exclude?(state[:queue_name])
44
+ elsif parsed_queues[:include]
45
+ parsed_queues[:include].include?(state[:queue_name])
46
+ else
47
+ true
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ attr_reader :queue_string
54
+
55
+ def job_query
56
+ @job_query.value
57
+ end
58
+
59
+ def parsed_queues
60
+ @parsed_queues.value
61
+ end
62
+ end
63
+ end
@@ -1,8 +1,12 @@
1
1
  module GoodJob
2
2
  # Ruby on Rails integration.
3
3
  class Railtie < ::Rails::Railtie
4
- initializer "good_job.logger" do
5
- ActiveSupport.on_load(:good_job) { self.logger = ::Rails.logger }
4
+ config.good_job = ActiveSupport::OrderedOptions.new
5
+
6
+ initializer "good_job.logger" do |_app|
7
+ ActiveSupport.on_load(:good_job) do
8
+ self.logger = ::Rails.logger
9
+ end
6
10
  GoodJob::LogSubscriber.attach_to :good_job
7
11
  end
8
12
 
@@ -40,19 +40,7 @@ module GoodJob # :nodoc:
40
40
  queue_string, max_threads = queue_string_and_max_threads.split(':')
41
41
  max_threads = (max_threads || configuration.max_threads).to_i
42
42
 
43
- job_query = GoodJob::Job.queue_string(queue_string)
44
- parsed = GoodJob::Job.queue_parser(queue_string)
45
- job_filter = proc do |state|
46
- if parsed[:exclude]
47
- parsed[:exclude].exclude?(state[:queue_name])
48
- elsif parsed[:include]
49
- parsed[:include].include? state[:queue_name]
50
- else
51
- true
52
- end
53
- end
54
- job_performer = GoodJob::Performer.new(job_query, :perform_with_advisory_lock, name: queue_string, filter: job_filter)
55
-
43
+ job_performer = GoodJob::JobPerformer.new(queue_string)
56
44
  GoodJob::Scheduler.new(job_performer, max_threads: max_threads)
57
45
  end
58
46
 
@@ -63,7 +51,7 @@ module GoodJob # :nodoc:
63
51
  end
64
52
  end
65
53
 
66
- # @param performer [GoodJob::Performer]
54
+ # @param performer [GoodJob::JobPerformer]
67
55
  # @param max_threads [Numeric, nil] number of seconds between polls for jobs
68
56
  def initialize(performer, max_threads: nil)
69
57
  raise ArgumentError, "Performer argument must implement #next" unless performer.respond_to?(:next)
@@ -1,4 +1,4 @@
1
1
  module GoodJob
2
2
  # GoodJob gem version.
3
- VERSION = '1.4.1'.freeze
3
+ VERSION = '1.5.0'.freeze
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: good_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Sheldon
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-09 00:00:00.000000000 Z
11
+ date: 2021-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob
@@ -358,11 +358,11 @@ files:
358
358
  - lib/good_job/configuration.rb
359
359
  - lib/good_job/current_execution.rb
360
360
  - lib/good_job/job.rb
361
+ - lib/good_job/job_performer.rb
361
362
  - lib/good_job/lockable.rb
362
363
  - lib/good_job/log_subscriber.rb
363
364
  - lib/good_job/multi_scheduler.rb
364
365
  - lib/good_job/notifier.rb
365
- - lib/good_job/performer.rb
366
366
  - lib/good_job/poller.rb
367
367
  - lib/good_job/railtie.rb
368
368
  - lib/good_job/scheduler.rb
@@ -1,60 +0,0 @@
1
- module GoodJob
2
- #
3
- # Performer queries the database for jobs and performs them on behalf of a
4
- # {Scheduler}. It mainly functions as glue between a {Scheduler} and the jobs
5
- # it should be executing.
6
- #
7
- # The Performer enforces a callable that does not rely on scoped/closure
8
- # variables because they might not be available when executed in a different
9
- # thread.
10
- #
11
- class Performer
12
- # @!attribute [r] name
13
- # @return [String]
14
- # a meaningful name to identify the performer in logs and for debugging.
15
- # This is usually set to the list of queues the performer will query,
16
- # e.g. +"-transactional_messages,batch_processing"+.
17
- attr_reader :name
18
-
19
- # @param target [Object]
20
- # An object that can perform jobs. It must respond to +method_name+ by
21
- # finding and performing jobs and is usually a {Job} query,
22
- # e.g. +GoodJob::Job.where(queue_name: ['queue1', 'queue2'])+.
23
- # @param method_name [Symbol]
24
- # The name of a method on +target+ that finds and performs jobs.
25
- # @param name [String]
26
- # A name for the performer to be used in logs and for debugging.
27
- # @param filter [#call]
28
- # Used to determine whether the performer should be used in GoodJob's
29
- # current state. GoodJob state is a +Hash+ that will be passed as the
30
- # first argument to +filter+ and includes info like the current queue.
31
- def initialize(target, method_name, name: nil, filter: nil)
32
- @target = target
33
- @method_name = method_name
34
- @name = name
35
- @filter = filter
36
- end
37
-
38
- # Find and perform any eligible jobs.
39
- def next
40
- @target.public_send(@method_name)
41
- end
42
-
43
- # Tests whether this performer should be used in GoodJob's current state by
44
- # calling the +filter+ callable set in {#initialize}. Always returns +true+
45
- # if there is no filter.
46
- #
47
- # For example, state will be a LISTEN/NOTIFY message that is passed down
48
- # from the Notifier to the Scheduler. The Scheduler is able to ask
49
- # its performer "does this message relate to you?", and if not, ignore it
50
- # to minimize thread wake-ups, database queries, and thundering herds.
51
- #
52
- # @return [Boolean] whether the performer's {#next} method should be
53
- # called in the current state.
54
- def next?(state = {})
55
- return true unless @filter.respond_to?(:call)
56
-
57
- @filter.call(state)
58
- end
59
- end
60
- end