rocketjob_mission_control 1.2.0 → 1.2.1
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/stylesheets/rocket_job_mission_control/callout.scss +3 -0
- data/app/controllers/rocket_job_mission_control/dirmon_entries_controller.rb +8 -9
- data/app/controllers/rocket_job_mission_control/jobs/failures_controller.rb +15 -11
- data/app/controllers/rocket_job_mission_control/workers_controller.rb +7 -2
- data/app/helpers/rocket_job_mission_control/workers_helper.rb +10 -6
- data/app/views/layouts/rocket_job_mission_control/application.html.haml +1 -1
- data/app/views/rocket_job_mission_control/dirmon_entries/_form.html.haml +3 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/_status.html.haml +3 -0
- data/app/views/rocket_job_mission_control/jobs/running.html.haml +2 -1
- data/app/views/rocket_job_mission_control/workers/index.html.haml +8 -4
- data/config/locales/en.yml +3 -1
- data/lib/rocket_job_mission_control/version.rb +1 -1
- data/spec/controllers/dirmon_entries_controller_spec.rb +51 -37
- data/spec/controllers/jobs/failures_controller_spec.rb +32 -10
- data/spec/controllers/workers_controller_spec.rb +1 -1
- data/spec/dummy/log/test.log +15294 -0
- data/spec/helpers/workers_helper_spec.rb +16 -0
- data/spec/views/workers/index.html.haml_spec.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 304c034afa2db7c0db432bc35a23cf61a98bb0ea
|
4
|
+
data.tar.gz: af4d336900d12e6f2aa7b3913e024ff7bd3dec8b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 322c4304792cba14b21561dbea0e3f33e7bcbe44db1dd4a21ae5598b9e9e8af4ae32a7e02419cc37344e3a687ac5e8089694d790ee00345cb3470a8b9026d0bb
|
7
|
+
data.tar.gz: 8c512bd2504b5f0dfd1acff972d661219a45d8ec53c4dd7c43696f62e10b94acb7d0c4301dbab2ec2831e8b38d3647b46203de897014d18644690e9e424eac8e
|
@@ -76,15 +76,14 @@ module RocketJobMissionControl
|
|
76
76
|
private
|
77
77
|
|
78
78
|
def parse_and_assign_arguments
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
79
|
+
arguments = params[:rocket_job_dirmon_entry][:arguments]
|
80
|
+
arguments = arguments.blank? ? '[]' : arguments
|
81
|
+
begin
|
82
|
+
arguments = JSON.parse(arguments)
|
83
|
+
@dirmon_entry.arguments = arguments.kind_of?(Array) ? arguments : [arguments]
|
84
|
+
rescue JSON::ParserError => e
|
85
|
+
@dirmon_entry.errors.add(:arguments, e.message)
|
86
86
|
end
|
87
|
-
|
88
87
|
end
|
89
88
|
|
90
89
|
def clean_values
|
@@ -116,7 +115,7 @@ module RocketJobMissionControl
|
|
116
115
|
def dirmon_params
|
117
116
|
params
|
118
117
|
.require(:rocket_job_dirmon_entry)
|
119
|
-
.permit(:name, :archive_directory, :pattern, :job_class_name).tap do |whitelist|
|
118
|
+
.permit(:name, :archive_directory, :pattern, :job_class_name, :perform_method).tap do |whitelist|
|
120
119
|
whitelist[:properties] = params[:rocket_job_dirmon_entry][:properties] if params[:rocket_job_dirmon_entry][:properties]
|
121
120
|
end
|
122
121
|
end
|
@@ -7,21 +7,25 @@ module RocketJobMissionControl
|
|
7
7
|
|
8
8
|
if @job && @job.failed?
|
9
9
|
@slice_errors = job_failures.list
|
10
|
-
@error_type = params[:error_type] || @slice_errors.first['_id']['error_class']
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
current_failure = selected_exception.first
|
11
|
+
if @slice_errors.present?
|
12
|
+
@error_type = params[:error_type] || @slice_errors.first['_id']['error_class']
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
}
|
14
|
+
offset = params.fetch(:offset, 0).to_i
|
15
|
+
selected_exception = job_failures.for_error(@error_type, offset)
|
16
|
+
current_failure = selected_exception.first
|
20
17
|
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
@pagination = {
|
19
|
+
offset: offset,
|
20
|
+
total: (selected_exception.count - 1),
|
21
|
+
}
|
24
22
|
|
23
|
+
if current_failure.present?
|
24
|
+
@failure_exception = current_failure['exception']
|
25
|
+
end
|
26
|
+
else
|
27
|
+
flash[:notice] = t(:no_errors, scope: [:job, :failures])
|
28
|
+
end
|
25
29
|
else
|
26
30
|
redirect_to(job_path(params[:job_id]))
|
27
31
|
end
|
@@ -6,12 +6,17 @@ module RocketJobMissionControl
|
|
6
6
|
@workers = RocketJob::Worker.sort(:name)
|
7
7
|
end
|
8
8
|
|
9
|
-
VALID_STATES = {
|
9
|
+
VALID_STATES = {
|
10
|
+
stop_all: 'stopped',
|
11
|
+
pause_all: 'paused',
|
12
|
+
resume_all: 'resumed',
|
13
|
+
destroy_zombies: 'destroyed if zombified',
|
14
|
+
}
|
10
15
|
|
11
16
|
def update_all
|
12
17
|
worker_action = params[:worker_action].to_sym
|
13
18
|
if VALID_STATES.keys.include?(worker_action)
|
14
|
-
RocketJob::Worker.send(
|
19
|
+
RocketJob::Worker.send(worker_action.to_sym)
|
15
20
|
flash[:notice] = t(:success, scope: [:worker, :update_all], worker_action: VALID_STATES[worker_action])
|
16
21
|
else
|
17
22
|
flash[:alert] = t(:invalid, scope: [:worker, :update_all])
|
@@ -2,12 +2,16 @@ module RocketJobMissionControl
|
|
2
2
|
module WorkersHelper
|
3
3
|
|
4
4
|
def worker_card_class(worker)
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
if worker.zombie?
|
6
|
+
'callout-zombie-top'
|
7
|
+
else
|
8
|
+
map = {
|
9
|
+
running: 'callout-success-top',
|
10
|
+
paused: 'callout-warning-top',
|
11
|
+
stopping: 'callout-alert-top',
|
12
|
+
}
|
13
|
+
map[worker.state] || 'callout-info-top'
|
14
|
+
end
|
11
15
|
end
|
12
16
|
|
13
17
|
end
|
@@ -18,6 +18,9 @@
|
|
18
18
|
.job.form-group
|
19
19
|
= f.label :job_class_name
|
20
20
|
= f.text_field :job_class_name, class: 'form-control'
|
21
|
+
.job.form-group
|
22
|
+
= f.label :perform_method
|
23
|
+
= f.text_field :perform_method, class: 'form-control'
|
21
24
|
.job_arguments.form-group
|
22
25
|
= f.label :arguments
|
23
26
|
= f.text_area :arguments,
|
@@ -17,7 +17,8 @@
|
|
17
17
|
- if job.kind_of?(RocketJob::SlicedJob)
|
18
18
|
.slice_count
|
19
19
|
%label Slices Running:
|
20
|
-
|
20
|
+
-#= job.input.find_all { |s| s.state == :running }.count
|
21
|
+
= job.input.collection.aggregate([{ '$match' => { state: 'queued' } },{ '$group' => { _id: nil, count: { '$sum' => 1 } } }] )
|
21
22
|
- else
|
22
23
|
.worker
|
23
24
|
%label Worker:
|
@@ -5,11 +5,11 @@
|
|
5
5
|
%ol.breadcrumb{ style: 'margin-bottom: 0'}
|
6
6
|
%li.active Workers
|
7
7
|
.btn-group.pull-right
|
8
|
-
- [:
|
9
|
-
= link_to("#{action.to_s.capitalize}
|
8
|
+
- [:stop_all, :pause_all, :resume_all, :destroy_zombies].each do |action|
|
9
|
+
= link_to("#{action.to_s.humanize.capitalize}",
|
10
10
|
rocket_job_mission_control.update_all_workers_path(worker_action: action),
|
11
11
|
method: :patch,
|
12
|
-
data: { confirm: t(:confirm, scope: [:worker, :update_all], action: action) },
|
12
|
+
data: { confirm: t(:confirm, scope: [:worker, :update_all], action: action.to_s.singularize.humanize.downcase) },
|
13
13
|
class: 'btn btn-default')
|
14
14
|
.clearfix
|
15
15
|
|
@@ -37,7 +37,11 @@
|
|
37
37
|
|
38
38
|
.time
|
39
39
|
%b Started:
|
40
|
-
=
|
40
|
+
= "#{RocketJob.seconds_as_duration(Time.now - worker.started_at)} ago"
|
41
|
+
|
42
|
+
.heartbeat
|
43
|
+
%b Last Heartbeat:
|
44
|
+
= "#{RocketJob.seconds_as_duration(Time.now - worker.heartbeat.updated_at)} ago"
|
41
45
|
|
42
46
|
.actions
|
43
47
|
= render partial: 'actions', locals: { worker: worker }
|
data/config/locales/en.yml
CHANGED
@@ -52,12 +52,14 @@ 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}
|
55
|
+
confirm: "Are you sure you want to %{action} workers?"
|
56
56
|
job:
|
57
57
|
find:
|
58
58
|
failure: "Could not find job with id: %{id}!"
|
59
59
|
action:
|
60
60
|
confirm: "Are you sure you want to %{action} this job?"
|
61
|
+
failures:
|
62
|
+
no_errors: 'No slice failures present.'
|
61
63
|
|
62
64
|
dirmon_entry:
|
63
65
|
find:
|
@@ -5,6 +5,11 @@ class FakeButGoodJob < RocketJob::Job
|
|
5
5
|
def perform(id)
|
6
6
|
id
|
7
7
|
end
|
8
|
+
|
9
|
+
def perform_with_no_params
|
10
|
+
100_000
|
11
|
+
end
|
12
|
+
|
8
13
|
end
|
9
14
|
|
10
15
|
module RocketJobMissionControl
|
@@ -185,52 +190,61 @@ module RocketJobMissionControl
|
|
185
190
|
|
186
191
|
describe 'POST #create' do
|
187
192
|
context 'with valid parameters' do
|
188
|
-
let(:dirmon_params) do
|
189
|
-
{
|
190
|
-
name: 'Test',
|
191
|
-
pattern: '/files/',
|
192
|
-
job_class_name: 'FakeButGoodJob',
|
193
|
-
arguments: [ 42 ].to_json,
|
194
|
-
properties: { description: '', priority: 42 },
|
195
|
-
}
|
196
|
-
end
|
197
193
|
|
198
|
-
|
199
|
-
|
200
|
-
|
194
|
+
{
|
195
|
+
perform: { argument: [42].to_json, expected_value: [42] },
|
196
|
+
perform_with_no_params: { argument: '', expected_value: [] },
|
197
|
+
}.each_pair do |perform_method, arguments|
|
198
|
+
context "and arguments are '#{arguments}'" do
|
199
|
+
let(:dirmon_params) do
|
200
|
+
{
|
201
|
+
name: 'Test',
|
202
|
+
pattern: '/files/',
|
203
|
+
job_class_name: 'FakeButGoodJob',
|
204
|
+
arguments: arguments[:argument],
|
205
|
+
properties: { description: '', priority: 42 },
|
206
|
+
perform_method: perform_method,
|
207
|
+
}
|
208
|
+
end
|
201
209
|
|
202
|
-
|
203
|
-
|
204
|
-
|
210
|
+
before do
|
211
|
+
post :create, rocket_job_dirmon_entry: dirmon_params
|
212
|
+
end
|
205
213
|
|
206
|
-
|
207
|
-
|
208
|
-
|
214
|
+
it 'creates the entry' do
|
215
|
+
expect(assigns(:dirmon_entry)).to be_persisted
|
216
|
+
end
|
209
217
|
|
210
|
-
|
211
|
-
|
212
|
-
|
218
|
+
it 'has no errors' do
|
219
|
+
expect(assigns(:dirmon_entry).errors.messages).to be_empty
|
220
|
+
end
|
213
221
|
|
214
|
-
|
215
|
-
|
216
|
-
|
222
|
+
it 'redirects to created entry' do
|
223
|
+
expect(response).to redirect_to(dirmon_entry_path(assigns(:dirmon_entry)))
|
224
|
+
end
|
217
225
|
|
218
|
-
|
219
|
-
|
220
|
-
|
226
|
+
it 'does not load all entries' do
|
227
|
+
expect(dirmon_list).to_not have_received(:sort)
|
228
|
+
end
|
221
229
|
|
222
|
-
|
223
|
-
|
224
|
-
|
230
|
+
it 'does not save blank properties' do
|
231
|
+
expect(assigns(:dirmon_entry).properties[:description]).to eq(nil)
|
232
|
+
end
|
225
233
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
end
|
230
|
-
end
|
234
|
+
it 'saves properties' do
|
235
|
+
expect(assigns(:dirmon_entry).properties[:priority]).to eq('42')
|
236
|
+
end
|
231
237
|
|
232
|
-
|
233
|
-
|
238
|
+
[:name, :pattern, :job_class_name].each do |attribute|
|
239
|
+
it "assigns the correct value for #{attribute}" do
|
240
|
+
expect(assigns(:dirmon_entry)[attribute]).to eq(dirmon_params[attribute])
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'persists arguments correctly' do
|
245
|
+
expect(assigns(:dirmon_entry).arguments).to eq(arguments[:expected_value])
|
246
|
+
end
|
247
|
+
end
|
234
248
|
end
|
235
249
|
end
|
236
250
|
|
@@ -29,17 +29,39 @@ module RocketJobMissionControl
|
|
29
29
|
get :index, job_id: job.id
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
|
-
|
32
|
+
context 'with slice errors' do
|
33
|
+
it 'succeeds' do
|
34
|
+
expect(response).to be_success
|
35
|
+
end
|
36
|
+
it 'returns the job' do
|
37
|
+
expect(assigns(:job)).to eq(job)
|
38
|
+
end
|
39
|
+
it 'returns the errors' do
|
40
|
+
expect(assigns(:slice_errors)).to eq(slice_errors)
|
41
|
+
end
|
42
|
+
it 'returns the first exception' do
|
43
|
+
expect(assigns(:failure_exception)).to eq(current_failure['exception'])
|
44
|
+
end
|
34
45
|
end
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
46
|
+
|
47
|
+
context 'with no slice errors' do
|
48
|
+
let(:slice_errors) { [] }
|
49
|
+
|
50
|
+
it 'succeeds' do
|
51
|
+
expect(response).to be_success
|
52
|
+
end
|
53
|
+
it 'returns the job' do
|
54
|
+
expect(assigns(:job)).to eq(job)
|
55
|
+
end
|
56
|
+
it 'returns no errors' do
|
57
|
+
expect(assigns(:slice_errors)).to eq(slice_errors)
|
58
|
+
end
|
59
|
+
it 'returns no exception' do
|
60
|
+
expect(assigns(:failure_exception)).to be_nil
|
61
|
+
end
|
62
|
+
it 'notifies the user' do
|
63
|
+
expect(flash[:notice]).to eq(I18n.t(:no_errors, scope: [:job, :failures]))
|
64
|
+
end
|
43
65
|
end
|
44
66
|
end
|
45
67
|
|
@@ -49,7 +49,7 @@ module RocketJobMissionControl
|
|
49
49
|
RocketJobMissionControl::WorkersController::VALID_STATES.each do |worker_action, action_message|
|
50
50
|
context "with '#{worker_action}' as the worker_action param" do
|
51
51
|
before do
|
52
|
-
allow(RocketJob::Worker).to receive(
|
52
|
+
allow(RocketJob::Worker).to receive(worker_action.to_sym)
|
53
53
|
patch :update_all, worker_action: worker_action
|
54
54
|
end
|
55
55
|
|