good_job 1.3.5 → 1.3.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -5
- data/engine/app/controllers/good_job/dashboards_controller.rb +2 -2
- data/engine/app/views/good_job/dashboards/index.html.erb +19 -7
- data/engine/app/views/layouts/good_job/base.html.erb +5 -5
- data/engine/app/views/shared/_chart.erb +1 -1
- data/engine/app/views/shared/_jobs_table.erb +27 -25
- data/lib/good_job/configuration.rb +1 -3
- data/lib/good_job/job.rb +7 -1
- data/lib/good_job/lockable.rb +27 -9
- data/lib/good_job/log_subscriber.rb +7 -7
- data/lib/good_job/notifier.rb +19 -14
- data/lib/good_job/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b5d625792328475faca2679c6718f344fc5162cac639be09f91197c998f2fdf
|
4
|
+
data.tar.gz: 4aef2c4ae814f2a0606c18e875c91e56f8a1411394c37d45f4e1141be719f080
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d309e288c89c65ec809cf7f9e138026b229aed9abb6ee667343c56ed1e96fb0833be36b7e1f1c6b064168957f537d572e2ceb5ecad0f6e754108762ace9fbd3b
|
7
|
+
data.tar.gz: c1b83122c14edcbe619c6198fae270f9dbb0398888232f96e8956be23ca0f5798422181a21ea08735a0089ad3a92c0405ee69731a8a205f3fe9c99ba2b27bb36
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,37 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v1.3.6](https://github.com/bensheldon/good_job/tree/v1.3.6) (2020-12-30)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.3.5...v1.3.6)
|
6
|
+
|
7
|
+
**Implemented enhancements:**
|
8
|
+
|
9
|
+
- Call GoodJob.on\_thread\_error when Notifier thread raises exception [\#185](https://github.com/bensheldon/good_job/pull/185) ([bensheldon](https://github.com/bensheldon))
|
10
|
+
- Improve dashboard UI, fix button state, add unfiltering [\#181](https://github.com/bensheldon/good_job/pull/181) ([bensheldon](https://github.com/bensheldon))
|
11
|
+
|
12
|
+
**Fixed bugs:**
|
13
|
+
|
14
|
+
- Replace ActiveRecord execute usage and avoid potential memory leakage [\#187](https://github.com/bensheldon/good_job/issues/187)
|
15
|
+
- Does good\_job hold on to advisory locks for finished jobs? [\#177](https://github.com/bensheldon/good_job/issues/177)
|
16
|
+
|
17
|
+
**Merged pull requests:**
|
18
|
+
|
19
|
+
- Run tests with Rails default configuration to enable Zeitwerk [\#190](https://github.com/bensheldon/good_job/pull/190) ([bensheldon](https://github.com/bensheldon))
|
20
|
+
- Update all Lockable queries to use exec\_query instead of execute; clear async\_exec results [\#189](https://github.com/bensheldon/good_job/pull/189) ([bensheldon](https://github.com/bensheldon))
|
21
|
+
- Have Lockable\#advisory\_locked? directly query pg\_locks table [\#188](https://github.com/bensheldon/good_job/pull/188) ([bensheldon](https://github.com/bensheldon))
|
22
|
+
- Update development gems, including Rails v6.1 and Rails HEAD [\#186](https://github.com/bensheldon/good_job/pull/186) ([bensheldon](https://github.com/bensheldon))
|
23
|
+
- Update Appraisals for Rails 6.1 [\#183](https://github.com/bensheldon/good_job/pull/183) ([bensheldon](https://github.com/bensheldon))
|
24
|
+
- Add Ruby 3 to CI test matrix [\#182](https://github.com/bensheldon/good_job/pull/182) ([bensheldon](https://github.com/bensheldon))
|
25
|
+
|
3
26
|
## [v1.3.5](https://github.com/bensheldon/good_job/tree/v1.3.5) (2020-12-17)
|
4
27
|
|
5
28
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.3.4...v1.3.5)
|
6
29
|
|
30
|
+
**Fixed bugs:**
|
31
|
+
|
32
|
+
- Ensure advisory lock CTE is MATERIALIZED on Postgres v12+ [\#179](https://github.com/bensheldon/good_job/pull/179) ([bensheldon](https://github.com/bensheldon))
|
33
|
+
- Ensure that deleted jobs are unlocked [\#178](https://github.com/bensheldon/good_job/pull/178) ([bensheldon](https://github.com/bensheldon))
|
34
|
+
|
7
35
|
**Closed issues:**
|
8
36
|
|
9
37
|
- not running jobs [\#168](https://github.com/bensheldon/good_job/issues/168)
|
@@ -11,15 +39,13 @@
|
|
11
39
|
|
12
40
|
**Merged pull requests:**
|
13
41
|
|
14
|
-
- Ensure advisory lock CTE is MATERIALIZED on Postgres v12+ [\#179](https://github.com/bensheldon/good_job/pull/179) ([bensheldon](https://github.com/bensheldon))
|
15
|
-
- Ensure that deleted jobs are unlocked [\#178](https://github.com/bensheldon/good_job/pull/178) ([bensheldon](https://github.com/bensheldon))
|
16
42
|
- Add Appraisal for Rails 6.1-rc2 [\#175](https://github.com/bensheldon/good_job/pull/175) ([bensheldon](https://github.com/bensheldon))
|
17
43
|
|
18
44
|
## [v1.3.4](https://github.com/bensheldon/good_job/tree/v1.3.4) (2020-12-02)
|
19
45
|
|
20
46
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.3.3...v1.3.4)
|
21
47
|
|
22
|
-
**
|
48
|
+
**Fixed bugs:**
|
23
49
|
|
24
50
|
- Fix job ordering for Rails 6.1 [\#174](https://github.com/bensheldon/good_job/pull/174) ([morgoth](https://github.com/morgoth))
|
25
51
|
|
@@ -27,7 +53,7 @@
|
|
27
53
|
|
28
54
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.3.2...v1.3.3)
|
29
55
|
|
30
|
-
**
|
56
|
+
**Implemented enhancements:**
|
31
57
|
|
32
58
|
- UI: Admin UI with filters and space efficient layout [\#173](https://github.com/bensheldon/good_job/pull/173) ([zealot128](https://github.com/zealot128))
|
33
59
|
|
@@ -428,6 +454,7 @@
|
|
428
454
|
**Merged pull requests:**
|
429
455
|
|
430
456
|
- Improve ActiveRecord usage for advisory locking [\#24](https://github.com/bensheldon/good_job/pull/24) ([bensheldon](https://github.com/bensheldon))
|
457
|
+
- Remove support for Rails 5.1 [\#23](https://github.com/bensheldon/good_job/pull/23) ([bensheldon](https://github.com/bensheldon))
|
431
458
|
|
432
459
|
## [v0.3.0](https://github.com/bensheldon/good_job/tree/v0.3.0) (2020-03-22)
|
433
460
|
|
@@ -446,7 +473,6 @@
|
|
446
473
|
|
447
474
|
**Merged pull requests:**
|
448
475
|
|
449
|
-
- Remove support for Rails 5.1 [\#23](https://github.com/bensheldon/good_job/pull/23) ([bensheldon](https://github.com/bensheldon))
|
450
476
|
- Gracefully shutdown Scheduler when executable receives TERM or INT [\#17](https://github.com/bensheldon/good_job/pull/17) ([bensheldon](https://github.com/bensheldon))
|
451
477
|
- Update Appraisals [\#16](https://github.com/bensheldon/good_job/pull/16) ([bensheldon](https://github.com/bensheldon))
|
452
478
|
|
@@ -42,11 +42,11 @@ module GoodJob
|
|
42
42
|
GoodJob::Job.group("serialized_params->>'job_class'").count
|
43
43
|
end
|
44
44
|
|
45
|
-
def
|
45
|
+
def to_params(override)
|
46
46
|
{
|
47
47
|
state: params[:state],
|
48
48
|
job_class: params[:job_class],
|
49
|
-
}.merge(override).delete_if { |_, v| v.nil? }
|
49
|
+
}.merge(override).delete_if { |_, v| v.nil? }
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -8,18 +8,30 @@
|
|
8
8
|
<small>Filter by job class</small>
|
9
9
|
<br>
|
10
10
|
<% @filter.job_classes.each do |name, count| %>
|
11
|
-
|
12
|
-
<%=
|
13
|
-
|
11
|
+
<% if params[:job_class] == name %>
|
12
|
+
<%= link_to(root_path(@filter.to_params(job_class: nil)), class: 'btn btn-sm btn-outline-secondary active', role: "button", "aria-pressed": true) do %>
|
13
|
+
<%= name %> (<%= count %>)
|
14
|
+
<% end %>
|
15
|
+
<% else %>
|
16
|
+
<%= link_to(root_path(@filter.to_params(job_class: name)), class: 'btn btn-sm btn-outline-secondary', role: "button") do %>
|
17
|
+
<%= name %> (<%= count %>)
|
18
|
+
<% end %>
|
19
|
+
<% end %>
|
14
20
|
<% end %>
|
15
21
|
</div>
|
16
22
|
<div>
|
17
23
|
<small>Filter by state</small>
|
18
24
|
<br>
|
19
25
|
<% @filter.states.each do |name, count| %>
|
20
|
-
|
21
|
-
<%=
|
22
|
-
|
26
|
+
<% if params[:state] == name %>
|
27
|
+
<%= link_to(root_path(@filter.to_params(state: nil)), class: 'btn btn-sm btn-outline-secondary active', role: "button", "aria-pressed": true) do %>
|
28
|
+
<%= name %> (<%= count %>)
|
29
|
+
<% end %>
|
30
|
+
<% else %>
|
31
|
+
<%= link_to(root_path(@filter.to_params(state: name)), class: 'btn btn-sm btn-outline-secondary', role: "button") do %>
|
32
|
+
<%= name %> (<%= count %>)
|
33
|
+
<% end %>
|
34
|
+
<% end %>
|
23
35
|
<% end %>
|
24
36
|
</div>
|
25
37
|
</div>
|
@@ -28,7 +40,7 @@
|
|
28
40
|
<% if @filter.jobs.present? %>
|
29
41
|
<%= render 'shared/jobs_table', jobs: @filter.jobs %>
|
30
42
|
|
31
|
-
<nav aria-label="Job pagination">
|
43
|
+
<nav aria-label="Job pagination" class="mt-3">
|
32
44
|
<ul class="pagination">
|
33
45
|
<li class="page-item">
|
34
46
|
<%= link_to({ after_scheduled_at: (@filter.last.scheduled_at || @filter.last.created_at), after_id: @filter.last.id }, class: "page-link") do %>
|
@@ -6,14 +6,14 @@
|
|
6
6
|
<%= csp_meta_tag %>
|
7
7
|
|
8
8
|
<style>
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
<%== render file: GoodJob::Engine.root.join("app", "assets", "vendor", "bootstrap", "bootstrap.css") %>
|
10
|
+
<%== render file: GoodJob::Engine.root.join("app", "assets", "vendor", "chartist", "chartist.css") %>
|
11
|
+
<%== render file: GoodJob::Engine.root.join("app", "assets", "style.css") %>
|
12
12
|
</style>
|
13
13
|
|
14
14
|
<script>
|
15
|
-
|
16
|
-
|
15
|
+
<%== render file: GoodJob::Engine.root.join("app", "assets", "vendor", "bootstrap", "bootstrap-native.js") %>
|
16
|
+
<%== render file: GoodJob::Engine.root.join("app", "assets", "vendor", "chartist", "chartist.js") %>
|
17
17
|
</script>
|
18
18
|
</head>
|
19
19
|
<body>
|
@@ -1,26 +1,28 @@
|
|
1
|
-
<div class="
|
2
|
-
<
|
3
|
-
<
|
4
|
-
<
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
<
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
1
|
+
<div class="card my-3">
|
2
|
+
<div class="table-responsive">
|
3
|
+
<table class="table card-table table-bordered table-hover table-sm mb-0">
|
4
|
+
<thead>
|
5
|
+
<th>GoodJob ID</th>
|
6
|
+
<th>ActiveJob ID</th>
|
7
|
+
<th>Job Class</th>
|
8
|
+
<th>Queue</th>
|
9
|
+
<th>Scheduled At</th>
|
10
|
+
<th>Error</th>
|
11
|
+
<th>ActiveJob Params</th>
|
12
|
+
</thead>
|
13
|
+
<tbody>
|
14
|
+
<% jobs.each do |job| %>
|
15
|
+
<tr id="<%= dom_id(job) %>">
|
16
|
+
<td><%= link_to job.id, active_job_path(job.serialized_params['job_id'], anchor: dom_id(job)) %></td>
|
17
|
+
<td><%= link_to job.serialized_params['job_id'], active_job_path(job.serialized_params['job_id']) %></td>
|
18
|
+
<td><%= job.serialized_params['job_class'] %></td>
|
19
|
+
<td><%= job.queue_name %></td>
|
20
|
+
<td><%= job.scheduled_at || job.created_at %></td>
|
21
|
+
<td><%= job.error %></td>
|
22
|
+
<td><pre><%= JSON.pretty_generate(job.serialized_params) %></pre></td>
|
23
|
+
</tr>
|
24
|
+
<% end %>
|
25
|
+
</tbody>
|
26
|
+
</table>
|
27
|
+
</div>
|
26
28
|
</div>
|
data/lib/good_job/job.rb
CHANGED
@@ -139,7 +139,7 @@ module GoodJob
|
|
139
139
|
unfinished.priority_ordered.only_scheduled.limit(1).with_advisory_lock do |good_jobs|
|
140
140
|
good_job = good_jobs.first
|
141
141
|
# TODO: Determine why some records are fetched without an advisory lock at all
|
142
|
-
break unless good_job&.
|
142
|
+
break unless good_job&.executable?
|
143
143
|
|
144
144
|
result, error = good_job.perform
|
145
145
|
end
|
@@ -216,6 +216,12 @@ module GoodJob
|
|
216
216
|
[result, job_error]
|
217
217
|
end
|
218
218
|
|
219
|
+
# Tests whether this job is safe to be executed by this thread.
|
220
|
+
# @return [Boolean]
|
221
|
+
def executable?
|
222
|
+
self.class.unscoped.unfinished.owns_advisory_locked.exists?(id: id)
|
223
|
+
end
|
224
|
+
|
219
225
|
private
|
220
226
|
|
221
227
|
def execute
|
data/lib/good_job/lockable.rb
CHANGED
@@ -141,9 +141,9 @@ module GoodJob
|
|
141
141
|
end
|
142
142
|
|
143
143
|
def supports_cte_materialization_specifiers?
|
144
|
-
return @
|
144
|
+
return @_supports_cte_materialization_specifiers if defined?(@_supports_cte_materialization_specifiers)
|
145
145
|
|
146
|
-
@
|
146
|
+
@_supports_cte_materialization_specifiers = ActiveRecord::Base.connection.postgresql_version >= 120000
|
147
147
|
end
|
148
148
|
end
|
149
149
|
|
@@ -153,10 +153,11 @@ module GoodJob
|
|
153
153
|
# all remaining locks).
|
154
154
|
# @return [Boolean] whether the lock was acquired.
|
155
155
|
def advisory_lock
|
156
|
-
|
157
|
-
|
156
|
+
query = <<~SQL.squish
|
157
|
+
SELECT 1 AS one
|
158
|
+
WHERE pg_try_advisory_lock(('x'||substr(md5($1 || $2::text), 1, 16))::bit(64)::bigint)
|
158
159
|
SQL
|
159
|
-
self.class.
|
160
|
+
self.class.connection.exec_query(query, 'GoodJob::Lockable Advisory Lock', [[nil, self.class.table_name], [nil, send(self.class.primary_key)]]).any?
|
160
161
|
end
|
161
162
|
|
162
163
|
# Releases an advisory lock on this record if it is locked by this database
|
@@ -166,9 +167,9 @@ module GoodJob
|
|
166
167
|
def advisory_unlock
|
167
168
|
query = <<~SQL.squish
|
168
169
|
SELECT 1 AS one
|
169
|
-
WHERE pg_advisory_unlock(('x'||substr(md5(
|
170
|
+
WHERE pg_advisory_unlock(('x'||substr(md5($1 || $2::text), 1, 16))::bit(64)::bigint)
|
170
171
|
SQL
|
171
|
-
self.class.connection.
|
172
|
+
self.class.connection.exec_query(query, 'GoodJob::Lockable Advisory Unlock', [[nil, self.class.table_name], [nil, send(self.class.primary_key)]]).any?
|
172
173
|
end
|
173
174
|
|
174
175
|
# Acquires an advisory lock on this record or raises
|
@@ -205,13 +206,30 @@ module GoodJob
|
|
205
206
|
# Tests whether this record has an advisory lock on it.
|
206
207
|
# @return [Boolean]
|
207
208
|
def advisory_locked?
|
208
|
-
|
209
|
+
query = <<~SQL.squish
|
210
|
+
SELECT 1 AS one
|
211
|
+
FROM pg_locks
|
212
|
+
WHERE pg_locks.locktype = 'advisory'
|
213
|
+
AND pg_locks.objsubid = 1
|
214
|
+
AND pg_locks.classid = ('x' || substr(md5($1 || $2::text), 1, 16))::bit(32)::int
|
215
|
+
AND pg_locks.objid = (('x' || substr(md5($1 || $2::text), 1, 16))::bit(64) << 32)::bit(32)::int
|
216
|
+
SQL
|
217
|
+
self.class.connection.exec_query(query, 'GoodJob::Lockable Advisory Locked?', [[nil, self.class.table_name], [nil, send(self.class.primary_key)]]).any?
|
209
218
|
end
|
210
219
|
|
211
220
|
# Tests whether this record is locked by the current database session.
|
212
221
|
# @return [Boolean]
|
213
222
|
def owns_advisory_lock?
|
214
|
-
|
223
|
+
query = <<~SQL.squish
|
224
|
+
SELECT 1 AS one
|
225
|
+
FROM pg_locks
|
226
|
+
WHERE pg_locks.locktype = 'advisory'
|
227
|
+
AND pg_locks.objsubid = 1
|
228
|
+
AND pg_locks.classid = ('x' || substr(md5($1 || $2::text), 1, 16))::bit(32)::int
|
229
|
+
AND pg_locks.objid = (('x' || substr(md5($1 || $2::text), 1, 16))::bit(64) << 32)::bit(32)::int
|
230
|
+
AND pg_locks.pid = pg_backend_pid()
|
231
|
+
SQL
|
232
|
+
self.class.connection.exec_query(query, 'GoodJob::Lockable Owns Advisory Lock?', [[nil, self.class.table_name], [nil, send(self.class.primary_key)]]).any?
|
215
233
|
end
|
216
234
|
|
217
235
|
# Releases all advisory locks on the record that are held by the current
|
@@ -218,13 +218,13 @@ module GoodJob
|
|
218
218
|
#
|
219
219
|
%w(info debug warn error fatal unknown).each do |level|
|
220
220
|
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
221
|
-
def #{level}(progname = nil, tags: [], &block)
|
222
|
-
return unless logger
|
223
|
-
|
224
|
-
tag_logger(*tags) do
|
225
|
-
logger.#{level}(progname, &block)
|
226
|
-
end
|
227
|
-
end
|
221
|
+
def #{level}(progname = nil, tags: [], &block) # def info(progname = nil, tags: [], &block)
|
222
|
+
return unless logger # return unless logger
|
223
|
+
#
|
224
|
+
tag_logger(*tags) do # tag_logger(*tags) do
|
225
|
+
logger.#{level}(progname, &block) # logger.info(progname, &block)
|
226
|
+
end # end
|
227
|
+
end #
|
228
228
|
METHOD
|
229
229
|
end
|
230
230
|
end
|
data/lib/good_job/notifier.rb
CHANGED
@@ -90,6 +90,18 @@ module GoodJob # :nodoc:
|
|
90
90
|
!@pool.running?
|
91
91
|
end
|
92
92
|
|
93
|
+
# Invoked on completion of ThreadPoolExecutor task
|
94
|
+
# @!visibility private
|
95
|
+
# @return [void]
|
96
|
+
def listen_observer(_time, _result, thread_error)
|
97
|
+
if thread_error
|
98
|
+
GoodJob.on_thread_error.call(thread_error) if GoodJob.on_thread_error.respond_to?(:call)
|
99
|
+
ActiveSupport::Notifications.instrument("notifier_notify_error.good_job", { error: thread_error })
|
100
|
+
end
|
101
|
+
|
102
|
+
listen unless shutdown?
|
103
|
+
end
|
104
|
+
|
93
105
|
private
|
94
106
|
|
95
107
|
def create_pool
|
@@ -100,7 +112,7 @@ module GoodJob # :nodoc:
|
|
100
112
|
future = Concurrent::Future.new(args: [@recipients, @pool, @listening], executor: @pool) do |recipients, pool, listening|
|
101
113
|
with_listen_connection do |conn|
|
102
114
|
ActiveSupport::Notifications.instrument("notifier_listen.good_job") do
|
103
|
-
conn.async_exec
|
115
|
+
conn.async_exec("LISTEN #{CHANNEL}").clear
|
104
116
|
end
|
105
117
|
|
106
118
|
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
|
@@ -120,14 +132,11 @@ module GoodJob # :nodoc:
|
|
120
132
|
listening.make_false
|
121
133
|
end
|
122
134
|
end
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
@listening.make_false
|
129
|
-
ActiveSupport::Notifications.instrument("notifier_unlisten.good_job") do
|
130
|
-
conn.async_exec "UNLISTEN *"
|
135
|
+
ensure
|
136
|
+
listening.make_false
|
137
|
+
ActiveSupport::Notifications.instrument("notifier_unlisten.good_job") do
|
138
|
+
conn.async_exec("UNLISTEN *").clear
|
139
|
+
end
|
131
140
|
end
|
132
141
|
end
|
133
142
|
|
@@ -135,16 +144,12 @@ module GoodJob # :nodoc:
|
|
135
144
|
future.execute
|
136
145
|
end
|
137
146
|
|
138
|
-
def listen_observer(_time, _result, _thread_error)
|
139
|
-
listen unless shutdown?
|
140
|
-
end
|
141
|
-
|
142
147
|
def with_listen_connection
|
143
148
|
ar_conn = ActiveRecord::Base.connection_pool.checkout.tap do |conn|
|
144
149
|
ActiveRecord::Base.connection_pool.remove(conn)
|
145
150
|
end
|
146
151
|
pg_conn = ar_conn.raw_connection
|
147
|
-
pg_conn.
|
152
|
+
pg_conn.async_exec("SET application_name = #{pg_conn.escape_identifier(self.class.name)}").clear
|
148
153
|
yield pg_conn
|
149
154
|
ensure
|
150
155
|
ar_conn&.disconnect!
|
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: 1.3.
|
4
|
+
version: 1.3.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Sheldon
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-12-
|
11
|
+
date: 2020-12-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|
@@ -441,7 +441,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
441
441
|
- !ruby/object:Gem::Version
|
442
442
|
version: '0'
|
443
443
|
requirements: []
|
444
|
-
rubygems_version: 3.
|
444
|
+
rubygems_version: 3.2.3
|
445
445
|
signing_key:
|
446
446
|
specification_version: 4
|
447
447
|
summary: A multithreaded, Postgres-based ActiveJob backend for Ruby on Rails
|