good_job 3.16.4 → 3.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/app/frontend/good_job/application.js +2 -0
  4. data/app/frontend/good_job/modules/theme_controller.js +44 -0
  5. data/app/frontend/good_job/vendor/bootstrap/bootstrap.bundle.min.js +3 -3
  6. data/app/frontend/good_job/vendor/bootstrap/bootstrap.min.css +3 -4
  7. data/app/views/good_job/batches/_jobs.erb +3 -3
  8. data/app/views/good_job/batches/_table.erb +1 -1
  9. data/app/views/good_job/batches/show.html.erb +1 -1
  10. data/app/views/good_job/cron_entries/index.html.erb +2 -2
  11. data/app/views/good_job/jobs/_executions.erb +2 -2
  12. data/app/views/good_job/jobs/_table.erb +10 -9
  13. data/app/views/good_job/jobs/show.html.erb +2 -2
  14. data/app/views/good_job/processes/index.html.erb +3 -3
  15. data/app/views/good_job/shared/_footer.erb +1 -1
  16. data/app/views/good_job/shared/_navbar.erb +50 -7
  17. data/app/views/good_job/shared/icons/_circle_half.html.erb +4 -0
  18. data/app/views/good_job/shared/icons/_moon_stars_fill.html.erb +5 -0
  19. data/app/views/good_job/shared/icons/_sun_fill.html.erb +4 -0
  20. data/app/views/layouts/good_job/application.html.erb +9 -1
  21. data/config/locales/de.yml +5 -0
  22. data/config/locales/en.yml +5 -0
  23. data/config/locales/es.yml +5 -0
  24. data/config/locales/fr.yml +5 -0
  25. data/config/locales/ja.yml +5 -0
  26. data/config/locales/nl.yml +5 -0
  27. data/config/locales/ru.yml +5 -0
  28. data/config/locales/tr.yml +5 -0
  29. data/config/locales/uk.yml +5 -0
  30. data/lib/good_job/cli.rb +6 -2
  31. data/lib/good_job/http_server.rb +75 -0
  32. data/lib/good_job/log_subscriber.rb +18 -0
  33. data/lib/good_job/probe_server.rb +4 -8
  34. data/lib/good_job/sd_notify.rb +157 -0
  35. data/lib/good_job/systemd_service.rb +69 -0
  36. data/lib/good_job/version.rb +1 -1
  37. data/lib/good_job.rb +2 -0
  38. metadata +9 -16
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is a copy of https://github.com/agis/ruby-sdnotify as of v0.1.1
4
+ # (commit 21240f1)
5
+ # Any changes have been marked with "FORK:" comments.
6
+ #
7
+ # It is included here because it is a very small gem, and doing so reduces
8
+ # the number of dependencies and the supply chain risks they pose.
9
+
10
+ # FORK: nest SdNotify inside the GoodJob module to prevent name collisions in
11
+ # case a GoodJob user also uses the actual sd_notify gem.
12
+ module GoodJob
13
+
14
+ # The MIT License
15
+ #
16
+ # Copyright (c) 2017, 2018, 2019, 2020 Agis Anastasopoulos
17
+ #
18
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
19
+ # this software and associated documentation files (the "Software"), to deal in
20
+ # the Software without restriction, including without limitation the rights to
21
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
22
+ # the Software, and to permit persons to whom the Software is furnished to do so,
23
+ # subject to the following conditions:
24
+ #
25
+ # The above copyright notice and this permission notice shall be included in all
26
+ # copies or substantial portions of the Software.
27
+ #
28
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
30
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
31
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
32
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34
+
35
+ require "socket"
36
+
37
+ # SdNotify is a pure-Ruby implementation of sd_notify(3). It can be used to
38
+ # notify systemd about state changes. Methods of this package are no-op on
39
+ # non-systemd systems (eg. Darwin).
40
+ #
41
+ # The API maps closely to the original implementation of sd_notify(3),
42
+ # therefore be sure to check the official man pages prior to using SdNotify.
43
+ #
44
+ # @see https://www.freedesktop.org/software/systemd/man/sd_notify.html
45
+ module SdNotify
46
+ # Exception raised when there's an error writing to the notification socket
47
+ class NotifyError < RuntimeError; end
48
+
49
+ READY = "READY=1"
50
+ RELOADING = "RELOADING=1"
51
+ STOPPING = "STOPPING=1"
52
+ STATUS = "STATUS="
53
+ ERRNO = "ERRNO="
54
+ MAINPID = "MAINPID="
55
+ WATCHDOG = "WATCHDOG=1"
56
+ FDSTORE = "FDSTORE=1"
57
+
58
+ def self.ready(unset_env=false)
59
+ notify(READY, unset_env)
60
+ end
61
+
62
+ def self.reloading(unset_env=false)
63
+ notify(RELOADING, unset_env)
64
+ end
65
+
66
+ def self.stopping(unset_env=false)
67
+ notify(STOPPING, unset_env)
68
+ end
69
+
70
+ # @param status [String] a custom status string that describes the current
71
+ # state of the service
72
+ def self.status(status, unset_env=false)
73
+ notify("#{STATUS}#{status}", unset_env)
74
+ end
75
+
76
+ # @param errno [Integer]
77
+ def self.errno(errno, unset_env=false)
78
+ notify("#{ERRNO}#{errno}", unset_env)
79
+ end
80
+
81
+ # @param pid [Integer]
82
+ def self.mainpid(pid, unset_env=false)
83
+ notify("#{MAINPID}#{pid}", unset_env)
84
+ end
85
+
86
+ def self.watchdog(unset_env=false)
87
+ notify(WATCHDOG, unset_env)
88
+ end
89
+
90
+ def self.fdstore(unset_env=false)
91
+ notify(FDSTORE, unset_env)
92
+ end
93
+
94
+ # @param [Boolean] true if the service manager expects watchdog keep-alive
95
+ # notification messages to be sent from this process.
96
+ #
97
+ # If the $WATCHDOG_USEC environment variable is set,
98
+ # and the $WATCHDOG_PID variable is unset or set to the PID of the current
99
+ # process
100
+ #
101
+ # @note Unlike sd_watchdog_enabled(3), this method does not mutate the
102
+ # environment.
103
+ def self.watchdog?
104
+ wd_usec = ENV["WATCHDOG_USEC"]
105
+ wd_pid = ENV["WATCHDOG_PID"]
106
+
107
+ return false if !wd_usec
108
+
109
+ begin
110
+ wd_usec = Integer(wd_usec)
111
+ rescue
112
+ return false
113
+ end
114
+
115
+ return false if wd_usec <= 0
116
+ return true if !wd_pid || wd_pid == $$.to_s
117
+
118
+ false
119
+ end
120
+
121
+ # Notify systemd with the provided state, via the notification socket, if
122
+ # any.
123
+ #
124
+ # Generally this method will be used indirectly through the other methods
125
+ # of the library.
126
+ #
127
+ # @param state [String]
128
+ # @param unset_env [Boolean]
129
+ #
130
+ # @return [Fixnum, nil] the number of bytes written to the notification
131
+ # socket or nil if there was no socket to report to (eg. the program wasn't
132
+ # started by systemd)
133
+ #
134
+ # @raise [NotifyError] if there was an error communicating with the systemd
135
+ # socket
136
+ #
137
+ # @see https://www.freedesktop.org/software/systemd/man/sd_notify.html
138
+ def self.notify(state, unset_env=false)
139
+ sock = ENV["NOTIFY_SOCKET"]
140
+
141
+ return nil if !sock
142
+
143
+ ENV.delete("NOTIFY_SOCKET") if unset_env
144
+
145
+ begin
146
+ Addrinfo.unix(sock, :DGRAM).connect do |s|
147
+ s.close_on_exec = true
148
+ s.write(state)
149
+ end
150
+ rescue StandardError => e
151
+ raise NotifyError, "#{e.class}: #{e.message}", e.backtrace
152
+ end
153
+ end
154
+ end
155
+
156
+ # FORK: Finish nesting inside GoodJob.
157
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'concurrent/timer_task'
4
+ require 'good_job/sd_notify'
5
+
6
+ module GoodJob # :nodoc:
7
+ #
8
+ # Manages communication with systemd to notify it about the status of the
9
+ # GoodJob CLI. If it doesn't look like systemd is controlling the process,
10
+ # SystemdService doesn't do anything.
11
+ #
12
+ class SystemdService
13
+ def self.task_observer(_time, _output, thread_error) # :nodoc:
14
+ return if thread_error.is_a? Concurrent::CancelledOperationError
15
+
16
+ ActiveSupport::Notifications.instrument("systemd_watchdog_error.good_job", { error: thread_error })
17
+ GoodJob._on_thread_error(thread_error) if thread_error
18
+ end
19
+
20
+ # Indicates whether the service is actively notifying systemd's watchdog.
21
+ def notifying?
22
+ @watchdog&.running? || false
23
+ end
24
+
25
+ # Notify systemd that the process is ready. If the service is configured in
26
+ # systemd to use the watchdog, this will also start pinging the watchdog.
27
+ def start
28
+ GoodJob::SdNotify.ready
29
+ run_watchdog
30
+ end
31
+
32
+ # Notify systemd that the process is stopping and stop pinging the watchdog
33
+ # if currently doing so. If given a block, it will wait for the block to
34
+ # complete before stopping watchdog notifications, so systemd has a clear
35
+ # indication when graceful shutdown started and finished.
36
+ def stop
37
+ GoodJob::SdNotify.stopping
38
+
39
+ yield if block_given?
40
+
41
+ @watchdog&.kill
42
+ @watchdog&.wait_for_termination
43
+ end
44
+
45
+ private
46
+
47
+ def run_watchdog
48
+ return false unless GoodJob::SdNotify.watchdog?
49
+
50
+ # Systemd recommends pinging the watchdog at half the configured interval:
51
+ # https://www.freedesktop.org/software/systemd/man/sd_watchdog_enabled.html
52
+ interval = watchdog_interval / 2
53
+
54
+ ActiveSupport::Notifications.instrument("systemd_watchdog_start.good_job", { interval: interval })
55
+ @watchdog = Concurrent::TimerTask.execute(execution_interval: interval) do
56
+ GoodJob::SdNotify.watchdog
57
+ end
58
+ @watchdog.add_observer(self.class, :task_observer)
59
+
60
+ true
61
+ end
62
+
63
+ def watchdog_interval
64
+ return 0.0 unless GoodJob::SdNotify.watchdog?
65
+
66
+ Integer(ENV.fetch('WATCHDOG_USEC')) / 1_000_000.0
67
+ end
68
+ end
69
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module GoodJob
4
4
  # GoodJob gem version.
