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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 89ef994e63adf5fe8dcbcdd230d9669d21c2cb6d9c62da622c8d8a197fcb3cef
4
- data.tar.gz: 6ed6d2cc6f75c5b4dc6976f3e360a5aeb27e3488fbd8035d086058b40d693025
3
+ metadata.gz: b8f0f56838ed9baa984ad7b70ece1c72009369149bb45522aa140298ff727d44
4
+ data.tar.gz: a076e6f1315911e9fcacc8be7be4e87d176f6a63fd4cf8e297b8985d928074cf
5
5
  SHA512:
6
- metadata.gz: f8d856f3797236bffecfffe5bcb58599aa0b2f843962fe09032eb0606d432d1f379dd564d00e29512bd6e3ca0c26c261401eed4b45806f21c660d9cd1a9a4838
7
- data.tar.gz: cd223dc763e1bb56d746f957aec29403ed78b6d89619fd4d4b23148d2f78a86c452e29e48249cf408cc4fff7c0ee564eb7032d9b02b24239a2d0215f40df5194
6
+ metadata.gz: 6eae147e6a6f22da09c87b246735d0844e09dbaaea2e9b2cc92664ad86efef95feb8572ddafa83964009572d5c55db5eefc9f589d63820fb77fc59ec8ac4f110
7
+ data.tar.gz: 3f884573f31e65c3d63c2b864a820b9e9dd5db2a71405f3514ffdd774458bb89c7b5a834878aba2a57b988cce02443fc2df8e986d09815f98784bdaa9de6b62f
@@ -1,6 +1,25 @@
1
1
  # Changelog
2
2
 
3
- ## [v1.5.0](https://github.com/bensheldon/good_job/tree/v1.5.0) (2021-01-17)
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
  ```
@@ -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
- \x5Separate multiple queues with commas; exclude queues with a leading minus;
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
- # @!attribute [r] options
16
- # The options that were explicitly set when initializing +Configuration+.
17
- # @return [Hash]
18
- #
19
- # @!attribute [r] env
20
- # The environment from which to read GoodJob's environment variables. By
21
- # default, this is the current process's environment, but it can be set
22
- # to something else in {#initialize}.
23
- # @return [Hash]
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 [Boolean]
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
@@ -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
@@ -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 {Performer} that will execute tasks.
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.
@@ -1,4 +1,4 @@
1
1
  module GoodJob
2
2
  # GoodJob gem version.
3
- VERSION = '1.5.0'.freeze
3
+ VERSION = '1.6.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.5.0
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-18 00:00:00.000000000 Z
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