good_job 2.4.0 → 2.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a8150ef0c4bf16e9091908964e629175bf1b3543c0955e796be67c46a842a55
4
- data.tar.gz: 707260ea8989fa5d108b533c0b61a39741be036de397980d37a725e1e188d6f2
3
+ metadata.gz: a0546a16ecd5760e3ca0dd5097ec950767b5993ac613489d5591d5d44eadc021
4
+ data.tar.gz: 9e21d8930806b1843d4c32abef233f89f48292229386da593ba82b3a94617eae
5
5
  SHA512:
6
- metadata.gz: 9b6b1292908f04a1e1bc72a541c1e8751856b8deb836046660290d766494f94d54f37b6070b614690c59ee34849c1051a88aa5f0c66f1c5931b765d2d9e0c685
7
- data.tar.gz: a3b6ed6bb8032e0ee772186b6846af655fee07e097bc2dc0be82185d8369141f6f14c611223c2e5c5239a2287dea4b2969d90ededb1e817b64f253a0b2b48699
6
+ metadata.gz: 6e3aa1deaa9973f0d435bc6eb77e4557f509a5e9dbd38e267a4268987561576323eda9bfb8bfa3af5ad7aec72c51b17f88121f7d202b1455c1ea17c8272cb6de
7
+ data.tar.gz: b812a3371f589db1464f3dabe35badee94bf2a8f132e68e64c438e8ddde4415598d133f2e956d335e021a0ea82b59fbc61c3eb77cab230be760516dbca270402
data/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # Changelog
2
2
 