5
- VERSION = '3.16.4'
5
+ VERSION = '3.17.0'
6
6
 
7
7
  # GoodJob version as Gem::Version object
8
8
  GEM_VERSION = Gem::Version.new(VERSION)
data/lib/good_job.rb CHANGED
@@ -29,9 +29,11 @@ require "good_job/log_subscriber"
29
29
  require "good_job/multi_scheduler"
30
30
  require "good_job/notifier"
31
31
  require "good_job/poller"
32
+ require "good_job/http_server"
32
33
  require "good_job/probe_server"
33
34
  require "good_job/scheduler"
34
35
  require "good_job/shared_executor"
36
+ require "good_job/systemd_service"
35
37
 
36
38
  # GoodJob is a multithreaded, Postgres-based, ActiveJob backend for Ruby on Rails.
37
39
  #
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.16.4
4
+ version: 3.17.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-07-30 00:00:00.000000000 Z
11
+ date: 2023-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob
@@ -94,20 +94,6 @@ 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'
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: benchmark-ips
113
99
  requirement: !ruby/object:Gem::Requirement
@@ -334,6 +320,7 @@ files:
334
320
  - app/frontend/good_job/modules/document_ready.js
335
321
  - app/frontend/good_job/modules/live_poll.js
336
322
  - app/frontend/good_job/modules/popovers.js
