good_job 4.5.1 → 4.6.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: 6c4f55ae789dad6bc4920527bdb107d7bc4422cbaec192dfc036b01ada67c54c
4
- data.tar.gz: 8757dec952a510559eae0f7bf1a3210128b72e21d6ed3d17763507b47c4628e8
3
+ metadata.gz: 4e6676f189c0e22c751837d8792b84ece28dfcc118941077abfcdfac7e352c18
4
+ data.tar.gz: 891e630829ec28fb022d516e50d5d9c61e51dc81531ce3f20c25f2facfee09c6
5
5
  SHA512:
6
- metadata.gz: da3bf2a776ffca2181d2d205250e015bc138bc23a95004a65c703631d195e1891bd9eafc86733017dbc10233fb1b978615dadac4cbcb384ce9823c28f7b5e36f
7
- data.tar.gz: a32557214eb62cc0cecb1d17750e83f074de0aef958b771c4846ff7e543432a1e9d474d0f922a241880b21beb07f96e6397bf0445f12286f169d5891cd61496c
6
+ metadata.gz: d443d783208de5f01cd003773943199c618f397a46a1ecb5d7e9167a9eaedc0511f9e4b3cec6122c17cd0be328b490230727024041b7622ad1f9f8afcaf817e1
7
+ data.tar.gz: fc1171540d6227d0e7757a09904b617791289daeec89c3045251b46e8d82959b9df4b5ecd0b4c812a2804ac7c7626712ebea93d3718984fb08a1592c097db068
data/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## [v4.6.0](https://github.com/bensheldon/good_job/tree/v4.6.0) (2024-12-12)
4
+
5
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v4.5.1...v4.6.0)
6
+
7
+ **Implemented enhancements:**
8
+
9
+ - Set job execution thread priority to `-3` when in async mode [\#1560](https://github.com/bensheldon/good_job/pull/1560) ([bensheldon](https://github.com/bensheldon))
10
+
11
+ **Closed issues:**
12
+
13
+ - Attaching metadata to jobs [\#1558](https://github.com/bensheldon/good_job/issues/1558)
14
+ - Lower Ruby Thread priority for jobs by default when running in Async mode [\#1554](https://github.com/bensheldon/good_job/issues/1554)
15
+ - NoMethodError: undefined method `\<' for nil \(process.rb:125 in stale?\) [\#1363](https://github.com/bensheldon/good_job/issues/1363)
16
+ - Install PgHero on the Demo app [\#1166](https://github.com/bensheldon/good_job/issues/1166)
17
+
18
+ **Merged pull requests:**
19
+
20
+ - Bump rails-html-sanitizer from 1.6.0 to 1.6.1 [\#1557](https://github.com/bensheldon/good_job/pull/1557) ([dependabot[bot]](https://github.com/apps/dependabot))
21
+ - Add PGHero to the demo app [\#1294](https://github.com/bensheldon/good_job/pull/1294) ([mec](https://github.com/mec))
22
+
3
23
  ## [v4.5.1](https://github.com/bensheldon/good_job/tree/v4.5.1) (2024-11-29)
4
24
 
5
25
  [Full Changelog](https://github.com/bensheldon/good_job/compare/v4.5.0...v4.5.1)
@@ -216,6 +216,7 @@ module GoodJob
216
216
  return unless execute_async?
217
217
 
218
218
  @capsule.start
219
+ @capsule.lower_thread_priority = true if GoodJob.configuration.lower_thread_priority.in?([true, nil])
219
220
  @_async_started = true
220
221
  end
221
222
 
@@ -24,6 +24,7 @@ module GoodJob
24
24
 
25
25
  @shared_executor = GoodJob::SharedExecutor.new
26
26
  @tracker = GoodJob::CapsuleTracker.new(executor: @shared_executor)
27
+ @lower_thread_priority = nil
27
28
 
28
29
  self.class.instances << self
29
30
  end
@@ -38,7 +39,9 @@ module GoodJob
38
39
 
39
40
  @notifier = GoodJob::Notifier.new(enable_listening: configuration.enable_listen_notify, capsule: self, executor: @shared_executor)
40
41
  @poller = GoodJob::Poller.new(poll_interval: configuration.poll_interval)
41
- @multi_scheduler = GoodJob::MultiScheduler.from_configuration(configuration, capsule: self, warm_cache_on_initialize: true)
42
+ @multi_scheduler = GoodJob::MultiScheduler.from_configuration(configuration, capsule: self, warm_cache_on_initialize: true).tap do |multischeduler|
43
+ multischeduler.lower_thread_priority = @lower_thread_priority unless @lower_thread_priority.nil?
44
+ end
42
45
  @notifier.recipients.push([@multi_scheduler, :create_thread])
43
46
  @poller.recipients.push(-> { @multi_scheduler.create_thread({ fanout: true }) })
44
47
 
@@ -110,6 +113,11 @@ module GoodJob
110
113
  @tracker.process_id
111
114
  end
112
115
 
116
+ def lower_thread_priority=(value)
117
+ @lower_thread_priority = value
118
+ @multi_scheduler&.lower_thread_priority = value
119
+ end
120
+
113
121
  private
114
122
 
115
123
  def configuration
@@ -383,6 +383,14 @@ module GoodJob
383
383
  end || false
384
384
  end
385
385
 
386
+ def lower_thread_priority
387
+ return options[:lower_thread_priority] unless options[:lower_thread_priority].nil?
388
+ return rails_config[:lower_thread_priority] unless rails_config[:lower_thread_priority].nil?
389
+ return ActiveModel::Type::Boolean.new.cast(env['GOOD_JOB_LOWER_THREAD_PRIORITY']) unless env['GOOD_JOB_LOWER_THREAD_PRIORITY'].nil?
390
+
391
+ nil
392
+ end
393
+
386
394
  # Whether to take an advisory lock on the process record in the notifier reactor.
387
395
  # @return [Boolean]
388
396
  def advisory_lock_heartbeat
@@ -19,7 +19,8 @@ module GoodJob
19
19
  max_cache: configuration.max_cache,
20
20
  warm_cache_on_initialize: warm_cache_on_initialize,
21
21
  cleanup_interval_seconds: configuration.cleanup_interval_seconds,
22
- cleanup_interval_jobs: configuration.cleanup_interval_jobs
22
+ cleanup_interval_jobs: configuration.cleanup_interval_jobs,
23
+ lower_thread_priority: configuration.lower_thread_priority
23
24
  )
24
25
  end
25
26
 
@@ -85,6 +86,12 @@ module GoodJob
85
86
  end
86
87
  end
87
88
 
89
+ def lower_thread_priority=(value)
90
+ schedulers.each do |scheduler|
91
+ scheduler.lower_thread_priority = value
92
+ end
93
+ end
94
+
88
95
  def stats
89
96
  scheduler_stats = schedulers.map(&:stats)
90
97
 
@@ -29,6 +29,9 @@ module GoodJob # :nodoc:
29
29
  fallback_policy: :discard,
30
30
  }.freeze
31
31
 
32
+ # In CRuby, this sets the thread quantum to ~12.5ms ( 100ms * 2^(-3) ).
33
+ LOW_THREAD_PRIORITY = -3
34
+
32
35
  # @!attribute [r] instances
33
36
  # @!scope class
34
37
  # List of all instantiated Schedulers in the current process.
@@ -39,13 +42,18 @@ module GoodJob # :nodoc:
39
42
  # @return [String]
40
43
  attr_reader :name
41
44
 
45
+ # Whether to lower the thread priority to a fixed value
46
+ # @return [Boolean]
47
+ attr_accessor :lower_thread_priority
48
+
42
49
  # @param performer [GoodJob::JobPerformer]
43
50
  # @param max_threads [Numeric, nil] number of seconds between polls for jobs
44
51
  # @param max_cache [Numeric, nil] maximum number of scheduled jobs to cache in memory
45
52
  # @param warm_cache_on_initialize [Boolean] whether to warm the cache immediately, or manually by calling +warm_cache+
46
53
  # @param cleanup_interval_seconds [Numeric, nil] number of seconds between cleaning up job records
47
54
  # @param cleanup_interval_jobs [Numeric, nil] number of executed jobs between cleaning up job records
48
- def initialize(performer, max_threads: nil, max_cache: nil, warm_cache_on_initialize: false, cleanup_interval_seconds: nil, cleanup_interval_jobs: nil)
55
+ # @param lower_thread_priority [Boolean] whether to lower the thread priority of execution threads
56
+ def initialize(performer, max_threads: nil, max_cache: nil, warm_cache_on_initialize: false, cleanup_interval_seconds: nil, cleanup_interval_jobs: nil, lower_thread_priority: false)
49
57
  raise ArgumentError, "Performer argument must implement #next" unless performer.respond_to?(:next)
50
58
 
51
59
  @performer = performer
@@ -62,6 +70,8 @@ module GoodJob # :nodoc:
62
70
  @cleanup_tracker = CleanupTracker.new(cleanup_interval_seconds: cleanup_interval_seconds, cleanup_interval_jobs: cleanup_interval_jobs)
63
71
  @executor_options[:name] = name
64
72
 
73
+ self.lower_thread_priority = lower_thread_priority
74
+
65
75
  create_executor
66
76
  warm_cache if warm_cache_on_initialize
67
77
  self.class.instances << self
@@ -271,6 +281,7 @@ module GoodJob # :nodoc:
271
281
  future = Concurrent::ScheduledTask.new(delay, args: [self, performer], executor: executor, timer_set: timer_set) do |thr_scheduler, thr_performer|
272
282
  Thread.current.name = Thread.current.name.sub("-worker-", "-thread-") if Thread.current.name
273
283
  Thread.current[:good_job_scheduler] = thr_scheduler
284
+ Thread.current.priority = -3 if thr_scheduler.lower_thread_priority
274
285
 
275
286
  Rails.application.reloader.wrap do
276
287
  thr_performer.next do |found|
@@ -2,7 +2,7 @@
2
2
 
3
3
  module GoodJob
4
4
  # GoodJob gem version.
5
- VERSION = '4.5.1'
5
+ VERSION = '4.6.0'
6
6
 
7
7
  # GoodJob version as Gem::Version object
8
8
  GEM_VERSION = Gem::Version.new(VERSION)
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: 4.5.1
4
+ version: 4.6.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: 2024-11-29 00:00:00.000000000 Z
11
+ date: 2024-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob