que-web 0.1.0 → 0.2.0

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
  SHA1:
3
- metadata.gz: d51e478e11b1c1e255dcc5ae5451d4a6b5e7475f
4
- data.tar.gz: 1e8ff161785552d15151a7d60dc76c270b55e873
3
+ metadata.gz: af7d992b8d986583e4673a431360507a4b9cf2f1
4
+ data.tar.gz: 3443eae0f23c8d246dc9fabad39fa3f9ac0b47d8
5
5
  SHA512:
6
- metadata.gz: e454491b1c4c596ab04d4157b4b97d5e0d94cd095d8c1a903e18e51a3ca0a37f0423bf08e635e2df3e3b5f6462639e0928842bf63a7c0d4da78c9253db086269
7
- data.tar.gz: 7cc37957dedac3a77fca6ab261fc96c3e0500f06bfea3c28494ada87078ad06bdc3b5dace98dafe190b3261e0bda820dd89b37de7f620d2098e3093b2533101e
6
+ metadata.gz: efaeba725f9552e3d69bfd9a538f5b4256496905fddb5513db980aba1c728a65b0172a3db16f4c41c792f2aca72e79763f066b16883aabe9f31df7d78fab6c8d
7
+ data.tar.gz: d8b54ec2bbb50f3d2741369f5c80ab6185404ffec06a31d6d2948bf4426fd97f11350a5ea86a268a28da6e751b239867c839edefc7e74be994e32643dd8d5248
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1
6
+ - jruby
7
+ notifications:
8
+ email: false
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # que-web
1
+ # que-web ![Travis](https://travis-ci.org/statianzo/que-web.svg)
2
2
 
3
3
  que-web is a web UI to the [Que](https://github.com/chanks/que) job queue.
4
4
 
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
1
  require "bundler/gem_tasks"
2
2
  require 'rake/testtask'
3
3
 
4
+ task :default => :test
5
+
4
6
  Rake::TestTask.new do |t|
5
7
  t.libs = ['spec', 'lib']
6
8
  t.pattern = 'spec/**/*_spec.rb'
@@ -33,6 +33,14 @@ map '/slow' do
33
33
  }
34
34
  end
35
35
 
36
+
37
+ map '/delayslow' do
38
+ run lambda { |env|
39
+ SlowJob.enqueue 'arg1', {name: 'delayslow', age: 20}, run_at: Time.now + 10
40
+ [200, {}, ['Failing job queued']]
41
+ }
42
+ end
43
+
36
44
  run lambda { |env|
37
45
  [200, {}, ['Hello']]
38
46
  }
