good_job 3.7.4 → 3.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -1
- data/app/controllers/good_job/jobs_controller.rb +1 -1
- data/app/models/good_job/execution.rb +1 -0
- data/app/models/good_job/lockable.rb +1 -0
- data/config/locales/fr.yml +83 -0
- data/lib/good_job/active_job_extensions/concurrency.rb +11 -10
- data/lib/good_job/job_performer.rb +9 -1
- data/lib/good_job/log_subscriber.rb +13 -0
- data/lib/good_job/scheduler.rb +5 -1
- data/lib/good_job/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d5d0c455a8d5d8f18fda38f1f9f126cc406250d188ee313d0352717c829cd126
|
4
|
+
data.tar.gz: 208b61ec3b48a7973b160093100b216eafbb96eee604e5e7edc2e7fb67bedfba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cac4f2c135e6c01cbdd6cd58c591d726ee8fbb66e623e3d1ed8bfb26e85e6b058e45bd60e3d2ba67b3133666df07d972db8eca75aa05df671b8284c01f45398f
|
7
|
+
data.tar.gz: 189ba8af30dc9e5a84c064090d5ede8a8f1da4bb56d2249f6ac4130ce3105c9c498f957ad05cf054f2697f83885570013c3c41ed5d197354c992b08518110656
|
data/CHANGELOG.md
CHANGED
@@ -1,10 +1,41 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v3.8.0](https://github.com/bensheldon/good_job/tree/v3.8.0) (2023-01-27)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v3.7.4...v3.8.0)
|
6
|
+
|
7
|
+
**Implemented enhancements:**
|
8
|
+
|
9
|
+
- Capture and log ActiveJob IDs that are interrupted when Scheduler is forced to shutdown [\#794](https://github.com/bensheldon/good_job/pull/794) ([bensheldon](https://github.com/bensheldon))
|
10
|
+
|
11
|
+
**Fixed bugs:**
|
12
|
+
|
13
|
+
- Ensure Concurrency Keys are string-like and return a better error when they cannot be cast to a string [\#791](https://github.com/bensheldon/good_job/pull/791) ([Earlopain](https://github.com/Earlopain))
|
14
|
+
|
15
|
+
**Closed issues:**
|
16
|
+
|
17
|
+
- Work is not being picked up at the expected rate [\#802](https://github.com/bensheldon/good_job/issues/802)
|
18
|
+
- Cleaning up preserved jobs only removes a subset of the jobs [\#801](https://github.com/bensheldon/good_job/issues/801)
|
19
|
+
- Dashboard fails to execute JS on latest Firefox 108 [\#792](https://github.com/bensheldon/good_job/issues/792)
|
20
|
+
- Concurrency key doesn't handle Hash: TypeError \(can't cast Hash\) [\#784](https://github.com/bensheldon/good_job/issues/784)
|
21
|
+
|
22
|
+
**Merged pull requests:**
|
23
|
+
|
24
|
+
- Bump fugit from 1.8.0 to 1.8.1 [\#808](https://github.com/bensheldon/good_job/pull/808) ([dependabot[bot]](https://github.com/apps/dependabot))
|
25
|
+
- Bump rubocop-rspec from 2.17.1 to 2.18.1 [\#807](https://github.com/bensheldon/good_job/pull/807) ([dependabot[bot]](https://github.com/apps/dependabot))
|
26
|
+
- Bump globalid from 1.0.0 to 1.0.1 [\#804](https://github.com/bensheldon/good_job/pull/804) ([dependabot[bot]](https://github.com/apps/dependabot))
|
27
|
+
- Bump rack from 2.2.4 to 2.2.6.2 [\#803](https://github.com/bensheldon/good_job/pull/803) ([dependabot[bot]](https://github.com/apps/dependabot))
|
28
|
+
- Bump nokogiri from 1.13.10 to 1.14.0 [\#800](https://github.com/bensheldon/good_job/pull/800) ([dependabot[bot]](https://github.com/apps/dependabot))
|
29
|
+
- Bump rubocop from 1.42.0 to 1.43.0 [\#799](https://github.com/bensheldon/good_job/pull/799) ([dependabot[bot]](https://github.com/apps/dependabot))
|
30
|
+
- Bump rubocop-rspec from 2.16.0 to 2.17.1 [\#798](https://github.com/bensheldon/good_job/pull/798) ([dependabot[bot]](https://github.com/apps/dependabot))
|
31
|
+
- Add French translation [\#795](https://github.com/bensheldon/good_job/pull/795) ([francois-ferrandis](https://github.com/francois-ferrandis))
|
32
|
+
- Bump rubocop-rails from 2.17.3 to 2.17.4 [\#780](https://github.com/bensheldon/good_job/pull/780) ([dependabot[bot]](https://github.com/apps/dependabot))
|
33
|
+
|
3
34
|
## [v3.7.4](https://github.com/bensheldon/good_job/tree/v3.7.4) (2023-01-10)
|
4
35
|
|
5
36
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v3.7.3...v3.7.4)
|
6
37
|
|
7
|
-
**
|
38
|
+
**Fixed bugs:**
|
8
39
|
|
9
40
|
- Update to es-module-shims v1.6.3 and use an inline script entry-point; remove script.js entrypoint; remove sourcemap references [\#793](https://github.com/bensheldon/good_job/pull/793) ([bensheldon](https://github.com/bensheldon))
|
10
41
|
|
@@ -80,7 +80,7 @@ module GoodJob
|
|
80
80
|
def destroy
|
81
81
|
@job = Job.find(params[:id])
|
82
82
|
@job.destroy_job
|
83
|
-
redirect_to jobs_path, notice: "Job has been destroyed"
|
83
|
+
redirect_to jobs_path, notice: "Job has been destroyed"
|
84
84
|
end
|
85
85
|
|
86
86
|
private
|
@@ -193,6 +193,7 @@ module GoodJob
|
|
193
193
|
binds = [
|
194
194
|
ActiveRecord::Relation::QueryAttribute.new('key', key, ActiveRecord::Type::String.new),
|
195
195
|
]
|
196
|
+
|
196
197
|
locked = connection.exec_query(pg_or_jdbc_query(query), 'GoodJob::Lockable Advisory Lock', binds).first['locked']
|
197
198
|
return locked unless block_given?
|
198
199
|
return nil unless locked
|
@@ -0,0 +1,83 @@
|
|
1
|
+
---
|
2
|
+
fr:
|
3
|
+
datetime:
|
4
|
+
distance_in_words:
|
5
|
+
about_x_hours:
|
6
|
+
one: environ 1 heure
|
7
|
+
other: environ %{count} heures
|
8
|
+
about_x_months:
|
9
|
+
one: environ 1 heure
|
10
|
+
other: environ %{count} heures
|
11
|
+
about_x_years:
|
12
|
+
one: environ 1 an
|
13
|
+
other: environ %{count} ans
|
14
|
+
almost_x_years:
|
15
|
+
one: presque 1 an
|
16
|
+
other: presque %{count} ans
|
17
|
+
half_a_minute: une demi-minute
|
18
|
+
less_than_x_minutes:
|
19
|
+
one: moins d'une minute
|
20
|
+
other: moins de %{count} minutes
|
21
|
+
less_than_x_seconds:
|
22
|
+
one: moins d'une seconde
|
23
|
+
other: moins de %{count} secondes
|
24
|
+
over_x_years:
|
25
|
+
one: plus d'un an
|
26
|
+
other: plus de %{count} ans
|
27
|
+
x_days:
|
28
|
+
one: 1 jour
|
29
|
+
other: "%{count} jours"
|
30
|
+
x_minutes:
|
31
|
+
one: 1 minute
|
32
|
+
other: "%{count} minutes"
|
33
|
+
x_months:
|
34
|
+
one: 1 mois
|
35
|
+
other: "%{count} mois"
|
36
|
+
x_seconds:
|
37
|
+
one: 1 seconde
|
38
|
+
other: "%{count} secondes"
|
39
|
+
x_years:
|
40
|
+
one: 1 an
|
41
|
+
other: "%{count} ans"
|
42
|
+
duration:
|
43
|
+
hours: "%{hour}h %{min}m"
|
44
|
+
less_than_10_seconds: "%{sec}s"
|
45
|
+
milliseconds: "%{ms}ms"
|
46
|
+
minutes: "%{min}m %{sec}s"
|
47
|
+
seconds: "%{sec}s"
|
48
|
+
good_job:
|
49
|
+
shared:
|
50
|
+
footer:
|
51
|
+
last_update_html: Dernière mise à jour <time id="page-updated-at" datetime="%{time}">%{time}</time>
|
52
|
+
wording: N'oublie pas, toi aussi tu fais du bon boulot !
|
53
|
+
navbar:
|
54
|
+
cron_schedules: Cron
|
55
|
+
jobs: Jobs
|
56
|
+
live_poll: En direct
|
57
|
+
name: "GoodJob 👍"
|
58
|
+
processes: Processus
|
59
|
+
status:
|
60
|
+
discarded: Abandonnés
|
61
|
+
queued: À la file
|
62
|
+
retried: Réessayés
|
63
|
+
running: En cours
|
64
|
+
scheduled: Programmés
|
65
|
+
succeeded: Réussis
|
66
|
+
number:
|
67
|
+
format:
|
68
|
+
delimiter: " "
|
69
|
+
separator: ","
|
70
|
+
human:
|
71
|
+
decimal_units:
|
72
|
+
format: "%n%u"
|
73
|
+
units:
|
74
|
+
billion: B
|
75
|
+
million: M
|
76
|
+
quadrillion: q
|
77
|
+
thousand: k
|
78
|
+
trillion: T
|
79
|
+
unit: ''
|
80
|
+
format:
|
81
|
+
delimiter: " "
|
82
|
+
precision: 3
|
83
|
+
separator: ","
|
@@ -4,6 +4,8 @@ module GoodJob
|
|
4
4
|
module Concurrency
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
|
+
VALID_TYPES = [String, Symbol, Numeric, Date, Time, TrueClass, FalseClass, NilClass].freeze
|
8
|
+
|
7
9
|
class ConcurrencyExceededError < StandardError
|
8
10
|
def backtrace
|
9
11
|
[] # suppress backtrace
|
@@ -30,6 +32,11 @@ module GoodJob
|
|
30
32
|
# Always allow jobs to be retried because the current job's execution will complete momentarily
|
31
33
|
next(block.call) if CurrentThread.active_job_id == job.job_id
|
32
34
|
|
35
|
+
# Only generate the concurrency key on the initial enqueue in case it is dynamic
|
36
|
+
job.good_job_concurrency_key ||= job._good_job_concurrency_key
|
37
|
+
key = job.good_job_concurrency_key
|
38
|
+
next(block.call) if key.blank?
|
39
|
+
|
33
40
|
enqueue_limit = job.class.good_job_concurrency_config[:enqueue_limit]
|
34
41
|
enqueue_limit = instance_exec(&enqueue_limit) if enqueue_limit.respond_to?(:call)
|
35
42
|
enqueue_limit = nil unless enqueue_limit.present? && (0...Float::INFINITY).cover?(enqueue_limit)
|
@@ -43,11 +50,6 @@ module GoodJob
|
|
43
50
|
limit = enqueue_limit || total_limit
|
44
51
|
next(block.call) unless limit
|
45
52
|
|
46
|
-
# Only generate the concurrency key on the initial enqueue in case it is dynamic
|
47
|
-
job.good_job_concurrency_key ||= job._good_job_concurrency_key
|
48
|
-
key = job.good_job_concurrency_key
|
49
|
-
next(block.call) if key.blank?
|
50
|
-
|
51
53
|
GoodJob::Execution.advisory_lock_key(key, function: "pg_advisory_lock") do
|
52
54
|
enqueue_concurrency = if enqueue_limit
|
53
55
|
GoodJob::Execution.where(concurrency_key: key).unfinished.advisory_unlocked.count
|
@@ -117,11 +119,10 @@ module GoodJob
|
|
117
119
|
key = self.class.good_job_concurrency_config[:key]
|
118
120
|
return if key.blank?
|
119
121
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
end
|
122
|
+
key = key.respond_to?(:call) ? instance_exec(&key) : key
|
123
|
+
raise TypeError, "Concurrency key must be a String; was a #{key.class}" unless VALID_TYPES.any? { |type| key.is_a?(type) }
|
124
|
+
|
125
|
+
key
|
125
126
|
end
|
126
127
|
end
|
127
128
|
end
|
@@ -10,6 +10,8 @@ module GoodJob
|
|
10
10
|
# The JobPerformer must be safe to execute across multiple threads.
|
11
11
|
#
|
12
12
|
class JobPerformer
|
13
|
+
cattr_accessor :performing_active_job_ids, default: Concurrent::Set.new
|
14
|
+
|
13
15
|
# @param queue_string [String] Queues to execute jobs from
|
14
16
|
def initialize(queue_string)
|
15
17
|
@queue_string = queue_string
|
@@ -24,7 +26,13 @@ module GoodJob
|
|
24
26
|
# Perform the next eligible job
|
25
27
|
# @return [Object, nil] Returns job result or +nil+ if no job was found
|
26
28
|
def next
|
27
|
-
|
29
|
+
active_job_id = nil
|
30
|
+
job_query.perform_with_advisory_lock(parsed_queues: parsed_queues, queue_select_limit: GoodJob.configuration.queue_select_limit) do |execution|
|
31
|
+
active_job_id = execution.active_job_id
|
32
|
+
performing_active_job_ids << active_job_id
|
33
|
+
end
|
34
|
+
ensure
|
35
|
+
performing_active_job_ids.delete(active_job_id)
|
28
36
|
end
|
29
37
|
|
30
38
|
# Tests whether this performer should be used in GoodJob's current state.
|
@@ -85,6 +85,19 @@ module GoodJob
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
+
def scheduler_shutdown_kill(event)
|
89
|
+
process_id = event.payload[:process_id]
|
90
|
+
|
91
|
+
warn(tags: [process_id]) do
|
92
|
+
active_job_ids = event.payload.fetch(:active_job_ids, [])
|
93
|
+
if active_job_ids.any?
|
94
|
+
"GoodJob scheduler has been killed. The following Active Jobs were interrupted: #{active_job_ids.join(' ')}"
|
95
|
+
else
|
96
|
+
"GoodJob scheduler has been killed."
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
88
101
|
# @!macro notification_responder
|
89
102
|
def scheduler_restart_pools(event)
|
90
103
|
process_id = event.payload[:process_id]
|
data/lib/good_job/scheduler.rb
CHANGED
@@ -121,7 +121,11 @@ module GoodJob # :nodoc:
|
|
121
121
|
|
122
122
|
if executor.shuttingdown? && timeout
|
123
123
|
executor_wait = timeout.negative? ? nil : timeout
|
124
|
-
|
124
|
+
|
125
|
+
unless executor.wait_for_termination(executor_wait)
|
126
|
+
instrument("scheduler_shutdown_kill", { active_job_ids: @performer.performing_active_job_ids.to_a })
|
127
|
+
executor.kill
|
128
|
+
end
|
125
129
|
end
|
126
130
|
end
|
127
131
|
end
|
data/lib/good_job/version.rb
CHANGED
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: 3.
|
4
|
+
version: 3.8.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: 2023-01-
|
11
|
+
date: 2023-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|
@@ -392,6 +392,7 @@ files:
|
|
392
392
|
- app/views/layouts/good_job/application.html.erb
|
393
393
|
- config/locales/en.yml
|
394
394
|
- config/locales/es.yml
|
395
|
+
- config/locales/fr.yml
|
395
396
|
- config/locales/nl.yml
|
396
397
|
- config/locales/ru.yml
|
397
398
|
- config/locales/ua.yml
|