good_job 2.5.0 → 2.6.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 +16 -0
- data/README.md +1 -1
- data/engine/app/assets/vendor/rails_ujs.js +747 -0
- data/engine/app/controllers/good_job/assets_controller.rb +4 -0
- data/engine/app/controllers/good_job/cron_entries_controller.rb +19 -0
- data/engine/app/filters/good_job/base_filter.rb +6 -5
- data/engine/app/filters/good_job/executions_filter.rb +1 -1
- data/engine/app/filters/good_job/jobs_filter.rb +1 -1
- data/engine/app/views/good_job/cron_entries/index.html.erb +51 -0
- data/engine/app/views/good_job/cron_entries/show.html.erb +4 -0
- data/engine/app/views/good_job/{shared/_executions_table.erb → executions/_table.erb} +1 -1
- data/engine/app/views/good_job/executions/index.html.erb +1 -1
- data/engine/app/views/good_job/{shared/_jobs_table.erb → jobs/_table.erb} +3 -3
- data/engine/app/views/good_job/jobs/index.html.erb +1 -1
- data/engine/app/views/good_job/jobs/show.html.erb +2 -2
- data/engine/app/views/good_job/shared/_filter.erb +9 -10
- data/engine/app/views/good_job/shared/icons/_play.html.erb +4 -0
- data/engine/app/views/layouts/good_job/base.html.erb +2 -1
- data/engine/config/routes.rb +8 -1
- data/{engine/app/models → lib}/good_job/active_job_job.rb +0 -0
- data/lib/good_job/configuration.rb +1 -1
- data/lib/good_job/cron_entry.rb +75 -4
- data/lib/good_job/cron_manager.rb +1 -5
- data/lib/good_job/current_thread.rb +26 -8
- data/lib/good_job/execution.rb +15 -13
- data/lib/good_job/version.rb +1 -1
- metadata +14 -11
- data/engine/app/controllers/good_job/cron_schedules_controller.rb +0 -9
- data/engine/app/views/good_job/cron_schedules/index.html.erb +0 -72
@@ -23,6 +23,10 @@ module GoodJob
|
|
23
23
|
render file: GoodJob::Engine.root.join("app", "assets", "vendor", "chartist", "chartist.js")
|
24
24
|
end
|
25
25
|
|
26
|
+
def rails_ujs_js
|
27
|
+
render file: GoodJob::Engine.root.join("app", "assets", "vendor", "rails_ujs.js")
|
28
|
+
end
|
29
|
+
|
26
30
|
def style_css
|
27
31
|
render file: GoodJob::Engine.root.join("app", "assets", "style.css")
|
28
32
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GoodJob
|
3
|
+
class CronEntriesController < GoodJob::BaseController
|
4
|
+
def index
|
5
|
+
@cron_entries = CronEntry.all
|
6
|
+
end
|
7
|
+
|
8
|
+
def show
|
9
|
+
@cron_entry = CronEntry.find(params[:id])
|
10
|
+
@jobs_filter = JobsFilter.new(params, @cron_entry.jobs)
|
11
|
+
end
|
12
|
+
|
13
|
+
def enqueue
|
14
|
+
@cron_entry = CronEntry.find(params[:id])
|
15
|
+
@cron_entry.enqueue(Time.current)
|
16
|
+
redirect_back(fallback_location: cron_entries_path, notice: "Cron entry has been enqueued.")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -3,10 +3,11 @@ module GoodJob
|
|
3
3
|
class BaseFilter
|
4
4
|
DEFAULT_LIMIT = 25
|
5
5
|
|
6
|
-
attr_accessor :params
|
6
|
+
attr_accessor :params, :base_query
|
7
7
|
|
8
|
-
def initialize(params)
|
8
|
+
def initialize(params, base_query = nil)
|
9
9
|
@params = params
|
10
|
+
@base_query = base_query || default_base_query
|
10
11
|
end
|
11
12
|
|
12
13
|
def records
|
@@ -24,13 +25,13 @@ module GoodJob
|
|
24
25
|
|
25
26
|
def job_classes
|
26
27
|
base_query.group("serialized_params->>'job_class'").count
|
27
|
-
.sort_by { |name, _count| name }
|
28
|
+
.sort_by { |name, _count| name.to_s }
|
28
29
|
.to_h
|
29
30
|
end
|
30
31
|
|
31
32
|
def queues
|
32
33
|
base_query.group(:queue_name).count
|
33
|
-
.sort_by { |name, _count| name }
|
34
|
+
.sort_by { |name, _count| name.to_s }
|
34
35
|
.to_h
|
35
36
|
end
|
36
37
|
|
@@ -94,7 +95,7 @@ module GoodJob
|
|
94
95
|
|
95
96
|
private
|
96
97
|
|
97
|
-
def
|
98
|
+
def default_base_query
|
98
99
|
raise NotImplementedError
|
99
100
|
end
|
100
101
|
|
@@ -0,0 +1,51 @@
|
|
1
|
+
<% if @cron_entries.present? %>
|
2
|
+
<div class="card my-3">
|
3
|
+
<div class="table-responsive">
|
4
|
+
<table class="table card-table table-bordered table-hover table-sm mb-0">
|
5
|
+
<thead>
|
6
|
+
<th>Key</th>
|
7
|
+
<th>Schedule</th>
|
8
|
+
<th>
|
9
|
+
Properties
|
10
|
+
<%= tag.button "Toggle", type: "button", class: "btn btn-sm btn-outline-primary", role: "button",
|
11
|
+
data: { bs_toggle: "collapse", bs_target: ".cron-entry-properties" },
|
12
|
+
aria: { expanded: false, controls: @cron_entries.map { |cron_entry| "##{dom_id(cron_entry, 'properties')}" }.join(" ") }
|
13
|
+
%>
|
14
|
+
</th>
|
15
|
+
<th>Description</th>
|
16
|
+
<th>Next scheduled</th>
|
17
|
+
<th>Last run</th>
|
18
|
+
<th>Actions</th>
|
19
|
+
</thead>
|
20
|
+
<tbody>
|
21
|
+
<% @cron_entries.each do |cron_entry| %>
|
22
|
+
<tr id="<%= dom_id(cron_entry) %>">
|
23
|
+
<td class="font-monospace"><%= cron_entry.key %></td>
|
24
|
+
<td class="font-monospace"><%= cron_entry.schedule %></td>
|
25
|
+
<td>
|
26
|
+
<%= tag.button("Preview", type: "button", class: "btn btn-sm btn-outline-primary", role: "button",
|
27
|
+
data: { bs_toggle: "collapse", bs_target: "##{dom_id(cron_entry, 'properties')}" },
|
28
|
+
aria: { expanded: false, controls: dom_id(cron_entry, 'properties') }) %>
|
29
|
+
<%= tag.pre(JSON.pretty_generate(cron_entry.display_properties), id: dom_id(cron_entry, 'properties'), class: "collapse cron-entry-properties") %>
|
30
|
+
</td>
|
31
|
+
<td><%= cron_entry.description %></td>
|
32
|
+
<td><%= cron_entry.next_at %></td>
|
33
|
+
<td>
|
34
|
+
<% if cron_entry.last_job.present? %>
|
35
|
+
<%= link_to cron_entry.last_at, cron_entry_path(cron_entry), title: "Job #{cron_entry.last_job.id}" %>
|
36
|
+
<% end %>
|
37
|
+
</td>
|
38
|
+
<td>
|
39
|
+
<%= button_to enqueue_cron_entry_path(cron_entry.id), method: :post, class: "btn btn-sm btn-outline-primary", form_class: "d-inline-block", aria: { label: "Run cron entry now" }, title: "Run cron entry now", data: { confirm: "Confirm run cron entry now" } do %>
|
40
|
+
<%= render "good_job/shared/icons/play" %>
|
41
|
+
<% end %>
|
42
|
+
</td>
|
43
|
+
</tr>
|
44
|
+
<% end %>
|
45
|
+
</tbody>
|
46
|
+
</table>
|
47
|
+
</div>
|
48
|
+
</div>
|
49
|
+
<% else %>
|
50
|
+
<em>No cron schedules present.</em>
|
51
|
+
<% end %>
|
@@ -44,7 +44,7 @@
|
|
44
44
|
<%= tag.pre JSON.pretty_generate(execution.serialized_params), id: dom_id(execution, "params"), class: "collapse job-params" %>
|
45
45
|
</td>
|
46
46
|
<td>
|
47
|
-
<%= button_to execution_path(execution.id), method: :delete, class: "btn btn-sm btn-outline-danger", title: "Delete execution" do %>
|
47
|
+
<%= button_to execution_path(execution.id), method: :delete, class: "btn btn-sm btn-outline-danger", title: "Delete execution", data: { confirm: "Confirm delete" } do %>
|
48
48
|
<%= render "good_job/shared/icons/trash" %>
|
49
49
|
<% end %>
|
50
50
|
</td>
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<%= render 'good_job/shared/filter', filter: @filter %>
|
6
6
|
|
7
7
|
<% if @filter.records.present? %>
|
8
|
-
<%= render 'good_job/
|
8
|
+
<%= render 'good_job/executions/table', executions: @filter.records %>
|
9
9
|
|
10
10
|
<nav aria-label="Job pagination" class="mt-3">
|
11
11
|
<ul class="pagination">
|
@@ -46,16 +46,16 @@
|
|
46
46
|
<td>
|
47
47
|
<div class="text-nowrap">
|
48
48
|
<% job_reschedulable = job.status.in? [:scheduled, :retried, :queued] %>
|
49
|
-
<%= button_to reschedule_job_path(job.id), method: :put, class: "btn btn-sm #{job_reschedulable ? 'btn-outline-primary' : 'btn-outline-secondary'}", form_class: "d-inline-block", disabled: !job_reschedulable, aria: { label: "Reschedule job" }, title: "Reschedule job" do %>
|
49
|
+
<%= button_to reschedule_job_path(job.id), method: :put, class: "btn btn-sm #{job_reschedulable ? 'btn-outline-primary' : 'btn-outline-secondary'}", form_class: "d-inline-block", disabled: !job_reschedulable, aria: { label: "Reschedule job" }, title: "Reschedule job", data: { confirm: "Confirm reschedule" } do %>
|
50
50
|
<%= render "good_job/shared/icons/skip_forward" %>
|
51
51
|
<% end %>
|
52
52
|
|
53
53
|
<% job_discardable = job.status.in? [:scheduled, :retried, :queued] %>
|
54
|
-
<%= button_to discard_job_path(job.id), method: :put, class: "btn btn-sm #{job_discardable ? 'btn-outline-primary' : 'btn-outline-secondary'}", form_class: "d-inline-block", disabled: !job_discardable, aria: { label: "Discard job" }, title: "Discard job" do %>
|
54
|
+
<%= button_to discard_job_path(job.id), method: :put, class: "btn btn-sm #{job_discardable ? 'btn-outline-primary' : 'btn-outline-secondary'}", form_class: "d-inline-block", disabled: !job_discardable, aria: { label: "Discard job" }, title: "Discard job", data: { confirm: "Confirm discard" } do %>
|
55
55
|
<%= render "good_job/shared/icons/stop" %>
|
56
56
|
<% end %>
|
57
57
|
|
58
|
-
<%= button_to retry_job_path(job.id), method: :put, class: "btn btn-sm #{job.status == :discarded ? 'btn-outline-primary' : 'btn-outline-secondary'}", form_class: "d-inline-block", disabled: job.status != :discarded, aria: { label: "Retry job" }, title: "Retry job" do %>
|
58
|
+
<%= button_to retry_job_path(job.id), method: :put, class: "btn btn-sm #{job.status == :discarded ? 'btn-outline-primary' : 'btn-outline-secondary'}", form_class: "d-inline-block", disabled: job.status != :discarded, aria: { label: "Retry job" }, title: "Retry job", data: { confirm: "Confirm retry" } do %>
|
59
59
|
<%= render "good_job/shared/icons/arrow_clockwise" %>
|
60
60
|
<% end %>
|
61
61
|
</div>
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<%= render 'good_job/shared/filter', filter: @filter %>
|
6
6
|
|
7
7
|
<% if @filter.records.present? %>
|
8
|
-
<%= render 'good_job/
|
8
|
+
<%= render 'good_job/jobs/table', jobs: @filter.records %>
|
9
9
|
<nav aria-label="Job pagination" class="mt-3">
|
10
10
|
<ul class="pagination">
|
11
11
|
<li class="page-item">
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<h1>ActiveJob ID: <code><%= @executions.first.id %></code></h1>
|
1
|
+
<h1 class="mb-3">ActiveJob ID: <code><%= @executions.first.id %></code></h1>
|
2
2
|
|
3
|
-
<%= render 'good_job/
|
3
|
+
<%= render 'good_job/executions/table', executions: @executions %>
|
@@ -1,16 +1,15 @@
|
|
1
1
|
<div class='card mb-2'>
|
2
2
|
<div class='card-body d-flex flex-wrap'>
|
3
|
-
|
4
3
|
<div class='me-4'>
|
5
4
|
<small>Filter by job class</small>
|
6
5
|
<br>
|
7
|
-
<%
|
6
|
+
<% filter.job_classes.each do |name, count| %>
|
8
7
|
<% if params[:job_class] == name %>
|
9
|
-
<%= link_to(
|
8
|
+
<%= link_to(filter.to_params(job_class: nil), class: 'btn btn-sm btn-outline-secondary active', role: "button", "aria-pressed": true) do %>
|
10
9
|
<%= name %> (<%= count %>)
|
11
10
|
<% end %>
|
12
11
|
<% else %>
|
13
|
-
<%= link_to(
|
12
|
+
<%= link_to(filter.to_params(job_class: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %>
|
14
13
|
<%= name %> (<%= count %>)
|
15
14
|
<% end %>
|
16
15
|
<% end %>
|
@@ -20,13 +19,13 @@
|
|
20
19
|
<div class='me-4'>
|
21
20
|
<small>Filter by state</small>
|
22
21
|
<br>
|
23
|
-
<%
|
22
|
+
<% filter.states.each do |name, count| %>
|
24
23
|
<% if params[:state] == name %>
|
25
|
-
<%= link_to(
|
24
|
+
<%= link_to(filter.to_params(state: nil), class: 'btn btn-sm btn-outline-secondary active', role: "button", "aria-pressed": true) do %>
|
26
25
|
<%= name %> (<%= count %>)
|
27
26
|
<% end %>
|
28
27
|
<% else %>
|
29
|
-
<%= link_to(
|
28
|
+
<%= link_to(filter.to_params(state: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %>
|
30
29
|
<%= name %> (<%= count %>)
|
31
30
|
<% end %>
|
32
31
|
<% end %>
|
@@ -36,13 +35,13 @@
|
|
36
35
|
<div>
|
37
36
|
<small>Filter by queue</small>
|
38
37
|
<br>
|
39
|
-
<%
|
38
|
+
<% filter.queues.each do |name, count| %>
|
40
39
|
<% if params[:queue_name] == name %>
|
41
|
-
<%= link_to(
|
40
|
+
<%= link_to(filter.to_params(queue_name: nil), class: 'btn btn-sm btn-outline-secondary active', role: "button", "aria-pressed": true) do %>
|
42
41
|
<%= name %> (<%= count %>)
|
43
42
|
<% end %>
|
44
43
|
<% else %>
|
45
|
-
<%= link_to(
|
44
|
+
<%= link_to(filter.to_params(queue_name: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %>
|
46
45
|
<%= name %> (<%= count %>)
|
47
46
|
<% end %>
|
48
47
|
<% end %>
|
@@ -0,0 +1,4 @@
|
|
1
|
+
<!-- https://icons.getbootstrap.com/icons/play/ -->
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-play" viewBox="0 0 16 16">
|
3
|
+
<path d="M10.804 8 5 4.633v6.734L10.804 8zm.792-.696a.802.802 0 0 1 0 1.392l-6.363 3.692C4.713 12.69 4 12.345 4 11.692V4.308c0-.653.713-.998 1.233-.696l6.363 3.692z" />
|
4
|
+
</svg>
|
@@ -11,6 +11,7 @@
|
|
11
11
|
|
12
12
|
<%= javascript_include_tag bootstrap_path(format: :js, v: GoodJob::VERSION) %>
|
13
13
|
<%= javascript_include_tag chartist_path(format: :js, v: GoodJob::VERSION) %>
|
14
|
+
<%= javascript_include_tag rails_ujs_path(format: :js, v: GoodJob::VERSION) %>
|
14
15
|
</head>
|
15
16
|
<body>
|
16
17
|
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
@@ -29,7 +30,7 @@
|
|
29
30
|
<%= link_to "All Jobs", jobs_path, class: ["nav-link", ("active" if current_page?(jobs_path))] %>
|
30
31
|
</li>
|
31
32
|
<li class="nav-item">
|
32
|
-
<%= link_to "Cron Schedules",
|
33
|
+
<%= link_to "Cron Schedules", cron_entries_path, class: ["nav-link", ("active" if current_page?(cron_entries_path))] %>
|
33
34
|
</li>
|
34
35
|
<li class="nav-item">
|
35
36
|
<div class="nav-link">
|
data/engine/config/routes.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
GoodJob::Engine.routes.draw do
|
3
3
|
root to: 'executions#index'
|
4
|
-
|
4
|
+
|
5
|
+
resources :cron_entries, only: %i[index show] do
|
6
|
+
member do
|
7
|
+
post :enqueue
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
5
11
|
resources :jobs, only: %i[index show] do
|
6
12
|
member do
|
7
13
|
put :discard
|
@@ -20,6 +26,7 @@ GoodJob::Engine.routes.draw do
|
|
20
26
|
|
21
27
|
constraints(format: :js) do
|
22
28
|
get :bootstrap, action: :bootstrap_js
|
29
|
+
get :rails_ujs, action: :rails_ujs_js
|
23
30
|
get :chartist, action: :chartist_js
|
24
31
|
end
|
25
32
|
end
|
File without changes
|
@@ -157,7 +157,7 @@ module GoodJob
|
|
157
157
|
alias enable_cron? enable_cron
|
158
158
|
|
159
159
|
def cron
|
160
|
-
env_cron = JSON.parse(ENV['GOOD_JOB_CRON']) if ENV['GOOD_JOB_CRON'].present?
|
160
|
+
env_cron = JSON.parse(ENV['GOOD_JOB_CRON'], symbolize_names: true) if ENV['GOOD_JOB_CRON'].present?
|
161
161
|
|
162
162
|
options[:cron] ||
|
163
163
|
rails_config[:cron] ||
|
data/lib/good_job/cron_entry.rb
CHANGED
@@ -12,14 +12,29 @@ module GoodJob # :nodoc:
|
|
12
12
|
|
13
13
|
attr_reader :params
|
14
14
|
|
15
|
+
def self.all(configuration: nil)
|
16
|
+
configuration ||= GoodJob::Configuration.new({})
|
17
|
+
configuration.cron_entries
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.find(key, configuration: nil)
|
21
|
+
all(configuration: configuration).find { |entry| entry.key == key.to_sym }.tap do |cron_entry|
|
22
|
+
raise ActiveRecord::RecordNotFound unless cron_entry
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
15
26
|
def initialize(params = {})
|
16
|
-
@params = params
|
27
|
+
@params = params
|
28
|
+
|
29
|
+
raise ArgumentError, "Invalid cron format: '#{cron}'" unless fugit.instance_of?(Fugit::Cron)
|
17
30
|
end
|
18
31
|
|
19
32
|
def key
|
20
33
|
params.fetch(:key)
|
21
34
|
end
|
35
|
+
|
22
36
|
alias id key
|
37
|
+
alias to_param key
|
23
38
|
|
24
39
|
def job_class
|
25
40
|
params.fetch(:class)
|
@@ -42,16 +57,61 @@ module GoodJob # :nodoc:
|
|
42
57
|
end
|
43
58
|
|
44
59
|
def next_at
|
45
|
-
fugit = Fugit::Cron.parse(cron)
|
46
60
|
fugit.next_time.to_t
|
47
61
|
end
|
48
62
|
|
49
|
-
def
|
50
|
-
|
63
|
+
def schedule
|
64
|
+
fugit.original
|
65
|
+
end
|
66
|
+
|
67
|
+
def fugit
|
68
|
+
@_fugit ||= Fugit.parse(cron)
|
69
|
+
end
|
70
|
+
|
71
|
+
def jobs
|
72
|
+
GoodJob::ActiveJobJob.where(cron_key: key)
|
73
|
+
end
|
74
|
+
|
75
|
+
def last_at
|
76
|
+
return if last_job.blank?
|
77
|
+
|
78
|
+
if GoodJob::ActiveJobJob.column_names.include?('cron_at')
|
79
|
+
(last_job.cron_at || last_job.created_at).localtime
|
80
|
+
else
|
81
|
+
last_job.created_at
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def enqueue(cron_at = nil)
|
86
|
+
GoodJob::CurrentThread.within do |current_thread|
|
87
|
+
current_thread.cron_key = key
|
88
|
+
current_thread.cron_at = cron_at
|
89
|
+
|
90
|
+
job_class.constantize.set(set_value).perform_later(*args_value)
|
91
|
+
end
|
51
92
|
rescue ActiveRecord::RecordNotUnique
|
52
93
|
false
|
53
94
|
end
|
54
95
|
|
96
|
+
def last_job
|
97
|
+
if GoodJob::ActiveJobJob.column_names.include?('cron_at')
|
98
|
+
jobs.order("cron_at DESC NULLS LAST").first
|
99
|
+
else
|
100
|
+
jobs.order(created_at: :asc).last
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def display_properties
|
105
|
+
{
|
106
|
+
key: key,
|
107
|
+
class: job_class,
|
108
|
+
cron: schedule,
|
109
|
+
set: display_property(set),
|
110
|
+
args: display_property(args),
|
111
|
+
description: display_property(description),
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
55
115
|
private
|
56
116
|
|
57
117
|
def set_value
|
@@ -63,5 +123,16 @@ module GoodJob # :nodoc:
|
|
63
123
|
value = args || []
|
64
124
|
value.respond_to?(:call) ? value.call : value
|
65
125
|
end
|
126
|
+
|
127
|
+
def display_property(value)
|
128
|
+
case value
|
129
|
+
when NilClass
|
130
|
+
"None"
|
131
|
+
when Proc
|
132
|
+
"Lambda/Callable"
|
133
|
+
else
|
134
|
+
value
|
135
|
+
end
|
136
|
+
end
|
66
137
|
end
|
67
138
|
end
|
@@ -89,11 +89,7 @@ module GoodJob # :nodoc:
|
|
89
89
|
thr_scheduler.create_task(thr_cron_entry)
|
90
90
|
|
91
91
|
Rails.application.executor.wrap do
|
92
|
-
|
93
|
-
CurrentThread.cron_key = thr_cron_entry.key
|
94
|
-
CurrentThread.cron_at = thr_cron_at
|
95
|
-
|
96
|
-
cron_entry.enqueue
|
92
|
+
cron_entry.enqueue(thr_cron_at)
|
97
93
|
end
|
98
94
|
end
|
99
95
|
|
@@ -5,6 +5,15 @@ module GoodJob
|
|
5
5
|
# Thread-local attributes for passing values from Instrumentation.
|
6
6
|
# (Cannot use ActiveSupport::CurrentAttributes because ActiveJob resets it)
|
7
7
|
module CurrentThread
|
8
|
+
# Resettable accessors for thread-local values.
|
9
|
+
ACCESSORS = %i[
|
10
|
+
cron_at
|
11
|
+
cron_key
|
12
|
+
error_on_discard
|
13
|
+
error_on_retry
|
14
|
+
execution
|
15
|
+
].freeze
|
16
|
+
|
8
17
|
# @!attribute [rw] cron_at
|
9
18
|
# @!scope class
|
10
19
|
# Cron At
|
@@ -36,13 +45,20 @@ module GoodJob
|
|
36
45
|
thread_mattr_accessor :execution
|
37
46
|
|
38
47
|
# Resets attributes
|
48
|
+
# @param [Hash] values to assign
|
39
49
|
# @return [void]
|
40
|
-
def self.reset
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
50
|
+
def self.reset(values = {})
|
51
|
+
ACCESSORS.each do |accessor|
|
52
|
+
send("#{accessor}=", values[accessor])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Exports values to hash
|
57
|
+
# @return [Hash]
|
58
|
+
def self.to_h
|
59
|
+
ACCESSORS.each_with_object({}) do |accessor, hash|
|
60
|
+
hash[accessor] = send(accessor)
|
61
|
+
end
|
46
62
|
end
|
47
63
|
|
48
64
|
# @return [String] UUID of the currently executing GoodJob::Execution
|
@@ -60,12 +76,14 @@ module GoodJob
|
|
60
76
|
(Thread.current.name || Thread.current.object_id).to_s
|
61
77
|
end
|
62
78
|
|
79
|
+
# Wrap the yielded block with CurrentThread values and reset after the block
|
80
|
+
# @yield [self]
|
63
81
|
# @return [void]
|
64
82
|
def self.within
|
65
|
-
|
83
|
+
original_values = to_h
|
66
84
|
yield(self)
|
67
85
|
ensure
|
68
|
-
reset
|
86
|
+
reset(original_values)
|
69
87
|
end
|
70
88
|
end
|
71
89
|
end
|
data/lib/good_job/execution.rb
CHANGED
@@ -309,22 +309,24 @@ module GoodJob
|
|
309
309
|
|
310
310
|
# @return [ExecutionResult]
|
311
311
|
def execute
|
312
|
-
GoodJob::CurrentThread.
|
313
|
-
|
312
|
+
GoodJob::CurrentThread.within do |current_thread|
|
313
|
+
current_thread.reset
|
314
|
+
current_thread.execution = self
|
314
315
|
|
315
|
-
|
316
|
-
|
317
|
-
|
316
|
+
# DEPRECATION: Remove deprecated `good_job:` parameter in GoodJob v3
|
317
|
+
ActiveSupport::Notifications.instrument("perform_job.good_job", { good_job: self, execution: self, process_id: current_thread.process_id, thread_name: current_thread.thread_name }) do
|
318
|
+
value = ActiveJob::Base.execute(active_job_data)
|
318
319
|
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
320
|
+
if value.is_a?(Exception)
|
321
|
+
handled_error = value
|
322
|
+
value = nil
|
323
|
+
end
|
324
|
+
handled_error ||= current_thread.error_on_retry || current_thread.error_on_discard
|
324
325
|
|
325
|
-
|
326
|
-
|
327
|
-
|
326
|
+
ExecutionResult.new(value: value, handled_error: handled_error)
|
327
|
+
rescue StandardError => e
|
328
|
+
ExecutionResult.new(value: nil, unhandled_error: e)
|
329
|
+
end
|
328
330
|
end
|
329
331
|
end
|
330
332
|
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.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-10-
|
11
|
+
date: 2021-10-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|
@@ -126,16 +126,16 @@ dependencies:
|
|
126
126
|
name: capybara
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- - "
|
129
|
+
- - "~>"
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version:
|
131
|
+
version: 3.35.0
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- - "
|
136
|
+
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version:
|
138
|
+
version: 3.35.0
|
139
139
|
- !ruby/object:Gem::Dependency
|
140
140
|
name: database_cleaner
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -351,27 +351,29 @@ files:
|
|
351
351
|
- engine/app/assets/vendor/bootstrap/bootstrap.min.css
|
352
352
|
- engine/app/assets/vendor/chartist/chartist.css
|
353
353
|
- engine/app/assets/vendor/chartist/chartist.js
|
354
|
+
- engine/app/assets/vendor/rails_ujs.js
|
354
355
|
- engine/app/controllers/good_job/assets_controller.rb
|
355
356
|
- engine/app/controllers/good_job/base_controller.rb
|
356
|
-
- engine/app/controllers/good_job/
|
357
|
+
- engine/app/controllers/good_job/cron_entries_controller.rb
|
357
358
|
- engine/app/controllers/good_job/executions_controller.rb
|
358
359
|
- engine/app/controllers/good_job/jobs_controller.rb
|
359
360
|
- engine/app/filters/good_job/base_filter.rb
|
360
361
|
- engine/app/filters/good_job/executions_filter.rb
|
361
362
|
- engine/app/filters/good_job/jobs_filter.rb
|
362
363
|
- engine/app/helpers/good_job/application_helper.rb
|
363
|
-
- engine/app/
|
364
|
-
- engine/app/views/good_job/
|
364
|
+
- engine/app/views/good_job/cron_entries/index.html.erb
|
365
|
+
- engine/app/views/good_job/cron_entries/show.html.erb
|
366
|
+
- engine/app/views/good_job/executions/_table.erb
|
365
367
|
- engine/app/views/good_job/executions/index.html.erb
|
368
|
+
- engine/app/views/good_job/jobs/_table.erb
|
366
369
|
- engine/app/views/good_job/jobs/index.html.erb
|
367
370
|
- engine/app/views/good_job/jobs/show.html.erb
|
368
371
|
- engine/app/views/good_job/shared/_chart.erb
|
369
|
-
- engine/app/views/good_job/shared/_executions_table.erb
|
370
372
|
- engine/app/views/good_job/shared/_filter.erb
|
371
|
-
- engine/app/views/good_job/shared/_jobs_table.erb
|
372
373
|
- engine/app/views/good_job/shared/icons/_arrow_clockwise.html.erb
|
373
374
|
- engine/app/views/good_job/shared/icons/_check.html.erb
|
374
375
|
- engine/app/views/good_job/shared/icons/_exclamation.html.erb
|
376
|
+
- engine/app/views/good_job/shared/icons/_play.html.erb
|
375
377
|
- engine/app/views/good_job/shared/icons/_skip_forward.html.erb
|
376
378
|
- engine/app/views/good_job/shared/icons/_stop.html.erb
|
377
379
|
- engine/app/views/good_job/shared/icons/_trash.html.erb
|
@@ -389,6 +391,7 @@ files:
|
|
389
391
|
- lib/good_job.rb
|
390
392
|
- lib/good_job/active_job_extensions.rb
|
391
393
|
- lib/good_job/active_job_extensions/concurrency.rb
|
394
|
+
- lib/good_job/active_job_job.rb
|
392
395
|
- lib/good_job/adapter.rb
|
393
396
|
- lib/good_job/cli.rb
|
394
397
|
- lib/good_job/configuration.rb
|