que-web 0.1.0 → 0.2.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 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