good_job 1.5.0 → 1.6.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 +21 -2
- data/README.md +3 -0
- data/lib/good_job/cli.rb +15 -1
- data/lib/good_job/configuration.rb +24 -11
- data/lib/good_job/daemon.rb +59 -0
- data/lib/good_job/lockable.rb +2 -2
- data/lib/good_job/scheduler.rb +1 -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: b8f0f56838ed9baa984ad7b70ece1c72009369149bb45522aa140298ff727d44
|
4
|
+
data.tar.gz: a076e6f1315911e9fcacc8be7be4e87d176f6a63fd4cf8e297b8985d928074cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6eae147e6a6f22da09c87b246735d0844e09dbaaea2e9b2cc92664ad86efef95feb8572ddafa83964009572d5c55db5eefc9f589d63820fb77fc59ec8ac4f110
|
7
|
+
data.tar.gz: 3f884573f31e65c3d63c2b864a820b9e9dd5db2a71405f3514ffdd774458bb89c7b5a834878aba2a57b988cce02443fc2df8e986d09815f98784bdaa9de6b62f
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,25 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## [v1.
|
3
|
+
## [v1.6.0](https://github.com/bensheldon/good_job/tree/v1.6.0) (2021-01-21)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.5.0...v1.6.0)
|
6
|
+
|
7
|
+
**Implemented enhancements:**
|
8
|
+
|
9
|
+
- Running as a daemon [\#88](https://github.com/bensheldon/good_job/issues/88)
|
10
|
+
- Add daemonize option to CLI [\#202](https://github.com/bensheldon/good_job/pull/202) ([bensheldon](https://github.com/bensheldon))
|
11
|
+
|
12
|
+
**Closed issues:**
|
13
|
+
|
14
|
+
- Rails 6.1 & async - `queue\_parser': undefined method `first' for "\*":String \(NoMethodError\) [\#195](https://github.com/bensheldon/good_job/issues/195)
|
15
|
+
|
16
|
+
**Merged pull requests:**
|
17
|
+
|
18
|
+
- Add scripts directory for benchmarking and dev tasks [\#204](https://github.com/bensheldon/good_job/pull/204) ([bensheldon](https://github.com/bensheldon))
|
19
|
+
- Fix YARD attr\_ declarations for documentation [\#203](https://github.com/bensheldon/good_job/pull/203) ([bensheldon](https://github.com/bensheldon))
|
20
|
+
- Remove Appraisal gemfile locks [\#201](https://github.com/bensheldon/good_job/pull/201) ([bensheldon](https://github.com/bensheldon))
|
21
|
+
|
22
|
+
## [v1.5.0](https://github.com/bensheldon/good_job/tree/v1.5.0) (2021-01-18)
|
4
23
|
|
5
24
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.4.1...v1.5.0)
|
6
25
|
|
@@ -41,7 +60,6 @@
|
|
41
60
|
|
42
61
|
**Implemented enhancements:**
|
43
62
|
|
44
|
-
- Format serialized params to ease reading [\#170](https://github.com/bensheldon/good_job/pull/170) ([morgoth](https://github.com/morgoth))
|
45
63
|
- Add JRuby support [\#167](https://github.com/bensheldon/good_job/pull/167) ([bensheldon](https://github.com/bensheldon))
|
46
64
|
|
47
65
|
## [v1.3.6](https://github.com/bensheldon/good_job/tree/v1.3.6) (2020-12-30)
|
@@ -117,6 +135,7 @@
|
|
117
135
|
**Implemented enhancements:**
|
118
136
|
|
119
137
|
- Extract polling from scheduler into Polling object [\#128](https://github.com/bensheldon/good_job/issues/128)
|
138
|
+
- Format serialized params to ease reading [\#170](https://github.com/bensheldon/good_job/pull/170) ([morgoth](https://github.com/morgoth))
|
120
139
|
|
121
140
|
**Fixed bugs:**
|
122
141
|
|
data/README.md
CHANGED
@@ -152,6 +152,8 @@ Options:
|
|
152
152
|
[--max-threads=COUNT] # Maximum number of threads to use for working jobs. (env var: GOOD_JOB_MAX_THREADS, default: 5)
|
153
153
|
[--queues=QUEUE_LIST] # Queues to work from. (env var: GOOD_JOB_QUEUES, default: *)
|
154
154
|
[--poll-interval=SECONDS] # Interval between polls for available jobs in seconds (env var: GOOD_JOB_POLL_INTERVAL, default: 1)
|
155
|
+
[--daemonize] # Run as a background daemon (default: false)
|
156
|
+
[--pidfile=PIDFILE] # Path to write daemonized Process ID (env var: GOOD_JOB_PIDFILE, default: tmp/pids/good_job.pid)
|
155
157
|
|
156
158
|
Executes queued jobs.
|
157
159
|
|
@@ -159,6 +161,7 @@ All options can be configured with environment variables.
|
|
159
161
|
See option descriptions for the matching environment variable name.
|
160
162
|
|
161
163
|
== Configuring queues
|
164
|
+
|
162
165
|
Separate multiple queues with commas; exclude queues with a leading minus;
|
163
166
|
separate isolated execution pools with semicolons and threads with colons.
|
164
167
|
```
|
data/lib/good_job/cli.rb
CHANGED
@@ -15,6 +15,11 @@ module GoodJob
|
|
15
15
|
# Requiring this loads the application's configuration and classes.
|
16
16
|
RAILS_ENVIRONMENT_RB = File.expand_path("config/environment.rb")
|
17
17
|
|
18
|
+
# @!visibility private
|
19
|
+
def self.exit_on_failure?
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
18
23
|
# @!macro thor.desc
|
19
24
|
# @!method $1
|
20
25
|
# @return [void]
|
@@ -27,7 +32,8 @@ module GoodJob
|
|
27
32
|
See option descriptions for the matching environment variable name.
|
28
33
|
|
29
34
|
== Configuring queues
|
30
|
-
|
35
|
+
|
36
|
+
Separate multiple queues with commas; exclude queues with a leading minus;
|
31
37
|
separate isolated execution pools with semicolons and threads with colons.
|
32
38
|
|
33
39
|
DESCRIPTION
|
@@ -43,10 +49,18 @@ module GoodJob
|
|
43
49
|
type: :numeric,
|
44
50
|
banner: 'SECONDS',
|
45
51
|
desc: "Interval between polls for available jobs in seconds (env var: GOOD_JOB_POLL_INTERVAL, default: 5)"
|
52
|
+
method_option :daemonize,
|
53
|
+
type: :boolean,
|
54
|
+
desc: "Run as a background daemon (default: false)"
|
55
|
+
method_option :pidfile,
|
56
|
+
type: :string,
|
57
|
+
desc: "Path to write daemonized Process ID (env var: GOOD_JOB_PIDFILE, default: tmp/pids/good_job.pid)"
|
46
58
|
def start
|
47
59
|
set_up_application!
|
48
60
|
configuration = GoodJob::Configuration.new(options)
|
49
61
|
|
62
|
+
Daemon.new(pidfile: configuration.pidfile).daemonize if configuration.daemonize?
|
63
|
+
|
50
64
|
notifier = GoodJob::Notifier.new
|
51
65
|
poller = GoodJob::Poller.new(poll_interval: configuration.poll_interval)
|
52
66
|
scheduler = GoodJob::Scheduler.from_configuration(configuration)
|
@@ -12,16 +12,15 @@ module GoodJob
|
|
12
12
|
# Default number of seconds to preserve jobs for {CLI#cleanup_preserved_jobs}
|
13
13
|
DEFAULT_CLEANUP_PRESERVED_JOBS_BEFORE_SECONDS_AGO = 24 * 60 * 60
|
14
14
|
|
15
|
-
#
|
16
|
-
#
|
17
|
-
|
18
|
-
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
|
24
|
-
attr_reader :options, :env
|
15
|
+
# The options that were explicitly set when initializing +Configuration+.
|
16
|
+
# @return [Hash]
|
17
|
+
attr_reader :options
|
18
|
+
|
19
|
+
# The environment from which to read GoodJob's environment variables. By
|
20
|
+
# default, this is the current process's environment, but it can be set
|
21
|
+
# to something else in {#initialize}.
|
22
|
+
# @return [Hash]
|
23
|
+
attr_reader :env
|
25
24
|
|
26
25
|
# @param options [Hash] Any explicitly specified configuration options to
|
27
26
|
# use. Keys are symbols that match the various methods on this class.
|
@@ -108,7 +107,7 @@ module GoodJob
|
|
108
107
|
|
109
108
|
# Number of seconds to preserve jobs when using the +good_job cleanup_preserved_jobs+ CLI command.
|
110
109
|
# This configuration is only used when {GoodJob.preserve_job_records} is +true+.
|
111
|
-
# @return [
|
110
|
+
# @return [Integer]
|
112
111
|
def cleanup_preserved_jobs_before_seconds_ago
|
113
112
|
(
|
114
113
|
options[:before_seconds_ago] ||
|
@@ -118,6 +117,20 @@ module GoodJob
|
|
118
117
|
).to_i
|
119
118
|
end
|
120
119
|
|
120
|
+
# Tests whether to daemonize the process.
|
121
|
+
# @return [Boolean]
|
122
|
+
def daemonize?
|
123
|
+
options[:daemonize] || false
|
124
|
+
end
|
125
|
+
|
126
|
+
# Path of the pidfile to create when running as a daemon.
|
127
|
+
# @return [Pathname,String]
|
128
|
+
def pidfile
|
129
|
+
options[:pidfile] ||
|
130
|
+
env['GOOD_JOB_PIDFILE'] ||
|
131
|
+
Rails.application.root.join('tmp', 'pids', 'good_job.pid')
|
132
|
+
end
|
133
|
+
|
121
134
|
private
|
122
135
|
|
123
136
|
def rails_config
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module GoodJob
|
2
|
+
#
|
3
|
+
# Manages daemonization of the current process.
|
4
|
+
#
|
5
|
+
class Daemon
|
6
|
+
# The path of the generated pidfile.
|
7
|
+
# @return [Pathname,String]
|
8
|
+
attr_reader :pidfile
|
9
|
+
|
10
|
+
# @param pidfile [Pathname,String] Pidfile path
|
11
|
+
def initialize(pidfile:)
|
12
|
+
@pidfile = pidfile
|
13
|
+
end
|
14
|
+
|
15
|
+
# Daemonizes the current process and writes out a pidfile.
|
16
|
+
def daemonize
|
17
|
+
check_pid
|
18
|
+
Process.daemon
|
19
|
+
write_pid
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def write_pid
|
25
|
+
File.open(pidfile, ::File::CREAT | ::File::EXCL | ::File::WRONLY) { |f| f.write(Process.pid.to_s) }
|
26
|
+
at_exit { File.delete(pidfile) if File.exist?(pidfile) }
|
27
|
+
rescue Errno::EEXIST
|
28
|
+
check_pid
|
29
|
+
retry
|
30
|
+
end
|
31
|
+
|
32
|
+
def delete_pid
|
33
|
+
File.delete(pidfile) if File.exist?(pidfile)
|
34
|
+
end
|
35
|
+
|
36
|
+
def check_pid
|
37
|
+
case pid_status(pidfile)
|
38
|
+
when :running, :not_owned
|
39
|
+
abort "A server is already running. Check #{pidfile}"
|
40
|
+
when :dead
|
41
|
+
File.delete(pidfile)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def pid_status(pidfile)
|
46
|
+
return :exited unless File.exist?(pidfile)
|
47
|
+
|
48
|
+
pid = ::File.read(pidfile).to_i
|
49
|
+
return :dead if pid.zero?
|
50
|
+
|
51
|
+
Process.kill(0, pid) # check process status
|
52
|
+
:running
|
53
|
+
rescue Errno::ESRCH
|
54
|
+
:dead
|
55
|
+
rescue Errno::EPERM
|
56
|
+
:not_owned
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/good_job/lockable.rb
CHANGED
@@ -92,8 +92,6 @@ module GoodJob
|
|
92
92
|
# @return [ActiveRecord::Relation]
|
93
93
|
scope :owns_advisory_locked, -> { joins_advisory_locks.where('"pg_locks"."pid" = pg_backend_pid()') }
|
94
94
|
|
95
|
-
# @!attribute [r] create_with_advisory_lock
|
96
|
-
# @return [Boolean]
|
97
95
|
# Whether an advisory lock should be acquired in the same transaction
|
98
96
|
# that created the record.
|
99
97
|
#
|
@@ -107,6 +105,8 @@ module GoodJob
|
|
107
105
|
# record = MyLockableRecord.create(create_with_advisory_lock: true)
|
108
106
|
# record.advisory_locked?
|
109
107
|
# => true
|
108
|
+
#
|
109
|
+
# @return [Boolean]
|
110
110
|
attr_accessor :create_with_advisory_lock
|
111
111
|
|
112
112
|
after_create -> { advisory_lock }, if: :create_with_advisory_lock
|
data/lib/good_job/scheduler.rb
CHANGED
@@ -8,7 +8,7 @@ module GoodJob # :nodoc:
|
|
8
8
|
# periodically checking for available tasks, executing tasks within a thread,
|
9
9
|
# and efficiently scaling active threads.
|
10
10
|
#
|
11
|
-
# Every scheduler has a single {
|
11
|
+
# Every scheduler has a single {JobPerformer} that will execute tasks.
|
12
12
|
# The scheduler is responsible for calling its performer efficiently across threads managed by an instance of +Concurrent::ThreadPoolExecutor+.
|
13
13
|
# If a performer does not have work, the thread will go to sleep.
|
14
14
|
# The scheduler maintains an instance of +Concurrent::TimerTask+, which wakes sleeping threads and causes them to check whether the performer has new work.
|
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: 1.
|
4
|
+
version: 1.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: 2021-01-
|
11
|
+
date: 2021-01-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|
@@ -357,6 +357,7 @@ files:
|
|
357
357
|
- lib/good_job/cli.rb
|
358
358
|
- lib/good_job/configuration.rb
|
359
359
|
- lib/good_job/current_execution.rb
|
360
|
+
- lib/good_job/daemon.rb
|
360
361
|
- lib/good_job/job.rb
|
361
362
|
- lib/good_job/job_performer.rb
|
362
363
|
- lib/good_job/lockable.rb
|