@@ -0,0 +1,23 @@
1
+ class Que::Web::Pager
2
+ attr_reader :current_page, :page_size, :total, :page_count
3
+
4
+ def initialize(page_no, page_size, total)
5
+ @current_page = page_no > 1 ? page_no : 1
6
+ @page_size = page_size
7
+ @total = total
8
+
9
+ @page_count = total > 0 ? (total / page_size.to_f).ceil : 1
10
+ end
11
+
12
+ def next_page
13
+ @current_page < @page_count ? (@current_page + 1) : nil
14
+ end
15
+
16
+ def prev_page
17
+ @current_page > 1 ? (@current_page - 1) : nil
18
+ end
19
+
20
+ def offset
21
+ (@current_page - 1) * @page_size
22
+ end
23
+ end
@@ -0,0 +1,56 @@
1
+ Que::Web::SQL = {
2
+ :dashboard_stats => %{
3
+ SELECT count(*) AS total,
4
+ count(locks.job_id) AS running,
5
+ sum((error_count > 0 AND locks.job_id IS NULL)::int) AS failing,
6
+ sum((error_count = 0 AND locks.job_id IS NULL)::int) AS scheduled
7
+ FROM que_jobs
8
+ LEFT JOIN (
9
+ SELECT (classid::bigint << 32) + objid::bigint AS job_id
10
+ FROM pg_locks
11
+ WHERE locktype = 'advisory'
12
+ ) locks USING (job_id)
13
+ }.freeze,
14
+ :failing_jobs => %{
15
+ SELECT que_jobs.*
16
+ FROM que_jobs
17
+ LEFT JOIN (
18
+ SELECT (classid::bigint << 32) + objid::bigint AS job_id
19
+ FROM pg_locks
20
+ WHERE locktype = 'advisory'
21
+ ) locks USING (job_id)
22
+ WHERE locks.job_id IS NULL AND error_count > 0
23
+ ORDER BY run_at
24
+ LIMIT $1::int
25
+ OFFSET $2::int
26
+ }.freeze,
27
+ :scheduled_jobs => %{
28
+ SELECT que_jobs.*
29
+ FROM que_jobs
30
+ LEFT JOIN (
31
+ SELECT (classid::bigint << 32) + objid::bigint AS job_id
32
+ FROM pg_locks
33
+ WHERE locktype = 'advisory'
34
+ ) locks USING (job_id)
35
+ WHERE locks.job_id IS NULL AND error_count = 0
36
+ ORDER BY run_at
37
+ LIMIT $1::int
38
+ OFFSET $2::int
39
+ }.freeze,
40
+ :delete_job => %{
41
+ DELETE
42
+ FROM que_jobs
43
+ WHERE job_id = $1::bigint
44
+ }.freeze,
45
+ :reschedule_job => %{
46
+ UPDATE que_jobs
47
+ SET run_at = $2::timestamptz
48
+ WHERE job_id = $1::bigint
49
+ }.freeze,
50
+ :fetch_job => %{
51
+ SELECT *
52
+ FROM que_jobs
53
+ WHERE job_id = $1::bigint
54
+ LIMIT 1
55
+ }.freeze,
56
+ }.freeze
@@ -1,21 +1,9 @@
1
1
  module Que::Web::Viewmodels
2
- class Dashboard
3
- attr_reader :running, :scheduled, :failing
4
- def initialize(job_stats, failing_count)
5
- @running = calculate_running(job_stats)
6
- @scheduled = calculate_scheduled(job_stats)
7
- @failing = failing_count
8
- end
9
-
10
-
11
- private
12
-
13
- def calculate_running(job_stats)
14
- job_stats.map{|s| s["count_working"]}.reduce(0, :+)
15
- end
16
-
17
- def calculate_scheduled(job_stats)
18
- job_stats.map{|s| s["count"]}.reduce(0, :+)
2
+ class Dashboard < Struct.new(:running, :scheduled, :failing)
3
+ def initialize(stats)
4
+ members.each do |m|
5
+ self[m] = stats[m.to_s]
6
+ end
19
7
  end
20
8
  end
21
9
  end
@@ -1,6 +1,6 @@
1
1
  module Que::Web::Viewmodels
2
2
  class Job < Struct.new(
3
- :args, :error_count, :job_class, :job_id, :last_error, :last_error,
3
+ :args, :error_count, :job_class, :job_id, :last_error,
4
4
  :pg_backend_pid, :pg_last_query, :pg_last_query_started_at, :pg_state,
5
5
  :pg_state_changed_at, :pg_transaction_started_at, :pg_waiting_on_lock,
6
6
  :priority, :queue, :run_at)
@@ -1,29 +1,13 @@
1
1
  module Que::Web::Viewmodels
2
2
  class JobList
3
- PAGE_SIZE = 10
3
+ extend Forwardable
4
+ attr_reader :page_jobs, :pager
4
5
 
5
- attr_reader :page_jobs, :total, :page
6
+ def_delegators :@pager, :total, :next_page, :prev_page, :current_page, :page_count
6
7
 
7
- def initialize(page_jobs, total, page)
8
+ def initialize(page_jobs, pager)
8
9
  @page_jobs = page_jobs.map{|j| Job.new(j)}
9
- @total = total
10
- @page = page
11
- end
12
-
13
- def next_page
14
- page.succ
15
- end
16
-
17
- def prev_page
18
- page.pred
19
- end
20
-
21
- def has_next?
22
- @page_jobs.length >= PAGE_SIZE
23
- end
24
-
25
- def has_prev?
26
- @page > 0
10
+ @pager = pager
27
11
  end
28
12
  end
