good_job 2.9.6 → 2.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/README.md +3 -3
- data/engine/app/filters/good_job/executions_filter.rb +1 -1
- data/engine/app/helpers/good_job/application_helper.rb +15 -0
- data/engine/app/views/good_job/cron_entries/index.html.erb +11 -1
- data/engine/app/views/good_job/executions/_table.erb +35 -29
- data/engine/app/views/good_job/executions/index.html.erb +2 -4
- data/engine/app/views/good_job/jobs/_table.erb +40 -36
- data/engine/app/views/good_job/jobs/index.html.erb +6 -3
- data/engine/app/views/good_job/processes/index.html.erb +4 -0
- data/engine/app/views/good_job/shared/_filter.erb +46 -54
- data/lib/good_job/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b22cbc6d37af9dd8db290a1dc8073d2cae14c63e5cf7180b06dce1a33fb9992
|
4
|
+
data.tar.gz: 8cd87b2d69afea84db87125bad625558783adea98fee138be852e6a51c43dc50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 230b335c5b6a03397c3212cd2bc59d87b2c735073233d068cf2c3045933b2aace533b0699a6fa1ecd41d77890af5aa18e1685b2c85f4c97c868773a3211736b7
|
7
|
+
data.tar.gz: b3fb4cb11f129fa8576e36c4e7401cdab927cf309bda963c3b82480dbe92663847b46a8e641b123e5ad7b28c53aa361d5fb6968131e23e85b0302768cc38e5d0
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v2.10.0](https://github.com/bensheldon/good_job/tree/v2.10.0) (2022-02-18)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v2.9.6...v2.10.0)
|
6
|
+
|
7
|
+
**Closed issues:**
|
8
|
+
|
9
|
+
- Cron jobs not getting run [\#519](https://github.com/bensheldon/good_job/issues/519)
|
10
|
+
- Slow queries with many finished entries and concurrency control [\#514](https://github.com/bensheldon/good_job/issues/514)
|
11
|
+
- Make default retry behaviour safer [\#505](https://github.com/bensheldon/good_job/issues/505)
|
12
|
+
|
13
|
+
**Merged pull requests:**
|
14
|
+
|
15
|
+
- Fix Benchmark job throughput script [\#522](https://github.com/bensheldon/good_job/pull/522) ([douglara](https://github.com/douglara))
|
16
|
+
- Update development Gemfile.lock [\#521](https://github.com/bensheldon/good_job/pull/521) ([bensheldon](https://github.com/bensheldon))
|
17
|
+
- Ensure Rails 6.0 is tested against Ruby 3.0; use Ruby 3.0 in demo environment [\#520](https://github.com/bensheldon/good_job/pull/520) ([bensheldon](https://github.com/bensheldon))
|
18
|
+
- Dashboard: update search filters and some small UI updates [\#518](https://github.com/bensheldon/good_job/pull/518) ([multiplegeorges](https://github.com/multiplegeorges))
|
19
|
+
- Document safer setting for retry\_on\_unhandled\_error [\#517](https://github.com/bensheldon/good_job/pull/517) ([tamaloa](https://github.com/tamaloa))
|
20
|
+
|
3
21
|
## [v2.9.6](https://github.com/bensheldon/good_job/tree/v2.9.6) (2022-02-07)
|
4
22
|
|
5
23
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v2.9.5...v2.9.6)
|
data/README.md
CHANGED
@@ -276,7 +276,7 @@ Available configuration options are:
|
|
276
276
|
- `cleanup_interval_seconds` (integer) Number of seconds a Scheduler will wait before cleaning up preserved jobs. Defaults to `nil`. Can also be set with the environment variable `GOOD_JOB_CLEANUP_INTERVAL_SECONDS`.
|
277
277
|
- `logger` ([Rails Logger](https://api.rubyonrails.org/classes/ActiveSupport/Logger.html)) lets you set a custom logger for GoodJob. It should be an instance of a Rails `Logger` (Default: `Rails.logger`).
|
278
278
|
- `preserve_job_records` (boolean) keeps job records in your database even after jobs are completed. (Default: `false`)
|
279
|
-
- `retry_on_unhandled_error` (boolean) causes jobs to be re-queued and retried if they raise an instance of `StandardError`. Instances of `Exception`, like SIGINT, will *always* be retried, regardless of this attribute’s value. (Default: `true`)
|
279
|
+
- `retry_on_unhandled_error` (boolean) causes jobs to be re-queued and retried if they raise an instance of `StandardError`. Be advised this may lead to jobs being repeated infinitely ([see below for more on retries](#retries)). Instances of `Exception`, like SIGINT, will *always* be retried, regardless of this attribute’s value. (Default: `true`)
|
280
280
|
- `on_thread_error` (proc, lambda, or callable) will be called when an Exception. It can be useful for logging errors to bug tracking services, like Sentry or Airbrake. Example:
|
281
281
|
|
282
282
|
```ruby
|
@@ -307,7 +307,7 @@ Good Job’s general behavior can also be configured via attributes directly on
|
|
307
307
|
- **`GoodJob.active_record_parent_class`** (string) The ActiveRecord parent class inherited by GoodJob's ActiveRecord model `GoodJob::Job` (defaults to `"ActiveRecord::Base"`). Configure this when using [multiple databases with ActiveRecord](https://guides.rubyonrails.org/active_record_multiple_databases.html) or when other custom configuration is necessary for the ActiveRecord model to connect to the Postgres database. _The value must be a String to avoid premature initialization of ActiveRecord._
|
308
308
|
- **`GoodJob.logger`** ([Rails Logger](https://api.rubyonrails.org/classes/ActiveSupport/Logger.html)) lets you set a custom logger for GoodJob. It should be an instance of a Rails `Logger`.
|
309
309
|
- **`GoodJob.preserve_job_records`** (boolean) keeps job records in your database even after jobs are completed. (Default: `false`)
|
310
|
-
- **`GoodJob.retry_on_unhandled_error`** (boolean) causes jobs to be re-queued and retried if they raise an instance of `StandardError`. Instances of `Exception`, like SIGINT, will *always* be retried, regardless of this attribute’s value. (Default: `true`)
|
310
|
+
- **`GoodJob.retry_on_unhandled_error`** (boolean) causes jobs to be re-queued and retried if they raise an instance of `StandardError`. Be advised this may lead to jobs being repeated infinitely ([see below for more on retries](#retries)). Instances of `Exception`, like SIGINT, will *always* be retried, regardless of this attribute’s value. (Default: `true`)
|
311
311
|
- **`GoodJob.on_thread_error`** (proc, lambda, or callable) will be called when an Exception. It can be useful for logging errors to bug tracking services, like Sentry or Airbrake.
|
312
312
|
|
313
313
|
You’ll generally want to configure these in `config/initializers/good_job.rb`, like so:
|
@@ -529,7 +529,7 @@ class ApplicationJob < ActiveJob::Base
|
|
529
529
|
end
|
530
530
|
```
|
531
531
|
|
532
|
-
When using `retry_on` with _a limited number of retries_, the final exception will not be rescued and will raise to GoodJob. GoodJob can be configured to discard un-handled exceptions instead of retrying them:
|
532
|
+
When using `retry_on` with _a limited number of retries_, the final exception will not be rescued and will raise to GoodJob. GoodJob can be configured to discard un-handled exceptions instead of retrying them. Be aware that if NOT setting `retry_on_unhandled_error` to `false` good_job will by default retry the failing job and may do this infinitely without pause thereby at least causing high load. In most cases `retry_on_unhandled_error` should be set as following:
|
533
533
|
|
534
534
|
```ruby
|
535
535
|
# config/initializers/good_job.rb
|
@@ -5,5 +5,20 @@ module GoodJob
|
|
5
5
|
text = timestamp.future? ? "in #{time_ago_in_words(timestamp)}" : "#{time_ago_in_words(timestamp)} ago"
|
6
6
|
tag.time(text, datetime: timestamp, title: timestamp)
|
7
7
|
end
|
8
|
+
|
9
|
+
def status_badge(status)
|
10
|
+
classes = case status
|
11
|
+
when :finished
|
12
|
+
"badge rounded-pill bg-success"
|
13
|
+
when :queued, :scheduled, :retried
|
14
|
+
"badge rounded-pill bg-secondary"
|
15
|
+
when :running
|
16
|
+
"badge rounded-pill bg-primary"
|
17
|
+
when :discarded
|
18
|
+
"badge rounded-pill bg-danger"
|
19
|
+
end
|
20
|
+
|
21
|
+
content_tag :span, status.to_s, class: classes
|
22
|
+
end
|
8
23
|
end
|
9
24
|
end
|
@@ -1,3 +1,7 @@
|
|
1
|
+
<div class="my-3 flex">
|
2
|
+
<h2>Cron Schedules</h2>
|
3
|
+
</div>
|
4
|
+
|
1
5
|
<% if @cron_entries.present? %>
|
2
6
|
<div class="card my-3">
|
3
7
|
<div class="table-responsive">
|
@@ -47,5 +51,11 @@
|
|
47
51
|
</div>
|
48
52
|
</div>
|
49
53
|
<% else %>
|
50
|
-
<
|
54
|
+
<div class="card my-3">
|
55
|
+
<div class="card-body">
|
56
|
+
<p class="card-text">
|
57
|
+
<em>No cron schedules found.</em>
|
58
|
+
</p>
|
59
|
+
</div>
|
60
|
+
</div>
|
51
61
|
<% end %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="card my-3">
|
2
2
|
<div class="table-responsive">
|
3
|
-
<table class="table card-table table-bordered table-hover table-sm mb-0">
|
3
|
+
<table class="table card-table table-bordered table-hover table-sm mb-0" id="executions_index_table">
|
4
4
|
<thead>
|
5
5
|
<tr>
|
6
6
|
<th>ActiveJob ID</th>
|
@@ -20,34 +20,40 @@
|
|
20
20
|
</tr>
|
21
21
|
</thead>
|
22
22
|
<tbody>
|
23
|
-
<% executions.
|
24
|
-
|
25
|
-
<
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
<%=
|
49
|
-
|
50
|
-
|
23
|
+
<% if executions.present? %>
|
24
|
+
<% executions.each do |execution| %>
|
25
|
+
<tr id="<%= dom_id(execution) %>">
|
26
|
+
<td>
|
27
|
+
<%= link_to job_path(execution.serialized_params['job_id']) do %>
|
28
|
+
<code><%= execution.active_job_id %></code>
|
29
|
+
<% end %>
|
30
|
+
</td>
|
31
|
+
<td>
|
32
|
+
<%= link_to job_path(execution.active_job_id, anchor: dom_id(execution)) do %>
|
33
|
+
<code><%= execution.id %></code>
|
34
|
+
<% end %>
|
35
|
+
</td>
|
36
|
+
<td><%= execution.serialized_params['job_class'] %></td>
|
37
|
+
<td><%= execution.queue_name %></td>
|
38
|
+
<td><%= relative_time(execution.scheduled_at || execution.created_at) %></td>
|
39
|
+
<td class="text-break"><%= truncate(execution.error, length: 1_000) %></td>
|
40
|
+
<td>
|
41
|
+
<%= tag.button "Preview", type: "button", class: "btn btn-sm btn-outline-primary", role: "button",
|
42
|
+
data: { bs_toggle: "collapse", bs_target: "##{dom_id(execution, 'params')}" },
|
43
|
+
aria: { expanded: false, controls: dom_id(execution, "params") }
|
44
|
+
%>
|
45
|
+
<%= tag.pre JSON.pretty_generate(execution.serialized_params), id: dom_id(execution, "params"), class: "collapse job-params" %>
|
46
|
+
</td>
|
47
|
+
<td>
|
48
|
+
<%= button_to execution_path(execution.id), method: :delete, class: "btn btn-sm btn-outline-danger", title: "Delete execution", data: { confirm: "Confirm delete" } do %>
|
49
|
+
<%= render "good_job/shared/icons/trash" %>
|
50
|
+
<% end %>
|
51
|
+
</td>
|
52
|
+
</tr>
|
53
|
+
<% end %>
|
54
|
+
<% else %>
|
55
|
+
<tr>
|
56
|
+
<td colspan="8" class="py-2 text-center text-muted">No executions found.</td>
|
51
57
|
</tr>
|
52
58
|
<% end %>
|
53
59
|
</tbody>
|
@@ -4,9 +4,9 @@
|
|
4
4
|
|
5
5
|
<%= render 'good_job/shared/filter', filter: @filter %>
|
6
6
|
|
7
|
-
|
8
|
-
<%= render 'good_job/executions/table', executions: @filter.records %>
|
7
|
+
<%= render 'good_job/executions/table', executions: @filter.records %>
|
9
8
|
|
9
|
+
<% if @filter.records.present? %>
|
10
10
|
<nav aria-label="Job pagination" class="mt-3">
|
11
11
|
<ul class="pagination">
|
12
12
|
<li class="page-item">
|
@@ -16,6 +16,4 @@
|
|
16
16
|
</li>
|
17
17
|
</ul>
|
18
18
|
</nav>
|
19
|
-
<% else %>
|
20
|
-
<em>No executions present.</em>
|
21
19
|
<% end %>
|
@@ -21,45 +21,49 @@
|
|
21
21
|
</tr>
|
22
22
|
</thead>
|
23
23
|
<tbody>
|
24
|
-
<% jobs.
|
25
|
-
|
26
|
-
<
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
</td>
|
31
|
-
<td>
|
32
|
-
<span class="badge bg-secondary"><%= job.status %></span>
|
33
|
-
</td>
|
34
|
-
<td><%= job.job_class %></td>
|
35
|
-
<td><%= job.queue_name %></td>
|
36
|
-
<td><%= relative_time(job.scheduled_at || job.created_at) %></td>
|
37
|
-
<td><%= job.executions_count %></td>
|
38
|
-
<td class="text-break"><%= truncate(job.recent_error, length: 1_000) %></td>
|
39
|
-
<td>
|
40
|
-
<%= tag.button "Preview", type: "button", class: "btn btn-sm btn-outline-primary", role: "button",
|
41
|
-
data: { bs_toggle: "collapse", bs_target: "##{dom_id(job, 'params')}" },
|
42
|
-
aria: { expanded: false, controls: dom_id(job, "params") }
|
43
|
-
%>
|
44
|
-
<%= tag.pre JSON.pretty_generate(job.serialized_params), id: dom_id(job, "params"), class: "collapse job-params" %>
|
45
|
-
</td>
|
46
|
-
<td>
|
47
|
-
<div class="text-nowrap">
|
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", data: { confirm: "Confirm reschedule" } do %>
|
50
|
-
<%= render "good_job/shared/icons/skip_forward" %>
|
24
|
+
<% if jobs.present? %>
|
25
|
+
<% jobs.each do |job| %>
|
26
|
+
<tr class="<%= dom_class(job) %>" id="<%= dom_id(job) %>">
|
27
|
+
<td>
|
28
|
+
<%= link_to job_path(job.id) do %>
|
29
|
+
<code><%= job.id %></code>
|
51
30
|
<% end %>
|
31
|
+
</td>
|
32
|
+
<td><%= status_badge(job.status) %></td>
|
33
|
+
<td><%= job.job_class %></td>
|
34
|
+
<td><%= job.queue_name %></td>
|
35
|
+
<td><%= relative_time(job.scheduled_at || job.created_at) %></td>
|
36
|
+
<td><%= job.executions_count %></td>
|
37
|
+
<td class="text-break"><%= truncate(job.recent_error, length: 1_000) %></td>
|
38
|
+
<td>
|
39
|
+
<%= tag.button "Preview", type: "button", class: "btn btn-sm btn-outline-primary", role: "button",
|
40
|
+
data: { bs_toggle: "collapse", bs_target: "##{dom_id(job, 'params')}" },
|
41
|
+
aria: { expanded: false, controls: dom_id(job, "params") }
|
42
|
+
%>
|
43
|
+
<%= tag.pre JSON.pretty_generate(job.serialized_params), id: dom_id(job, "params"), class: "collapse job-params" %>
|
44
|
+
</td>
|
45
|
+
<td>
|
46
|
+
<div class="text-nowrap">
|
47
|
+
<% job_reschedulable = job.status.in? [:scheduled, :retried, :queued] %>
|
48
|
+
<%= 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 %>
|
49
|
+
<%= render "good_job/shared/icons/skip_forward" %>
|
50
|
+
<% end %>
|
52
51
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
<% job_discardable = job.status.in? [:scheduled, :retried, :queued] %>
|
53
|
+
<%= 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 %>
|
54
|
+
<%= render "good_job/shared/icons/stop" %>
|
55
|
+
<% end %>
|
57
56
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
57
|
+
<%= 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 %>
|
58
|
+
<%= render "good_job/shared/icons/arrow_clockwise" %>
|
59
|
+
<% end %>
|
60
|
+
</div>
|
61
|
+
</td>
|
62
|
+
</tr>
|
63
|
+
<% end %>
|
64
|
+
<% else %>
|
65
|
+
<tr>
|
66
|
+
<td colspan="8" class="py-2 text-center text-muted">No jobs found.</td>
|
63
67
|
</tr>
|
64
68
|
<% end %>
|
65
69
|
</tbody>
|
@@ -1,11 +1,16 @@
|
|
1
|
+
<div class="my-3 flex">
|
2
|
+
<h2>All Jobs</h2>
|
3
|
+
</div>
|
4
|
+
|
1
5
|
<div class="card my-3 p-6">
|
2
6
|
<%= render 'good_job/shared/chart', chart_data: GoodJob::ScheduledByQueueChart.new(@filter).data %>
|
3
7
|
</div>
|
4
8
|
|
5
9
|
<%= render 'good_job/shared/filter', filter: @filter %>
|
6
10
|
|
11
|
+
<%= render 'good_job/jobs/table', jobs: @filter.records %>
|
12
|
+
|
7
13
|
<% if @filter.records.present? %>
|
8
|
-
<%= render 'good_job/jobs/table', jobs: @filter.records %>
|
9
14
|
<nav aria-label="Job pagination" class="mt-3">
|
10
15
|
<ul class="pagination">
|
11
16
|
<li class="page-item">
|
@@ -15,6 +20,4 @@
|
|
15
20
|
</li>
|
16
21
|
</ul>
|
17
22
|
</nav>
|
18
|
-
<% else %>
|
19
|
-
<em>No jobs present.</em>
|
20
23
|
<% end %>
|
@@ -1,66 +1,58 @@
|
|
1
|
-
|
2
|
-
<div class=
|
3
|
-
<div class=
|
4
|
-
<
|
5
|
-
<
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
<% end %>
|
11
|
-
<% else %>
|
12
|
-
<%= link_to(filter.to_params(job_class: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %>
|
13
|
-
<%= name %> (<%= count %>)
|
14
|
-
<% end %>
|
1
|
+
<%= form_with(url: "", method: :get, local: true, id: "filter_form") do |form| %>
|
2
|
+
<div class="d-flex flex-row w-100">
|
3
|
+
<div class="me-2">
|
4
|
+
<label for="job_class_filter">Job class</label>
|
5
|
+
<select name="job_class" id="job_class_filter" class="form-select">
|
6
|
+
<option value="" <%= "selected='selected'" if params[:job_class].blank? %>>All jobs</option>
|
7
|
+
|
8
|
+
<% filter.job_classes.each do |name, count| %>
|
9
|
+
<option value="<%= name.to_param %>" <%= "selected='selected'" if params[:job_class] == name %>><%= name %> (<%= count %>)</option>
|
15
10
|
<% end %>
|
16
|
-
|
11
|
+
</select>
|
17
12
|
</div>
|
18
13
|
|
19
|
-
<div class=
|
20
|
-
<
|
21
|
-
<
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
<% end %>
|
27
|
-
<% else %>
|
28
|
-
<%= link_to(filter.to_params(state: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %>
|
29
|
-
<%= name %> (<%= count %>)
|
30
|
-
<% end %>
|
14
|
+
<div class="me-2">
|
15
|
+
<label for="job_state_filter">State</label>
|
16
|
+
<select name="state" id="job_state_filter" class="form-select">
|
17
|
+
<option value="" <%= "selected='selected'" if params[:state].blank? %>>All states</option>
|
18
|
+
|
19
|
+
<% filter.states.each do |name, count| %>
|
20
|
+
<option value="<%= name.to_param %>" <%= "selected='selected'" if params[:state] == name %>><%= name %> (<%= count %>)</option>
|
31
21
|
<% end %>
|
32
|
-
|
22
|
+
</select>
|
33
23
|
</div>
|
34
24
|
|
35
|
-
<div class=
|
36
|
-
<
|
37
|
-
<
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
<% end %>
|
43
|
-
<% else %>
|
44
|
-
<%= link_to(filter.to_params(queue_name: name), class: 'btn btn-sm btn-outline-secondary', role: "button") do %>
|
45
|
-
<%= name %> (<%= count %>)
|
46
|
-
<% end %>
|
25
|
+
<div class="me-2">
|
26
|
+
<label for="job_queue_filter">Queue</label>
|
27
|
+
<select name="queue_name" id="job_queue_filter" class="form-select">
|
28
|
+
<option value="" <%= "selected='selected'" if params[:queue_name].blank? %>>All queues</option>
|
29
|
+
|
30
|
+
<% filter.queues.each do |name, count| %>
|
31
|
+
<option value="<%= name.to_param %>" <%= "selected='selected'" if params[:queue_name] == name %>><%= name %> (<%= count %>)</option>
|
47
32
|
<% end %>
|
48
|
-
|
33
|
+
</select>
|
49
34
|
</div>
|
50
35
|
|
51
|
-
<div class="
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
<% end %>
|
36
|
+
<div class="me-2 flex-fill d-flex flex-col align-items-end">
|
37
|
+
<label class="visually-hidden" for="query" aria-label="Search by class, job id, job params, and error text.">Search by class, job id, job params, and error text.</label>
|
38
|
+
<%= search_field_tag "query", params[:query], class: "form-control", placeholder: "Search by class, job id, job params, and error text." %>
|
39
|
+
</div>
|
56
40
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
</div>
|
63
|
-
<% end %>
|
41
|
+
<div class="d-flex flex-col align-items-end">
|
42
|
+
<div>
|
43
|
+
<%= form.submit "Search", name: nil, class: "btn btn-primary" %>
|
44
|
+
<%= link_to "Clear all", filter.to_params(job_class: nil, state: nil, queue_name: nil, query: nil), class: "btn btn-secondary" %>
|
45
|
+
</div>
|
64
46
|
</div>
|
65
47
|
</div>
|
66
|
-
|
48
|
+
<% end %>
|
49
|
+
|
50
|
+
<%= javascript_tag nonce: true do %>
|
51
|
+
document.addEventListener("DOMContentLoaded", () => {
|
52
|
+
document.querySelectorAll("#job_class_filter, #job_state_filter, #job_queue_filter").forEach((filter) => {
|
53
|
+
filter.addEventListener("change", () => {
|
54
|
+
document.querySelector("#filter_form").submit();
|
55
|
+
});
|
56
|
+
})
|
57
|
+
})
|
58
|
+
<% 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.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Sheldon
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-02-
|
11
|
+
date: 2022-02-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|
@@ -448,7 +448,7 @@ metadata:
|
|
448
448
|
homepage_uri: https://github.com/bensheldon/good_job
|
449
449
|
source_code_uri: https://github.com/bensheldon/good_job
|
450
450
|
rubygems_mfa_required: 'true'
|
451
|
-
post_install_message:
|
451
|
+
post_install_message:
|
452
452
|
rdoc_options:
|
453
453
|
- "--title"
|
454
454
|
- GoodJob - a multithreaded, Postgres-based ActiveJob backend for Ruby on Rails
|
@@ -471,8 +471,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
471
471
|
- !ruby/object:Gem::Version
|
472
472
|
version: '0'
|
473
473
|
requirements: []
|
474
|
-
rubygems_version: 3.
|
475
|
-
signing_key:
|
474
|
+
rubygems_version: 3.3.7
|
475
|
+
signing_key:
|
476
476
|
specification_version: 4
|
477
477
|
summary: A multithreaded, Postgres-based ActiveJob backend for Ruby on Rails
|
478
478
|
test_files: []
|