sidekiq-hierarchy 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +14 -0
- data/CONTRIBUTING.md +57 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +396 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/img/dashboard.png +0 -0
- data/img/failed_workflow.png +0 -0
- data/img/in_progress_workflow.png +0 -0
- data/img/job.png +0 -0
- data/img/workflow_set.png +0 -0
- data/lib/sidekiq-hierarchy.rb +1 -0
- data/lib/sidekiq/hierarchy.rb +105 -0
- data/lib/sidekiq/hierarchy/callback_registry.rb +33 -0
- data/lib/sidekiq/hierarchy/client/middleware.rb +23 -0
- data/lib/sidekiq/hierarchy/faraday/middleware.rb +16 -0
- data/lib/sidekiq/hierarchy/http.rb +8 -0
- data/lib/sidekiq/hierarchy/job.rb +290 -0
- data/lib/sidekiq/hierarchy/notifications.rb +8 -0
- data/lib/sidekiq/hierarchy/observers.rb +9 -0
- data/lib/sidekiq/hierarchy/observers/job_update.rb +15 -0
- data/lib/sidekiq/hierarchy/observers/workflow_update.rb +18 -0
- data/lib/sidekiq/hierarchy/rack/middleware.rb +27 -0
- data/lib/sidekiq/hierarchy/server/middleware.rb +62 -0
- data/lib/sidekiq/hierarchy/version.rb +5 -0
- data/lib/sidekiq/hierarchy/web.rb +149 -0
- data/lib/sidekiq/hierarchy/workflow.rb +130 -0
- data/lib/sidekiq/hierarchy/workflow_set.rb +134 -0
- data/sidekiq-hierarchy.gemspec +33 -0
- data/web/views/_job_progress_bar.erb +28 -0
- data/web/views/_job_table.erb +37 -0
- data/web/views/_job_timings.erb +10 -0
- data/web/views/_progress_bar.erb +8 -0
- data/web/views/_search_bar.erb +17 -0
- data/web/views/_summary_bar.erb +30 -0
- data/web/views/_workflow_progress_bar.erb +24 -0
- data/web/views/_workflow_set_clear.erb +7 -0
- data/web/views/_workflow_table.erb +33 -0
- data/web/views/_workflow_timings.erb +14 -0
- data/web/views/_workflow_tree.erb +82 -0
- data/web/views/_workflow_tree_node.erb +18 -0
- data/web/views/job.erb +12 -0
- data/web/views/not_found.erb +1 -0
- data/web/views/status.erb +120 -0
- data/web/views/workflow.erb +45 -0
- data/web/views/workflow_set.erb +3 -0
- metadata +225 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sidekiq/hierarchy/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "sidekiq-hierarchy"
|
8
|
+
spec.version = Sidekiq::Hierarchy::VERSION
|
9
|
+
spec.authors = ["Anuj Das"]
|
10
|
+
spec.email = ["anujdas@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{A set of sidekiq middlewares to track workflows consisting of multiple levels of sidekiq jobs}
|
13
|
+
spec.description = %q{A set of sidekiq middlewares to track workflows consisting of multiple levels of sidekiq jobs}
|
14
|
+
spec.homepage = 'https://www.github.com/anujdas/sidekiq-hierarchy'
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_dependency 'sidekiq', '~> 3.3'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.10'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
27
|
+
spec.add_development_dependency 'rspec-its'
|
28
|
+
spec.add_development_dependency 'fakeredis'
|
29
|
+
spec.add_development_dependency 'rspec-sidekiq'
|
30
|
+
|
31
|
+
spec.add_development_dependency 'faraday'
|
32
|
+
spec.add_development_dependency 'rack'
|
33
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<% status = job.status %>
|
2
|
+
<% enqueued_at = job.enqueued_at %>
|
3
|
+
<% run_at = job.run_at %>
|
4
|
+
|
5
|
+
<% if status == :enqueued %>
|
6
|
+
<%= erb sidekiq_hierarchy_template(:_progress_bar), locals: {bars: [[:enqueued, 1.0]]} %>
|
7
|
+
|
8
|
+
<% elsif status == :requeued %>
|
9
|
+
<%= erb sidekiq_hierarchy_template(:_progress_bar), locals: {bars: [[:requeued, 1.0]]} %>
|
10
|
+
|
11
|
+
<% elsif status == :running %>
|
12
|
+
<% runtime = Time.now - enqueued_at %>
|
13
|
+
<% enqueued_pct = (run_at - enqueued_at) / runtime %>
|
14
|
+
<% run_pct = 1.0 - enqueued_pct %>
|
15
|
+
<%= erb sidekiq_hierarchy_template(:_progress_bar), locals: {bars: [[:enqueued, enqueued_pct], [:running, run_pct]], active: true} %>
|
16
|
+
|
17
|
+
<% elsif status == :complete %>
|
18
|
+
<% runtime = job.complete_at - enqueued_at %>
|
19
|
+
<% enqueued_pct = (run_at - enqueued_at) / runtime %>
|
20
|
+
<% run_pct = 1.0 - enqueued_pct %>
|
21
|
+
<%= erb sidekiq_hierarchy_template(:_progress_bar), locals: {bars: [[:enqueued, enqueued_pct], [:complete, run_pct]]} %>
|
22
|
+
|
23
|
+
<% elsif status == :failed %>
|
24
|
+
<% runtime = job.failed_at - enqueued_at %>
|
25
|
+
<% enqueued_pct = (run_at - enqueued_at) / runtime %>
|
26
|
+
<% failed_pct = 1.0 - enqueued_pct %>
|
27
|
+
<%= erb sidekiq_hierarchy_template(:_progress_bar), locals: {bars: [[:enqueued, enqueued_pct], [:failed, failed_pct]]} %>
|
28
|
+
<% end %>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<table class="table table-hover table-bordered table-striped table-white">
|
2
|
+
<thead>
|
3
|
+
<tr>
|
4
|
+
<th>JID</th>
|
5
|
+
<th>Class</th>
|
6
|
+
<th>Queue</th>
|
7
|
+
<th>Status</th>
|
8
|
+
<th>Enqueued at</th>
|
9
|
+
<th>Run at</th>
|
10
|
+
<th>Completed at</th>
|
11
|
+
<th>Failed at</th>
|
12
|
+
</tr>
|
13
|
+
</thead>
|
14
|
+
|
15
|
+
<tbody>
|
16
|
+
<% jobs.each do |job| %>
|
17
|
+
<tr>
|
18
|
+
<td>
|
19
|
+
<a href="<%= job_url(job) %>">
|
20
|
+
<%= job.jid %>
|
21
|
+
</a>
|
22
|
+
</td>
|
23
|
+
<td><%= job.info['class'] %></td>
|
24
|
+
<td><%= job.info['queue'] %></td>
|
25
|
+
<td>
|
26
|
+
<span class="label label-<%= bootstrap_status(job.status) %>">
|
27
|
+
<%= job.status %>
|
28
|
+
</span>
|
29
|
+
</td>
|
30
|
+
<td><%= job.enqueued_at %></td>
|
31
|
+
<td><%= job.run_at %></td>
|
32
|
+
<td><%= job.complete_at %></td>
|
33
|
+
<td><%= job.failed_at %></td>
|
34
|
+
</tr>
|
35
|
+
<% end %>
|
36
|
+
</tbody>
|
37
|
+
</table>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<% if run_at = job.run_at %>
|
2
|
+
<dl class="dl-horizontal">
|
3
|
+
<dt>Enqueued for</dt>
|
4
|
+
<dd><%= run_at - job.enqueued_at %> seconds</dd>
|
5
|
+
<% if run_at && finished_at = (job.complete_at || job.failed_at) %>
|
6
|
+
<dt>Ran for</dt>
|
7
|
+
<dd><%= finished_at - run_at %> seconds</dd>
|
8
|
+
<% end %>
|
9
|
+
</dl>
|
10
|
+
<% end %>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<%# input: local var 'bars', in the format [[status, width], ...]; local var 'active', true == moving bar %>
|
2
|
+
<div class="progress<%= ' progress-striped active' if !!locals[:active] %>">
|
3
|
+
<% bars.each do |status, width| %>
|
4
|
+
<div class="progress-bar progress-bar-<%= bootstrap_status(status) %>" style="width: <%= width * 100 %>%">
|
5
|
+
<%= status.to_s.capitalize %>
|
6
|
+
</div>
|
7
|
+
<% end %>
|
8
|
+
</div>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<div class="row col-sm-12" style="margin: 20px 0">
|
2
|
+
<form class="form-inline col-sm-6" action="<%= workflow_url %>" method="get">
|
3
|
+
<div class="form-group">
|
4
|
+
<label for="workflow_jid" class="sr-only">Workflow ID</label>
|
5
|
+
<input type="search" class="form-control" name="workflow_jid" placeholder="Enter Workflow ID" size="24">
|
6
|
+
</div>
|
7
|
+
<button type="submit" class="btn btn-default">Search workflows</button>
|
8
|
+
</form>
|
9
|
+
|
10
|
+
<form class="form-inline col-sm-6" action="<%= job_url %>" method="get">
|
11
|
+
<div class="form-group">
|
12
|
+
<label for="jid" class="sr-only">Job ID</label>
|
13
|
+
<input type="search" class="form-control" name="jid" placeholder="Enter Job ID" size="24">
|
14
|
+
</div>
|
15
|
+
<button type="submit" class="btn btn-default">Search jobs</button>
|
16
|
+
</form>
|
17
|
+
</div>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<div class="col-sm-12 summary_bar">
|
2
|
+
<ul class="list-unstyled summary row">
|
3
|
+
<li class="busy col-sm-4" style="width: 33%">
|
4
|
+
<a href="<%= workflow_set_url(:running) %>">
|
5
|
+
<span class="count">
|
6
|
+
<%= Sidekiq::Hierarchy::RunningSet.new.size %>
|
7
|
+
</span>
|
8
|
+
<span class="desc">Running</span>
|
9
|
+
</a>
|
10
|
+
</li>
|
11
|
+
|
12
|
+
<li class="processed col-sm-4" style="width: 33%">
|
13
|
+
<a href="<%= workflow_set_url(:complete) %>">
|
14
|
+
<span class="count">
|
15
|
+
<%= Sidekiq::Hierarchy::CompleteSet.new.size %>
|
16
|
+
</span>
|
17
|
+
<span class="desc">Complete</span>
|
18
|
+
</a>
|
19
|
+
</li>
|
20
|
+
|
21
|
+
<li class="dead col-sm-4" style="width: 33%">
|
22
|
+
<a href="<%= workflow_set_url(:failed) %>">
|
23
|
+
<span class="count">
|
24
|
+
<%= Sidekiq::Hierarchy::FailedSet.new.size %>
|
25
|
+
</span>
|
26
|
+
<span class="desc">Failed</span>
|
27
|
+
</a>
|
28
|
+
</li>
|
29
|
+
</ul>
|
30
|
+
</div>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<% enqueued_at = workflow.enqueued_at %>
|
2
|
+
<% run_at = workflow.run_at %>
|
3
|
+
|
4
|
+
<% if workflow.root.enqueued? %>
|
5
|
+
<%= erb sidekiq_hierarchy_template(:_progress_bar), locals: {bars: [[:enqueued, 1.0]]} %>
|
6
|
+
|
7
|
+
<% elsif workflow.running? %>
|
8
|
+
<% runtime = Time.now - enqueued_at %>
|
9
|
+
<% enqueued_pct = (run_at - enqueued_at) / runtime %>
|
10
|
+
<% run_pct = 1.0 - enqueued_pct %>
|
11
|
+
<%= erb sidekiq_hierarchy_template(:_progress_bar), locals: {bars: [[:enqueued, enqueued_pct], [:running, run_pct]], active: true} %>
|
12
|
+
|
13
|
+
<% elsif complete_at = workflow.complete_at %>
|
14
|
+
<% runtime = complete_at - enqueued_at %>
|
15
|
+
<% enqueued_pct = (run_at - enqueued_at) / runtime %>
|
16
|
+
<% run_pct = 1.0 - enqueued_pct %>
|
17
|
+
<%= erb sidekiq_hierarchy_template(:_progress_bar), locals: {bars: [[:enqueued, enqueued_pct], [:complete, run_pct]]} %>
|
18
|
+
|
19
|
+
<% elsif failed_at = workflow.failed_at %>
|
20
|
+
<% runtime = failed_at - enqueued_at %>
|
21
|
+
<% enqueued_pct = (run_at - enqueued_at) / runtime %>
|
22
|
+
<% failed_pct = 1.0 - enqueued_pct %>
|
23
|
+
<%= erb sidekiq_hierarchy_template(:_progress_bar), locals: {bars: [[:enqueued, enqueued_pct], [:failed, failed_pct]]} %>
|
24
|
+
<% end %>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<form action="<%= workflow_set_url(status) %>" method="post">
|
2
|
+
<div style="margin:0;padding:0">
|
3
|
+
<input name="_method" type="hidden" value="delete" />
|
4
|
+
<input name="authenticity_token" type="hidden" value="<%= session[:csrf] %>">
|
5
|
+
</div>
|
6
|
+
<button type="submit" class="btn btn-sm btn-danger" onclick="return confirm('Are you sure? This is irreversible and potentially very expensive')">Clear Set</button>
|
7
|
+
</form>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<div class="table_container">
|
2
|
+
<table class="table table-hover table-bordered table-striped table-white">
|
3
|
+
<thead>
|
4
|
+
<tr>
|
5
|
+
<th>Workflow ID</th>
|
6
|
+
<th>Status</th>
|
7
|
+
<th>Enqueued at</th>
|
8
|
+
<th>Run at</th>
|
9
|
+
<th>Completed at</th>
|
10
|
+
<th>Failed at</th>
|
11
|
+
<th>Jobs</th>
|
12
|
+
</tr>
|
13
|
+
</thead>
|
14
|
+
|
15
|
+
<tbody>
|
16
|
+
<% workflows.each do |workflow| %>
|
17
|
+
<tr>
|
18
|
+
<td>
|
19
|
+
<a href="<%= workflow_url(workflow) %>">
|
20
|
+
<%= workflow.jid %>
|
21
|
+
</a>
|
22
|
+
</td>
|
23
|
+
<td><%= workflow.status %></td>
|
24
|
+
<td><%= workflow.enqueued_at %></td>
|
25
|
+
<td><%= workflow.run_at %></td>
|
26
|
+
<td><%= workflow.complete_at %></td>
|
27
|
+
<td><%= workflow.failed_at %></td>
|
28
|
+
<td><%= workflow.jobs.count %></td>
|
29
|
+
</tr>
|
30
|
+
<% end%>
|
31
|
+
</tbody>
|
32
|
+
</table>
|
33
|
+
</div>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<% if run_at = workflow.run_at %>
|
2
|
+
<dl class="dl-horizontal">
|
3
|
+
<% if workflow.complete? %>
|
4
|
+
<dt>Ran for</dt>
|
5
|
+
<dd><%= workflow.complete_at - run_at %> seconds</dd>
|
6
|
+
<% elsif workflow.failed? %>
|
7
|
+
<dt>Failed in</dt>
|
8
|
+
<dd><%= workflow.failed_at - run_at %> seconds</dd>
|
9
|
+
<% else %>
|
10
|
+
<dt>Running for</dt>
|
11
|
+
<dd><%= Time.now - run_at %> seconds</dd>
|
12
|
+
<% end %>
|
13
|
+
</dl>
|
14
|
+
<% end %>
|
@@ -0,0 +1,82 @@
|
|
1
|
+
<style>
|
2
|
+
/* Lifted from http://www.cssscript.com/demo/minimalist-tree-view-in-pure-css */
|
3
|
+
/* Alternative styling: http://www.goocode.net/css/153-pure-css-to-create-family-tree.html */
|
4
|
+
|
5
|
+
ul.workflow_tree {
|
6
|
+
padding-left: 0px;
|
7
|
+
}
|
8
|
+
|
9
|
+
.workflow_tree li {
|
10
|
+
list-style-type: none;
|
11
|
+
margin: 10px;
|
12
|
+
position: relative;
|
13
|
+
}
|
14
|
+
|
15
|
+
.workflow_tree li::before {
|
16
|
+
content: "";
|
17
|
+
position: absolute;
|
18
|
+
top: -7px;
|
19
|
+
left: -20px;
|
20
|
+
border-left: 1px solid #ccc;
|
21
|
+
border-bottom: 1px solid #ccc;
|
22
|
+
border-radius: 0 0 0 0px;
|
23
|
+
width: 20px;
|
24
|
+
height: 15px;
|
25
|
+
}
|
26
|
+
|
27
|
+
.workflow_tree li::after {
|
28
|
+
position: absolute;
|
29
|
+
content: "";
|
30
|
+
top: 8px;
|
31
|
+
left: -20px;
|
32
|
+
border-left: 1px solid #ccc;
|
33
|
+
border-top: 1px solid #ccc;
|
34
|
+
border-radius: 0px 0 0 0;
|
35
|
+
width: 20px;
|
36
|
+
height: 100%;
|
37
|
+
}
|
38
|
+
|
39
|
+
.workflow_tree li:last-child::after {
|
40
|
+
display: none;
|
41
|
+
}
|
42
|
+
|
43
|
+
.workflow_tree li:last-child:before{
|
44
|
+
border-radius: 0 0 0 5px;
|
45
|
+
}
|
46
|
+
|
47
|
+
ul.workflow_tree > li:first-child::before {
|
48
|
+
display: none;
|
49
|
+
}
|
50
|
+
|
51
|
+
ul.workflow_tree > li:first-child::after {
|
52
|
+
border-radius: 5px 0 0 0;
|
53
|
+
}
|
54
|
+
|
55
|
+
.workflow_tree li a {
|
56
|
+
border-radius: 5px;
|
57
|
+
padding: 2px 5px;
|
58
|
+
}
|
59
|
+
|
60
|
+
.workflow_tree li a:hover, .workflow_tree li a:focus {
|
61
|
+
background: #ccc;
|
62
|
+
color: #000;
|
63
|
+
text-decoration: none;
|
64
|
+
}
|
65
|
+
|
66
|
+
.workflow_tree li a:hover+ul li a, .workflow_tree li a:focus+ul li a {
|
67
|
+
color: #000;
|
68
|
+
}
|
69
|
+
|
70
|
+
.workflow_tree li a:hover+ul li::after, .workflow_tree li a:focus+ul li::after,
|
71
|
+
.workflow_tree li a:hover+ul li::before, .workflow_tree li a:focus+ul li::before
|
72
|
+
.workflow_tree li a:hover+ul::before, .workflow_tree li a:focus+ul::before
|
73
|
+
.workflow_tree li a:hover+ul ul::before, .workflow_tree li a:focus+ul ul::before{
|
74
|
+
border-color: #000;
|
75
|
+
}
|
76
|
+
</style>
|
77
|
+
|
78
|
+
<ul class="workflow_tree">
|
79
|
+
<% unless root.root? %><ul><% end %>
|
80
|
+
<%= erb sidekiq_hierarchy_template(:_workflow_tree_node), locals: {job: root} %>
|
81
|
+
<% unless root.root? %></ul><% end %>
|
82
|
+
</ul>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<li>
|
2
|
+
<a href="<%= root_path %>hierarchy/jobs/<%= job.jid %>">
|
3
|
+
<span title="<%= job.jid %>">
|
4
|
+
<%= job.info['class'] %>
|
5
|
+
</span>
|
6
|
+
(<%= job.info['queue'] %>)
|
7
|
+
<span class="label label-<%= bootstrap_status(job.status) %>">
|
8
|
+
<%= job.status %> <%= relative_time(status_updated_at(job)) %>
|
9
|
+
</span>
|
10
|
+
</a>
|
11
|
+
<% unless job.leaf? %>
|
12
|
+
<ul>
|
13
|
+
<% job.children.each do |child| %>
|
14
|
+
<%= erb sidekiq_hierarchy_template(:_workflow_tree_node), locals: {job: child} %>
|
15
|
+
<% end %>
|
16
|
+
</ul>
|
17
|
+
<% end %>
|
18
|
+
</li>
|
data/web/views/job.erb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
<a href="<%= workflow_url(@workflow) %>">
|
2
|
+
<h3>Workflow <%= @workflow.jid %></h3>
|
3
|
+
</a>
|
4
|
+
<h4>Job <%= @job.jid %></h4>
|
5
|
+
|
6
|
+
<%= erb sidekiq_hierarchy_template(:_job_progress_bar), locals: {job: @job} %>
|
7
|
+
|
8
|
+
<%= erb sidekiq_hierarchy_template(:_job_table), locals: {jobs: [@job]} %>
|
9
|
+
<%= erb sidekiq_hierarchy_template(:_job_timings), locals: {job: @job} %>
|
10
|
+
|
11
|
+
<h4>Job Tree</h4>
|
12
|
+
<%= erb sidekiq_hierarchy_template(:_workflow_tree), locals: {root: @job} %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<h2>404 NOT FOUND</h2>
|
@@ -0,0 +1,120 @@
|
|
1
|
+
<h3>Sidekiq Hierarchy</h3>
|
2
|
+
|
3
|
+
<%= erb sidekiq_hierarchy_template(:_summary_bar) %>
|
4
|
+
<%= erb sidekiq_hierarchy_template(:_search_bar) %>
|
5
|
+
|
6
|
+
<div class="panel panel-info">
|
7
|
+
<div class="panel-heading">
|
8
|
+
<a href="<%= workflow_set_url(:running) %>">
|
9
|
+
<h4>Running Workflows</h4>
|
10
|
+
</a>
|
11
|
+
</div>
|
12
|
+
|
13
|
+
<div class="panel-body">
|
14
|
+
<div class="table_container">
|
15
|
+
<table class="table table-hover table-bordered table-striped table-white">
|
16
|
+
<thead>
|
17
|
+
<tr>
|
18
|
+
<th>Workflow ID</th>
|
19
|
+
<th>Enqueued at</th>
|
20
|
+
<th>Run at</th>
|
21
|
+
</tr>
|
22
|
+
</thead>
|
23
|
+
|
24
|
+
<tbody>
|
25
|
+
<% @running.each do |workflow| %>
|
26
|
+
<tr>
|
27
|
+
<td>
|
28
|
+
<a href="<%= workflow_url(workflow) %>">
|
29
|
+
<%= workflow.jid %>
|
30
|
+
</a>
|
31
|
+
</td>
|
32
|
+
<td><%= relative_time(workflow.enqueued_at) %></td>
|
33
|
+
<td><%= relative_time(workflow.run_at) if workflow.run_at %></td>
|
34
|
+
</tr>
|
35
|
+
<% end%>
|
36
|
+
</tbody>
|
37
|
+
</table>
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
|
42
|
+
<div class="panel panel-success">
|
43
|
+
<div class="panel-heading">
|
44
|
+
<a href="<%= workflow_set_url(:complete) %>">
|
45
|
+
<h4>Complete Workflows</h4>
|
46
|
+
</a>
|
47
|
+
</div>
|
48
|
+
|
49
|
+
<div class="panel-body">
|
50
|
+
<div class="table_container">
|
51
|
+
<table class="table table-hover table-bordered table-striped table-white">
|
52
|
+
<thead>
|
53
|
+
<tr>
|
54
|
+
<th>Workflow ID</th>
|
55
|
+
<th>Enqueued at</th>
|
56
|
+
<th>Run at</th>
|
57
|
+
<th>Completed at</th>
|
58
|
+
</tr>
|
59
|
+
</thead>
|
60
|
+
|
61
|
+
<tbody>
|
62
|
+
<% @complete.each do |workflow| %>
|
63
|
+
<tr>
|
64
|
+
<td>
|
65
|
+
<a href="<%= workflow_url(workflow) %>">
|
66
|
+
<%= workflow.jid %>
|
67
|
+
</a>
|
68
|
+
</td>
|
69
|
+
<td><%= relative_time(workflow.enqueued_at) %></td>
|
70
|
+
<td><%= relative_time(workflow.run_at) %></td>
|
71
|
+
<td><%= relative_time(workflow.complete_at) %></td>
|
72
|
+
</tr>
|
73
|
+
<% end%>
|
74
|
+
</tbody>
|
75
|
+
</table>
|
76
|
+
</div>
|
77
|
+
|
78
|
+
<%= erb sidekiq_hierarchy_template(:_workflow_set_clear), locals: {status: :complete} %>
|
79
|
+
</div>
|
80
|
+
</div>
|
81
|
+
|
82
|
+
<div class="panel panel-danger">
|
83
|
+
<div class="panel-heading">
|
84
|
+
<a href="<%= workflow_set_url(:failed) %>">
|
85
|
+
<h4>Failed Workflows</h4>
|
86
|
+
</a>
|
87
|
+
</div>
|
88
|
+
|
89
|
+
<div class="panel-body">
|
90
|
+
<div class="table_container">
|
91
|
+
<table class="table table-hover table-bordered table-striped table-white">
|
92
|
+
<thead>
|
93
|
+
<tr>
|
94
|
+
<th>Workflow ID</th>
|
95
|
+
<th>Enqueued at</th>
|
96
|
+
<th>Run at</th>
|
97
|
+
<th>Failed at</th>
|
98
|
+
</tr>
|
99
|
+
</thead>
|
100
|
+
|
101
|
+
<tbody>
|
102
|
+
<% @failed.each do |workflow| %>
|
103
|
+
<tr>
|
104
|
+
<td>
|
105
|
+
<a href="<%= workflow_url(workflow) %>">
|
106
|
+
<%= workflow.jid %>
|
107
|
+
</a>
|
108
|
+
</td>
|
109
|
+
<td><%= relative_time(workflow.enqueued_at) %></td>
|
110
|
+
<td><%= relative_time(workflow.run_at) %></td>
|
111
|
+
<td><%= relative_time(workflow.failed_at) %></td>
|
112
|
+
</tr>
|
113
|
+
<% end %>
|
114
|
+
</tbody>
|
115
|
+
</table>
|
116
|
+
</div>
|
117
|
+
|
118
|
+
<%= erb sidekiq_hierarchy_template(:_workflow_set_clear), locals: {status: :failed} %>
|
119
|
+
</div>
|
120
|
+
</div>
|