rocketjob_mission_control 1.1.0 → 1.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 +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
|