good_job 3.28.0 → 3.28.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b22f482dcf118c82d0b5889c6c37fd72bb65ff9a010f4fcc486bc2f0c4fc0bbe
4
- data.tar.gz: 83b1d597eee0f0c9c37b4afdf82f96e2164bef2d3b27181c10678327803f718e
3
+ metadata.gz: 3bbf6aa5c2cdbc7b2ff5b5f7dd31a219140934b799737c192aa8de55e5030bca
4
+ data.tar.gz: 1f7c614722781287cf6482af08fe97d4af5305fdfbd7583ce343277b7b8fe5a1
5
5
  SHA512:
6
- metadata.gz: b0b84290323a36b818cf92763e9df745737099f3990c934914e8ae700d6cb3a2ceb237764a8ff24fe923d5a8af0d18394e14a6aec516085a2bf057579341747e
7
- data.tar.gz: 030e271e5218499dbbce39e21803a5da6ede65422addb33ba5a0024582ac0996418471664061ce54700b1e9a5819eeeac517c479bb79d329577985e148752811
6
+ metadata.gz: 3f97f043eed52700808203c42ab9a714a7fdefdd33f3a201045a9a1649e675de6305386439f4707788a89842993902187c21b89939e4458e6a1750d25d6972d1
7
+ data.tar.gz: a3591c147f153964a0d929d8b49c43386b9f03bf53414471eed55d5312d9bb72e0fbd0ee49b966519570b4a13f33d4fa5ddda91c47d6fa31342af928cfa8185a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## [v3.28.1](https://github.com/bensheldon/good_job/tree/v3.28.1) (2024-04-24)
4
+
5
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v3.28.0...v3.28.1)
6
+
7
+ **Fixed bugs:**
8
+
9
+ - Ensure job context does not leak into extensions when`perform_now` is called within another job [\#1336](https://github.com/bensheldon/good_job/pull/1336) ([bensheldon](https://github.com/bensheldon))
10
+
11
+ **Closed issues:**
12
+
13
+ - Executing perform\_now on a good\_job with GoodJobs::ActiveJobExtensions::Concurrency can run twice [\#1335](https://github.com/bensheldon/good_job/issues/1335)
14
+ - `erb_lint` doesn't lint all files [\#1329](https://github.com/bensheldon/good_job/issues/1329)
15
+ - Server hangs after \#1297 [\#1301](https://github.com/bensheldon/good_job/issues/1301)
16
+ - Figure out how to use bind parameters for time queries [\#1285](https://github.com/bensheldon/good_job/issues/1285)
17
+
18
+ **Merged pull requests:**
19
+
20
+ - Upgrade development / demo Ruby to v3.3.1 [\#1333](https://github.com/bensheldon/good_job/pull/1333) ([bensheldon](https://github.com/bensheldon))
21
+ - Exploratory testing for presence of scheduled\_at when enqueuing [\#1332](https://github.com/bensheldon/good_job/pull/1332) ([bensheldon](https://github.com/bensheldon))
22
+ - Run `erb_lint` against all the views and partials [\#1331](https://github.com/bensheldon/good_job/pull/1331) ([bensheldon](https://github.com/bensheldon))
23
+
3
24
  ## [v3.28.0](https://github.com/bensheldon/good_job/tree/v3.28.0) (2024-04-19)
4
25
 
5
26
  [Full Changelog](https://github.com/bensheldon/good_job/compare/v3.27.4...v3.28.0)
@@ -2,14 +2,14 @@
2
2
  <div class="list-group list-group-flush text-nowrap table-jobs" role="table">
3
3
  <header class="list-group-item bg-body-tertiary">
4
4
  <div class="row small text-muted text-uppercase align-items-center">
5
- <div class="col-4"><%=t "good_job.models.batch.jobs" %></div>
6
- <div class="d-none d-lg-block col-lg-1 text-lg-center"><%=t "good_job.models.job.queue" %></div>
7
- <div class="d-none d-lg-block col-lg-1 text-lg-end"><%=t "good_job.models.job.priority" %></div>
8
- <div class="d-none d-lg-block col-lg-1 text-lg-end"><%=t "good_job.models.job.attempts" %></div>
5
+ <div class="col-4"><%= t("good_job.models.batch.jobs") %></div>
6
+ <div class="d-none d-lg-block col-lg-1 text-lg-center"><%= t "good_job.models.job.queue" %></div>
7
+ <div class="d-none d-lg-block col-lg-1 text-lg-end"><%= t "good_job.models.job.priority" %></div>
8
+ <div class="d-none d-lg-block col-lg-1 text-lg-end"><%= t "good_job.models.job.attempts" %></div>
9
9
  <div class="col text-end">
10
10
  <%= tag.button type: "button", class: "btn btn-sm text-muted", role: "button",
11
11
  data: { bs_toggle: "collapse", bs_target: ".job-params" },
12
- aria: { expanded: false, controls: jobs.map { |job| "##{dom_id(job, "params")}" }.join(" ") } do %>
12
+ aria: { expanded: false, controls: jobs.map { |job| "##{dom_id(job, 'params')}" }.join(" ") } do %>
13
13
  <%= render_icon "info" %>
14
14
  <span class="visually-hidden">Inspect</span>
15
15
  <% end %>
@@ -26,22 +26,24 @@
26
26
  <%= tag.h5 tag.code(link_to(job.display_name, job_path(job), class: "text-reset text-decoration-none")), class: "text-reset mb-0" %>
27
27
  </div>
28
28
  <div class="col-4 col-lg-1 text-lg-center">
29
- <div class="d-lg-none small text-muted mt-1"><%=t "good_job.models.job.queue" %></div>
29
+ <div class="d-lg-none small text-muted mt-1"><%= t "good_job.models.job.queue" %></div>
30
30
  <span class="badge bg-primary text-dark font-monospace"><%= job.queue_name %></span>
31
31
  </div>
32
32
  <div class="col-4 col-lg-1 text-lg-end">
33
- <div class="d-lg-none small text-muted mt-1"><%=t "good_job.models.job.priority" %>Priority</div>
33
+ <div class="d-lg-none small text-muted mt-1"><%= t "good_job.models.job.priority" %>Priority</div>
34
34
  <span class="font-monospace fw-bold"><%= job.priority %></span>
35
35
  </div>
36
36
  <div class="col-4 col-lg-1 text-lg-end">
37
- <div class="d-lg-none small text-muted mt-1"><%=t "good_job.models.job.attempts" %></div>
37
+ <div class="d-lg-none small text-muted mt-1"><%= t "good_job.models.job.attempts" %></div>
38
38
  <% if job.executions_count > 0 && job.status != :finished %>
39
- <%= tag.span job.executions_count, class: "badge rounded-pill bg-danger", data: {
40
- bs_toggle: "popover",
41
- bs_trigger: "hover focus click",
42
- bs_placement: "bottom",
43
- bs_content: job.recent_error
44
- } %>
39
+ <%= tag.span job.executions_count, class: "badge rounded-pill bg-danger",
40
+ data: {
41
+ bs_toggle: "popover",
42
+ bs_trigger: "hover focus click",
43
+ bs_placement: "bottom",
44
+ bs_content: job.recent_error,
45
+ }
46
+ %>
45
47
  <% else %>
46
48
  <span class="badge bg-secondary rounded-pill"><%= job.executions_count %></span>
47
49
  <% end %>
@@ -53,33 +55,33 @@
53
55
  <div class="dropdown float-end">
54
56
  <button class="d-flex align-items-center btn btn-sm" type="button" id="<%= dom_id(job, :actions) %>" data-bs-toggle="dropdown" aria-expanded="false">
55
57
  <%= render_icon :dots %>
56
- <span class="visually-hidden"><%=t ".actions.title" %></span>
58
+ <span class="visually-hidden"><%= t ".actions.title" %></span>
57
59
  </button>
58
60
  <ul class="dropdown-menu shadow" aria-labelledby="<%= dom_id(job, :actions) %>">
59
61
  <li>
60
62
  <% job_reschedulable = job.status.in? [:scheduled, :retried, :queued] %>
61
63
  <%= link_to reschedule_job_path(job.id), method: :put, class: "dropdown-item #{'disabled' unless job_reschedulable}", title: t(".actions.reschedule"), data: { confirm: t(".actions.confirm_reschedule"), disable: true } do %>
62
64
  <%= render_icon "skip_forward" %>
63
- <%=t "good_job.actions.reschedule" %>
65
+ <%= t "good_job.actions.reschedule" %>
64
66
  <% end %>
65
67
  </li>
66
68
  <li>
67
69
  <% job_discardable = job.status.in? [:scheduled, :retried, :queued] %>
68
70
  <%= link_to discard_job_path(job.id), method: :put, class: "dropdown-item #{'disabled' unless job_discardable}", title: t(".actions.discard"), data: { confirm: t(".actions.confirm_discard"), disable: true } do %>
69
71
  <%= render_icon "stop" %>
70
- <%=t "good_job.actions.discard" %>
72
+ <%= t "good_job.actions.discard" %>
71
73
  <% end %>
72
74
  </li>
73
75
  <li>
74
76
  <%= link_to retry_job_path(job.id), method: :put, class: "dropdown-item #{'disabled' unless job.status == :discarded}", title: t(".actions.retry"), data: { confirm: t(".actions.confirm_retry"), disable: true } do %>
75
77
  <%= render_icon "arrow_clockwise" %>
76
- <%=t "good_job.actions.retry" %>
78
+ <%= t "good_job.actions.retry" %>
77
79
  <% end %>
78
80
  </li>
79
81
  <li>
80
82
  <%= link_to job_path(job.id), method: :delete, class: "dropdown-item #{'disabled' unless job.status.in? [:discarded, :finished]}", title: t(".actions.destroy"), data: { confirm: t(".actions.confirm_destroy"), disable: true } do %>
81
83
  <%= render_icon "trash" %>
82
- <%=t "good_job.actions.destroy" %>
84
+ <%= t "good_job.actions.destroy" %>
83
85
  <% end %>
84
86
  </li>
85
87
 
@@ -89,7 +91,7 @@
89
91
  data: { bs_toggle: "collapse" },
90
92
  aria: { expanded: false, controls: dom_id(job, "params") } do %>
91
93
  <%= render_icon "info" %>
92
- <%=t "good_job.actions.inspect" %>
94
+ <%= t "good_job.actions.inspect" %>
93
95
  <% end %>
94
96
  </li>
95
97
  </ul>
@@ -103,7 +105,7 @@
103
105
  <% end %>
104
106
  <% else %>
105
107
  <div class="list-group-item py-4 text-center text-muted">
106
- <%=t ".no_jobs_found" %>
108
+ <%= t ".no_jobs_found" %>
107
109
  </div>
108
110
  <% end %>
109
111
  </div>
@@ -2,18 +2,18 @@
2
2
  <div class="list-group list-group-flush text-nowrap table-batches" role="table">
3
3
  <header class="list-group-item bg-body-tertiary">
4
4
  <div class="row small text-muted text-uppercase align-items-center">
5
- <div class="col-4"><%=t "good_job.models.batch.name" %></div>
6
- <div class="col-lg-1 d-none d-lg-block"><%=t "good_job.models.batch.created" %></div>
7
- <div class="col-lg-1 d-none d-lg-block"><%=t "good_job.models.batch.enqueued" %></div>
8
- <div class="col-lg-1 d-none d-lg-block"><%=t "good_job.models.batch.discarded" %></div>
9
- <div class="col-lg-1 d-none d-lg-block"><%=t "good_job.models.batch.finished" %></div>
10
- <div class="col-lg-1 d-none d-lg-block"><%=t "good_job.models.batch.jobs" %></div>
5
+ <div class="col-4"><%= t "good_job.models.batch.name" %></div>
6
+ <div class="col-lg-1 d-none d-lg-block"><%= t "good_job.models.batch.created" %></div>
7
+ <div class="col-lg-1 d-none d-lg-block"><%= t "good_job.models.batch.enqueued" %></div>
8
+ <div class="col-lg-1 d-none d-lg-block"><%= t "good_job.models.batch.discarded" %></div>
9
+ <div class="col-lg-1 d-none d-lg-block"><%= t "good_job.models.batch.finished" %></div>
10
+ <div class="col-lg-1 d-none d-lg-block"><%= t "good_job.models.batch.jobs" %></div>
11
11
  <div class="col text-end">
12
12
  <%= tag.button type: "button", class: "btn btn-sm text-muted", role: "button",
13
13
  data: { bs_toggle: "collapse", bs_target: ".batch-properties" },
14
- aria: { expanded: false, controls: batches.map { |batch| "##{dom_id(batch, "params")}" }.join(" ") } do %>
14
+ aria: { expanded: false, controls: batches.map { |batch| "##{dom_id(batch, 'params')}" }.join(" ") } do %>
15
15
  <%= render_icon "info" %>
16
- <span class="visually-hidden"><%=t "good_job.actions.inspect" %></span>
16
+ <span class="visually-hidden"><%= t "good_job.actions.inspect" %></span>
17
17
  <% end %>
18
18
  </div>
19
19
  </div>
@@ -33,29 +33,29 @@
33
33
  <% end %>
34
34
  </div>
35
35
  <div class="col-6 col-lg-1 text-wrap">
36
- <div class="d-lg-none small text-muted mt-1"><%=t "good_job.models.batch.created_at" %></div>
36
+ <div class="d-lg-none small text-muted mt-1"><%= t "good_job.models.batch.created_at" %></div>
37
37
  <%= relative_time(batch.created_at) %>
38
38
  </div>
39
39
  <div class="col-6 col-lg-1 text-wrap">
40
40
  <% if batch.enqueued_at %>
41
- <div class="d-lg-none small text-muted mt-1"><%=t "good_job.models.batch.enqueued_at" %></div>
41
+ <div class="d-lg-none small text-muted mt-1"><%= t "good_job.models.batch.enqueued_at" %></div>
42
42
  <%= relative_time(batch.enqueued_at) %>
43
43
  <% end %>
44
44
  </div>
45
45
  <div class="col-6 col-lg-1 text-wrap">
46
46
  <% if batch.discarded_at %>
47
- <div class="d-lg-none small text-muted mt-1"><%=t "good_job.models.batch.discarded_at" %></div>
47
+ <div class="d-lg-none small text-muted mt-1"><%= t "good_job.models.batch.discarded_at" %></div>
48
48
  <%= relative_time(batch.discarded_at) %>
49
49
  <% end %>
50
50
  </div>
51
51
  <div class="col-6 col-lg-1 text-wrap">
52
52
  <% if batch.finished_at %>
53
- <div class="d-lg-none small text-muted mt-1"><%=t "good_job.models.batch.finished_at" %></div>
53
+ <div class="d-lg-none small text-muted mt-1"><%= t "good_job.models.batch.finished_at" %></div>
54
54
  <%= relative_time(batch.finished_at) %>
55
55
  <% end %>
56
56
  </div>
57
57
  <div class="col-6 col-lg-1">
58
- <div class="d-lg-none small text-muted mt-1"><%=t "good_job.models.batch.jobs" %></div>
58
+ <div class="d-lg-none small text-muted mt-1"><%= t "good_job.models.batch.jobs" %></div>
59
59
  <%= batch.jobs.count %>
60
60
  </div>
61
61
  <div class="col text-end">
@@ -64,7 +64,7 @@
64
64
  data: { bs_toggle: "collapse", bs_target: "##{dom_id(batch, 'properties')}" },
65
65
  aria: { expanded: false, controls: dom_id(batch, "state") } do %>
66
66
  <%= render_icon "info" %>
67
- <span class="visually-hidden"><%=t "good_job.actions.inspect" %></span>
67
+ <span class="visually-hidden"><%= t "good_job.actions.inspect" %></span>
68
68
  <% end %>
69
69
  </div>
70
70
  </div>
@@ -75,7 +75,7 @@
75
75
  <% end %>
76
76
  <% else %>
77
77
  <div class="list-group-item py-4 text-center text-muted">
78
- <%=t ".no_batches_found" %>
78
+ <%= t ".no_batches_found" %>
79
79
  </div>
80
80
  <% end %>
81
81
  </div>
@@ -1,4 +1,4 @@
1
- <h5><%=t ".title" %></h5>
1
+ <h5><%= t ".title" %></h5>
2
2
  <div class="card mb-4" data-live-poll-region="executions-table">
3
3
  <div class="list-group list-group-flush">
4
4
  <% executions.each do |execution| %>
@@ -10,12 +10,12 @@
10
10
  </div>
11
11
  <div class="col-md-2 small">
12
12
  <% if execution.queue_latency %>
13
- <%= format_duration execution.queue_latency %> <span class="text-muted"><%=t ".in_queue" %></span>
13
+ <%= format_duration execution.queue_latency %> <span class="text-muted"><%= t ".in_queue" %></span>
14
14
  <% end %>
15
15
  </div>
16
16
  <div class="col-md-2 small">
17
17
  <% if execution.runtime_latency %>
18
- <%= format_duration execution.runtime_latency %> <span class="text-muted"><%=t ".runtime" %></span>
18
+ <%= format_duration execution.runtime_latency %> <span class="text-muted"><%= t ".runtime" %></span>
19
19
  <% end %>
20
20
  </div>
21
21
  <div class="col">
@@ -28,20 +28,20 @@
28
28
  data: { bs_toggle: "collapse", bs_target: "##{dom_id(execution, 'params')}" },
29
29
  aria: { expanded: false, controls: dom_id(execution, "params") } do %>
30
30
  <%= render_icon "info" %>
31
- <span class="visually-hidden"><%=t "good_job.actions.inspect" %></span>
31
+ <span class="visually-hidden"><%= t "good_job.actions.inspect" %></span>
32
32
  <% end %>
33
33
  </div>
34
34
  </div>
35
35
  </div>
36
36
  <% if execution.error %>
37
37
  <div class="mt-3 small">
38
- <strong class="small text-danger"><%=t "good_job.shared.error" %>:</strong>
38
+ <strong class="small text-danger"><%= t "good_job.shared.error" %>:</strong>
39
39
  <code class="text-wrap text-break m-0 text-secondary-emphasis"><%= execution.error %></code>
40
40
  </div>
41
41
  <% if GoodJob::DiscreteExecution.backtrace_migrated? && execution.error_backtrace&.any? %>
42
- <%= tag.ul class: "nav nav-tabs small w-fit-content", id: dom_id(execution, :tab), role:"tablist" do %>
42
+ <%= tag.ul class: "nav nav-tabs small w-fit-content", id: dom_id(execution, :tab), role: "tablist" do %>
43
43
  <li class="nav-item" role="presentation">
44
- <%= tag.button t(".application_trace"), class: "nav-link active p-1", id: dom_id(execution, :application), data: { bs_toggle: "tab", bs_target: dom_id(execution, :"#application_pane") }, type: "button", role: "tab", aria: { controls: dom_id(execution, :application_pane), selected: true } %>
44
+ <%= tag.button t(".application_trace"), class: "nav-link active p-1", id: dom_id(execution, :application), data: { bs_toggle: "tab", bs_target: dom_id(execution, :"#application_pane") }, type: "button", role: "tab", aria: { controls: dom_id(execution, :application_pane), selected: true } %>
45
45
  </li>
46
46
  <li class="nav-item" role="presentation">
47
47
  <%= tag.button t(".full_trace"), class: "nav-link p-1", id: dom_id(execution, :full), data: { bs_toggle: "tab", bs_target: dom_id(execution, :"#full_pane") }, type: "button", role: "tab", aria: { controls: dom_id(execution, :full_pane), selected: false } %>
@@ -1,176 +1,178 @@
1
1
  <%= form_with(url: mass_update_jobs_path(filter.to_params), method: :put, local: true, data: { "checkbox-toggle": "job_ids" }) do |form| %>
2
- <div class="my-3 card" data-gj-poll-replace id="jobs-table">
3
- <div class="list-group list-group-flush text-nowrap table-jobs" role="table">
4
- <header class="list-group-item bg-body-tertiary">
5
- <div class="row small text-muted text-uppercase align-items-center">
6
- <div class="col-lg-4 d-flex gap-2 flex-wrap">
7
- <div class="form-check d-flex flex-row px-0 mb-0">
8
- <%= check_box_tag('toggle_job_ids', "1", false, data: { "checkbox-toggle-all": "job_ids" }) %>
9
- <%= label_tag('toggle_job_ids', t(".toggle_all_jobs"), class: "visually-hidden") %>
10
- </div>
11
- <%= form.button type: 'submit', name: 'mass_action', value: 'reschedule', class: 'ms-1 btn btn-sm btn-outline-secondary', title: t(".actions.reschedule_all"), data: { confirm: t(".actions.confirm_reschedule_all"), disable: true } do %>
12
- <span class="me-1"><%= render_icon "skip_forward" %></span> <%=t "good_job.actions.reschedule" %>
13
- <% end %>
14
-
15
- <%= form.button type: 'submit', name: 'mass_action', value: 'retry', class: 'btn btn-sm btn-outline-secondary', title: t(".actions.retry_all"), data: { confirm: t(".actions.confirm_retry_all"), disable: true } do %>
16
- <span class="me-1"><%= render_icon "arrow_clockwise" %></span> <%=t "good_job.actions.retry" %>
17
- <% end %>
2
+ <div class="my-3 card" data-gj-poll-replace id="jobs-table">
3
+ <div class="list-group list-group-flush text-nowrap table-jobs" role="table">
4
+ <header class="list-group-item bg-body-tertiary">
5
+ <div class="row small text-muted text-uppercase align-items-center">
6
+ <div class="col-lg-4 d-flex gap-2 flex-wrap">
7
+ <div class="form-check d-flex flex-row px-0 mb-0">
8
+ <%= check_box_tag('toggle_job_ids', "1", false, data: { "checkbox-toggle-all": "job_ids" }) %>
9
+ <%= label_tag('toggle_job_ids', t(".toggle_all_jobs"), class: "visually-hidden") %>
10
+ </div>
11
+ <%= form.button type: 'submit', name: 'mass_action', value: 'reschedule', class: 'ms-1 btn btn-sm btn-outline-secondary', title: t(".actions.reschedule_all"), data: { confirm: t(".actions.confirm_reschedule_all"), disable: true } do %>
12
+ <span class="me-1"><%= render_icon "skip_forward" %></span> <%= t "good_job.actions.reschedule" %>
13
+ <% end %>
18
14
 
19
- <div class="btn-group" role="group">
20
- <%= form.button type: 'submit', name: 'mass_action', value: 'discard', class: 'btn btn-sm btn-outline-secondary', title: t(".actions.discard_all"), data: { confirm: t(".actions.confirm_discard_all"), disable: true } do %>
21
- <span class="me-1"><%= render_icon "stop" %></span> <%=t "good_job.actions.discard" %>
15
+ <%= form.button type: 'submit', name: 'mass_action', value: 'retry', class: 'btn btn-sm btn-outline-secondary', title: t(".actions.retry_all"), data: { confirm: t(".actions.confirm_retry_all"), disable: true } do %>
16
+ <span class="me-1"><%= render_icon "arrow_clockwise" %></span> <%= t "good_job.actions.retry" %>
22
17
  <% end %>
23
- <button id="destroy-dropdown-toggle" type="button" class="btn btn-sm btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
24
- <span class="visually-hidden"><%=t ".toggle_actions" %></span>
25
- </button>
26
- <ul class="dropdown-menu" aria-labelledby="destroy-dropdown-toggle">
27
- <li>
28
- <%= form.button type: 'submit', name: 'mass_action', value: 'destroy', class: 'btn dropdown-item', title: t(".actions.destroy_all"), data: { confirm: t(".actions.confirm_destroy_all"), disable: true } do %>
29
- <span class="me-1"><%= render_icon "trash" %></span> <%=t "good_job.actions.destroy" %>
30
- <% end %>
31
- </li>
32
- </ul>
33
- </div>
34
18
 
35
- </div>
36
- <div class="d-none d-lg-block col-lg-1 text-lg-center"><%=t "good_job.models.job.queue" %></div>
37
- <div class="d-none d-lg-block col-lg-1 text-lg-end"><%=t "good_job.models.job.priority" %></div>
38
- <div class="d-none d-lg-block col-lg-1 text-lg-end"><%=t "good_job.models.job.attempts" %></div>
39
- <div class="col text-end">
40
- <%= tag.button type: "button", class: "btn btn-sm text-muted", role: "button",
41
- data: { bs_toggle: "collapse", bs_target: ".job-params" },
42
- aria: { expanded: false, controls: jobs.map { |job| "##{dom_id(job, "params")}" }.join(" ") } do %>
19
+ <div class="btn-group" role="group">
20
+ <%= form.button type: 'submit', name: 'mass_action', value: 'discard', class: 'btn btn-sm btn-outline-secondary', title: t(".actions.discard_all"), data: { confirm: t(".actions.confirm_discard_all"), disable: true } do %>
21
+ <span class="me-1"><%= render_icon "stop" %></span> <%= t "good_job.actions.discard" %>
22
+ <% end %>
23
+ <button id="destroy-dropdown-toggle" type="button" class="btn btn-sm btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
24
+ <span class="visually-hidden"><%= t ".toggle_actions" %></span>
25
+ </button>
26
+ <ul class="dropdown-menu" aria-labelledby="destroy-dropdown-toggle">
27
+ <li>
28
+ <%= form.button type: 'submit', name: 'mass_action', value: 'destroy', class: 'btn dropdown-item', title: t(".actions.destroy_all"), data: { confirm: t(".actions.confirm_destroy_all"), disable: true } do %>
29
+ <span class="me-1"><%= render_icon "trash" %></span> <%= t "good_job.actions.destroy" %>
30
+ <% end %>
31
+ </li>
32
+ </ul>
33
+ </div>
34
+
35
+ </div>
36
+ <div class="d-none d-lg-block col-lg-1 text-lg-center"><%= t "good_job.models.job.queue" %></div>
37
+ <div class="d-none d-lg-block col-lg-1 text-lg-end"><%= t "good_job.models.job.priority" %></div>
38
+ <div class="d-none d-lg-block col-lg-1 text-lg-end"><%= t "good_job.models.job.attempts" %></div>
39
+ <div class="col text-end">
40
+ <%= tag.button type: "button", class: "btn btn-sm text-muted", role: "button",
41
+ data: { bs_toggle: "collapse", bs_target: ".job-params" },
42
+ aria: { expanded: false, controls: jobs.map { |job| "##{dom_id(job, 'params')}" }.join(" ") } do %>
43
43
  <%= render_icon "info" %>
44
- <span class="visually-hidden"><%=t "good_job.actions.inspect" %></span>
45
- <% end %>
46
- </div>
47
- </div>
48
- </header>
49
- <label role="row" class="list-group-item list-group-item-warning list-group-item-action py-2 d-none" data-checkbox-toggle-show="job_ids">
50
- <div class="row">
51
- <div class="col-auto">
52
- <%= check_box_tag "all_job_ids", 1, false, disabled: true, data: { "checkbox-toggle-show": "job_ids"} %>
44
+ <span class="visually-hidden"><%= t "good_job.actions.inspect" %></span>
45
+ <% end %>
46
+ </div>
53
47
  </div>
54
- <div class="col-auto">
55
- <%=t ".actions.apply_to_all", count: filter.filtered_count %>
48
+ </header>
49
+ <label role="row" class="list-group-item list-group-item-warning list-group-item-action py-2 d-none" data-checkbox-toggle-show="job_ids">
50
+ <div class="row">
51
+ <div class="col-auto">
52
+ <%= check_box_tag "all_job_ids", 1, false, disabled: true, data: { "checkbox-toggle-show": "job_ids" } %>
53
+ </div>
54
+ <div class="col-auto">
55
+ <%= t ".actions.apply_to_all", count: filter.filtered_count %>
56
+ </div>
56
57
  </div>
57
- </div>
58
- </label>
58
+ </label>
59
59
 
60
- <% if jobs.present? %>
61
- <% jobs.each do |job| %>
62
- <%= label_tag dom_id(job, :checkbox), id: dom_id(job), role: "row", class: "list-group-item list-group-item-action py-3" do %>
63
- <div class="row align-items-center">
64
- <div class="col-lg-4 d-flex">
65
- <%= check_box_tag 'job_ids[]', job.id, false, id: dom_id(job, :checkbox), data: { "checkbox-toggle-each": "job_ids" } %>
66
- <div class="ms-2">
67
- <%= tag.code link_to(job.id, job_path(job), class: "small text-muted text-decoration-none") %>
68
- <%= tag.h5 tag.code(link_to(job.display_name, job_path(job), class: "text-reset text-decoration-none")), class: "text-reset mb-0" %>
69
- <% if job.error %>
70
- <div class="mt-1 small">
71
- <strong class="small text-danger"><%=t "good_job.shared.error" %>:</strong>
72
- <code class="text-wrap text-break m-0 text-secondary-emphasis"><%= job.error %></code>
73
- </div>
74
- <% end %>
60
+ <% if jobs.present? %>
61
+ <% jobs.each do |job| %>
62
+ <%= label_tag dom_id(job, :checkbox), id: dom_id(job), role: "row", class: "list-group-item list-group-item-action py-3" do %>
63
+ <div class="row align-items-center">
64
+ <div class="col-lg-4 d-flex">
65
+ <%= check_box_tag 'job_ids[]', job.id, false, id: dom_id(job, :checkbox), data: { "checkbox-toggle-each": "job_ids" } %>
66
+ <div class="ms-2">
67
+ <%= tag.code link_to(job.id, job_path(job), class: "small text-muted text-decoration-none") %>
68
+ <%= tag.h5 tag.code(link_to(job.display_name, job_path(job), class: "text-reset text-decoration-none")), class: "text-reset mb-0" %>
69
+ <% if job.error %>
70
+ <div class="mt-1 small">
71
+ <strong class="small text-danger"><%= t "good_job.shared.error" %>:</strong>
72
+ <code class="text-wrap text-break m-0 text-secondary-emphasis"><%= job.error %></code>
73
+ </div>
74
+ <% end %>
75
+ </div>
75
76
  </div>
76
- </div>
77
- <div class="col-4 col-lg-1 text-lg-center">
78
- <div class="d-lg-none small text-muted mt-1"><%=t "good_job.models.job.queue" %></div>
79
- <span class="badge bg-primary font-monospace"><%= job.queue_name %></span>
80
- </div>
81
- <div class="col-4 col-lg-1 text-lg-end">
82
- <div class="d-lg-none small text-muted mt-1"><%=t "good_job.models.job.priority" %></div>
83
- <%= job.priority %>
84
- </div>
85
- <div class="col-4 col-lg-1 text-lg-end">
86
- <div class="d-lg-none small text-muted mt-1"><%=t "good_job.models.job.attempts" %></div>
87
- <% if job.executions_count > 0 && job.status != :succeeded %>
88
- <%= tag.span job.executions_count, class: "badge rounded-pill bg-danger", data: {
77
+ <div class="col-4 col-lg-1 text-lg-center">
78
+ <div class="d-lg-none small text-muted mt-1"><%= t "good_job.models.job.queue" %></div>
79
+ <span class="badge bg-primary font-monospace"><%= job.queue_name %></span>
80
+ </div>
81
+ <div class="col-4 col-lg-1 text-lg-end">
82
+ <div class="d-lg-none small text-muted mt-1"><%= t "good_job.models.job.priority" %></div>
83
+ <%= job.priority %>
84
+ </div>
85
+ <div class="col-4 col-lg-1 text-lg-end">
86
+ <div class="d-lg-none small text-muted mt-1"><%= t "good_job.models.job.attempts" %></div>
87
+ <% if job.executions_count > 0 && job.status != :succeeded %>
88
+ <%= tag.span job.executions_count, class: "badge rounded-pill bg-danger",
89
+ data: {
89
90
  bs_toggle: "popover",
90
91
  bs_trigger: "hover focus click",
91
92
  bs_placement: "bottom",
92
93
  bs_content: job.display_error,
93
- } %>
94
- <% else %>
95
- <span class="badge bg-secondary rounded-pill"><%= job.executions_count %></span>
96
- <% end %>
97
- </div>
98
- <div class="mt-3 mt-lg-0 col">
99
- <div class="d-flex gap-3 align-items-start justify-content-end">
100
- <%= tag.span relative_time(job.last_status_at), class: "small mt-1" %>
101
- <div>
102
- <%= status_badge job.status %>
103
- <% if job.status == :discarded && job.class.error_event_migrated? && job.error_event %>
104
- <div class="text-black text-center" >
105
- <small><%= t(job.error_event, scope: 'good_job.error_event') %></small>
106
- </div>
107
- <% end %>
108
- </div>
94
+ }
95
+ %>
96
+ <% else %>
97
+ <span class="badge bg-secondary rounded-pill"><%= job.executions_count %></span>
98
+ <% end %>
99
+ </div>
100
+ <div class="mt-3 mt-lg-0 col">
101
+ <div class="d-flex gap-3 align-items-start justify-content-end">
102
+ <%= tag.span relative_time(job.last_status_at), class: "small mt-1" %>
103
+ <div>
104
+ <%= status_badge job.status %>
105
+ <% if job.status == :discarded && job.class.error_event_migrated? && job.error_event %>
106
+ <div class="text-black text-center">
107
+ <small><%= t(job.error_event, scope: 'good_job.error_event') %></small>
108
+ </div>
109
+ <% end %>
110
+ </div>
109
111
 
110
- <div class="dropdown float-end">
111
- <button class="d-flex align-items-center btn btn-sm" type="button" id="<%= dom_id(job, :actions) %>" data-bs-toggle="dropdown" aria-expanded="false">
112
- <%= render_icon "dots" %>
113
- <span class="visually-hidden"><%=t ".actions.title" %></span>
114
- </button>
115
- <ul class="dropdown-menu shadow" aria-labelledby="<%= dom_id(job, :actions) %>">
116
- <li>
117
- <% job_reschedulable = job.status.in? [:scheduled, :retried, :queued] %>
118
- <%= link_to reschedule_job_path(job.id), method: :put, class: "dropdown-item #{'disabled' unless job_reschedulable}", title: t("good_job.jobs.actions.reschedule"), data: { confirm: t("good_job.jobs.actions.confirm_reschedule"), disable: true } do %>
119
- <%= render_icon "skip_forward" %>
120
- <%=t "good_job.actions.reschedule" %>
121
- <% end %>
122
- </li>
123
- <li>
124
- <% job_discardable = job.status.in? [:scheduled, :retried, :queued] %>
125
- <%= link_to discard_job_path(job.id), method: :put, class: "dropdown-item #{'disabled' unless job_discardable}", title: t("good_job.jobs.actions.discard"), data: { confirm: t("good_job.jobs.actions.confirm_discard"), disable: true } do %>
126
- <%= render_icon "stop" %>
127
- <%=t "good_job.actions.discard" %>
128
- <% end %>
129
- </li>
130
- <li>
131
- <% job_force_discardable = job.status.in? [:running] %>
132
- <%= link_to force_discard_job_path(job.id), method: :put, class: "dropdown-item #{'disabled' unless job_force_discardable}", title: t("good_job.jobs.actions.force_discard"), data: { confirm: t("good_job.jobs.actions.confirm_force_discard"), disable: true } do %>
133
- <%= render_icon "eject" %>
134
- <%=t "good_job.actions.force_discard" %>
135
- <% end %>
136
- </li>
137
- <li>
138
- <%= link_to retry_job_path(job.id), method: :put, class: "dropdown-item #{'disabled' unless job.status == :discarded}", title: t("good_job.jobs.actions.retry"), data: { confirm: t("good_job.jobs.actions.confirm_retry"), disable: true } do %>
139
- <%= render_icon "arrow_clockwise" %>
140
- <%=t "good_job.actions.retry" %>
141
- <% end %>
142
- </li>
143
- <li>
144
- <%= link_to job_path(job.id), method: :delete, class: "dropdown-item #{'disabled' unless job.status.in? [:discarded, :succeeded]}", title: t("good_job.jobs.actions.destroy"), data: { confirm: t("good_job.jobs.actions.confirm_destroy"), disable: true } do %>
145
- <%= render_icon "trash" %>
146
- <%=t "good_job.actions.destroy" %>
147
- <% end %>
148
- </li>
112
+ <div class="dropdown float-end">
113
+ <button class="d-flex align-items-center btn btn-sm" type="button" id="<%= dom_id(job, :actions) %>" data-bs-toggle="dropdown" aria-expanded="false">
114
+ <%= render_icon "dots" %>
115
+ <span class="visually-hidden"><%= t ".actions.title" %></span>
116
+ </button>
117
+ <ul class="dropdown-menu shadow" aria-labelledby="<%= dom_id(job, :actions) %>">
118
+ <li>
119
+ <% job_reschedulable = job.status.in? [:scheduled, :retried, :queued] %>
120
+ <%= link_to reschedule_job_path(job.id), method: :put, class: "dropdown-item #{'disabled' unless job_reschedulable}", title: t("good_job.jobs.actions.reschedule"), data: { confirm: t("good_job.jobs.actions.confirm_reschedule"), disable: true } do %>
121
+ <%= render_icon "skip_forward" %>
122
+ <%= t "good_job.actions.reschedule" %>
123
+ <% end %>
124
+ </li>
125
+ <li>
126
+ <% job_discardable = job.status.in? [:scheduled, :retried, :queued] %>
127
+ <%= link_to discard_job_path(job.id), method: :put, class: "dropdown-item #{'disabled' unless job_discardable}", title: t("good_job.jobs.actions.discard"), data: { confirm: t("good_job.jobs.actions.confirm_discard"), disable: true } do %>
128
+ <%= render_icon "stop" %>
129
+ <%= t "good_job.actions.discard" %>
130
+ <% end %>
131
+ </li>
132
+ <li>
133
+ <% job_force_discardable = job.status.in? [:running] %>
134
+ <%= link_to force_discard_job_path(job.id), method: :put, class: "dropdown-item #{'disabled' unless job_force_discardable}", title: t("good_job.jobs.actions.force_discard"), data: { confirm: t("good_job.jobs.actions.confirm_force_discard"), disable: true } do %>
135
+ <%= render_icon "eject" %>
136
+ <%= t "good_job.actions.force_discard" %>
137
+ <% end %>
138
+ </li>
139
+ <li>
140
+ <%= link_to retry_job_path(job.id), method: :put, class: "dropdown-item #{'disabled' unless job.status == :discarded}", title: t("good_job.jobs.actions.retry"), data: { confirm: t("good_job.jobs.actions.confirm_retry"), disable: true } do %>
141
+ <%= render_icon "arrow_clockwise" %>
142
+ <%= t "good_job.actions.retry" %>
143
+ <% end %>
144
+ </li>
145
+ <li>
146
+ <%= link_to job_path(job.id), method: :delete, class: "dropdown-item #{'disabled' unless job.status.in? [:discarded, :succeeded]}", title: t("good_job.jobs.actions.destroy"), data: { confirm: t("good_job.jobs.actions.confirm_destroy"), disable: true } do %>
147
+ <%= render_icon "trash" %>
148
+ <%= t "good_job.actions.destroy" %>
149
+ <% end %>
150
+ </li>
149
151
 
150
- <li>
151
- <%= link_to "##{dom_id(job, 'params')}",
152
- class: "dropdown-item",
153
- data: { bs_toggle: "collapse" },
154
- aria: { expanded: false, controls: dom_id(job, "params") } do %>
155
- <%= render_icon "info" %>
156
- <%=t "good_job.actions.inspect" %>
157
- <% end %>
158
- </li>
159
- </ul>
152
+ <li>
153
+ <%= link_to "##{dom_id(job, 'params')}",
154
+ class: "dropdown-item",
155
+ data: { bs_toggle: "collapse" },
156
+ aria: { expanded: false, controls: dom_id(job, "params") } do %>
157
+ <%= render_icon "info" %>
158
+ <%= t "good_job.actions.inspect" %>
159
+ <% end %>
160
+ </li>
161
+ </ul>
162
+ </div>
160
163
  </div>
161
164
  </div>
162
165
  </div>
163
- </div>
164
- <% end %>
165
- <%= tag.div id: dom_id(job, "params"), class: "job-params list-group-item collapse small bg-dark text-light" do %>
166
- <%= tag.pre JSON.pretty_generate(job.display_serialized_params) %>
166
+ <% end %>
167
+ <%= tag.div id: dom_id(job, "params"), class: "job-params list-group-item collapse small bg-dark text-light" do %>
168
+ <%= tag.pre JSON.pretty_generate(job.display_serialized_params) %>
169
+ <% end %>
167
170
  <% end %>
171
+ <% else %>
172
+ <div class="list-group-item py-4 text-center text-muted">
173
+ <%= t ".no_jobs_found" %>
174
+ </div>
168
175
  <% end %>
169
- <% else %>
170
- <div class="list-group-item py-4 text-center text-muted">
171
- <%=t ".no_jobs_found" %>
172
- </div>
173
- <% end %>
176
+ </div>
174
177
  </div>
175
- </div>
176
178
  <% end %>
@@ -12,7 +12,7 @@
12
12
  <div class="me-md-2 mb-2 mb-md-0">
13
13
  <%= label_tag "job_queue_filter", t(".queue_name"), class: "visually-hidden" %>
14
14
  <select name="queue_name" id="job_queue_filter" class="form-select form-select-sm">
15
- <option value="" <%= "selected='selected'" if params[:queue_name].blank? %>><%=t ".all_queues" %></option>
15
+ <option value="" <%= "selected='selected'" if params[:queue_name].blank? %>><%= t ".all_queues" %></option>
16
16
 
17
17
  <% filter.queues.each do |name, count| %>
18
18
  <option value="<%= name.to_param %>" <%= "selected='selected'" if params[:queue_name] == name %>><%= name %> (<%= number_with_delimiter(count, translate_hash('good_job.number.format')) %>)</option>
@@ -23,7 +23,7 @@
23
23
  <div class="me-md-2 mb-2 mb-md-0">
24
24
  <%= label_tag "job_class_filter", t(".job_name"), class: "visually-hidden" %>
25
25
  <select name="job_class" id="job_class_filter" class="form-select form-select-sm">
26
- <option value="" <%= "selected='selected'" if params[:job_class].blank? %>><%=t ".all_jobs" %></option>
26
+ <option value="" <%= "selected='selected'" if params[:job_class].blank? %>><%= t ".all_jobs" %></option>
27
27
 
28
28
  <% filter.job_classes.each do |name, count| %>
29
29
  <option value="<%= name.to_param %>" <%= "selected='selected'" if params[:job_class] == name %>><%= name %> (<%= number_with_delimiter(count, translate_hash('good_job.number.format')) %>)</option>
@@ -33,14 +33,14 @@
33
33
 
34
34
  <div class="me-md-2 mb-2 mb-md-0 flex-fill">
35
35
  <%= label_tag "query", t(".search"), class: "visually-hidden" %>
36
- <%= search_field_tag "query", params[:query], class: "form-control form-control-sm", placeholder: t(".placeholder") %>
36
+ <%= search_field_tag "query", params[:query], class: "form-control form-control-sm", placeholder: t(".placeholder"), autocomplete: "off" %>
37
37
  </div>
38
38
 
39
39
  <div class="d-flex flex-col align-items-end">
40
40
  <div>
41
41
  <%= form.submit t(".search"), name: nil, class: "btn btn-primary btn-sm" %>
42
42
  <%= link_to filter.to_params(job_class: nil, state: nil, queue_name: nil, query: nil), class: "btn btn-secondary btn-sm" do %>
43
- <%=t ".clear" %>
43
+ <%= t ".clear" %>
44
44
  <% end %>
45
45
  </div>
46
46
  </div>
@@ -49,21 +49,21 @@
49
49
 
50
50
  <ul data-controller="async-values" data-async-values-url-value="<%= metrics_job_status_path %>" data-live-poll-region="filter-tabs" class="nav nav-tabs my-3">
51
51
  <li class="nav-item">
52
- <%= link_to t(".all"), filter.to_params(state: nil), class: "nav-link #{"active" unless params[:state].present?}" %>
52
+ <%= link_to t(".all"), filter.to_params(state: nil), class: "nav-link #{'active' if params[:state].blank?}" %>
53
53
  </li>
54
54
 
55
55
  <% filter.state_names.each do |name| %>
56
56
  <li class="nav-item">
57
- <%= link_to filter.to_params(state: name), class: "nav-link #{"active" if params[:state] == name}" do %>
57
+ <%= link_to filter.to_params(state: name), class: "nav-link #{'active' if params[:state] == name}" do %>
58
58
  <%= t(name, scope: 'good_job.status') %>
59
- <span data-async-values-target="value", data-async-values-key="<%= name %>" data-async-values-zero-class="bg-secondary" class="badge bg-primary rounded-pill d-none"></span>
59
+ <span data-async-values-target="value" data-async-values-key="<%= name %>" data-async-values-zero-class="bg-secondary" class="badge bg-primary rounded-pill d-none"></span>
60
60
  <% end %>
61
61
  </li>
62
62
  <% end %>
63
63
  </ul>
64
64
  </div>
65
65
 
66
- <%= javascript_tag nonce: true do %>
66
+ <script nonce="<%= content_security_policy_nonce %>">
67
67
  document.addEventListener("DOMContentLoaded", () => {
68
68
  document.querySelectorAll("#job_class_filter, #job_queue_filter").forEach((filter) => {
69
69
  filter.addEventListener("change", () => {
@@ -71,5 +71,5 @@
71
71
  });
72
72
  })
73
73
  })
74
- <% end %>
74
+ </script>
75
75
  </div>
@@ -23,7 +23,7 @@
23
23
  </li>
24
24
  <li class="nav-item">
25
25
  <%= link_to batches_path, class: ["nav-link", ("active" if controller_name == 'batches')] do %>
26
- <%=t ".batches" %>
26
+ <%= t ".batches" %>
27
27
  <span data-async-values-target="value" data-async-values-key="batches_count" class="badge bg-secondary rounded-pill d-none"></span>
28
28
  <% end %>
29
29
  </li>
@@ -5,7 +5,7 @@
5
5
  </div>
6
6
  <div class="flex-fill text-end">
7
7
  <% last_updated_at = Time.current.utc.iso8601 %>
8
- <%= t(".last_updated") %>&nbsp;<time id="page-updated-at" datetime="<%= last_updated_at %>"><%== last_updated_at %></time>
8
+ <%= t(".last_updated") %>&nbsp;<time id="page-updated-at" datetime="<%= last_updated_at %>"><%= last_updated_at %></time>
9
9
  </div>
10
10
  </div>
11
11
  </nav>
@@ -12,13 +12,13 @@
12
12
  to reduce potential screen flickering during reloading of your site."
13
13
  https://getbootstrap.com/docs/5.3/customize/color-modes/#javascript
14
14
  %>
15
- <%= tag.script "", nonce: content_security_policy_nonce do %>
15
+ <script nonce="<%= content_security_policy_nonce %>">
16
16
  let theme = localStorage.getItem('good_job-theme');
17
17
  if (!["light", "dark"].includes(theme)) {
18
18
  theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
19
19
  }
20
20
  document.documentElement.setAttribute('data-bs-theme', theme);
21
- <% end %>
21
+ </script>
22
22
 
23
23
  <%# Do not use asset tag helpers to avoid paths being overriden by config.asset_host %>
24
24
  <%= tag.link rel: "stylesheet", href: frontend_static_path(:bootstrap, format: :css, v: GoodJob::VERSION, locale: nil), nonce: content_security_policy_nonce %>
@@ -6,7 +6,7 @@ module GoodJob
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  def batch
9
- @_batch ||= CurrentThread.execution&.batch&.to_batch
9
+ @_batch ||= CurrentThread.execution&.batch&.to_batch if CurrentThread.execution.present? && CurrentThread.execution.active_job_id == job_id
10
10
  end
11
11
  alias batch? batch
12
12
  end
@@ -75,7 +75,7 @@ module GoodJob
75
75
  key = job.good_job_concurrency_key
76
76
  next if key.blank?
77
77
 
78
- if CurrentThread.execution.blank?
78
+ if CurrentThread.execution.blank? || CurrentThread.execution.active_job_id != job_id
79
79
  logger.debug("Ignoring concurrency limits because the job is executed with `perform_now`.")
80
80
  next
81
81
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module GoodJob
4
4
  # GoodJob gem version.
5
- VERSION = '3.28.0'
5
+ VERSION = '3.28.1'
6
6
 
7
7
  # GoodJob version as Gem::Version object
8
8
  GEM_VERSION = Gem::Version.new(VERSION)
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.28.0
4
+ version: 3.28.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: 2024-04-19 00:00:00.000000000 Z
11
+ date: 2024-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob
@@ -431,7 +431,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
431
431
  - !ruby/object:Gem::Version
432
432
  version: '0'
433
433
  requirements: []
434
- rubygems_version: 3.5.4
434
+ rubygems_version: 3.5.9
435
435
  signing_key:
436
436
  specification_version: 4
437
437
  summary: A multithreaded, Postgres-based ActiveJob backend for Ruby on Rails