29
13
  end
data/lib/que/web.rb CHANGED
@@ -2,6 +2,9 @@ require "sinatra"
2
2
 
3
3
  module Que
4
4
  class Web < Sinatra::Base
5
+ VERSION = "0.2.0"
6
+ PAGE_SIZE = 10
7
+
5
8
  use Rack::MethodOverride
6
9
 
7
10
  set :root, File.expand_path("../../../web", __FILE__)
@@ -9,28 +12,73 @@ module Que
9
12
  set :views, proc { File.expand_path("views", root) }
10
13
 
11
14
  get "/" do
12
- job_stats = Que.job_stats
13
- failing_count = Que.execute("SELECT count(*) FROM que_jobs WHERE error_count > 0")[0]["count"]
14
- @dashboard = Viewmodels::Dashboard.new(job_stats, failing_count)
15
+ stats = Que.execute SQL[:dashboard_stats]
16
+ @dashboard = Viewmodels::Dashboard.new(stats[0])
15
17
  erb :index
16
18
  end
17
19
 
20
+ get "/running" do
21
+ worker_states = Que.worker_states
22
+ pager = get_pager worker_states.count
23
+ @list = Viewmodels::JobList.new(worker_states, pager)
24
+ erb :running
25
+ end
26
+
18
27
  get "/failing" do
19
- failing_count = Que.execute("SELECT count(*) FROM que_jobs WHERE error_count > 0")[0]["count"]
20
- failing_jobs = Que.execute("SELECT * FROM que_jobs WHERE error_count > 0")
21
- @list = Viewmodels::JobList.new(failing_jobs, failing_count, 0)
28
+ stats = Que.execute SQL[:dashboard_stats]
29
+ pager = get_pager stats[0]["failing"]
30
+ failing_jobs = Que.execute SQL[:failing_jobs], [pager.page_size, pager.offset]
31
+ @list = Viewmodels::JobList.new(failing_jobs, pager)
22
32
  erb :failing
23
33
  end
24
34
 
35
+ get "/scheduled" do
36
+ stats = Que.execute SQL[:dashboard_stats]
37
+ pager = get_pager stats[0]["scheduled"]
38
+ scheduled_jobs = Que.execute SQL[:scheduled_jobs], [pager.page_size, pager.offset]
39
+
40
+ @list = Viewmodels::JobList.new(scheduled_jobs, pager)
41
+ erb :scheduled
42
+ end
43
+
44
+ get "/jobs/:id" do |id|
45
+ job_id = id.to_i
46
+ jobs = []
47
+ if job_id > 0
48
+ jobs = Que.execute SQL[:fetch_job], [job_id]
49
+ end
50
+
51
+ if jobs.empty?
52
+ redirect to "", 303
53
+ else
54
+ @job = Viewmodels::Job.new(jobs.first)
55
+ erb :show
56
+ end
57
+ end
58
+
59
+ put "/jobs/:id" do |id|
60
+ job_id = id.to_i
61
+ if job_id > 0
62
+ Que.execute SQL[:reschedule_job], [job_id, Time.now]
63
+ end
64
+
65
+ redirect request.referrer, 303
66
+ end
67
+
25
68
  delete "/jobs/:id" do |id|
26
69
  job_id = id.to_i
27
70
  if job_id > 0
28
- Que.execute "DELETE FROM que_jobs WHERE job_id = $1::bigint", [job_id]
71
+ Que.execute SQL[:delete_job], [job_id]
29
72
  end
30
73
 
31
74
  redirect request.referrer, 303
32
75
  end
33
76
 
77
+ def get_pager(record_count)
78
+ page = (params[:page] || 1).to_i
79
+ Pager.new(page, PAGE_SIZE, record_count)
80
+ end
81
+
34
82
  helpers do
35
83
  def root_path
36
84
  "#{env['SCRIPT_NAME']}/"
@@ -46,3 +94,5 @@ module Que
46
94
  end
47
95
 
48
96
  require "que/web/viewmodels"
97
+ require "que/web/sql"
98
+ require "que/web/pager"
data/que-web.gemspec CHANGED
@@ -1,11 +1,10 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'que/web/version'
5
4
 