323
+ - app/frontend/good_job/modules/theme_controller.js
337
324
  - app/frontend/good_job/modules/toasts.js
338
325
  - app/frontend/good_job/style.css
339
326
  - app/frontend/good_job/vendor/bootstrap/bootstrap.bundle.min.js
@@ -378,15 +365,18 @@ files:
378
365
  - app/views/good_job/shared/_navbar.erb
379
366
  - app/views/good_job/shared/icons/_arrow_clockwise.html.erb
380
367
  - app/views/good_job/shared/icons/_check.html.erb
368
+ - app/views/good_job/shared/icons/_circle_half.html.erb
381
369
  - app/views/good_job/shared/icons/_clock.html.erb
382
370
  - app/views/good_job/shared/icons/_dash_circle.html.erb
383
371
  - app/views/good_job/shared/icons/_dots.html.erb
384
372
  - app/views/good_job/shared/icons/_exclamation.html.erb
385
373
  - app/views/good_job/shared/icons/_info.html.erb
374
+ - app/views/good_job/shared/icons/_moon_stars_fill.html.erb
386
375
  - app/views/good_job/shared/icons/_pause.html.erb
387
376
  - app/views/good_job/shared/icons/_play.html.erb
388
377
  - app/views/good_job/shared/icons/_skip_forward.html.erb
389
378
  - app/views/good_job/shared/icons/_stop.html.erb
379
+ - app/views/good_job/shared/icons/_sun_fill.html.erb
390
380
  - app/views/good_job/shared/icons/_trash.html.erb
391
381
  - app/views/layouts/good_job/application.html.erb
392
382
  - config/locales/de.yml
@@ -427,6 +417,7 @@ files:
427
417
  - lib/good_job/daemon.rb
428
418
  - lib/good_job/dependencies.rb
429
419
  - lib/good_job/engine.rb
420
+ - lib/good_job/http_server.rb
430
421
  - lib/good_job/interrupt_error.rb
431
422
  - lib/good_job/job_performer.rb
432
423
  - lib/good_job/log_subscriber.rb
@@ -437,7 +428,9 @@ files:
437
428
  - lib/good_job/poller.rb
438
429
  - lib/good_job/probe_server.rb
439
430
  - lib/good_job/scheduler.rb
431
+ - lib/good_job/sd_notify.rb
440
432
  - lib/good_job/shared_executor.rb
433
+ - lib/good_job/systemd_service.rb
441
434
  - lib/good_job/version.rb
442
435
  homepage: https://github.com/bensheldon/good_job
443
436
  licenses: