libis-workflow 2.0.11 → 2.0.12
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/README.md +0 -10
- data/lib/libis/workflow.rb +1 -0
- data/lib/libis/workflow/base/run.rb +6 -1
- data/lib/libis/workflow/base/workflow.rb +0 -6
- data/lib/libis/workflow/status.rb +25 -0
- data/lib/libis/workflow/task_group.rb +3 -0
- data/lib/libis/workflow/task_runner.rb +70 -0
- data/lib/libis/workflow/version.rb +1 -1
- data/spec/workflow_spec.rb +16 -5
- metadata +3 -3
- data/lib/libis/workflow/tasks/analyzer.rb +0 -58
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f79b538ba0bf95e113d0f5fcf24abf11d924436a
|
4
|
+
data.tar.gz: 93e10a182e7788367a63f5e520b861027d6eea68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d71d3a5142ecae99d83f35dab0efcc94ecc693ec2117f4970efa3a46d3c0f11ec423a77af8ad8d4efb1ace566e2ad7716538a6bfcf77f8483f59879f1dbe0f1d
|
7
|
+
data.tar.gz: 9baa84b4a68faedbff5723123ce1dc2c8863cce3558bfe19c7ec5b1f9a528cad0626890f4b38b6d4a2f1761c66c18d32000f995cfb42795ae2c38ea3e8ad80c5
|
data/README.md
CHANGED
@@ -50,10 +50,6 @@ name has to be provided to the job configuration so that the job can instantiate
|
|
50
50
|
will be able to execute the tasks in proper order on all the WorkItems supplied/collected. Each task can be implemented
|
51
51
|
with code to run or simply contain a list of child tasks.
|
52
52
|
|
53
|
-
One task is predefined:
|
54
|
-
::Libis::Workflow::Tasks::Analyzer - analyzes the workflow run and summarizes the results. It is always included as the
|
55
|
-
last task by the workflow unless you supply a closing task called 'Analyzer' yourself.
|
56
|
-
|
57
53
|
The whole ingester workflow is configured by a Singleton object ::Libis::Workflow::Config which contains settings for
|
58
54
|
logging and paths where tasks and workitems can be found.
|
59
55
|
|
@@ -297,12 +293,6 @@ You have some options to control how the task will behave in special cases. Thes
|
|
297
293
|
the task, which can be set (and fixed with the 'frozen' option) on the task, but can be configured at run-time with the
|
298
294
|
help of workflow input parameters and run options.
|
299
295
|
|
300
|
-
#### Preventing any logging output from the task
|
301
|
-
|
302
|
-
Logging output can be blocked on a task-by-task basis by setting the 'quiet' parameter to true. Probably not usefull
|
303
|
-
except for the Analyzer task where the parameter is fixed to true. Logging output would otherwise intervene with the
|
304
|
-
log summary processing performed by the task.
|
305
|
-
|
306
296
|
#### Performing an action on the work item and all child items recursively
|
307
297
|
|
308
298
|
With the 'recursive' parameter set to true, your task's process_item method will be called for the work item and then
|
data/lib/libis/workflow.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
|
3
3
|
require 'libis/workflow/base/work_item'
|
4
|
+
require 'libis/workflow/task_runner'
|
4
5
|
|
5
6
|
module Libis
|
6
7
|
module Workflow
|
@@ -72,10 +73,14 @@ module Libis
|
|
72
73
|
|
73
74
|
self.save!
|
74
75
|
|
76
|
+
runner = Libis::Workflow::TaskRunner.new nil
|
77
|
+
|
75
78
|
self.tasks.each do |task|
|
76
|
-
task
|
79
|
+
runner << task
|
77
80
|
end
|
78
81
|
|
82
|
+
runner.run self
|
83
|
+
|
79
84
|
end
|
80
85
|
|
81
86
|
protected
|
@@ -84,12 +84,6 @@ module Libis
|
|
84
84
|
|
85
85
|
self.class.require_all
|
86
86
|
|
87
|
-
unless !self.config['tasks'].empty? &&
|
88
|
-
self.config['tasks'].last['class'] &&
|
89
|
-
self.config['tasks'].last['class'].split('::').last == 'Analyzer'
|
90
|
-
self.config['tasks'] << {'class' => '::Libis::Workflow::Tasks::Analyzer'}
|
91
|
-
end
|
92
|
-
|
93
87
|
self.config
|
94
88
|
end
|
95
89
|
|
@@ -11,6 +11,15 @@ module Libis
|
|
11
11
|
FAILED: 5
|
12
12
|
}
|
13
13
|
|
14
|
+
STATUS_TEXT = [
|
15
|
+
'not started',
|
16
|
+
'started',
|
17
|
+
'done',
|
18
|
+
'waiting for running async process',
|
19
|
+
'waiting for halted async process',
|
20
|
+
'failed'
|
21
|
+
]
|
22
|
+
|
14
23
|
# Changes the status of the object. The status changed is logged in the status_log with the current timestamp.
|
15
24
|
#
|
16
25
|
# @param [Array] x Array with status and task
|
@@ -29,6 +38,15 @@ module Libis
|
|
29
38
|
status_symbol(entry[:status]) rescue :NOT_STARTED
|
30
39
|
end
|
31
40
|
|
41
|
+
# Get last known status text for a given task
|
42
|
+
#
|
43
|
+
# @param [String] task task name to check item status for
|
44
|
+
# @return [Symbol] the status code
|
45
|
+
def status_text(task = nil)
|
46
|
+
entry = status_entry(task)
|
47
|
+
status_string(entry[:status]) rescue STATUS_TEXT.first
|
48
|
+
end
|
49
|
+
|
32
50
|
# Gets the last known status label of the object.
|
33
51
|
#
|
34
52
|
# @param [String] task name of task to get the status for
|
@@ -78,6 +96,13 @@ module Libis
|
|
78
96
|
STATUS.has_key?(x) ? x : nil
|
79
97
|
end
|
80
98
|
|
99
|
+
def status_string(x)
|
100
|
+
return STATUS_TEXT[x] if x.is_a?(Integer)
|
101
|
+
return STATUS_TEXT[STATUS[x]] if STATUS.has_key?(x)
|
102
|
+
x = x.to_s.upcase.to_sym
|
103
|
+
STATUS.has_key?(x) ? STATUS_TEXT[STATUS[x]] : 'unknown status'
|
104
|
+
end
|
105
|
+
|
81
106
|
end
|
82
107
|
end
|
83
108
|
end
|
@@ -18,6 +18,7 @@ module Libis
|
|
18
18
|
|
19
19
|
def <<(task)
|
20
20
|
self.tasks << task
|
21
|
+
task.parent = self
|
21
22
|
end
|
22
23
|
|
23
24
|
def apply_options(opts)
|
@@ -45,6 +46,8 @@ module Libis
|
|
45
46
|
end
|
46
47
|
|
47
48
|
substatus_check(status, item, 'task')
|
49
|
+
|
50
|
+
info item.status_text(self.namepath).capitalize, item
|
48
51
|
end
|
49
52
|
|
50
53
|
def stop_processing_subtasks
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require_relative 'task_group'
|
2
|
+
|
3
|
+
module Libis
|
4
|
+
module Workflow
|
5
|
+
|
6
|
+
# noinspection RubyTooManyMethodsInspection
|
7
|
+
class TaskRunner < Libis::Workflow::TaskGroup
|
8
|
+
|
9
|
+
parameter abort_on_failure: true, frozen: true
|
10
|
+
parameter recursive: false, frozen: true
|
11
|
+
|
12
|
+
def names
|
13
|
+
Array.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def namepath
|
17
|
+
'Run'
|
18
|
+
end
|
19
|
+
|
20
|
+
def run(item)
|
21
|
+
|
22
|
+
check_item_type ::Libis::Workflow::Base::WorkItem, item
|
23
|
+
self.workitem = item
|
24
|
+
|
25
|
+
info 'Ingest run started.', item
|
26
|
+
|
27
|
+
super
|
28
|
+
|
29
|
+
recursive_run(item)
|
30
|
+
self.workitem = item
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def recursive_run(item)
|
37
|
+
|
38
|
+
item.properties['ingest_failed'] = item.check_status(:FAILED)
|
39
|
+
|
40
|
+
item.summary = {}
|
41
|
+
item.log_history.each do |log|
|
42
|
+
level = log[:severity]
|
43
|
+
item.summary[level.to_s] ||= 0
|
44
|
+
item.summary[level.to_s] += 1
|
45
|
+
end
|
46
|
+
|
47
|
+
item.each do |i|
|
48
|
+
recursive_run i
|
49
|
+
i.summary.each do |level, count|
|
50
|
+
item.summary[level] ||= 0
|
51
|
+
item.summary[level] += (count || 0)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
rescue RuntimeError => ex
|
56
|
+
|
57
|
+
self.workitem = item
|
58
|
+
error 'Failed to analyze item: %s - %s', item, item.class, item.name
|
59
|
+
error 'Exception: %s', item, ex.message
|
60
|
+
|
61
|
+
ensure
|
62
|
+
|
63
|
+
item.save!
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Libis
|
2
2
|
module Workflow
|
3
|
-
VERSION = '2.0.
|
3
|
+
VERSION = '2.0.12' unless const_defined? :VERSION # the guard is against a redefinition warning that happens on Travis
|
4
4
|
end
|
5
5
|
end
|
data/spec/workflow_spec.rb
CHANGED
@@ -57,9 +57,9 @@ describe 'TestWorkflow' do
|
|
57
57
|
}
|
58
58
|
|
59
59
|
it 'should contain three tasks' do
|
60
|
-
expect(workflow.config['tasks'].size).to eq
|
60
|
+
expect(workflow.config['tasks'].size).to eq 2
|
61
61
|
expect(workflow.config['tasks'].first['class']).to eq 'CollectFiles'
|
62
|
-
expect(workflow.config['tasks'].last['
|
62
|
+
expect(workflow.config['tasks'].last['name']).to eq 'ProcessFiles'
|
63
63
|
end
|
64
64
|
|
65
65
|
# noinspection RubyResolve
|
@@ -83,12 +83,15 @@ describe 'TestWorkflow' do
|
|
83
83
|
it 'should return expected debug output' do
|
84
84
|
|
85
85
|
sample_out = <<STR
|
86
|
+
INFO -- Run - TestRun : Ingest run started.
|
87
|
+
INFO -- Run - TestRun : Running subtask (1/2): CollectFiles
|
86
88
|
DEBUG -- CollectFiles - TestRun : Processing subitem (1/1): items
|
87
89
|
DEBUG -- CollectFiles - items : Processing subitem (1/3): test_dir_item.rb
|
88
90
|
DEBUG -- CollectFiles - items : Processing subitem (2/3): test_file_item.rb
|
89
91
|
DEBUG -- CollectFiles - items : Processing subitem (3/3): test_run.rb
|
90
92
|
DEBUG -- CollectFiles - items : 3 of 3 subitems passed
|
91
93
|
DEBUG -- CollectFiles - TestRun : 1 of 1 subitems passed
|
94
|
+
INFO -- Run - TestRun : Running subtask (2/2): ProcessFiles
|
92
95
|
INFO -- ProcessFiles - TestRun : Running subtask (1/2): ChecksumTester
|
93
96
|
DEBUG -- ProcessFiles/ChecksumTester - TestRun : Processing subitem (1/1): items
|
94
97
|
DEBUG -- ProcessFiles/ChecksumTester - items : Processing subitem (1/3): test_dir_item.rb
|
@@ -103,7 +106,8 @@ DEBUG -- ProcessFiles/CamelizeName - Items : Processing subitem (2/3): test_file
|
|
103
106
|
DEBUG -- ProcessFiles/CamelizeName - Items : Processing subitem (3/3): test_run.rb
|
104
107
|
DEBUG -- ProcessFiles/CamelizeName - Items : 3 of 3 subitems passed
|
105
108
|
DEBUG -- ProcessFiles/CamelizeName - TestRun : 1 of 1 subitems passed
|
106
|
-
INFO --
|
109
|
+
INFO -- ProcessFiles - TestRun : Done
|
110
|
+
INFO -- Run - TestRun : Done
|
107
111
|
STR
|
108
112
|
sample_out = sample_out.lines.to_a
|
109
113
|
|
@@ -118,12 +122,13 @@ STR
|
|
118
122
|
end
|
119
123
|
|
120
124
|
expect(run.summary['DEBUG']).to eq 18
|
121
|
-
expect(run.log_history.size).to eq
|
122
|
-
expect(run.status_log.size).to eq
|
125
|
+
expect(run.log_history.size).to eq 13
|
126
|
+
expect(run.status_log.size).to eq 10
|
123
127
|
expect(run.items.first.log_history.size).to eq 12
|
124
128
|
expect(run.items.first.status_log.size).to eq 6
|
125
129
|
|
126
130
|
[
|
131
|
+
{task: 'Run', status: :STARTED},
|
127
132
|
{task: 'CollectFiles', status: :STARTED},
|
128
133
|
{task: 'CollectFiles', status: :DONE},
|
129
134
|
{task: 'ProcessFiles', status: :STARTED},
|
@@ -132,6 +137,7 @@ STR
|
|
132
137
|
{task: 'ProcessFiles/CamelizeName', status: :STARTED},
|
133
138
|
{task: 'ProcessFiles/CamelizeName', status: :DONE},
|
134
139
|
{task: 'ProcessFiles', status: :DONE},
|
140
|
+
{task: 'Run', status: :DONE},
|
135
141
|
].each_with_index do |h, i|
|
136
142
|
h.keys.each { |key| expect(run.status_log[i][key]).to eq h[key] }
|
137
143
|
end
|
@@ -159,14 +165,19 @@ STR
|
|
159
165
|
end
|
160
166
|
|
161
167
|
[
|
168
|
+
{severity: 'INFO', task: 'Run', message: 'Ingest run started.'},
|
169
|
+
{severity: 'INFO', task: 'Run', message: 'Running subtask (1/2): CollectFiles'},
|
162
170
|
{severity: 'DEBUG', task: 'CollectFiles', message: 'Processing subitem (1/1): items'},
|
163
171
|
{severity: 'DEBUG', task: 'CollectFiles', message: '1 of 1 subitems passed'},
|
172
|
+
{severity: 'INFO', task: 'Run', message: 'Running subtask (2/2): ProcessFiles'},
|
164
173
|
{severity: 'INFO', task: 'ProcessFiles', message: 'Running subtask (1/2): ChecksumTester'},
|
165
174
|
{severity: 'DEBUG', task: 'ProcessFiles/ChecksumTester', message: 'Processing subitem (1/1): items'},
|
166
175
|
{severity: 'DEBUG', task: 'ProcessFiles/ChecksumTester', message: '1 of 1 subitems passed'},
|
167
176
|
{severity: 'INFO', task: 'ProcessFiles', message: 'Running subtask (2/2): CamelizeName'},
|
168
177
|
{severity: 'DEBUG', task: 'ProcessFiles/CamelizeName', message: 'Processing subitem (1/1): items'},
|
169
178
|
{severity: 'DEBUG', task: 'ProcessFiles/CamelizeName', message: '1 of 1 subitems passed'},
|
179
|
+
{severity: 'INFO', task: 'ProcessFiles', message: 'Done'},
|
180
|
+
{severity: 'INFO', task: 'Run', message: 'Done'},
|
170
181
|
].each_with_index do |h, i|
|
171
182
|
h.keys.each { |key| expect(run.log_history[i][key]).to eq h[key] }
|
172
183
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: libis-workflow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kris Dekeyser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-04-
|
11
|
+
date: 2016-04-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -155,7 +155,7 @@ files:
|
|
155
155
|
- lib/libis/workflow/status.rb
|
156
156
|
- lib/libis/workflow/task.rb
|
157
157
|
- lib/libis/workflow/task_group.rb
|
158
|
-
- lib/libis/workflow/
|
158
|
+
- lib/libis/workflow/task_runner.rb
|
159
159
|
- lib/libis/workflow/version.rb
|
160
160
|
- lib/libis/workflow/work_item.rb
|
161
161
|
- lib/libis/workflow/worker.rb
|
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'libis/workflow/task'
|
2
|
-
|
3
|
-
module Libis
|
4
|
-
module Workflow
|
5
|
-
module Tasks
|
6
|
-
|
7
|
-
class Analyzer < Task
|
8
|
-
|
9
|
-
parameter quiet: true, frozen: true
|
10
|
-
parameter recursive: false, frozen: true
|
11
|
-
|
12
|
-
# @param [Libis::Workflow::Base::WorkItem] item
|
13
|
-
def run(item)
|
14
|
-
|
15
|
-
recursive_run(item)
|
16
|
-
self.workitem = item
|
17
|
-
info 'Ingest finished', item
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def recursive_run(item)
|
24
|
-
|
25
|
-
item.properties['ingest_failed'] = item.check_status(:FAILED)
|
26
|
-
|
27
|
-
item.summary = {}
|
28
|
-
item.log_history.each do |log|
|
29
|
-
level = log[:severity]
|
30
|
-
item.summary[level.to_s] ||= 0
|
31
|
-
item.summary[level.to_s] += 1
|
32
|
-
end
|
33
|
-
|
34
|
-
item.each do |i|
|
35
|
-
recursive_run i
|
36
|
-
i.summary.each do |level, count|
|
37
|
-
item.summary[level] ||= 0
|
38
|
-
item.summary[level] += (count || 0)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
rescue RuntimeError => ex
|
43
|
-
|
44
|
-
self.workitem = item
|
45
|
-
error 'Failed to analyze item: %s - %s', item, item.class, item.name
|
46
|
-
error 'Exception: %s', item, ex.message
|
47
|
-
|
48
|
-
ensure
|
49
|
-
|
50
|
-
item.save!
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|