6
5
  Gem::Specification.new do |spec|
7
6
  spec.name = "que-web"
8
- spec.version = "0.1.0"
7
+ spec.version = "0.2.0"
9
8
  spec.authors = ["Jason Staten"]
10
9
  spec.email = ["jstaten07@gmail.com"]
11
10
  spec.summary = %q{A web interface for the que queue}
@@ -23,4 +22,5 @@ Gem::Specification.new do |spec|
23
22
 
24
23
  spec.add_development_dependency "bundler", "~> 1.6"
25
24
  spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "minitest", "~> 5.4"
26
26
  end
@@ -0,0 +1,53 @@
1
+ require "spec_helper"
2
+ require "que/web/pager"
3
+
4
+ describe Que::Web::Pager do
5
+ subject { Que::Web::Pager.new(4, 10, 105) }
6
+
7
+ it "provides passed values" do
8
+ subject.current_page.must_equal 4
9
+ subject.page_size.must_equal 10
10
+ subject.total.must_equal 105
11
+ end
12
+
13
+ it "provides a page count" do
14
+ subject.page_count.must_equal 11
15
+ end
16
+
17
+ it "defaults to page count of 1 if total is 0" do
18
+ pager = Que::Web::Pager.new(4, 10, 0)
19
+ pager.page_count.must_equal 1
20
+ end
21
+
22
+ it "increments next page if it exists" do
23
+ subject.next_page.must_equal 5
24
+ end
25
+
26
+ it "provides nil next page if on last page" do
27
+ pager = Que::Web::Pager.new(11, 10, 105)
28
+ pager.next_page.must_be_nil
29
+ end
30
+
31
+ it "decrements prev page if it exists" do
32
+ subject.prev_page.must_equal 3
33
+ end
34
+
35
+ it "provides nil prev page if on first page" do
36
+ pager = Que::Web::Pager.new(1, 10, 105)
37
+ pager.prev_page.must_be_nil
38
+ end
39
+
40
+ it "determines offset" do
41
+ subject.offset.must_equal 30
42
+ end
43
+
44
+ it "sets page_no less than 1 to 1 for current page" do
45
+ pager = Que::Web::Pager.new(-3, 10, 105)
46
+ pager.current_page.must_equal 1
47
+ end
48
+
49
+ it "provides range centering current page" do
50
+ pager = Que::Web::Pager.new(-3, 10, 105)
51
+ pager.current_page.must_equal 1
52
+ end
53
+ end
@@ -1,25 +1,17 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Que::Web::Viewmodels::Dashboard do
4
- let(:job_stats) {
5
- [
6
- {"queue"=>"", "job_class"=>"FailJob", "count"=>8, "count_working"=>0, "count_errored"=>8, "highest_error_count"=>11, "oldest_run_at"=> Time.new(2014,11,12,6,0,0)},
7
- {"queue"=>"", "job_class"=>"SuccessJob", "count"=>2, "count_working"=>2, "count_errored"=>2, "highest_error_count"=>0, "oldest_run_at"=> Time.new(2014,11,12,8,0,0)},
8
- {"queue"=>"", "job_class"=>"OtherJob", "count"=>7, "count_working"=>4, "count_errored"=>2, "highest_error_count"=>0, "oldest_run_at"=> Time.new(2014,11,12,9,0,0)}
9
- ]
4
+ let(:dashboard_stats) {
5
+ {
6
+ "total" => 10,
7
+ "running" => 6,
8
+ "failing" => 2,
9
+ "scheduled" => 2
10
+ }
10
11
  }
11
- let(:failing_count) { 7 }
12
- let(:subject) { Que::Web::Viewmodels::Dashboard.new(job_stats, failing_count) }
12
+ let(:subject) { Que::Web::Viewmodels::Dashboard.new(dashboard_stats) }
13
13
 
14
- it 'tallies running jobs' do
15
- subject.running.must_equal 6
16
- end
17
-
18
- it 'tallies scheduled jobs' do
19
- subject.scheduled.must_equal 17
20
- end
21
-
22
- it 'uses failing jobs' do
23
- subject.failing.must_equal failing_count
14
+ it 'passes through values' do
15
+ subject.scheduled.must_equal 2
24
16
  end
25
17
  end
@@ -10,40 +10,20 @@ describe Que::Web::Viewmodels::JobList do
10
10
  "queue"=>"foo"
11
11
  }
