good_job 3.1.0 → 3.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +62 -7
- data/README.md +35 -31
- data/app/assets/good_job/modules/application.js +2 -0
- data/app/assets/good_job/modules/popovers.js +7 -0
- data/app/assets/good_job/style.css +4 -0
- data/app/helpers/good_job/application_helper.rb +2 -2
- data/{lib → app/models/concerns}/good_job/filterable.rb +0 -0
- data/app/models/concerns/good_job/reportable.rb +43 -0
- data/{lib → app}/models/good_job/active_job_job.rb +0 -0
- data/{lib → app}/models/good_job/base_record.rb +0 -0
- data/{lib → app}/models/good_job/cron_entry.rb +1 -1
- data/{lib → app}/models/good_job/execution.rb +42 -45
- data/{lib → app/models}/good_job/execution_result.rb +0 -0
- data/{lib → app}/models/good_job/job.rb +2 -27
- data/{lib → app}/models/good_job/lockable.rb +0 -0
- data/{lib → app}/models/good_job/process.rb +4 -0
- data/app/views/good_job/cron_entries/index.html.erb +60 -57
- data/app/views/good_job/jobs/_executions.erb +31 -28
- data/app/views/good_job/jobs/_table.erb +138 -109
- data/app/views/good_job/jobs/show.html.erb +40 -31
- data/app/views/good_job/processes/index.html.erb +60 -32
- data/app/views/good_job/shared/_navbar.erb +1 -1
- data/app/views/good_job/shared/icons/_dots.html.erb +3 -0
- data/app/views/good_job/shared/icons/_info.html.erb +4 -0
- data/lib/generators/good_job/templates/install/migrations/create_good_jobs.rb.erb +4 -4
- data/lib/generators/good_job/templates/update/migrations/01_create_good_jobs.rb.erb +4 -4
- data/lib/good_job/adapter.rb +13 -11
- data/lib/good_job/cli.rb +4 -4
- data/lib/good_job/configuration.rb +6 -1
- data/lib/good_job/daemon.rb +2 -2
- data/lib/good_job/job_performer.rb +1 -1
- data/lib/good_job/notifier.rb +1 -0
- data/lib/good_job/version.rb +1 -1
- data/lib/good_job.rb +29 -14
- metadata +19 -30
- data/lib/good_job/active_job_extensions.rb +0 -5
@@ -1,38 +1,66 @@
|
|
1
|
-
<div class="
|
2
|
-
<h2>Processes</h2>
|
1
|
+
<div class="bg-light break-out border-bottom">
|
2
|
+
<h2 class="container-fluid pt-3 pb-2">Processes</h2>
|
3
3
|
</div>
|
4
4
|
|
5
|
-
<div data-live-poll-region="processes">
|
6
|
-
|
7
|
-
<
|
8
|
-
<div class="
|
9
|
-
<
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
<td><%= process.id %></td>
|
21
|
-
<td><%= relative_time(process.created_at) %></td>
|
22
|
-
<td><%= tag.pre JSON.pretty_generate(process.state) %></td>
|
23
|
-
</tr>
|
5
|
+
<div class="card my-3" data-live-poll-region="processes">
|
6
|
+
<div class="list-group list-group-flush text-nowrap" role="table">
|
7
|
+
<header class="list-group-item bg-light">
|
8
|
+
<div class="row small text-muted text-uppercase align-items-center">
|
9
|
+
<div class="col">Process</div>
|
10
|
+
<div class="col">Schedulers</div>
|
11
|
+
<div class="col-2 d-flex gap-2">
|
12
|
+
<span>Started</span>
|
13
|
+
</div>
|
14
|
+
<div class="col-auto">
|
15
|
+
<%= tag.button type: "button", class: "btn btn-sm text-muted ms-auto", role: "button",
|
16
|
+
data: { bs_toggle: "collapse", bs_target: ".process-state" },
|
17
|
+
aria: { expanded: false, controls: @processes.map { |process| "##{dom_id(process, 'state')}" }.join(" ") } do %>
|
18
|
+
<%= render_icon "info" %>
|
19
|
+
<span class="visually-hidden">Inspect</span>
|
24
20
|
<% end %>
|
25
|
-
|
26
|
-
</table>
|
21
|
+
</div>
|
27
22
|
</div>
|
28
|
-
</
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
23
|
+
</header>
|
24
|
+
<% @processes.each do |process| %>
|
25
|
+
<div id="<%= dom_id(process) %>" class="<%= dom_class(process) %> list-group-item py-3" role="row">
|
26
|
+
<div class="row align-items-center">
|
27
|
+
<div class="col">
|
28
|
+
<%= tag.code title: process.state['proctitle'], class: "font-monospace" do %>
|
29
|
+
<span class="text-muted opacity-50">$</span>
|
30
|
+
<%= process.basename %>
|
31
|
+
<% end %>
|
32
|
+
<div>
|
33
|
+
<span class="text-muted small">PID</span>
|
34
|
+
<span class="badge rounded-pill bg-light text-dark"><%= process.state["pid"] %></span>
|
35
|
+
<span class="text-muted small">@</span>
|
36
|
+
<span class="badge rounded-pill bg-light text-dark"><%= process.state["hostname"] %></span>
|
37
|
+
</div>
|
38
|
+
</div>
|
39
|
+
<div class="col">
|
40
|
+
<% process.state["schedulers"].each do |scheduler| %>
|
41
|
+
<pre class="mb-0"><%= scheduler %></pre>
|
42
|
+
<% end %>
|
43
|
+
</div>
|
44
|
+
<div class="col-2 small"><%= relative_time(process.created_at) %></div>
|
45
|
+
<div class="col-auto">
|
46
|
+
<%= tag.button type: "button", class: "btn btn-sm text-muted ms-auto", role: "button",
|
47
|
+
title: "Inspect",
|
48
|
+
data: { bs_toggle: "collapse", bs_target: "##{dom_id(process, 'state')}" },
|
49
|
+
aria: { expanded: false, controls: dom_id(process, "state") } do %>
|
50
|
+
<%= render_icon "info" %>
|
51
|
+
<span class="visually-hidden">Inspect</span>
|
52
|
+
<% end %>
|
53
|
+
</div>
|
54
|
+
</div>
|
35
55
|
</div>
|
36
|
-
|
37
|
-
|
56
|
+
<%= tag.div id: dom_id(process, "state"), class: "process-state list-group-item collapse small bg-dark text-light" do %>
|
57
|
+
<%= tag.pre JSON.pretty_generate(process.state) %>
|
58
|
+
<% end %>
|
59
|
+
<% end %>
|
60
|
+
<% if @processes.empty? %>
|
61
|
+
<div class="list-group-item py-4 text-center text-muted">
|
62
|
+
No GoodJob processes found.
|
63
|
+
</div>
|
64
|
+
<% end %>
|
65
|
+
</div>
|
38
66
|
</div>
|
@@ -24,7 +24,7 @@
|
|
24
24
|
<li class="nav-item">
|
25
25
|
<%= link_to processes_path, class: ["nav-link", ("active" if controller_name == 'processes')] do %>
|
26
26
|
<%= t(".processes") %>
|
27
|
-
<% processes_count = GoodJob::Process.count %>
|
27
|
+
<% processes_count = GoodJob::Process.active.count %>
|
28
28
|
<span class="badge bg-secondary rounded-pill <%= "bg-danger" if processes_count == 0 %>"><%= processes_count %></span>
|
29
29
|
<% end %>
|
30
30
|
</li>
|
@@ -0,0 +1,3 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-three-dots" viewBox="0 0 16 16">
|
2
|
+
<path d="M3 9.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z" />
|
3
|
+
</svg>
|
@@ -0,0 +1,4 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16">
|
2
|
+
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
|
3
|
+
<path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z" />
|
4
|
+
</svg>
|
@@ -7,9 +7,9 @@ class CreateGoodJobs < ActiveRecord::Migration<%= migration_version %>
|
|
7
7
|
t.text :queue_name
|
8
8
|
t.integer :priority
|
9
9
|
t.jsonb :serialized_params
|
10
|
-
t.
|
11
|
-
t.
|
12
|
-
t.
|
10
|
+
t.datetime :scheduled_at
|
11
|
+
t.datetime :performed_at
|
12
|
+
t.datetime :finished_at
|
13
13
|
t.text :error
|
14
14
|
|
15
15
|
t.timestamps
|
@@ -18,7 +18,7 @@ class CreateGoodJobs < ActiveRecord::Migration<%= migration_version %>
|
|
18
18
|
t.text :concurrency_key
|
19
19
|
t.text :cron_key
|
20
20
|
t.uuid :retried_good_job_id
|
21
|
-
t.
|
21
|
+
t.datetime :cron_at
|
22
22
|
end
|
23
23
|
|
24
24
|
create_table :good_job_processes, id: :uuid do |t|
|
@@ -7,9 +7,9 @@ class CreateGoodJobs < ActiveRecord::Migration<%= migration_version %>
|
|
7
7
|
t.text :queue_name
|
8
8
|
t.integer :priority
|
9
9
|
t.jsonb :serialized_params
|
10
|
-
t.
|
11
|
-
t.
|
12
|
-
t.
|
10
|
+
t.datetime :scheduled_at
|
11
|
+
t.datetime :performed_at
|
12
|
+
t.datetime :finished_at
|
13
13
|
t.text :error
|
14
14
|
|
15
15
|
t.timestamps
|
@@ -18,7 +18,7 @@ class CreateGoodJobs < ActiveRecord::Migration<%= migration_version %>
|
|
18
18
|
t.text :concurrency_key
|
19
19
|
t.text :cron_key
|
20
20
|
t.uuid :retried_good_job_id
|
21
|
-
t.
|
21
|
+
t.datetime :cron_at
|
22
22
|
end
|
23
23
|
|
24
24
|
create_table :good_job_processes, id: :uuid do |t|
|
data/lib/good_job/adapter.rb
CHANGED
@@ -10,6 +10,8 @@ module GoodJob
|
|
10
10
|
# @return [Array<GoodJob::Adapter>, nil]
|
11
11
|
cattr_reader :instances, default: [], instance_reader: false
|
12
12
|
|
13
|
+
attr_reader :execution_mode
|
14
|
+
|
13
15
|
# @param execution_mode [Symbol, nil] specifies how and where jobs should be executed. You can also set this with the environment variable +GOOD_JOB_EXECUTION_MODE+.
|
14
16
|
#
|
15
17
|
# - +:inline+ executes jobs immediately in whatever process queued them (usually the web server process). This should only be used in test and development environments.
|
@@ -25,8 +27,8 @@ module GoodJob
|
|
25
27
|
# - +production+ and all other environments: +:external+
|
26
28
|
#
|
27
29
|
def initialize(execution_mode: nil)
|
28
|
-
@
|
29
|
-
@
|
30
|
+
@execution_mode = (execution_mode || GoodJob.configuration.execution_mode).to_sym
|
31
|
+
GoodJob::Configuration.validate_execution_mode(@execution_mode)
|
30
32
|
self.class.instances << self
|
31
33
|
|
32
34
|
start_async if GoodJob.async_ready?
|
@@ -82,7 +84,7 @@ module GoodJob
|
|
82
84
|
# @return [void]
|
83
85
|
def shutdown(timeout: :default)
|
84
86
|
timeout = if timeout == :default
|
85
|
-
|
87
|
+
GoodJob.configuration.shutdown_timeout
|
86
88
|
else
|
87
89
|
timeout
|
88
90
|
end
|
@@ -95,21 +97,21 @@ module GoodJob
|
|
95
97
|
# Whether in +:async+ execution mode.
|
96
98
|
# @return [Boolean]
|
97
99
|
def execute_async?
|
98
|
-
|
99
|
-
(
|
100
|
+
execution_mode == :async_all ||
|
101
|
+
(execution_mode.in?([:async, :async_server]) && in_server_process?)
|
100
102
|
end
|
101
103
|
|
102
104
|
# Whether in +:external+ execution mode.
|
103
105
|
# @return [Boolean]
|
104
106
|
def execute_externally?
|
105
|
-
|
106
|
-
(
|
107
|
+
execution_mode == :external ||
|
108
|
+
(execution_mode.in?([:async, :async_server]) && !in_server_process?)
|
107
109
|
end
|
108
110
|
|
109
111
|
# Whether in +:inline+ execution mode.
|
110
112
|
# @return [Boolean]
|
111
113
|
def execute_inline?
|
112
|
-
|
114
|
+
execution_mode == :inline
|
113
115
|
end
|
114
116
|
|
115
117
|
# Start async executors
|
@@ -118,12 +120,12 @@ module GoodJob
|
|
118
120
|
return unless execute_async?
|
119
121
|
|
120
122
|
@notifier = GoodJob::Notifier.new
|
121
|
-
@poller = GoodJob::Poller.new(poll_interval:
|
122
|
-
@scheduler = GoodJob::Scheduler.from_configuration(
|
123
|
+
@poller = GoodJob::Poller.new(poll_interval: GoodJob.configuration.poll_interval)
|
124
|
+
@scheduler = GoodJob::Scheduler.from_configuration(GoodJob.configuration, warm_cache_on_initialize: true)
|
123
125
|
@notifier.recipients << [@scheduler, :create_thread]
|
124
126
|
@poller.recipients << [@scheduler, :create_thread]
|
125
127
|
|
126
|
-
@cron_manager = GoodJob::CronManager.new(
|
128
|
+
@cron_manager = GoodJob::CronManager.new(GoodJob.configuration.cron_entries, start_on_initialize: true) if GoodJob.configuration.enable_cron?
|
127
129
|
|
128
130
|
@_async_started = true
|
129
131
|
end
|
data/lib/good_job/cli.rb
CHANGED
@@ -85,7 +85,8 @@ module GoodJob
|
|
85
85
|
|
86
86
|
def start
|
87
87
|
set_up_application!
|
88
|
-
|
88
|
+
GoodJob.configuration.options.merge!(options.symbolize_keys)
|
89
|
+
configuration = GoodJob.configuration
|
89
90
|
|
90
91
|
Daemon.new(pidfile: configuration.pidfile).daemonize if configuration.daemonize?
|
91
92
|
|
@@ -142,10 +143,9 @@ module GoodJob
|
|
142
143
|
|
143
144
|
def cleanup_preserved_jobs
|
144
145
|
set_up_application!
|
146
|
+
GoodJob.configuration.options.merge!(options.symbolize_keys)
|
145
147
|
|
146
|
-
|
147
|
-
|
148
|
-
GoodJob.cleanup_preserved_jobs(older_than: configuration.cleanup_preserved_jobs_before_seconds_ago)
|
148
|
+
GoodJob.cleanup_preserved_jobs(older_than: GoodJob.configuration.cleanup_preserved_jobs_before_seconds_ago)
|
149
149
|
end
|
150
150
|
|
151
151
|
no_commands do
|
@@ -27,7 +27,12 @@ module GoodJob
|
|
27
27
|
# Default to not running cron
|
28
28
|
DEFAULT_ENABLE_CRON = false
|
29
29
|
|
30
|
+
def self.validate_execution_mode(execution_mode)
|
31
|
+
raise ArgumentError, "GoodJob execution mode must be one of #{EXECUTION_MODES.join(', ')}. It was '#{execution_mode}' which is not valid." unless execution_mode.in?(EXECUTION_MODES)
|
32
|
+
end
|
33
|
+
|
30
34
|
# The options that were explicitly set when initializing +Configuration+.
|
35
|
+
# It is safe to modify this hash in place; be sure to symbolize keys.
|
31
36
|
# @return [Hash]
|
32
37
|
attr_reader :options
|
33
38
|
|
@@ -47,7 +52,7 @@ module GoodJob
|
|
47
52
|
end
|
48
53
|
|
49
54
|
def validate!
|
50
|
-
|
55
|
+
self.class.validate_execution_mode(execution_mode)
|
51
56
|
end
|
52
57
|
|
53
58
|
# Specifies how and where jobs should be executed. See {Adapter#initialize}
|
data/lib/good_job/daemon.rb
CHANGED
@@ -26,7 +26,7 @@ module GoodJob
|
|
26
26
|
# @return [void]
|
27
27
|
def write_pid
|
28
28
|
File.open(pidfile, ::File::CREAT | ::File::EXCL | ::File::WRONLY) { |f| f.write(::Process.pid.to_s) }
|
29
|
-
at_exit { File.delete(pidfile) if File.exist?(pidfile) }
|
29
|
+
at_exit { File.delete(pidfile) if File.exist?(pidfile) } # rubocop:disable Lint/NonAtomicFileOperation
|
30
30
|
rescue Errno::EEXIST
|
31
31
|
check_pid
|
32
32
|
retry
|
@@ -34,7 +34,7 @@ module GoodJob
|
|
34
34
|
|
35
35
|
# @return [void]
|
36
36
|
def delete_pid
|
37
|
-
File.delete(pidfile) if File.exist?(pidfile)
|
37
|
+
File.delete(pidfile) if File.exist?(pidfile) # rubocop:disable Lint/NonAtomicFileOperation
|
38
38
|
end
|
39
39
|
|
40
40
|
# @return [void]
|
@@ -24,7 +24,7 @@ module GoodJob
|
|
24
24
|
# Perform the next eligible job
|
25
25
|
# @return [Object, nil] Returns job result or +nil+ if no job was found
|
26
26
|
def next
|
27
|
-
job_query.perform_with_advisory_lock
|
27
|
+
job_query.perform_with_advisory_lock(parsed_queues: parsed_queues)
|
28
28
|
end
|
29
29
|
|
30
30
|
# Tests whether this performer should be used in GoodJob's current state.
|
data/lib/good_job/notifier.rb
CHANGED
data/lib/good_job/version.rb
CHANGED
data/lib/good_job.rb
CHANGED
@@ -2,19 +2,29 @@
|
|
2
2
|
require "active_job"
|
3
3
|
require "active_job/queue_adapters"
|
4
4
|
|
5
|
-
require "
|
6
|
-
zeitwerk_options = Gem::Version.new(Zeitwerk::VERSION) >= Gem::Version.new("2.6.0") ? { warn_on_extra_files: false } : {}
|
7
|
-
Zeitwerk::Loader.for_gem(**zeitwerk_options).tap do |loader|
|
8
|
-
loader.inflector.inflect({
|
9
|
-
"cli" => "CLI",
|
10
|
-
})
|
11
|
-
loader.push_dir("#{__dir__}/models")
|
12
|
-
loader.ignore("#{__dir__}/generators")
|
13
|
-
loader.setup
|
14
|
-
end
|
15
|
-
|
5
|
+
require "good_job/version"
|
16
6
|
require "good_job/engine"
|
17
7
|
|
8
|
+
require "good_job/adapter"
|
9
|
+
require "active_job/queue_adapters/good_job_adapter"
|
10
|
+
require "good_job/active_job_extensions/concurrency"
|
11
|
+
|
12
|
+
require "good_job/assignable_connection"
|
13
|
+
require "good_job/cleanup_tracker"
|
14
|
+
require "good_job/cli"
|
15
|
+
require "good_job/configuration"
|
16
|
+
require "good_job/cron_manager"
|
17
|
+
require 'good_job/current_thread'
|
18
|
+
require "good_job/daemon"
|
19
|
+
require "good_job/dependencies"
|
20
|
+
require "good_job/job_performer"
|
21
|
+
require "good_job/log_subscriber"
|
22
|
+
require "good_job/multi_scheduler"
|
23
|
+
require "good_job/notifier"
|
24
|
+
require "good_job/poller"
|
25
|
+
require "good_job/probe_server"
|
26
|
+
require "good_job/scheduler"
|
27
|
+
|
18
28
|
# GoodJob is a multithreaded, Postgres-based, ActiveJob backend for Ruby on Rails.
|
19
29
|
#
|
20
30
|
# +GoodJob+ is the top-level namespace and exposes configuration attributes.
|
@@ -69,6 +79,12 @@ module GoodJob
|
|
69
79
|
# @return [Proc, nil]
|
70
80
|
mattr_accessor :on_thread_error, default: nil
|
71
81
|
|
82
|
+
# @!attribute [rw] configuration
|
83
|
+
# @!scope class
|
84
|
+
# Global configuration object for GoodJob.
|
85
|
+
# @return [GoodJob::Configuration, nil]
|
86
|
+
mattr_accessor :configuration, default: GoodJob::Configuration.new({})
|
87
|
+
|
72
88
|
# Called with exception when a GoodJob thread raises an exception
|
73
89
|
# @param exception [Exception] Exception that was raised
|
74
90
|
# @return [void]
|
@@ -135,10 +151,9 @@ module GoodJob
|
|
135
151
|
# @params older_than [nil,Numeric,ActiveSupport::Duration] Jobs older than this will be destroyed (default: +86400+).
|
136
152
|
# @return [Integer] Number of jobs that were destroyed.
|
137
153
|
def self.cleanup_preserved_jobs(older_than: nil)
|
138
|
-
|
139
|
-
older_than ||= configuration.cleanup_preserved_jobs_before_seconds_ago
|
154
|
+
older_than ||= GoodJob.configuration.cleanup_preserved_jobs_before_seconds_ago
|
140
155
|
timestamp = Time.current - older_than
|
141
|
-
include_discarded = configuration.cleanup_discarded_jobs?
|
156
|
+
include_discarded = GoodJob.configuration.cleanup_discarded_jobs?
|
142
157
|
|
143
158
|
ActiveSupport::Notifications.instrument("cleanup_preserved_jobs.good_job", { older_than: older_than, timestamp: timestamp }) do |payload|
|
144
159
|
old_jobs = GoodJob::Job.where('finished_at <= ?', timestamp)
|
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.1
|
4
|
+
version: 3.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Sheldon
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-07-
|
11
|
+
date: 2022-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|
@@ -108,20 +108,6 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '1.3'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: zeitwerk
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - ">="
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '2.0'
|
118
|
-
type: :runtime
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - ">="
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '2.0'
|
125
111
|
- !ruby/object:Gem::Dependency
|
126
112
|
name: benchmark-ips
|
127
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -168,16 +154,16 @@ dependencies:
|
|
168
154
|
name: dotenv
|
169
155
|
requirement: !ruby/object:Gem::Requirement
|
170
156
|
requirements:
|
171
|
-
- - "
|
157
|
+
- - "~>"
|
172
158
|
- !ruby/object:Gem::Version
|
173
|
-
version:
|
159
|
+
version: 2.7.6
|
174
160
|
type: :development
|
175
161
|
prerelease: false
|
176
162
|
version_requirements: !ruby/object:Gem::Requirement
|
177
163
|
requirements:
|
178
|
-
- - "
|
164
|
+
- - "~>"
|
179
165
|
- !ruby/object:Gem::Version
|
180
|
-
version:
|
166
|
+
version: 2.7.6
|
181
167
|
- !ruby/object:Gem::Dependency
|
182
168
|
name: foreman
|
183
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -365,6 +351,7 @@ files:
|
|
365
351
|
- app/assets/good_job/modules/checkbox_toggle.js
|
366
352
|
- app/assets/good_job/modules/document_ready.js
|
367
353
|
- app/assets/good_job/modules/live_poll.js
|
354
|
+
- app/assets/good_job/modules/popovers.js
|
368
355
|
- app/assets/good_job/modules/toasts.js
|
369
356
|
- app/assets/good_job/scripts.js
|
370
357
|
- app/assets/good_job/style.css
|
@@ -382,6 +369,16 @@ files:
|
|
382
369
|
- app/filters/good_job/base_filter.rb
|
383
370
|
- app/filters/good_job/jobs_filter.rb
|
384
371
|
- app/helpers/good_job/application_helper.rb
|
372
|
+
- app/models/concerns/good_job/filterable.rb
|
373
|
+
- app/models/concerns/good_job/reportable.rb
|
374
|
+
- app/models/good_job/active_job_job.rb
|
375
|
+
- app/models/good_job/base_record.rb
|
376
|
+
- app/models/good_job/cron_entry.rb
|
377
|
+
- app/models/good_job/execution.rb
|
378
|
+
- app/models/good_job/execution_result.rb
|
379
|
+
- app/models/good_job/job.rb
|
380
|
+
- app/models/good_job/lockable.rb
|
381
|
+
- app/models/good_job/process.rb
|
385
382
|
- app/views/good_job/cron_entries/index.html.erb
|
386
383
|
- app/views/good_job/cron_entries/show.html.erb
|
387
384
|
- app/views/good_job/jobs/_executions.erb
|
@@ -398,7 +395,9 @@ files:
|
|
398
395
|
- app/views/good_job/shared/icons/_check.html.erb
|
399
396
|
- app/views/good_job/shared/icons/_clock.html.erb
|
400
397
|
- app/views/good_job/shared/icons/_dash_circle.html.erb
|
398
|
+
- app/views/good_job/shared/icons/_dots.html.erb
|
401
399
|
- app/views/good_job/shared/icons/_exclamation.html.erb
|
400
|
+
- app/views/good_job/shared/icons/_info.html.erb
|
402
401
|
- app/views/good_job/shared/icons/_play.html.erb
|
403
402
|
- app/views/good_job/shared/icons/_skip_forward.html.erb
|
404
403
|
- app/views/good_job/shared/icons/_stop.html.erb
|
@@ -416,7 +415,6 @@ files:
|
|
416
415
|
- lib/generators/good_job/templates/update/migrations/01_create_good_jobs.rb.erb
|
417
416
|
- lib/generators/good_job/update_generator.rb
|
418
417
|
- lib/good_job.rb
|
419
|
-
- lib/good_job/active_job_extensions.rb
|
420
418
|
- lib/good_job/active_job_extensions/concurrency.rb
|
421
419
|
- lib/good_job/adapter.rb
|
422
420
|
- lib/good_job/assignable_connection.rb
|
@@ -428,8 +426,6 @@ files:
|
|
428
426
|
- lib/good_job/daemon.rb
|
429
427
|
- lib/good_job/dependencies.rb
|
430
428
|
- lib/good_job/engine.rb
|
431
|
-
- lib/good_job/execution_result.rb
|
432
|
-
- lib/good_job/filterable.rb
|
433
429
|
- lib/good_job/job_performer.rb
|
434
430
|
- lib/good_job/log_subscriber.rb
|
435
431
|
- lib/good_job/multi_scheduler.rb
|
@@ -439,13 +435,6 @@ files:
|
|
439
435
|
- lib/good_job/probe_server.rb
|
440
436
|
- lib/good_job/scheduler.rb
|
441
437
|
- lib/good_job/version.rb
|
442
|
-
- lib/models/good_job/active_job_job.rb
|
443
|
-
- lib/models/good_job/base_record.rb
|
444
|
-
- lib/models/good_job/cron_entry.rb
|
445
|
-
- lib/models/good_job/execution.rb
|
446
|
-
- lib/models/good_job/job.rb
|
447
|
-
- lib/models/good_job/lockable.rb
|
448
|
-
- lib/models/good_job/process.rb
|
449
438
|
homepage: https://github.com/bensheldon/good_job
|
450
439
|
licenses:
|
451
440
|
- MIT
|