good_job 2.6.2 → 2.7.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 +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +57 -0
- data/engine/app/controllers/good_job/base_controller.rb +19 -0
- data/lib/good_job/cli.rb +8 -0
- data/lib/good_job/configuration.rb +7 -0
- data/lib/good_job/probe_server.rb +51 -0
- data/lib/good_job/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f44a377e368104479ccd928977d0c99c673e468fdcce61530cdfef1ee045c61d
|
4
|
+
data.tar.gz: 3a5b29ba222be53ee571036ed27275517cb810a03bbd9b6fa5733b215742ef50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 833b35f3faa5660d45e14adbb15d2b6f65c7a7cbc127ae0d6d9085844e55fe33c6c1b02cbb6196f5f753bdf7ec76cff18a1976cef3ca26288960f6028c6d3fac
|
7
|
+
data.tar.gz: def64d311e93139e7232fddd9aec1f0c0e0ff49696680dede67f87705d3a0dbc9338d083f1f2a22fdfff572465032c6ec75c97dee1ece7ffac20ca46c76fdc6c
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v2.7.0](https://github.com/bensheldon/good_job/tree/v2.7.0) (2021-11-10)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v2.6.2...v2.7.0)
|
6
|
+
|
7
|
+
**Implemented enhancements:**
|
8
|
+
|
9
|
+
- Add http probe for CLI healthcheck/readiness/liveliness [\#452](https://github.com/bensheldon/good_job/pull/452) ([bensheldon](https://github.com/bensheldon))
|
10
|
+
- Add explicit Content Security Policy \(CSP\) for Dashboard [\#449](https://github.com/bensheldon/good_job/pull/449) ([bensheldon](https://github.com/bensheldon))
|
11
|
+
|
12
|
+
**Closed issues:**
|
13
|
+
|
14
|
+
- Add a default Content-Security-Policy for the Dashboard [\#420](https://github.com/bensheldon/good_job/issues/420)
|
15
|
+
|
3
16
|
## [v2.6.2](https://github.com/bensheldon/good_job/tree/v2.6.2) (2021-11-05)
|
4
17
|
|
5
18
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v2.6.1...v2.6.2)
|
data/README.md
CHANGED
@@ -55,6 +55,7 @@ For more of the story of GoodJob, read the [introductory blog post](https://isla
|
|
55
55
|
- [Migrate to GoodJob from a different ActiveJob backend](#migrate-to-goodjob-from-a-different-activejob-backend)
|
56
56
|
- [Monitor and preserve worked jobs](#monitor-and-preserve-worked-jobs)
|
57
57
|
- [PgBouncer compatibility](#pgbouncer-compatibility)
|
58
|
+
- [CLI HTTP health check probes](#cli-http-healthcheck-probes)
|
58
59
|
- [Contribute](#contribute)
|
59
60
|
- [Gem development](#gem-development)
|
60
61
|
- [Release](#release)
|
@@ -170,6 +171,7 @@ Options:
|
|
170
171
|
[--enable-cron] # Whether to run cron process (default: false)
|
171
172
|
[--daemonize] # Run as a background daemon (default: false)
|
172
173
|
[--pidfile=PIDFILE] # Path to write daemonized Process ID (env var: GOOD_JOB_PIDFILE, default: tmp/pids/good_job.pid)
|
174
|
+
[--probe-port=PORT] # Port for http health check (env var: GOOD_JOB_PROBE_PORT, default: nil)
|
173
175
|
|
174
176
|
Executes queued jobs.
|
175
177
|
|
@@ -837,6 +839,61 @@ A workaround to this limitation is to make a direct database connection availabl
|
|
837
839
|
GoodJob.active_record_parent_class = "ApplicationDirectRecord"
|
838
840
|
```
|
839
841
|
|
842
|
+
### CLI HTTP health check probes
|
843
|
+
|
844
|
+
GoodJob's CLI offers an http health check probe to better manage process lifecycle in containerized environments like Kubernetes:
|
845
|
+
|
846
|
+
```bash
|
847
|
+
# Run the CLI with a health check on port 7001
|
848
|
+
good_job start --probe-port=7001
|
849
|
+
|
850
|
+
# or via an environment variable
|
851
|
+
GOOD_JOB_PROBE_PORT=7001 good_job start
|
852
|
+
|
853
|
+
# Probe the status
|
854
|
+
curl localhost:7001/status
|
855
|
+
curl localhost:7001/status/started
|
856
|
+
curl localhost:7001/status/connected
|
857
|
+
```
|
858
|
+
|
859
|
+
Multiple health checks are available at different paths:
|
860
|
+
|
861
|
+
- `/` or `/status`: the CLI process is running
|
862
|
+
- `/status/started`: the multithreaded job executor is running
|
863
|
+
- `/status/connected`: the database connection is established
|
864
|
+
|
865
|
+
This can be configured, for example with Kubernetes:
|
866
|
+
|
867
|
+
```yaml
|
868
|
+
spec:
|
869
|
+
containers:
|
870
|
+
- name: good_job
|
871
|
+
image: my_app:latest
|
872
|
+
env:
|
873
|
+
- name: RAILS_ENV
|
874
|
+
value: production
|
875
|
+
- name: GOOD_JOB_PROBE_PORT
|
876
|
+
value: 7001
|
877
|
+
command:
|
878
|
+
- good_job
|
879
|
+
- start
|
880
|
+
ports:
|
881
|
+
- name: probe-port
|
882
|
+
containerPort: 7001
|
883
|
+
startupProbe:
|
884
|
+
httpGet:
|
885
|
+
path: "/status/started"
|
886
|
+
port: probe-port
|
887
|
+
failureThreshold: 30
|
888
|
+
periodSeconds: 10
|
889
|
+
livenessProbe:
|
890
|
+
httpGet:
|
891
|
+
path: "/status/connected"
|
892
|
+
port: probe-port
|
893
|
+
failureThreshold: 1
|
894
|
+
periodSeconds: 10
|
895
|
+
```
|
896
|
+
|
840
897
|
## Contribute
|
841
898
|
|
842
899
|
Contributions are welcomed and appreciated 🙏
|
@@ -5,6 +5,25 @@ module GoodJob
|
|
5
5
|
|
6
6
|
around_action :switch_locale
|
7
7
|
|
8
|
+
content_security_policy do |policy|
|
9
|
+
policy.default_src(:none) if policy.default_src.blank?
|
10
|
+
policy.connect_src(:self) if policy.connect_src.blank?
|
11
|
+
policy.base_uri(:none) if policy.base_uri.blank?
|
12
|
+
policy.font_src(:self) if policy.font_src.blank?
|
13
|
+
policy.img_src(:self, :data) if policy.img_src.blank?
|
14
|
+
policy.object_src(:none) if policy.object_src.blank?
|
15
|
+
policy.script_src(:self) if policy.script_src.blank?
|
16
|
+
policy.style_src(:self) if policy.style_src.blank?
|
17
|
+
policy.form_action(:self) if policy.form_action.blank?
|
18
|
+
policy.frame_ancestors(:none) if policy.frame_ancestors.blank?
|
19
|
+
end
|
20
|
+
|
21
|
+
before_action do
|
22
|
+
next if request.content_security_policy_nonce_generator
|
23
|
+
|
24
|
+
request.content_security_policy_nonce_generator = ->(_request) { SecureRandom.base64(16) }
|
25
|
+
end
|
26
|
+
|
8
27
|
private
|
9
28
|
|
10
29
|
def switch_locale(&action)
|
data/lib/good_job/cli.rb
CHANGED
@@ -79,6 +79,9 @@ module GoodJob
|
|
79
79
|
method_option :pidfile,
|
80
80
|
type: :string,
|
81
81
|
desc: "Path to write daemonized Process ID (env var: GOOD_JOB_PIDFILE, default: tmp/pids/good_job.pid)"
|
82
|
+
method_option :probe_port,
|
83
|
+
type: :numeric,
|
84
|
+
desc: "Port for http health check (env var: GOOD_JOB_PROBE_PORT, default: nil)"
|
82
85
|
|
83
86
|
def start
|
84
87
|
set_up_application!
|
@@ -93,6 +96,10 @@ module GoodJob
|
|
93
96
|
poller.recipients << [scheduler, :create_thread]
|
94
97
|
|
95
98
|
cron_manager = GoodJob::CronManager.new(configuration.cron_entries, start_on_initialize: true) if configuration.enable_cron?
|
99
|
+
if configuration.probe_port
|
100
|
+
probe_server = GoodJob::ProbeServer.new(port: configuration.probe_port)
|
101
|
+
probe_server.start
|
102
|
+
end
|
96
103
|
|
97
104
|
@stop_good_job_executable = false
|
98
105
|
%w[INT TERM].each do |signal|
|
@@ -106,6 +113,7 @@ module GoodJob
|
|
106
113
|
|
107
114
|
executors = [notifier, poller, cron_manager, scheduler].compact
|
108
115
|
GoodJob._shutdown_all(executors, timeout: configuration.shutdown_timeout)
|
116
|
+
probe_server&.stop
|
109
117
|
end
|
110
118
|
|
111
119
|
default_task :start
|
@@ -195,6 +195,13 @@ module GoodJob
|
|
195
195
|
Rails.application.root.join('tmp', 'pids', 'good_job.pid')
|
196
196
|
end
|
197
197
|
|
198
|
+
# Port of the probe server
|
199
|
+
# @return [nil,Integer]
|
200
|
+
def probe_port
|
201
|
+
options[:probe_port] ||
|
202
|
+
env['GOOD_JOB_PROBE_PORT']
|
203
|
+
end
|
204
|
+
|
198
205
|
private
|
199
206
|
|
200
207
|
def rails_config
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GoodJob
|
4
|
+
class ProbeServer
|
5
|
+
RACK_SERVER = 'webrick'
|
6
|
+
|
7
|
+
def self.task_observer(time, output, thread_error) # rubocop:disable Lint/UnusedMethodArgument
|
8
|
+
return if thread_error.is_a? Concurrent::CancelledOperationError
|
9
|
+
|
10
|
+
GoodJob.on_thread_error.call(thread_error) if thread_error && GoodJob.on_thread_error.respond_to?(:call)
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(port:)
|
14
|
+
@port = port
|
15
|
+
end
|
16
|
+
|
17
|
+
def start
|
18
|
+
@handler = Rack::Handler.get(RACK_SERVER)
|
19
|
+
@future = Concurrent::Future.new(args: [@handler, @port, GoodJob.logger]) do |thr_handler, thr_port, thr_logger|
|
20
|
+
thr_handler.run(self, Port: thr_port, Logger: thr_logger, AccessLog: [])
|
21
|
+
end
|
22
|
+
@future.add_observer(self.class, :task_observer)
|
23
|
+
@future.execute
|
24
|
+
end
|
25
|
+
|
26
|
+
def running?
|
27
|
+
@handler&.instance_variable_get(:@server)&.status == :Running
|
28
|
+
end
|
29
|
+
|
30
|
+
def stop
|
31
|
+
@handler&.shutdown
|
32
|
+
@future&.value # wait for Future to exit
|
33
|
+
end
|
34
|
+
|
35
|
+
def call(env)
|
36
|
+
case Rack::Request.new(env).path
|
37
|
+
when '/', '/status'
|
38
|
+
[200, {}, ["OK"]]
|
39
|
+
when '/status/started'
|
40
|
+
started = GoodJob::Scheduler.instances.any? && GoodJob::Scheduler.instances.all?(&:running?)
|
41
|
+
started ? [200, {}, ["Started"]] : [503, {}, ["Not started"]]
|
42
|
+
when '/status/connected'
|
43
|
+
connected = GoodJob::Scheduler.instances.any? && GoodJob::Scheduler.instances.all?(&:running?) &&
|
44
|
+
GoodJob::Notifier.instances.any? && GoodJob::Notifier.instances.all?(&:listening?)
|
45
|
+
connected ? [200, {}, ["Connected"]] : [503, {}, ["Not connected"]]
|
46
|
+
else
|
47
|
+
[404, {}, ["Not found"]]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
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: 2.
|
4
|
+
version: 2.7.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-11-
|
11
|
+
date: 2021-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: 0.14.1
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: webrick
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.3'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.3'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: zeitwerk
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -410,6 +424,7 @@ files:
|
|
410
424
|
- lib/good_job/multi_scheduler.rb
|
411
425
|
- lib/good_job/notifier.rb
|
412
426
|
- lib/good_job/poller.rb
|
427
|
+
- lib/good_job/probe_server.rb
|
413
428
|
- lib/good_job/railtie.rb
|
414
429
|
- lib/good_job/scheduler.rb
|
415
430
|
- lib/good_job/version.rb
|