12
12
  }
13
- let(:subject) { Que::Web::Viewmodels::JobList.new([job], 1, 3) }
13
+ let(:pager) { Que::Web::Pager.new(1,10,105) }
14
+ let(:subject) { Que::Web::Viewmodels::JobList.new([job], pager) }
14
15
 
15
16
  it "maps jobs" do
16
17
  subject.page_jobs.length.must_equal 1
17
18
  subject.page_jobs.first.queue.must_equal "foo"
18
19
  end
19
20
 
20
- it "provides next page" do
21
- subject.next_page.must_equal 4
21
+ it "exposes pager" do
22
+ subject.pager.must_equal pager
22
23
  end
23
24
 
24
- it "provides prevous page" do
25
- subject.prev_page.must_equal 2
25
+ it "maps total from pager" do
26
+ subject.total.must_equal pager.total
26
27
  end
27
28
 
28
- it "has next when full page" do
29
- subject.page_jobs.concat [job] * 9
30
- subject.has_next?.must_equal true
31
- end
32
-
33
- it "does not have next not full page" do
34
- subject.has_next?.must_equal false
35
- end
36
-
37
- it "has prev page when greater than 0" do
38
- subject.has_prev?.must_equal true
39
- end
40
-
41
- it "does not have prev page when equal to 0" do
42
- list = subject.class.new([], 1, 0)
43
- list.has_prev?.must_equal false
44
- end
45
-
46
- it "does not have next not full page" do
47
- subject.has_next?.must_equal false
48
- end
49
29
  end
@@ -53,3 +53,6 @@ button.plain {
53
53
  color: inherit;
54
54
  font-weight: normal;
55
55
  }
56
+ .form-inline {
57
+ display: inline-block;
58
+ }
@@ -0,0 +1,15 @@
1
+ <% if @list.page_count > 1 %>
2
+ <ul class="pagination">
3
+ <% if @list.prev_page %>
4
+ <li class="arrow"><a href="<%= request.path %>?page=<%= @list.prev_page %>">&laquo; Previous</a></li>
5
+ <% else %>
6
+ <li class="arrow unavailable"><a disabled>&laquo; Previous</a></li>
7
+ <% end %>
8
+ <li class="unavailable"><a disabled>Page <%= @list.current_page %> of <%= @list.page_count %></a></li>
9
+ <% if @list.next_page %>
10
+ <li class="arrow"><a href="<%= request.path %>?page=<%= @list.next_page %>">Next &raquo;</a></li>
11
+ <% else %>
12
+ <li class="arrow unavailable"><a disabled>Next &raquo;</a></li>
13
+ <% end %>
14
+ </ul>
15
+ <% end %>
@@ -14,28 +14,38 @@
14
14
  <th>Queue</th>
15
15
  <th>Args</th>
16
16
  <th></th>
17
+ <th></th>
17
18
  </tr>
18
19
  </thead>
19
20
  <tbody>
20
21
  <% @list.page_jobs.each do |job| %>
21
22
  <tr>
22
- <td><%= job.run_at.utc %></td>
23
+ <td><a href="<%= to "jobs/#{job.job_id}" %>"><%= job.run_at.utc %></a></td>
23
24
  <td><%= job.error_count %></td>
24
25
  <td><%= job.job_class %></td>
25
26
  <td><%= job.queue %></td>
26
27
  <td><pre><%= job.args.map(&:inspect).join(', ') %></pre></td>
27
28
  <td>
28
- <form action="<%= to "/jobs/#{job.job_id}" %>" method="post">
29
+ <form action="<%= to "jobs/#{job.job_id}" %>" method="post">
30
+ <input type="hidden" name="_method" value="put" />
31
+ <button class="plain" title="Retry Immediately"><i class="fa fa-refresh"></i></button>
32
+ </form>
33
+ </td>
34
+ <td>
35
+ <form action="<%= to "jobs/#{job.job_id}" %>" method="post">
29
36
  <input type="hidden" name="_method" value="delete" />
