que-web 0.7.2 → 0.8.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 +5 -5
- data/CHANGELOG.md +6 -0
- data/lib/que/web.rb +6 -9
- data/lib/que/web/sql.rb +14 -14
- data/lib/que/web/viewmodels/dashboard.rb +1 -1
- data/lib/que/web/viewmodels/job.rb +4 -5
- data/que-web.gemspec +4 -4
- data/spec/viewmodels/dashboard_spec.rb +4 -4
- data/spec/viewmodels/job_list_spec.rb +7 -6
- data/spec/viewmodels/job_spec.rb +9 -8
- data/spec/web_spec.rb +7 -7
- data/web/views/_navbar.erb +1 -1
- data/web/views/_search.erb +1 -1
- data/web/views/failing.erb +3 -3
- data/web/views/running.erb +1 -1
- data/web/views/scheduled.erb +3 -3
- data/web/views/show.erb +7 -4
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 47ad5fd3031d35ffde2d864982d7f7d044b3fd2bc193f8922a9bad7ab71784a6
|
4
|
+
data.tar.gz: eca71d27a53c880ba3b1d7fd389556d675badf38b5e91631dff93e1f17eb7652
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5e19332be846121014c41f85fb5d86bb5bb672745f136e2e9e5bfd75c36a5c39bbfe68711f8b51e8c7db578adfd1106f4a415acf76f5387e7f4421de4ead8b5
|
7
|
+
data.tar.gz: c0511bdd77dfad2284ee0781b52e51392df33dd62856ccd99b27beb09360430abb6df9ce92ea5a2e44df5477b1d2b2032bcb6d8a3f346b3ddb7e75d91719c350
|
data/CHANGELOG.md
CHANGED
data/lib/que/web.rb
CHANGED
@@ -20,7 +20,7 @@ module Que
|
|
20
20
|
end
|
21
21
|
|
22
22
|
get "/running" do
|
23
|
-
worker_states = search_running Que.
|
23
|
+
worker_states = search_running Que.job_states
|
24
24
|
pager = get_pager worker_states.count
|
25
25
|
@list = Viewmodels::JobList.new(worker_states, pager)
|
26
26
|
erb :running
|
@@ -28,7 +28,7 @@ module Que
|
|
28
28
|
|
29
29
|
get "/failing" do
|
30
30
|
stats = Que.execute SQL[:dashboard_stats], [search]
|
31
|
-
pager = get_pager stats[0][
|
31
|
+
pager = get_pager stats[0][:failing]
|
32
32
|
failing_jobs = Que.execute SQL[:failing_jobs], [pager.page_size, pager.offset, search]
|
33
33
|
@list = Viewmodels::JobList.new(failing_jobs, pager)
|
34
34
|
erb :failing
|
@@ -36,9 +36,8 @@ module Que
|
|
36
36
|
|
37
37
|
get "/scheduled" do
|
38
38
|
stats = Que.execute SQL[:dashboard_stats], [search]
|
39
|
-
pager = get_pager stats[0][
|
39
|
+
pager = get_pager stats[0][:scheduled]
|
40
40
|
scheduled_jobs = Que.execute SQL[:scheduled_jobs], [pager.page_size, pager.offset, search]
|
41
|
-
|
42
41
|
@list = Viewmodels::JobList.new(scheduled_jobs, pager)
|
43
42
|
erb :scheduled
|
44
43
|
end
|
@@ -62,9 +61,7 @@ module Que
|
|
62
61
|
job_id = id.to_i
|
63
62
|
if job_id > 0
|
64
63
|
run_at = Time.now
|
65
|
-
|
66
64
|
updated_rows = Que.execute SQL[:reschedule_job], [job_id, run_at]
|
67
|
-
|
68
65
|
if updated_rows.empty?
|
69
66
|
# Didn't get the advisory lock
|
70
67
|
set_flash "warning", "Job #{job_id} not rescheduled as it was already runnning"
|
@@ -163,7 +160,7 @@ module Que
|
|
163
160
|
|
164
161
|
def search_running(jobs)
|
165
162
|
return jobs unless search_param
|
166
|
-
jobs.select { |job| job.fetch(
|
163
|
+
jobs.select { |job| job.fetch(:job_class).include? search_param }
|
167
164
|
end
|
168
165
|
|
169
166
|
def search_param
|
@@ -183,8 +180,8 @@ module Que
|
|
183
180
|
end
|
184
181
|
|
185
182
|
def format_error(job)
|
186
|
-
return unless job.
|
187
|
-
line = job.
|
183
|
+
return unless job.last_error_message
|
184
|
+
line = job.last_error_message.lines.first || ''
|
188
185
|
truncate line, 30
|
189
186
|
end
|
190
187
|
|
data/lib/que/web/sql.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
lock_job_sql = <<-SQL.freeze
|
2
|
-
SELECT
|
2
|
+
SELECT id, pg_try_advisory_lock(id) AS locked
|
3
3
|
FROM que_jobs
|
4
|
-
WHERE
|
4
|
+
WHERE id = $1::bigint
|
5
5
|
SQL
|
6
6
|
|
7
7
|
lock_all_failing_jobs_sql = <<-SQL.freeze
|
8
|
-
SELECT
|
8
|
+
SELECT id, pg_try_advisory_lock(id) AS locked
|
9
9
|
FROM que_jobs
|
10
10
|
WHERE error_count > 0
|
11
11
|
SQL
|
12
12
|
|
13
13
|
lock_all_scheduled_jobs_sql = <<-SQL.freeze
|
14
|
-
SELECT
|
14
|
+
SELECT id, pg_try_advisory_lock(id) AS locked
|
15
15
|
FROM que_jobs
|
16
16
|
WHERE error_count = 0
|
17
17
|
SQL
|
@@ -23,8 +23,8 @@ def reschedule_all_jobs_query(scope)
|
|
23
23
|
SET run_at = $1::timestamptz
|
24
24
|
FROM target
|
25
25
|
WHERE target.locked
|
26
|
-
AND target.
|
27
|
-
RETURNING pg_advisory_unlock(target.
|
26
|
+
AND target.id = que_jobs.id
|
27
|
+
RETURNING pg_advisory_unlock(target.id)
|
28
28
|
SQL
|
29
29
|
end
|
30
30
|
|
@@ -34,8 +34,8 @@ def delete_jobs_query(scope)
|
|
34
34
|
DELETE FROM que_jobs
|
35
35
|
USING target
|
36
36
|
WHERE target.locked
|
37
|
-
AND target.
|
38
|
-
RETURNING pg_advisory_unlock(target.
|
37
|
+
AND target.id = que_jobs.id
|
38
|
+
RETURNING pg_advisory_unlock(target.id)
|
39
39
|
SQL
|
40
40
|
end
|
41
41
|
|
@@ -50,7 +50,7 @@ Que::Web::SQL = {
|
|
50
50
|
SELECT (classid::bigint << 32) + objid::bigint AS job_id
|
51
51
|
FROM pg_locks
|
52
52
|
WHERE locktype = 'advisory'
|
53
|
-
) locks
|
53
|
+
) locks ON (que_jobs.id=locks.job_id)
|
54
54
|
WHERE
|
55
55
|
job_class LIKE ($1)
|
56
56
|
SQL
|
@@ -61,7 +61,7 @@ Que::Web::SQL = {
|
|
61
61
|
SELECT (classid::bigint << 32) + objid::bigint AS job_id
|
62
62
|
FROM pg_locks
|
63
63
|
WHERE locktype = 'advisory'
|
64
|
-
) locks
|
64
|
+
) locks ON (que_jobs.id=locks.job_id)
|
65
65
|
WHERE locks.job_id IS NULL AND error_count > 0 AND job_class LIKE ($3)
|
66
66
|
ORDER BY run_at
|
67
67
|
LIMIT $1::int
|
@@ -74,7 +74,7 @@ Que::Web::SQL = {
|
|
74
74
|
SELECT (classid::bigint << 32) + objid::bigint AS job_id
|
75
75
|
FROM pg_locks
|
76
76
|
WHERE locktype = 'advisory'
|
77
|
-
) locks
|
77
|
+
) locks ON (que_jobs.id=locks.job_id)
|
78
78
|
WHERE locks.job_id IS NULL AND error_count = 0 AND job_class LIKE ($3)
|
79
79
|
ORDER BY run_at
|
80
80
|
LIMIT $1::int
|
@@ -89,15 +89,15 @@ Que::Web::SQL = {
|
|
89
89
|
SET run_at = $2::timestamptz
|
90
90
|
FROM target
|
91
91
|
WHERE target.locked
|
92
|
-
AND target.
|
93
|
-
RETURNING pg_advisory_unlock(target.
|
92
|
+
AND target.id = que_jobs.id
|
93
|
+
RETURNING pg_advisory_unlock(target.id)
|
94
94
|
SQL
|
95
95
|
reschedule_all_scheduled_jobs: reschedule_all_jobs_query(lock_all_scheduled_jobs_sql),
|
96
96
|
reschedule_all_failing_jobs: reschedule_all_jobs_query(lock_all_failing_jobs_sql),
|
97
97
|
fetch_job: <<-SQL.freeze,
|
98
98
|
SELECT *
|
99
99
|
FROM que_jobs
|
100
|
-
WHERE
|
100
|
+
WHERE id = $1::bigint
|
101
101
|
LIMIT 1
|
102
102
|
SQL
|
103
103
|
}.freeze
|
@@ -1,13 +1,12 @@
|
|
1
1
|
module Que::Web::Viewmodels
|
2
2
|
class Job < Struct.new(
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
:priority, :queue, :run_at)
|
3
|
+
:priority, :run_at, :id, :job_class, :error_count, :last_error_message,
|
4
|
+
:queue, :last_error_backtrace, :finished_at, :expired_at, :args, :data,
|
5
|
+
:backend_pid)
|
7
6
|
|
8
7
|
def initialize(job)
|
9
8
|
members.each do |m|
|
10
|
-
self[m] = job[m
|
9
|
+
self[m] = job[m]
|
11
10
|
end
|
12
11
|
end
|
13
12
|
|
data/que-web.gemspec
CHANGED
@@ -4,9 +4,9 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "que-web"
|
7
|
-
spec.version = "0.
|
8
|
-
spec.authors = ["Jason Staten"]
|
9
|
-
spec.email = ["jstaten07@gmail.com"]
|
7
|
+
spec.version = "0.8.0"
|
8
|
+
spec.authors = ["Jason Staten", "Bruno Porto"]
|
9
|
+
spec.email = ["jstaten07@gmail.com", "brunotporto@gmail.com"]
|
10
10
|
spec.summary = %q{A web interface for the que queue}
|
11
11
|
spec.description = %q{A web interface for the que queue}
|
12
12
|
spec.homepage = "https://github.com/statianzo/que-web"
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.add_dependency "que", "~> 0.
|
20
|
+
spec.add_dependency "que", "~> 1.0.0.beta3"
|
21
21
|
spec.add_dependency "sinatra"
|
22
22
|
spec.add_dependency "erubis"
|
23
23
|
|
@@ -3,10 +3,10 @@ require "spec_helper"
|
|
3
3
|
describe Que::Web::Viewmodels::Dashboard do
|
4
4
|
let(:dashboard_stats) {
|
5
5
|
{
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
total: 10,
|
7
|
+
running: 6,
|
8
|
+
failing: 2,
|
9
|
+
scheduled: 2
|
10
10
|
}
|
11
11
|
}
|
12
12
|
let(:subject) { Que::Web::Viewmodels::Dashboard.new(dashboard_stats) }
|
@@ -2,12 +2,13 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Que::Web::Viewmodels::JobList do
|
4
4
|
let(:job) {
|
5
|
-
{
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
{priority: 100, run_at: Time.now,
|
6
|
+
id: 555, job_class: "SuccessJob",
|
7
|
+
args: ["arg1", {name: "foo", age: 10}],
|
8
|
+
error_count: 0,
|
9
|
+
last_error_message: nil,
|
10
|
+
last_error_backtrace: nil,
|
11
|
+
queue: "foo"
|
11
12
|
}
|
12
13
|
}
|
13
14
|
let(:pager) { Que::Web::Pager.new(1,10,105) }
|
data/spec/viewmodels/job_spec.rb
CHANGED
@@ -2,19 +2,20 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Que::Web::Viewmodels::Job do
|
4
4
|
let(:source_job) {
|
5
|
-
{
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
{priority: 100, run_at: Time.now - 3600,
|
6
|
+
job_id: 555, job_class: "SuccessJob",
|
7
|
+
args: ["arg1", {name: "foo", age: 10}],
|
8
|
+
error_count: 0,
|
9
|
+
last_error_message: nil,
|
10
|
+
last_error_backtracd: nil,
|
11
|
+
queue: "foo"
|
11
12
|
}
|
12
13
|
}
|
13
14
|
let(:subject) { Que::Web::Viewmodels::Job.new(source_job) }
|
14
15
|
|
15
16
|
it 'maps fields from source' do
|
16
|
-
subject.priority.must_equal source_job[
|
17
|
-
subject.queue.must_equal source_job[
|
17
|
+
subject.priority.must_equal source_job[:priority]
|
18
|
+
subject.queue.must_equal source_job[:queue]
|
18
19
|
end
|
19
20
|
|
20
21
|
describe 'schedule' do
|
data/spec/web_spec.rb
CHANGED
@@ -16,7 +16,7 @@ describe Que::Web::Helpers do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def error_job(last_error)
|
19
|
-
Que::Web::Viewmodels::Job.new(
|
19
|
+
Que::Web::Viewmodels::Job.new(last_error_message: last_error)
|
20
20
|
end
|
21
21
|
|
22
22
|
describe '#format_error' do
|
@@ -36,10 +36,10 @@ describe Que::Web::Helpers do
|
|
36
36
|
describe '#search_running' do
|
37
37
|
let(:jobs) do
|
38
38
|
[
|
39
|
-
{
|
40
|
-
{
|
41
|
-
{
|
42
|
-
{
|
39
|
+
{ job_class: 'JobClassA' },
|
40
|
+
{ job_class: 'JobClassB' },
|
41
|
+
{ job_class: 'JobClassA2' },
|
42
|
+
{ job_class: 'JobClassC' }
|
43
43
|
]
|
44
44
|
end
|
45
45
|
|
@@ -65,8 +65,8 @@ describe Que::Web::Helpers do
|
|
65
65
|
it 'returns only the jobs whose class matches the search' do
|
66
66
|
subject.search_running(jobs).must_equal(
|
67
67
|
[
|
68
|
-
{
|
69
|
-
{
|
68
|
+
{ job_class: 'JobClassA' },
|
69
|
+
{ job_class: 'JobClassA2' }
|
70
70
|
]
|
71
71
|
)
|
72
72
|
end
|
data/web/views/_navbar.erb
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
<li class="<%= active_class('failing') %>"><a href="<%= link_to 'failing' %>"><span>Failing</span></a></li>
|
12
12
|
</ul>
|
13
13
|
<ul class="right version">
|
14
|
-
<li>Que <%= Que::
|
14
|
+
<li>Que <%= Que::VERSION %></li>
|
15
15
|
<li><%= Time.now.utc.strftime("%D %H:%M:%S %Z") %></li>
|
16
16
|
</ul>
|
17
17
|
</section>
|
data/web/views/_search.erb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
<form class="search" action="<%= request.path %>" method="get">
|
2
2
|
<div class="row collapse">
|
3
3
|
<div class="small-8 columns">
|
4
|
-
<input type="text" name="search" value="<%= search_param %>" />
|
4
|
+
<input type="text" name="search" value="<%= search_param %>", placeholder="Job Class Name" />
|
5
5
|
</div>
|
6
6
|
<div class="small-4 columns">
|
7
7
|
<button class="button postfix">Search</button>
|
data/web/views/failing.erb
CHANGED
@@ -24,7 +24,7 @@
|
|
24
24
|
<tbody>
|
25
25
|
<% @list.page_jobs.each do |job| %>
|
26
26
|
<tr>
|
27
|
-
<td><a href="<%= link_to "jobs/#{job.
|
27
|
+
<td><a href="<%= link_to "jobs/#{job.id}" %>">
|
28
28
|
<%== relative_time job.run_at %></a>
|
29
29
|
<%== erb :_past_due, locals: {job: job} %>
|
30
30
|
</td>
|
@@ -34,13 +34,13 @@
|
|
34
34
|
<td><pre><%= format_args job %></pre></td>
|
35
35
|
<td><%= format_error job %></pre></td>
|
36
36
|
<td>
|
37
|
-
<form action="<%= link_to "jobs/#{job.
|
37
|
+
<form action="<%= link_to "jobs/#{job.id}" %>" method="post">
|
38
38
|
<input type="hidden" name="_method" value="put" />
|
39
39
|
<button class="plain" title="Retry Immediately"><i class="fa fa-refresh"></i></button>
|
40
40
|
</form>
|
41
41
|
</td>
|
42
42
|
<td>
|
43
|
-
<form action="<%= link_to "jobs/#{job.
|
43
|
+
<form action="<%= link_to "jobs/#{job.id}" %>" method="post">
|
44
44
|
<input type="hidden" name="_method" value="delete" />
|
45
45
|
<button class="plain" title="Delete"><i class="fa fa-trash"></i></button>
|
46
46
|
</form>
|
data/web/views/running.erb
CHANGED
@@ -20,7 +20,7 @@
|
|
20
20
|
<tbody>
|
21
21
|
<% @list.page_jobs.each do |job| %>
|
22
22
|
<tr>
|
23
|
-
<td><%== relative_time job.
|
23
|
+
<td><%== relative_time job.run_at %></td>
|
24
24
|
<td><%= job.job_class %></td>
|
25
25
|
<td><%= job.queue %></td>
|
26
26
|
<td><pre><%= job.args.map(&:inspect).join(', ') %></pre></td>
|
data/web/views/scheduled.erb
CHANGED
@@ -23,20 +23,20 @@
|
|
23
23
|
<% @list.page_jobs.each do |job| %>
|
24
24
|
<tr>
|
25
25
|
<td>
|
26
|
-
<a href="<%= link_to "jobs/#{job.
|
26
|
+
<a href="<%= link_to "jobs/#{job.id}" %>"><%== relative_time job.run_at %></a>
|
27
27
|
<%== erb :_past_due, locals: {job: job}%>
|
28
28
|
</td>
|
29
29
|
<td><%= job.job_class %></td>
|
30
30
|
<td><%= job.queue %></td>
|
31
31
|
<td><pre><%= format_args job %></pre></td>
|
32
32
|
<td>
|
33
|
-
<form action="<%= link_to "jobs/#{job.
|
33
|
+
<form action="<%= link_to "jobs/#{job.id}" %>" method="post">
|
34
34
|
<input type="hidden" name="_method" value="put" />
|
35
35
|
<button class="plain" title="Run Immediately"><i class="fa fa-play-circle"></i></button>
|
36
36
|
</form>
|
37
37
|
</td>
|
38
38
|
<td>
|
39
|
-
<form action="<%= link_to "jobs/#{job.
|
39
|
+
<form action="<%= link_to "jobs/#{job.id}" %>" method="post">
|
40
40
|
<input type="hidden" name="_method" value="delete" />
|
41
41
|
<button class="plain" title="Delete"><i class="fa fa-trash"></i></button>
|
42
42
|
</form>
|
data/web/views/show.erb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="row">
|
2
2
|
<div class="small-12 columns">
|
3
|
-
<h1>Job <%= @job.
|
3
|
+
<h1>Job <%= @job.id %></h1>
|
4
4
|
</div>
|
5
5
|
</div>
|
6
6
|
<div class="row">
|
@@ -36,7 +36,10 @@
|
|
36
36
|
</tr>
|
37
37
|
<tr>
|
38
38
|
<th>Last Error</th>
|
39
|
-
<td
|
39
|
+
<td>
|
40
|
+
<pre><%= @job.last_error_message %></pre>
|
41
|
+
<pre><%= @job.last_error_backtrace %></pre>
|
42
|
+
</td>
|
40
43
|
</tr>
|
41
44
|
</tbody>
|
42
45
|
</table>
|
@@ -44,11 +47,11 @@
|
|
44
47
|
</div>
|
45
48
|
<div class="row">
|
46
49
|
<div class="small-12 columns">
|
47
|
-
<form class="form-inline" action="<%= link_to "/jobs/#{@job.
|
50
|
+
<form class="form-inline" action="<%= link_to "/jobs/#{@job.id}" %>" method="post">
|
48
51
|
<input type="hidden" name="_method" value="put" />
|
49
52
|
<button><i class="fa fa-play-circle"></i> Run Immediately</button>
|
50
53
|
</form>
|
51
|
-
<form class="form-inline" maction="<%= link_to "/jobs/#{@job.
|
54
|
+
<form class="form-inline" maction="<%= link_to "/jobs/#{@job.id}" %>" method="post">
|
52
55
|
<input type="hidden" name="_method" value="Delete" />
|
53
56
|
<button class="button alert"><i class="fa fa-trash"></i> Delete</button>
|
54
57
|
</form>
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: que-web
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Staten
|
8
|
+
- Bruno Porto
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2018-
|
12
|
+
date: 2018-10-24 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: que
|
@@ -16,14 +17,14 @@ dependencies:
|
|
16
17
|
requirements:
|
17
18
|
- - "~>"
|
18
19
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
20
|
+
version: 1.0.0.beta3
|
20
21
|
type: :runtime
|
21
22
|
prerelease: false
|
22
23
|
version_requirements: !ruby/object:Gem::Requirement
|
23
24
|
requirements:
|
24
25
|
- - "~>"
|
25
26
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
27
|
+
version: 1.0.0.beta3
|
27
28
|
- !ruby/object:Gem::Dependency
|
28
29
|
name: sinatra
|
29
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -97,6 +98,7 @@ dependencies:
|
|
97
98
|
description: A web interface for the que queue
|
98
99
|
email:
|
99
100
|
- jstaten07@gmail.com
|
101
|
+
- brunotporto@gmail.com
|
100
102
|
executables: []
|
101
103
|
extensions: []
|
102
104
|
extra_rdoc_files: []
|
@@ -178,7 +180,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
178
180
|
version: '0'
|
179
181
|
requirements: []
|
180
182
|
rubyforge_project:
|
181
|
-
rubygems_version: 2.6
|
183
|
+
rubygems_version: 2.7.6
|
182
184
|
signing_key:
|
183
185
|
specification_version: 4
|
184
186
|
summary: A web interface for the que queue
|