rocketjob_mission_control 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/rocket_job_mission_control/dirmon_entries.js.coffee +18 -0
- data/app/assets/stylesheets/rocket_job_mission_control/base.scss +33 -59
- data/app/assets/stylesheets/rocket_job_mission_control/bootstrap_and_overrides.scss +12 -0
- data/app/assets/stylesheets/rocket_job_mission_control/callout.scss +8 -0
- data/app/assets/stylesheets/rocket_job_mission_control/jobs.scss +35 -0
- data/app/controllers/rocket_job_mission_control/application_controller.rb +0 -2
- data/app/controllers/rocket_job_mission_control/dirmon_entries_controller.rb +125 -0
- data/app/controllers/rocket_job_mission_control/jobs/failures_controller.rb +31 -0
- data/app/helpers/rocket_job_mission_control/application_helper.rb +7 -0
- data/app/helpers/rocket_job_mission_control/jobs_helper.rb +18 -11
- data/app/helpers/rocket_job_mission_control/pagination_helper.rb +7 -0
- data/app/helpers/rocket_job_mission_control/slices_helper.rb +9 -0
- data/app/models/job_failures.rb +30 -0
- data/app/views/layouts/rocket_job_mission_control/application.html.haml +3 -1
- data/app/views/layouts/rocket_job_mission_control/partials/_header.html.haml +2 -2
- data/app/views/layouts/rocket_job_mission_control/partials/_sidebar.html.haml +4 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/_form.html.haml +36 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/_list.html.haml +31 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/_properties.html.haml +8 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/_status.html.haml +23 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/edit.html.haml +8 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/index.html.haml +11 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/new.html.haml +9 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/show.html.haml +26 -0
- data/app/views/rocket_job_mission_control/jobs/_list.html.haml +34 -30
- data/app/views/rocket_job_mission_control/jobs/failures/_pagination.html.haml +16 -0
- data/app/views/rocket_job_mission_control/jobs/failures/index.html.haml +32 -0
- data/app/views/rocket_job_mission_control/jobs/index.html.haml +10 -8
- data/app/views/rocket_job_mission_control/jobs/running.html.haml +1 -1
- data/app/views/rocket_job_mission_control/jobs/show.html.haml +39 -35
- data/app/views/rocket_job_mission_control/workers/_actions.html.haml +4 -4
- data/app/views/rocket_job_mission_control/workers/index.html.haml +50 -45
- data/config/locales/en.yml +23 -1
- data/config/routes.rb +8 -0
- data/lib/rocket_job_mission_control/version.rb +1 -1
- data/spec/controllers/dirmon_entries_controller_spec.rb +451 -0
- data/spec/controllers/jobs/failures_controller_spec.rb +60 -0
- data/spec/dummy/config/environments/test.rb +1 -1
- data/spec/dummy/config/mongo.yml +15 -0
- data/spec/dummy/log/development.log +2 -0
- data/spec/dummy/log/test.log +52763 -2015
- data/spec/helpers/jobs_helper_spec.rb +27 -0
- data/spec/helpers/pagination_helper_spec.rb +21 -0
- data/spec/helpers/slices_helper_spec.rb +33 -0
- data/spec/models/job_failures_spec.rb +14 -0
- data/spec/views/workers/index.html.haml_spec.rb +23 -0
- metadata +35 -4
@@ -0,0 +1,23 @@
|
|
1
|
+
%div
|
2
|
+
%label Name:
|
3
|
+
= @dirmon_entry.name
|
4
|
+
%div
|
5
|
+
%label Pattern:
|
6
|
+
= @dirmon_entry.pattern
|
7
|
+
%div
|
8
|
+
%label Job Class Name:
|
9
|
+
= @dirmon_entry.job_class_name
|
10
|
+
%div
|
11
|
+
%label Archive Directory:
|
12
|
+
= @dirmon_entry.archive_directory
|
13
|
+
.parameters
|
14
|
+
%label Arguments:
|
15
|
+
%pre
|
16
|
+
%code= pretty_print_array_or_hash(@dirmon_entry.arguments)
|
17
|
+
.parameters
|
18
|
+
%label Properties:
|
19
|
+
%pre
|
20
|
+
%code= pretty_print_array_or_hash(@dirmon_entry.properties)
|
21
|
+
.id
|
22
|
+
%label ID:
|
23
|
+
= @dirmon_entry.id
|
@@ -0,0 +1,11 @@
|
|
1
|
+
.row
|
2
|
+
#queue
|
3
|
+
= render partial: 'list', locals: { jobs: @jobs }
|
4
|
+
|
5
|
+
.col-md-8
|
6
|
+
.job-status
|
7
|
+
#job
|
8
|
+
.welcome_screen
|
9
|
+
= link_to image_tag('rocket_job_mission_control/rocket-icon-512x512.png'), 'http://rocketjob.io'
|
10
|
+
%h1 Welcome to rocketjob
|
11
|
+
%p High volume, priority based, Enterprise Batch Processing solution for Ruby
|
@@ -0,0 +1,26 @@
|
|
1
|
+
.row
|
2
|
+
#queue
|
3
|
+
= render partial: 'list', locals: { jobs: @jobs }
|
4
|
+
|
5
|
+
.col-md-8.job-status
|
6
|
+
#job
|
7
|
+
.lead= @dirmon_entry.job_class_name + "#{'#' + @dirmon_entry.perform_method.to_s unless @dirmon_entry.perform_method == :perform }"
|
8
|
+
|
9
|
+
.job-state.inline-block
|
10
|
+
.left status
|
11
|
+
.right{ class: @dirmon_entry.state }
|
12
|
+
= @dirmon_entry.state
|
13
|
+
|
14
|
+
.btn-toolbar.job-actions.pull-right
|
15
|
+
.btn-group{ style: 'margin-right: 1em;' }
|
16
|
+
= link_to "Destroy", dirmon_entry_path(@dirmon_entry), method: :delete, class: 'btn btn-default', :data => { :confirm => 'Are you sure?' }
|
17
|
+
- if @dirmon_entry.disabled? || @dirmon_entry.pending?
|
18
|
+
= link_to "Enable", enable_dirmon_entry_path(@dirmon_entry.id), method: :put, class: "btn btn-default"
|
19
|
+
- if @dirmon_entry.enabled?
|
20
|
+
= link_to "Disable", disable_dirmon_entry_path(@dirmon_entry.id), method: :put, class: "btn btn-default", :data => { :confirm => 'Are you sure?' }
|
21
|
+
.btn-group
|
22
|
+
= link_to "Edit", edit_dirmon_entry_path(@dirmon_entry), class: "btn btn-default"
|
23
|
+
|
24
|
+
.clearfix
|
25
|
+
|
26
|
+
= render partial: 'status', locals: { dirmon_entry: @job }
|
@@ -1,31 +1,35 @@
|
|
1
|
-
.col-md-4
|
2
|
-
.
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
1
|
+
.col-md-4
|
2
|
+
.job-list
|
3
|
+
.filter
|
4
|
+
%ol.breadcrumb
|
5
|
+
%li.active Jobs
|
6
|
+
.btn-group.pull-right{ data: { toggle: 'buttons' } }
|
7
|
+
- job_states.each do |state|
|
8
|
+
- enabled = @states.include?(state.to_s) || @states.empty?
|
9
|
+
- title = enabled ? 'Hide' : 'Show'
|
10
|
+
%label.btn.btn-default.state-toggle{ class: ('active' if enabled), title: "#{title} #{state.capitalize}" }
|
11
|
+
= check_box_tag(state, state, enabled)
|
12
|
+
%i.fa{class: job_state_icon(state)}
|
13
|
+
.clearfix
|
14
|
+
.list
|
15
|
+
- if jobs.empty?
|
16
|
+
.card.inner
|
17
|
+
.title
|
18
|
+
.lead.text-center No Jobs Found.
|
19
|
+
- else
|
20
|
+
- jobs.each do |job|
|
21
|
+
= link_to(job_path(id: job.id, states: @states), class: "card callout callout-#{job.state} #{job_selected_class(job, @job)}") do
|
22
|
+
.inner
|
23
|
+
.title
|
24
|
+
.lead
|
25
|
+
%i.fa{class: job_icon(job), style: 'font-size: 75%;', title: job.state}
|
26
|
+
= job_title(job)
|
23
27
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
.description= job.description.try(:truncate, 50)
|
29
|
+
.info
|
30
|
+
.duration.pull-left
|
31
|
+
%i.fa.fa-clock-o
|
32
|
+
= job.duration
|
33
|
+
- if job.running?
|
34
|
+
.progress.pull-right
|
35
|
+
.progress-bar{ style: "width: #{job.percent_complete}%;", title: "#{job.percent_complete}% percent complete."}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
- previous_offset = [0, pagination[:offset].pred].max
|
2
|
+
- next_offset = [pagination[:total], pagination[:offset].next].min
|
3
|
+
|
4
|
+
%ul.pagination
|
5
|
+
%li
|
6
|
+
= link_to(job_failures_path(error_type: error_type, offset: 0), class: "btn btn-default #{page_nav_disabled_class(pagination[:offset], 0)}", title: 'First') do
|
7
|
+
%i.fa.fa-angle-double-left
|
8
|
+
%li
|
9
|
+
= link_to(job_failures_path(error_type: error_type, offset: previous_offset), class: "btn btn-default #{page_nav_disabled_class(pagination[:offset], 0)}", title: 'Previous') do
|
10
|
+
%i.fa.fa-angle-left
|
11
|
+
%li
|
12
|
+
= link_to(job_failures_path(error_type: error_type, offset: next_offset), class: "btn btn-default #{page_nav_disabled_class(pagination[:offset], pagination[:total])}", title: 'Next') do
|
13
|
+
%i.fa.fa-angle-right
|
14
|
+
%li
|
15
|
+
= link_to(job_failures_path(error_type: error_type, offset: pagination[:total]), class: "btn btn-default #{page_nav_disabled_class(pagination[:offset], pagination[:total])}", title: 'Last') do
|
16
|
+
%i.fa.fa-angle-double-right
|
@@ -0,0 +1,32 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-4
|
3
|
+
.job-list
|
4
|
+
.list-top
|
5
|
+
%ol.breadcrumb
|
6
|
+
%li= link_to(job_title(@job), job_path(@job))
|
7
|
+
%li.active Failures
|
8
|
+
.clearfix
|
9
|
+
.list
|
10
|
+
- @slice_errors.each do |slice_error|
|
11
|
+
= link_to(job_failures_path(@job, error_type: slice_error['_id']['error_class']), class: "card callout") do
|
12
|
+
.inner
|
13
|
+
.title
|
14
|
+
.lead
|
15
|
+
= slice_error['_id']['error_class']
|
16
|
+
|
17
|
+
.description
|
18
|
+
= "Occurences: #{slice_error['count'].to_i}"
|
19
|
+
|
20
|
+
- if @failure_exception
|
21
|
+
.col-md-8
|
22
|
+
.job-status
|
23
|
+
.failures
|
24
|
+
.lead= @failure_exception['class_name']
|
25
|
+
.pagination-buttons.pull-right= render partial: 'pagination', locals: { error_type: @failure_exception['class_name'], pagination: @pagination }
|
26
|
+
|
27
|
+
.clearfix
|
28
|
+
.message
|
29
|
+
%pre
|
30
|
+
%code= @failure_exception['message']
|
31
|
+
.error
|
32
|
+
%pre.small= @failure_exception['backtrace'].join("\n")
|
@@ -1,9 +1,11 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
.row
|
2
|
+
#queue
|
3
|
+
= render partial: 'list', locals: { jobs: @jobs }
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
.col-md-8
|
6
|
+
.job-status
|
7
|
+
#job
|
8
|
+
.welcome_screen
|
9
|
+
= link_to image_tag('rocket_job_mission_control/rocket-icon-512x512.png'), 'http://rocketjob.io'
|
10
|
+
%h1 Welcome to rocketjob
|
11
|
+
%p High volume, priority based, Enterprise Batch Processing solution for Ruby
|
@@ -1,50 +1,54 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
.row
|
2
|
+
#queue
|
3
|
+
= render partial: 'list', locals: { jobs: @jobs }
|
3
4
|
|
4
|
-
.col-md-8.job-status
|
5
|
-
|
6
|
-
|
5
|
+
.col-md-8.job-status
|
6
|
+
#job
|
7
|
+
.lead= job_title(@job)
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
.job-state.inline-block
|
10
|
+
.left state
|
11
|
+
.right{ class: @job.state.to_s }
|
12
|
+
= @job.state
|
12
13
|
|
13
|
-
|
14
|
-
|
14
|
+
.priority.pull-right
|
15
|
+
= form_for(@job, as: :job, url: job_path(@job), html: {method: :patch}) do |f|
|
15
16
|
|
16
|
-
|
17
|
-
|
17
|
+
.input-group.priority-group
|
18
|
+
= f.text_field(:priority, class: 'form-control')
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
.input-group-btn-vertical
|
21
|
+
%button#increase_priority.btn.btn-default.up{ type: 'button' }
|
22
|
+
%i.fa.fa-caret-up
|
22
23
|
|
23
|
-
|
24
|
-
|
24
|
+
%button#decrease_priority.btn.btn-default.down{ type: 'button' }
|
25
|
+
%i.fa.fa-caret-down
|
25
26
|
|
26
|
-
|
27
|
+
= submit_tag "set", class: "btn btn-sm btn-primary priority-set"
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
.job-actions.btn-group.pull-right{ style: 'margin-right: 1em;' }
|
30
|
+
- valid_events = @job.aasm.events.collect{ |e| e.name }
|
31
|
+
- if valid_events.include?(:abort)
|
32
|
+
= job_action_link('abort', rocket_job_mission_control.abort_job_path(@job), :patch)
|
32
33
|
|
33
|
-
|
34
|
-
|
34
|
+
- if @job.completed? || @job.aborted?
|
35
|
+
= job_action_link('destroy', rocket_job_mission_control.job_path(@job), :delete)
|
35
36
|
|
36
|
-
|
37
|
-
|
37
|
+
- if valid_events.include?(:fail)
|
38
|
+
= job_action_link('fail', rocket_job_mission_control.fail_job_path(@job), :patch)
|
38
39
|
|
39
|
-
|
40
|
-
|
40
|
+
- if valid_events.include?(:pause)
|
41
|
+
= job_action_link('pause', rocket_job_mission_control.pause_job_path(@job), :patch)
|
41
42
|
|
42
|
-
|
43
|
-
|
43
|
+
- if valid_events.include?(:resume)
|
44
|
+
= job_action_link('resume', rocket_job_mission_control.resume_job_path(@job), :patch)
|
44
45
|
|
45
|
-
|
46
|
-
|
46
|
+
- if valid_events.include?(:retry)
|
47
|
+
= job_action_link('retry', rocket_job_mission_control.retry_job_path(@job), :patch)
|
47
48
|
|
48
|
-
|
49
|
+
- if @job.failed? && @job.kind_of?(RocketJob::SlicedJob)
|
50
|
+
= link_to("view errors", job_failures_path(@job), class: 'btn btn-default')
|
49
51
|
|
50
|
-
|
52
|
+
.clearfix
|
53
|
+
|
54
|
+
= render partial: 'status', locals: { job: @job }
|
@@ -1,9 +1,9 @@
|
|
1
1
|
- if worker.stopping?
|
2
2
|
%p Worker is stopping...
|
3
|
-
= link_to "destroy", worker_path(worker), method: :delete, class: 'btn btn-danger'
|
3
|
+
= link_to "destroy", rocket_job_mission_control.worker_path(worker), method: :delete, class: 'btn btn-danger'
|
4
4
|
-else
|
5
|
-
= link_to "stop", stop_worker_path(worker), method: :patch, class: 'btn btn-danger'
|
5
|
+
= link_to "stop", rocket_job_mission_control.stop_worker_path(worker), method: :patch, class: 'btn btn-danger'
|
6
6
|
- if worker.paused?
|
7
|
-
= link_to "resume", resume_worker_path(worker), method: :patch, class: 'btn btn-default'
|
7
|
+
= link_to "resume", rocket_job_mission_control.resume_worker_path(worker), method: :patch, class: 'btn btn-default'
|
8
8
|
- else
|
9
|
-
= link_to "pause", pause_worker_path(worker), method: :patch, class: 'btn btn-default'
|
9
|
+
= link_to "pause", rocket_job_mission_control.pause_worker_path(worker), method: :patch, class: 'btn btn-default'
|
@@ -1,51 +1,56 @@
|
|
1
1
|
#workers
|
2
2
|
- if @workers.present?
|
3
|
-
.
|
4
|
-
.
|
5
|
-
%
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
3
|
+
.row
|
4
|
+
.col-xs-12
|
5
|
+
%ol.breadcrumb{ style: 'margin-bottom: 0'}
|
6
|
+
%li.active Workers
|
7
|
+
.btn-group.pull-right
|
8
|
+
- [:stop, :pause, :resume].each do |action|
|
9
|
+
= link_to("#{action.to_s.capitalize} All",
|
10
|
+
rocket_job_mission_control.update_all_workers_path(worker_action: action),
|
11
|
+
method: :patch,
|
12
|
+
data: { confirm: t(:confirm, scope: [:worker, :update_all], action: action) },
|
13
|
+
class: 'btn btn-default')
|
14
|
+
.clearfix
|
12
15
|
|
13
16
|
.grid
|
14
|
-
- @workers.
|
15
|
-
.
|
16
|
-
|
17
|
-
.
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
= render partial: 'actions', locals: { worker: worker }
|
17
|
+
- @workers.each_slice(4) do |workers|
|
18
|
+
.row
|
19
|
+
- workers.each do |worker|
|
20
|
+
.card.col-xs-12.col-sm-6.col-md-3.col-lg-3
|
21
|
+
.inner.callout-top{ class: worker_card_class(worker) }
|
22
|
+
.title
|
23
|
+
%h3
|
24
|
+
= worker.name
|
25
|
+
|
26
|
+
.state
|
27
|
+
%b State:
|
28
|
+
= worker.state
|
29
|
+
|
30
|
+
.threads.max_threads
|
31
|
+
%b Max Threads:
|
32
|
+
= worker.max_threads
|
33
|
+
|
34
|
+
.threads.current_threads
|
35
|
+
%b Current Threads:
|
36
|
+
= worker.heartbeat.current_threads.to_i
|
37
|
+
|
38
|
+
.time
|
39
|
+
%b Started:
|
40
|
+
= worker.started_at.strftime("%b, %d %Y at %l:%M %p")
|
41
|
+
|
42
|
+
.actions
|
43
|
+
= render partial: 'actions', locals: { worker: worker }
|
42
44
|
|
43
45
|
- else
|
44
|
-
.
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
46
|
+
.row
|
47
|
+
.col-md-6.col-md-offset-3
|
48
|
+
.panel.panel-default
|
49
|
+
.panel-body
|
50
|
+
.lead
|
51
|
+
There are currently no workers.
|
52
|
+
You can start a worker with the following command:
|
53
|
+
|
54
|
+
.code-block
|
55
|
+
%pre
|
56
|
+
%code.language-bash bin/rocketjob
|
data/config/locales/en.yml
CHANGED
@@ -52,6 +52,28 @@ en:
|
|
52
52
|
update_all:
|
53
53
|
success: "Workers have been %{worker_action}."
|
54
54
|
invalid: "Action not allowed."
|
55
|
+
confirm: "Are you sure you want to %{action} all workers?"
|
55
56
|
job:
|
56
57
|
find:
|
57
|
-
|
58
|
+
failure: "Could not find job with id: %{id}!"
|
59
|
+
action:
|
60
|
+
confirm: "Are you sure you want to %{action} this job?"
|
61
|
+
|
62
|
+
dirmon_entry:
|
63
|
+
find:
|
64
|
+
failure: "Could not find entry with id: %{id}!"
|
65
|
+
create:
|
66
|
+
success: "Dirmon successfully created."
|
67
|
+
failure: "Error attempting to create."
|
68
|
+
destroy:
|
69
|
+
success: "Dirmon successfully destroyed."
|
70
|
+
failure: "Error attempting to destroy Dirmon."
|
71
|
+
enable:
|
72
|
+
success: "Dirmon successfully enabled."
|
73
|
+
failure: "Error attempting to enable Dirmon."
|
74
|
+
disable:
|
75
|
+
success: "Dirmon successfully disabled."
|
76
|
+
failure: "Error attempting to disable Dirmon."
|
77
|
+
update:
|
78
|
+
success: "Dirmon has been updated."
|
79
|
+
invalid: "Error attempting to update Dirmon."
|
data/config/routes.rb
CHANGED
@@ -11,6 +11,7 @@ RocketJobMissionControl::Engine.routes.draw do
|
|
11
11
|
collection do
|
12
12
|
get :running
|
13
13
|
end
|
14
|
+
resources :failures, controller: 'jobs/failures', only: [:index]
|
14
15
|
end
|
15
16
|
|
16
17
|
resources :workers, only: [:index, :destroy] do
|
@@ -24,5 +25,12 @@ RocketJobMissionControl::Engine.routes.draw do
|
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
28
|
+
resources :dirmon_entries do
|
29
|
+
member do
|
30
|
+
put :enable
|
31
|
+
put :disable
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
27
35
|
root to: "jobs#index"
|
28
36
|
end
|