30
- <input type="hidden" name="queue" value="<%= job.queue %>" />
31
- <input type="hidden" name="run_at" value="<%= job.run_at %>" />
32
- <input type="hidden" name="priority" value="<%= job.priority %>" />
33
- <button class="plain"><i class="fa fa-trash"></i></button>
37
+ <button class="plain" title="Delete"><i class="fa fa-trash"></i></button>
34
38
  </form>
35
39
  </td>
36
40
  </tr>
37
41
  <% end %>
38
42
  </tbody>
39
43
  </table>
44
+
45
+ </div>
46
+ </div>
47
+ <div class="row">
48
+ <div class="small-12 columns">
49
+ <%= erb :_pager %>
40
50
  </div>
41
51
  </div>
@@ -0,0 +1,29 @@
1
+ <div class="row">
2
+ <div class="small-12 columns">
3
+ <h1><%= @list.total %> Running Job<%= @list.total == 1 ? "" : "s" %></h1>
4
+ </div>
5
+ </div>
6
+ <div class="row">
7
+ <div class="small-12 columns">
8
+ <table>
9
+ <thead>
10
+ <tr>
11
+ <th>Started</th>
12
+ <th>Job</th>
13
+ <th>Queue</th>
14
+ <th>Args</th>
15
+ </tr>
16
+ </thead>
17
+ <tbody>
18
+ <% @list.page_jobs.each do |job| %>
19
+ <tr>
20
+ <td><%= job.pg_state_changed_at.utc %></td>
21
+ <td><%= job.job_class %></td>
22
+ <td><%= job.queue %></td>
23
+ <td><pre><%= job.args.map(&:inspect).join(', ') %></pre></td>
24
+ </tr>
25
+ <% end %>
26
+ </tbody>
27
+ </table>
28
+ </div>
29
+ </div>
@@ -0,0 +1,48 @@
1
+ <div class="row">
2
+ <div class="small-12 columns">
3
+ <h1><%= @list.total %> Scheduled Job<%= @list.total == 1 ? "" : "s" %></h1>
4
+ </div>
5
+ </div>
6
+ <div class="row">
7
+ <div class="small-12 columns">
8
+ <table>
9
+ <thead>
10
+ <tr>
11
+ <th>Run At</th>
12
+ <th>Job</th>
13
+ <th>Queue</th>
14
+ <th>Args</th>
15
+ <th></th>
16
+ <th></th>
17
+ </tr>
18
+ </thead>
19
+ <tbody>
20
+ <% @list.page_jobs.each do |job| %>
21
+ <tr>
22
+ <td><a href="<%= to "jobs/#{job.job_id}" %>"><%= job.run_at.utc %></a></td>
23
+ <td><%= job.job_class %></td>
24
+ <td><%= job.queue %></td>
25
+ <td><pre><%= job.args.map(&:inspect).join(', ') %></pre></td>
26
+ <td>
27
+ <form action="<%= to "jobs/#{job.job_id}" %>" method="post">
28
+ <input type="hidden" name="_method" value="put" />
29
+ <button class="plain" title="Run Immediately"><i class="fa fa-play-circle"></i></button>
30
+ </form>
31
+ </td>
32
+ <td>
33
+ <form action="<%= to "jobs/#{job.job_id}" %>" method="post">
34
+ <input type="hidden" name="_method" value="delete" />
35
+ <button class="plain" title="Delete"><i class="fa fa-trash"></i></button>
36
+ </form>
37
+ </td>
38
+ </tr>
39
+ <% end %>
40
+ </tbody>
41
+ </table>
42
+ </div>
43
+ </div>
44
+ <div class="row">
45
+ <div class="small-12 columns">
46
+ <%= erb :_pager %>
47
+ </div>
48
+ </div>
@@ -0,0 +1,53 @@
1
+ <div class="row">
2
+ <div class="small-12 columns">
3
+ <h1>Job <%= @job.job_id %></h1>
4
+ </div>
5
+ </div>
6
+ <div class="row">
7
+ <div class="small-12 columns">
8
+ <table>
9
+ <tbody>
10
+ <tr>
11
+ <th>Job</th>
12
+ <td><%= @job.job_class %></td>
13
+ </tr>
14
+ <tr>
15
+ <th>Queue</th>
16
+ <td><%= @job.queue %></td>
17
+ </tr>
18
+ <tr>
19
+ <th>Priority</th>
20
+ <td><%= @job.priority %></td>
21
+ </tr>
22
+ <tr>
23
+ <th>Run At</th>
24
+ <td><%= @job.run_at.utc %></td>
25
+ </tr>
26
+ <tr>
27
+ <th>Failures</th>
28
+ <td><pre><%= @job.error_count %></pre></td>
29
+ </tr>
30
+ <tr>
31
+ <th>Args</th>
32
+ <td><pre><%= @job.args.map(&:inspect).join(', ') %></pre></td>
33
+ </tr>
34
+ <tr>
35
+ <th>Last Error</th>
36
+ <td><pre><%= @job.last_error %></pre></td>
37
+ </tr>
38
+ </tbody>
39
+ </table>
40
+ </div>
41
+ </div>
42
+ <div class="row">
43
+ <div class="small-12 columns">
44
+ <form class="form-inline" action="<%= to "/jobs/#{@job.job_id}" %>" method="post">
45
+ <input type="hidden" name="_method" value="put" />
46
+ <button><i class="fa fa-play-circle"></i> Run Immediately</button>
47
+ </form>
48
+ <form class="form-inline" maction="<%= to "/jobs/#{@job.job_id}" %>" method="post">
49
+ <input type="hidden" name="_method" value="Delete" />
50
+ <button class="button alert"><i class="fa fa-trash"></i> Delete</button>
51
+ </form>
52
+ </div>
53
+ </div>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: que-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Staten
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.4'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.4'
69
83
  description: A web interface for the que queue