3
+ ## [v2.4.1](https://github.com/bensheldon/good_job/tree/v2.4.1) (2021-10-11)
4
+
5
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v2.4.0...v2.4.1)
6
+
7
+ **Implemented enhancements:**
8
+
9
+ - Support Datadog APM / `dd-trace-rb` [\#323](https://github.com/bensheldon/good_job/issues/323)
10
+ - Display info about used timezone. [\#398](https://github.com/bensheldon/good_job/pull/398) ([morgoth](https://github.com/morgoth))
11
+ - Display cron schedules args in dashboard [\#396](https://github.com/bensheldon/good_job/pull/396) ([aried3r](https://github.com/aried3r))
12
+
13
+ **Fixed bugs:**
14
+
15
+ - Inline adapter should raise unhandled exceptions during execution [\#416](https://github.com/bensheldon/good_job/pull/416) ([bensheldon](https://github.com/bensheldon))
16
+ - Enforce english locale in UI [\#407](https://github.com/bensheldon/good_job/pull/407) ([morgoth](https://github.com/morgoth))
17
+
18
+ **Closed issues:**
19
+
20
+ - Finished jobs don't show up as finished [\#415](https://github.com/bensheldon/good_job/issues/415)
21
+ - Inline adapter should raise unhandled exceptions during execution [\#410](https://github.com/bensheldon/good_job/issues/410)
22
+ - Rewrite Scheduler "worker" thread name to be `thread` [\#406](https://github.com/bensheldon/good_job/issues/406)
23
+ - "WARNING: you don't own a lock of type ExclusiveLock" in Development [\#388](https://github.com/bensheldon/good_job/issues/388)
24
+ - Improve Readme's "Optimize queues, threads, processes" section [\#132](https://github.com/bensheldon/good_job/issues/132)
25
+
26
+ **Merged pull requests:**
27
+
28
+ - Ignore Rails HEAD Appraisal until `rails new` fixed [\#419](https://github.com/bensheldon/good_job/pull/419) ([bensheldon](https://github.com/bensheldon))
29
+ - Warn in Readme that configuration should not go into `config/initializers/*.rb` [\#418](https://github.com/bensheldon/good_job/pull/418) ([bensheldon](https://github.com/bensheldon))
30
+ - Replace worker wording [\#409](https://github.com/bensheldon/good_job/pull/409) ([Hugo-Hache](https://github.com/Hugo-Hache))
31
+ - Improve Readme's "Optimize queues, threads, processes" section [\#405](https://github.com/bensheldon/good_job/pull/405) ([Hugo-Hache](https://github.com/Hugo-Hache))
32
+ - Update GH Test Matrix with more PG versions [\#401](https://github.com/bensheldon/good_job/pull/401) ([tedhexaflow](https://github.com/tedhexaflow))
33
+ - Extract cron configuration hash into CronEntry ActiveModel objects [\#400](https://github.com/bensheldon/good_job/pull/400) ([bensheldon](https://github.com/bensheldon))
34
+ - Remove errant copy-paste from app.json [\#397](https://github.com/bensheldon/good_job/pull/397) ([morgoth](https://github.com/morgoth))
35
+
3
36
  ## [v2.4.0](https://github.com/bensheldon/good_job/tree/v2.4.0) (2021-10-02)
4
37
 
5
38
  [Full Changelog](https://github.com/bensheldon/good_job/compare/v2.3.1...v2.4.0)
data/README.md CHANGED
@@ -212,7 +212,11 @@ to delete old records and preserve space in your database.
212
212
 
213
213
  To use GoodJob, you can set `config.active_job.queue_adapter` to a `:good_job`.
214
214
 
215
- Additional configuration can be provided via `config.good_job.OPTION = ...` for example:
215
+ Additional configuration can be provided via `config.good_job.OPTION = ...`.
216
+
217
+ _Configuration **must** be placed into `config/application.rb` or `config/environments/{RAILS_ENV}.rb`; configuration may not work correctly if placed into `config/initializers/*.rb` because application initializers run _after_ gem initialization (see [Rails#36650](https://github.com/rails/rails/issues/36650) and [GoodJob#380](https://github.com/bensheldon/good_job/issues/380))._
218
+
219
+ Configuration examples:
216
220
 
217
221
  ```ruby
218
222
  # config/application.rb
@@ -576,43 +580,62 @@ end
576
580
 
577
581
  By default, GoodJob creates a single thread execution pool that will execute jobs from any queue. Depending on your application's workload, job types, and service level objectives, you may wish to optimize execution resources. For example, providing dedicated execution resources for transactional emails so they are not delayed by long-running batch jobs. Some options:
578
582
 
579
- - Multiple execution pools within a single process:
583
+ - Multiple isolated execution pools within a single process:
584
+
585
+ For moderate workloads, multiple isolated thread execution pools offers a good balance between congestion management and economy.
586
+
587
+ A pool is configured with the following syntax `<participating_queues>:<thread_count>`:
588
+
589
+ - `<participating_queues>`: either `queue1,queue2` (only those queues), `*` (all) or `-queue1,queue2` (all except those queues).
590
+ - `<thread_count>`: a count overriding for this specific pool the global `max-threads`.
591
+
592
+ Pool configurations are separated with a semicolon (;) in the `queues` configuration
580
593
 
581
594
  ```bash
582
- $ bundle exec good_job --queues="transactional_messages:2;batch_processing:1;-transactional_messages,batch_processing:2;*" --max-threads=5
595
+ $ bundle exec good_job \
596
+ --queues="transactional_messages:2;batch_processing:1;-transactional_messages,batch_processing:2;*" \
597
+ --max-threads=5
583
598
  ```
584
599
 
585
- This configuration will result in a single process with 4 isolated thread execution pools. Isolated execution pools are separated with a semicolon (`;`) and queue names and thread counts with a colon (`:`)
600
+ This configuration will result in a single process with 4 isolated thread execution pools.
586
601
 
587
- - `transactional_messages:2`: execute jobs enqueued on `transactional_messages` with up to 2 threads.
588
- - `batch_processing:1` execute jobs enqueued on `batch_processing` with a single thread.
589
- - `-transactional_messages,batch_processing`: execute jobs enqueued on _any_ queue _excluding_ `transactional_messages` or `batch_processing` with up to 2 threads.
590
- - `*`: execute jobs on any queue on up to 5 threads, as configured by `--max-threads=5`
591
-
592
- For moderate workloads, multiple isolated thread execution pools offers a good balance between congestion management and economy.
602
+ - `transactional_messages:2`: execute jobs enqueued on `transactional_messages`, with up to 2 threads.
603
+ - `batch_processing:1` execute jobs enqueued on `batch_processing`, with a single thread.
604
+ - `-transactional_messages,batch_processing`: execute jobs enqueued on _any_ queue _excluding_ `transactional_messages` or `batch_processing`, with up to 2 threads.
605
+ - `*`: execute jobs on any queue, with up to 5 threads (as configured by `--max-threads=5`).
593
606
 
594
607
  Configuration can be injected by environment variables too:
595
608
 
596
609
  ```bash
597
- $ GOOD_JOB_QUEUES="transactional_messages:2;batch_processing:1;-transactional_messages,batch_processing:2;*" GOOD_JOB_MAX_THREADS=5 bundle exec good_job
610
+ $ GOOD_JOB_QUEUES="transactional_messages:2;batch_processing:1;-transactional_messages,batch_processing:2;*" \
611
+ GOOD_JOB_MAX_THREADS=5 \
612
+ bundle exec good_job
598
613
  ```
599
614
 
600
- - Multiple processes; for example, on Heroku:
615
+ - Multiple processes:
616
+
617
+ While multiple isolated thread execution pools offer a way to provide dedicated execution resources, those resources are bound to a single machine. To scale them independently, define several processes.
618
+
619
+ For example, this configuration on Heroku allows to customize the dyno count (instances), or type (CPU/RAM), per process type:
601
620
 
602
621
  ```procfile
603
622
  # Procfile
604
623
 
605
- # Separate dyno types
624
+ # Separate process types
606
625
  worker: bundle exec good_job --max-threads=5
607
626
  transactional_worker: bundle exec good_job --queues="transactional_messages" --max-threads=2
608
627
  batch_worker: bundle exec good_job --queues="batch_processing" --max-threads=1
628
+ ```
629
+
630
+ To optimize for CPU performance at the expense of greater memory and system resource usage, while keeping a single process type (and thus a single dyno), combine several processes and wait for them:
609
631
 
610
- # Combined multi-process dyno
632
+ ```procfile
633
+ # Procfile
634
+
635
+ # Combined multi-process
611
636
  combined_worker: bundle exec good_job --max-threads=5 & bundle exec good_job --queues="transactional_messages" --max-threads=2 & bundle exec good_job --queues="batch_processing" --max-threads=1 & wait -n
612
637
  ```
613
638
 
614
- Running multiple processes can optimize for CPU performance at the expense of greater memory and system resource usage.
615
-
616
639
  Keep in mind, queue operations and management is an advanced discipline. This stuff is complex, especially for heavy workloads and unique processing requirements. Good job 👍
617
640
 
618
641
  ### Database connections
@@ -2,5 +2,13 @@
2
2
  module GoodJob
3
3
  class BaseController < ActionController::Base # rubocop:disable Rails/ApplicationController
4
4
  protect_from_forgery with: :exception
5
+
6
+ around_action :switch_locale
7
+
8
+ private
9
+
10
+ def switch_locale(&action)
11
+ I18n.with_locale(:en, &action)
12
+ end
5
13
  end
6
14
  end
@@ -3,7 +3,7 @@ module GoodJob
3
3
  class CronSchedulesController < GoodJob::BaseController
4
4
  def index
5
5
  configuration = GoodJob::Configuration.new({})
6
- @cron_schedules = configuration.cron
6
+ @cron_entries = configuration.cron_entries
7
7
  end
8
8
  end
9
9
  end
@@ -1,4 +1,4 @@
1
- <% if @cron_schedules.present? %>
1
+ <% if @cron_entries.present? %>
2
2
  <div class="card my-3">
3
3
  <div class="table-responsive">
4
4
  <table class="table card-table table-bordered table-hover table-sm mb-0">
@@ -9,7 +9,14 @@
9
9
  Set&nbsp;
10
10
  <%= tag.button "Toggle", type: "button", class: "btn btn-sm btn-outline-primary", role: "button",
11
11
  data: { bs_toggle: "collapse", bs_target: ".job-properties" },
12
- aria: { expanded: false, controls: @cron_schedules.map { |job_key, _| "##{job_key.to_param}" }.join(" ") }
12
+ aria: { expanded: false, controls: @cron_entries.map { |cron_entry| dom_id(cron_entry, 'properties') }.join(" ") }
13
+ %>
14
+ </th>
15
+ <th>
16
+ Args&nbsp;
17
+ <%= tag.button "Toggle", type: "button", class: "btn btn-sm btn-outline-primary", role: "button",
18
+ data: { bs_toggle: "collapse", bs_target: ".job-args" },
19
+ aria: { expanded: false, controls: @cron_entries.map { |cron_entry| dom_id(cron_entry, 'args') }.join(" ") }
13
20
  %>
14
21
  </th>
15
22
  <th>Class</th>
@@ -17,28 +24,43 @@
17
24
  <th>Next scheduled</th>
18
25
  </thead>
19
26
  <tbody>
20
- <% @cron_schedules.each do |job_key, job| %>
27
+ <% @cron_entries.each do |cron_entry| %>
21
28
  <tr>
22
- <td class="font-monospace"><%= job_key %></td>
23
- <td class="font-monospace"><%= job[:cron] %></td>
29
+ <td class="font-monospace"><%= cron_entry.key %></td>
30
+ <td class="font-monospace"><%= cron_entry.cron %></td>
31
+ <td>
32
+ <%=
33
+ case cron_entry.set
34
+ when NilClass
35
+ "None"
36
+ when Proc
37
+ "Lambda/Callable"
38
+ when Hash
39
+ tag.button("Preview", type: "button", class: "btn btn-sm btn-outline-primary", role: "button",
40
+ data: { bs_toggle: "collapse", bs_target: "##{dom_id(cron_entry, 'properties')}" },
41
+ aria: { expanded: false, controls: dom_id(cron_entry, 'properties') }) +
42
+ tag.pre(JSON.pretty_generate(cron_entry.set), id: dom_id(cron_entry, 'properties'), class: "collapse job-properties")
43
+ end
44
+ %>
45
+ </td>
24
46
  <td>
25
47
  <%=
26
- case job[:set]
48
+ case cron_entry.args
27
49
  when NilClass
28
50
  "None"
29
51
  when Proc
30
52
  "Lambda/Callable"
31
53
  when Hash
32
54
  tag.button("Preview", type: "button", class: "btn btn-sm btn-outline-primary", role: "button",
33
- data: { bs_toggle: "collapse", bs_target: "##{job_key.to_param}" },
34
- aria: { expanded: false, controls: job_key.to_param }) +
35
- tag.pre(JSON.pretty_generate(job[:set]), id: job_key.to_param, class: "collapse job-properties")
55
+ data: { bs_toggle: "collapse", bs_target: "##{dom_id(cron_entry, 'args')}" },
56
+ aria: { expanded: false, controls: dom_id(cron_entry, 'args') }) +
57
+ tag.pre(JSON.pretty_generate(cron_entry.args), id: dom_id(cron_entry, 'args'), class: "collapse job-args")
36
58
  end
37
59
  %>
38
60
  </td>
39
- <td class="font-monospace"><%= job[:class] %></td>
40
- <td><%= job[:description] %></td>
41
- <td><%= Fugit.parse_cron(job[:cron]).next_time.to_local_time %></td>
61
+ <td class="font-monospace"><%= cron_entry.job_class %></td>
62
+ <td><%= cron_entry.description %></td>
63
+ <td><%= cron_entry.next_at.to_local_time %></td>
42
64
  </tr>
43
65
  <% end %>
44
66
  </tbody>
@@ -49,6 +49,7 @@
49
49
  </li>
50
50
  -->
51
51
  </ul>
52
+ <div class="text-muted" title="Now is <%= Time.current %>">Times are displayed in <%= Time.current.zone %> timezone</div>
52
53
  </div>
53
54
  </div>
54
55
  </nav>
@@ -38,7 +38,7 @@ module GoodJob
38
38
  @notifier.recipients << [@scheduler, :create_thread]
39
39
  @poller.recipients << [@scheduler, :create_thread]
40
40
 
41
- @cron_manager = GoodJob::CronManager.new(@configuration.cron, start_on_initialize: Rails.application.initialized?) if @configuration.enable_cron?
41
+ @cron_manager = GoodJob::CronManager.new(@configuration.cron_entries, start_on_initialize: Rails.application.initialized?) if @configuration.enable_cron?
42
42
  end
43
43
  end
44
44
 
@@ -64,10 +64,12 @@ module GoodJob
64
64
 
65
65
  if execute_inline?
66
66
  begin
67
- execution.perform
67
+ result = execution.perform
68
68
  ensure
69
69
  execution.advisory_unlock
70
70
  end
71
+
72
+ raise result.unhandled_error if result.unhandled_error
71
73
  else
72
74
  job_state = { queue_name: execution.queue_name }
73
75
  job_state[:scheduled_at] = execution.scheduled_at if execution.scheduled_at
data/lib/good_job/cli.rb CHANGED
@@ -91,7 +91,9 @@ module GoodJob
91
91
  scheduler = GoodJob::Scheduler.from_configuration(configuration, warm_cache_on_initialize: true)
92
92
  notifier.recipients << [scheduler, :create_thread]
93
93
  poller.recipients << [scheduler, :create_thread]
94
- cron_manager = GoodJob::CronManager.new(configuration.cron, start_on_initialize: true) if configuration.enable_cron?
94
+
95
+ cron_manager = GoodJob::CronManager.new(configuration.cron_entries, start_on_initialize: true) if configuration.enable_cron?
96
+
95
97
  @stop_good_job_executable = false
96
98
  %w[INT TERM].each do |signal|
97
99
  trap(signal) { @stop_good_job_executable = true }
@@ -165,6 +165,10 @@ module GoodJob
165
165
  {}
166
166
  end
167
167
 
168
+ def cron_entries
169
+ cron.map { |cron_key, params| GoodJob::CronEntry.new(params.merge(key: cron_key)) }
170
+ end
171
+
168
172
  # Number of seconds to preserve jobs when using the +good_job cleanup_preserved_jobs+ CLI command.
169
173
  # This configuration is only used when {GoodJob.preserve_job_records} is +true+.
170
174
  # @return [Integer]
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+ require "concurrent/hash"
3
+ require "concurrent/scheduled_task"
4
+ require "fugit"
5
+
6
+ module GoodJob # :nodoc:
7
+ #
8
+ # A CronEntry represents a single scheduled item's properties.
9
+ #
10
+ class CronEntry
11
+ include ActiveModel::Model
12
+
13
+ attr_reader :params
14
+
15
+ def initialize(params = {})
16
+ @params = params.with_indifferent_access
17
+ end
18
+
19
+ def key
20
+ params.fetch(:key)
21
+ end
22
+ alias id key
23
+
24
+ def job_class
25
+ params.fetch(:class)
26
+ end
27
+
28
+ def cron
29
+ params.fetch(:cron)
30
+ end
31
+
32
+ def set
33
+ params[:set]
34
+ end
35
+
36
+ def args
37
+ params[:args]
38
+ end
39
+
40
+ def description
41
+ params[:description]
42
+ end
43
+
44
+ def next_at
45
+ fugit = Fugit::Cron.parse(cron)
46
+ fugit.next_time
47
+ end
48
+
49
+ def enqueue
50
+ job_class.constantize.set(set_value).perform_later(*args_value)
51
+ end
52
+
53
+ private
54
+
55
+ def set_value
56
+ value = set || {}
57
+ value.respond_to?(:call) ? value.call : value
58
+ end
59
+
60
+ def args_value
61
+ value = args || []
62
+ value.respond_to?(:call) ? value.call : value
63
+ end
64
+ end
65
+ end
@@ -11,7 +11,7 @@ module GoodJob # :nodoc:
11
11
  # @!attribute [r] instances
12
12
  # @!scope class
13
13
  # List of all instantiated CronManagers in the current process.
14
- # @return [Array<GoodJob::CronManagers>, nil]
14
+ # @return [Array<GoodJob::CronManager>, nil]
15
15
  cattr_reader :instances, default: [], instance_reader: false
16
16
 
17
17
  # Task observer for cron task
@@ -26,13 +26,13 @@ module GoodJob # :nodoc:
26
26
 
27
27
  # Execution configuration to be scheduled
28
28
  # @return [Hash]
29
- attr_reader :schedules
29
+ attr_reader :cron_entries
30
30
 
31
- # @param schedules [Hash]
31
+ # @param cron_entries [Array<CronEntry>]
32
32
  # @param start_on_initialize [Boolean]
33
- def initialize(schedules = {}, start_on_initialize: false)
33
+ def initialize(cron_entries = [], start_on_initialize: false)
34
34
  @running = false
35
- @schedules = schedules
35
+ @cron_entries = cron_entries
36
36
  @tasks = Concurrent::Hash.new
37
37
 
38
38
  self.class.instances << self
@@ -42,9 +42,11 @@ module GoodJob # :nodoc:
42
42
 
43
43
  # Schedule tasks that will enqueue jobs based on their schedule
44
44
  def start
45
- ActiveSupport::Notifications.instrument("cron_manager_start.good_job", cron_jobs: @schedules) do
45
+ ActiveSupport::Notifications.instrument("cron_manager_start.good_job", cron_entries: cron_entries) do
46
46
  @running = true
47
- schedules.each_key { |cron_key| create_task(cron_key) }
47
+ cron_entries.each do |cron_entry|
48
+ create_task(cron_entry)
49
+ end
48
50
  end
49
51
  end
50
52
 
@@ -78,36 +80,22 @@ module GoodJob # :nodoc:
78
80
  end
79
81
 
80
82
  # Enqueues a scheduled task
81
- # @param cron_key [Symbol, String] the key within the schedule to use
82
- def create_task(cron_key)
83
- schedule = @schedules[cron_key]
84
- return false if schedule.blank?
85
-
86
- fugit = Fugit::Cron.parse(schedule.fetch(:cron))
87
- delay = [(fugit.next_time - Time.current).to_f, 0].max
88
-
89
- future = Concurrent::ScheduledTask.new(delay, args: [self, cron_key]) do |thr_scheduler, thr_cron_key|
83
+ # @param cron_entry [CronEntry] the CronEntry object to schedule
84
+ def create_task(cron_entry)
85
+ delay = [(cron_entry.next_at - Time.current).to_f, 0].max
86
+ future = Concurrent::ScheduledTask.new(delay, args: [self, cron_entry]) do |thr_scheduler, thr_cron_entry|
90
87
  # Re-schedule the next cron task before executing the current task
91
- thr_scheduler.create_task(thr_cron_key)
92
-
93
- CurrentThread.reset
94
- CurrentThread.cron_key = thr_cron_key
88
+ thr_scheduler.create_task(thr_cron_entry)
95
89
 
96
90
  Rails.application.executor.wrap do
97
- schedule = thr_scheduler.schedules.fetch(thr_cron_key).with_indifferent_access
98
- job_class = schedule.fetch(:class).constantize
99
-
100
- job_set_value = schedule.fetch(:set, {})
101
- job_set = job_set_value.respond_to?(:call) ? job_set_value.call : job_set_value
102
-
103
- job_args_value = schedule.fetch(:args, [])
104
- job_args = job_args_value.respond_to?(:call) ? job_args_value.call : job_args_value
91
+ CurrentThread.reset
92
+ CurrentThread.cron_key = thr_cron_entry.key
105
93
 
106
- job_class.set(job_set).perform_later(*job_args)
94
+ cron_entry.enqueue
107
95
  end
108
96
  end
109
97
 
110
- @tasks[cron_key] = future
98
+ @tasks[cron_entry.key] = future
111
99
  future.add_observer(self.class, :task_observer)
112
100
  future.execute
113
101
  end
@@ -59,11 +59,11 @@ module GoodJob
59
59
 
60
60
  # @!macro notification_responder
61
61
  def cron_manager_start(event)
62
- cron_jobs = event.payload[:cron_jobs]
63
- cron_jobs_count = cron_jobs.size
62
+ cron_entries = event.payload[:cron_entries]
63
+ cron_jobs_count = cron_entries.size
64
64
 
65
65
  info do
66
- "GoodJob started cron with #{cron_jobs_count} #{'jobs'.pluralize(cron_jobs_count)}."
66
+ "GoodJob started cron with #{cron_jobs_count} #{'job'.pluralize(cron_jobs_count)}."
67
67
  end
68
68
  end
69
69
 
@@ -230,6 +230,7 @@ module GoodJob # :nodoc:
230
230
  # @return [void]
231
231
  def create_task(delay = 0)
232
232
  future = Concurrent::ScheduledTask.new(delay, args: [performer], executor: executor, timer_set: timer_set) do |thr_performer|
233
+ Thread.current.name = Thread.current.name.sub("-worker-", "-thread-") if Thread.current.name
233
234
  Rails.application.reloader.wrap do
234
235
  thr_performer.next
235
236
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module GoodJob
3
3
  # GoodJob gem version.
4
- VERSION = '2.4.0'
4
+ VERSION = '2.4.1'
5
5
  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: 2.4.0
4
+ version: 2.4.1
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-10-02 00:00:00.000000000 Z
11
+ date: 2021-10-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob
@@ -387,6 +387,7 @@ files:
387
387
  - lib/good_job/adapter.rb
388
388
  - lib/good_job/cli.rb
389
389
  - lib/good_job/configuration.rb
390
+ - lib/good_job/cron_entry.rb
390
391
  - lib/good_job/cron_manager.rb
391
392
  - lib/good_job/current_thread.rb
392
393
  - lib/good_job/daemon.rb