70
84
  email:
71
85
  - jstaten07@gmail.com
@@ -74,6 +88,7 @@ extensions: []
74
88
  extra_rdoc_files: []
75
89
  files:
76
90
  - ".gitignore"
91
+ - ".travis.yml"
77
92
  - Gemfile
78
93
  - LICENSE.txt
79
94
  - README.md
@@ -84,12 +99,14 @@ files:
84
99
  - examples/rack/boot.rb
85
100
  - examples/rack/config.ru
86
101
  - lib/que/web.rb
87
- - lib/que/web/version.rb
102
+ - lib/que/web/pager.rb
103
+ - lib/que/web/sql.rb
88
104
  - lib/que/web/viewmodels.rb
89
105
  - lib/que/web/viewmodels/dashboard.rb
90
106
  - lib/que/web/viewmodels/job.rb
91
107
  - lib/que/web/viewmodels/job_list.rb
92
108
  - que-web.gemspec
109
+ - spec/pager_spec.rb
93
110
  - spec/spec_helper.rb
94
111
  - spec/viewmodels/dashboard_spec.rb
95
112
  - spec/viewmodels/job_list_spec.rb
@@ -111,9 +128,13 @@ files:
111
128
  - web/public/styles/normalize.css
112
129
  - web/views/_footer.erb
113
130
  - web/views/_navbar.erb
131
+ - web/views/_pager.erb
114
132
  - web/views/failing.erb
115
133
  - web/views/index.erb
116
134
  - web/views/layout.erb
135
+ - web/views/running.erb
136
+ - web/views/scheduled.erb
137
+ - web/views/show.erb
117
138
  homepage: https://github.com/statianzo/que-web
118
139
  licenses:
119
140
  - BSD
@@ -139,6 +160,7 @@ signing_key:
139
160
  specification_version: 4
140
161
  summary: A web interface for the que queue
141
162
  test_files:
163
+ - spec/pager_spec.rb
142
164
  - spec/spec_helper.rb
143
165
  - spec/viewmodels/dashboard_spec.rb
144
166
  - spec/viewmodels/job_list_spec.rb
File without changes