libis-workflow 2.0.beta.9 → 2.0.beta.10
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/.travis.yml +8 -13
- data/README.md +190 -94
- data/lib/libis/workflow/base/dir_item.rb +15 -0
- data/lib/libis/workflow/base/file_item.rb +82 -0
- data/lib/libis/workflow/base/run.rb +21 -9
- data/lib/libis/workflow/base/work_item.rb +246 -0
- data/lib/libis/workflow/base/workflow.rb +66 -13
- data/lib/libis/workflow/base.rb +6 -0
- data/lib/libis/workflow/dir_item.rb +12 -0
- data/lib/libis/workflow/file_item.rb +17 -0
- data/lib/libis/workflow/run.rb +3 -4
- data/lib/libis/workflow/task.rb +22 -17
- data/lib/libis/workflow/tasks/analyzer.rb +6 -3
- data/lib/libis/workflow/version.rb +1 -1
- data/lib/libis/workflow/work_item.rb +51 -0
- data/lib/libis/workflow.rb +12 -6
- data/spec/items/test_dir_item.rb +2 -3
- data/spec/items/test_file_item.rb +2 -3
- data/spec/items/test_run.rb +1 -1
- data/spec/tasks/camelize_name.rb +1 -1
- data/spec/tasks/checksum_tester.rb +1 -1
- data/spec/workflow_spec.rb +29 -80
- metadata +10 -7
- data/lib/libis/workflow/workitems/dir_item.rb +0 -12
- data/lib/libis/workflow/workitems/file_item.rb +0 -78
- data/lib/libis/workflow/workitems/work_item.rb +0 -231
- data/lib/libis/workflow/workitems.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 23bc91f367eb73cccde5236f1dde4720145a09a3
|
4
|
+
data.tar.gz: f5431781f4a3cd3cb2289c55531b96dd8244d187
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e530a4ee73533d7ea9d3419d1c5473d770a9d6e9fa8e770d78bdf2266a9439ced5300baf7a2f7c269bd341057997a6190b5564e41a1c4610c0a88d6314aaf989
|
7
|
+
data.tar.gz: abbac4ae9505e6634b96d3af9aa7f93bd0644f2f901cecb0a216f19ac6a645536bbeae38a4bc55f24c0b171aa39e0df019ec30c59864bc5a1015d0bc6c52a01a
|
data/.travis.yml
CHANGED
@@ -1,30 +1,25 @@
|
|
1
1
|
language: ruby
|
2
|
-
|
2
|
+
sudo: false
|
3
3
|
bundler_args: --without development
|
4
4
|
cache: bundler
|
5
5
|
rvm:
|
6
|
-
- 1.
|
7
|
-
- 2.
|
8
|
-
- 2.2
|
6
|
+
- 2.1.0
|
7
|
+
- 2.2.0
|
9
8
|
- ruby-head
|
10
|
-
- jruby-
|
9
|
+
- jruby-9.0.1.0
|
11
10
|
jdk:
|
12
11
|
- openjdk7
|
13
12
|
- oraclejdk7
|
14
13
|
- oraclejdk8
|
15
14
|
matrix:
|
16
15
|
exclude:
|
17
|
-
- rvm: 1.
|
16
|
+
- rvm: 2.1.0
|
18
17
|
jdk: oraclejdk7
|
19
|
-
- rvm: 1.
|
18
|
+
- rvm: 2.1.0
|
20
19
|
jdk: oraclejdk8
|
21
|
-
- rvm: 2.
|
20
|
+
- rvm: 2.2.0
|
22
21
|
jdk: oraclejdk7
|
23
|
-
- rvm: 2.
|
24
|
-
jdk: oraclejdk8
|
25
|
-
- rvm: 2.2
|
26
|
-
jdk: oraclejdk7
|
27
|
-
- rvm: 2.2
|
22
|
+
- rvm: 2.2.0
|
28
23
|
jdk: oraclejdk8
|
29
24
|
- rvm: ruby-head
|
30
25
|
jdk: oraclejdk7
|
data/README.md
CHANGED
@@ -26,26 +26,35 @@ Or install it yourself as:
|
|
26
26
|
## Architecture
|
27
27
|
|
28
28
|
This gem is essentially a simple, custom workflow system. The core of the workflow are the tasks. You can - and should -
|
29
|
-
create your own tasks by creating new classes
|
29
|
+
create your own tasks by creating new classes inherited from ::Libis::Workflow::Task. The ::Libis::Workflow::Task class
|
30
30
|
and the included ::Libis::Workflow::Base::Logger module provide the necessary attributes and methods to make them work
|
31
|
-
in the workflow. See the detailed documentation for the
|
32
|
-
|
33
|
-
The objects that the tasks will be working on should include the ::Libis::Workflow::WorkItem module.
|
34
|
-
When working with file objects the module ::Libis::Workflow::FileItem and/or ::Libis::Workflow::DirItem
|
35
|
-
be included for additional file-specific functionality.
|
36
|
-
Work items can be organized in different types and a hierarchical structure.
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
31
|
+
in the workflow. See the detailed documentation for the class and module for more information.
|
32
|
+
|
33
|
+
The objects that the tasks will be working on should include the ::Libis::Workflow::Base::WorkItem module.
|
34
|
+
When working with file objects the module ::Libis::Workflow::Base::FileItem and/or ::Libis::Workflow::Base::DirItem
|
35
|
+
modules should be included for additional file-specific functionality.
|
36
|
+
Work items can be organized in different types and a hierarchical structure. A simple implementation of work items with
|
37
|
+
in-memory storage is provided as classes ::Libis::Workflow::WorkItem, ::Libis::Workflow::FileItem and
|
38
|
+
::Libis::Workflow::DirItem.
|
39
|
+
|
40
|
+
All the tasks will be organized into a workflow object for which a base module ::Libis::Workflow::Base::Workflow is
|
41
|
+
provided. It contains all the basic logic required for proper configuration and operation. Again a in-memory
|
42
|
+
implementation is provided in the class ::Libis::Workflow::Workflow for your convenience to be used as-is or to derive
|
43
|
+
your own from.
|
44
|
+
|
45
|
+
The workflow object will be able to execute the tasks in proper order on all the WorkItems supplied/collected. Each
|
46
|
+
task can be implemented with code to run or simply contain a list of child tasks. When a workflow is executed a special
|
47
|
+
run object is created that captures the configuration, logs and workitems generated while executing the tasks. Essential
|
48
|
+
logic is provided in the module ::Libis::Workflow::Base::Run with a simple in-memory implementation in
|
49
|
+
::Libis::Workflow::Run. The run object's class name has to be provided to the workflow configuration so that the
|
50
|
+
workflow can instantiate the correct object.
|
51
|
+
|
52
|
+
One tasks is predefined:
|
44
53
|
::Libis::Workflow::Tasks::Analyzer - analyzes the workflow run and summarizes the results. It is always included as the
|
45
54
|
last task by the workflow unless you supply a closing task called 'Analyzer' yourself.
|
46
55
|
|
47
56
|
The whole ingester workflow is configured by a Singleton object ::Libis::Workflow::Config which contains settings for
|
48
|
-
logging
|
57
|
+
logging and paths where tasks and workitems can be found.
|
49
58
|
|
50
59
|
## Usage
|
51
60
|
|
@@ -60,17 +69,20 @@ well. This is shown in the examples below.
|
|
60
69
|
|
61
70
|
### Workflows
|
62
71
|
|
63
|
-
|
64
|
-
by calling the 'run' method. This will create
|
65
|
-
method on it. The Workflow constructor takes no arguments, but is should be configured
|
66
|
-
method with the workflow configuration as an argument. The 'run' method takes an option Hash
|
72
|
+
An implementation of ::Libis::Workflow::Base::Workflow contains the definition of a workflow. Once instantiated, it can
|
73
|
+
be run by calling the 'run' method. This will create an intance of an implementation of ::Libis::Workflow::Base::Run,
|
74
|
+
configure it and call the 'run' method on it. The Workflow constructor takes no arguments, but is should be configured
|
75
|
+
by calling the 'configure' method with the workflow configuration as an argument. The 'run' method takes an option Hash
|
76
|
+
as argument.
|
67
77
|
|
68
78
|
#### Workflow configuration
|
69
79
|
|
70
80
|
A workflow configuration is a Hash with:
|
81
|
+
* name: String to identify the workflow
|
82
|
+
* description: String with detailed textual information
|
71
83
|
* tasks: Array of task descriptions
|
72
|
-
*
|
73
|
-
for each run and serves as the root work item for that particular run.
|
84
|
+
* run_object: String with class name of the ::Libis::Workflow::Base::Run implementation to be created. An istance of
|
85
|
+
this class will be created for each run and serves as the root work item for that particular run.
|
74
86
|
* input: Hash with input variable definitions
|
75
87
|
|
76
88
|
##### Task description
|
@@ -79,7 +91,15 @@ is a Hash with:
|
|
79
91
|
* class: String with class name of the task
|
80
92
|
* name: String with the name of the task
|
81
93
|
* tasks: Array with task definitions of sub-tasks
|
82
|
-
*
|
94
|
+
* any task parameter values. Each task can define parameters that configure the task. It is using the
|
95
|
+
::Libis::Tools::Parameter class for this.
|
96
|
+
|
97
|
+
The ::Libis::Workflow::Task base class allready defines the following parameters:
|
98
|
+
* quiet: Prevent generating log output. Default: false
|
99
|
+
* abort_on_error: Stop all tasks when an error occurs. Default: false
|
100
|
+
* always_run: Run this task, even if the item failed a previous task. Default: false
|
101
|
+
* subitems: Do not process the given item, but only the subitems. Default: false
|
102
|
+
* recursive: Run the task on all subitems recursively. Default: false
|
83
103
|
|
84
104
|
If 'class' is not present, the default '::Libis::Workflow::Task' with the given name will be instantiated, which simply
|
85
105
|
iterates over the child items of the given work item and performs each sub-task on each of the child items. If a 'class'
|
@@ -88,28 +108,17 @@ the chapter on 'Tasks' below for more information on tasks.
|
|
88
108
|
|
89
109
|
##### Input variable definition
|
90
110
|
|
91
|
-
The
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
#### Options
|
104
|
-
|
105
|
-
The option Hash contains special run-time configuration parameters for the workflow:
|
106
|
-
* action: String with the action that should be taken. Currently only 'start' is supported. In the future support for
|
107
|
-
'restart' and 'continue' will be added.
|
108
|
-
* interactive: Boolean that indicates if the user should be queried to input values for variables that have no value set.
|
109
|
-
This will pause the workflow run and is therefore not compatible with scheduling the workflow. For unattended runs the
|
110
|
-
options should be set to false, causing the run to throw an exception if an input variable is missing a value.
|
111
|
-
|
112
|
-
Remaining values are considered to be (default) values for the input variables.
|
111
|
+
The input variables define parameters for the workflow. When a workflow is run, it can give values for any of these
|
112
|
+
input variable and the workflow run will use the new values instead of the defaults.
|
113
|
+
|
114
|
+
The key of the input Hash is the unique name of the variable. The value is another Hash with the parameter definition.
|
115
|
+
See ::Libis::Tools::Parameter for the content of this Hash.
|
116
|
+
|
117
|
+
An additional property of the parameters is the 'propagate_to' property. It defines how the workflow run should push
|
118
|
+
the values set for the input parameters to the parameters on the tasks. These task parameters can be addressed by a
|
119
|
+
'<Task class or Task name>[#<parameter name>]' string. If necessary the task class or name may be specified as a full
|
120
|
+
path with '/' separators. The parameter name part is optional and considered to be the same as the input parameter name
|
121
|
+
if absent.
|
113
122
|
|
114
123
|
#### Run-time configuration
|
115
124
|
|
@@ -125,7 +134,7 @@ Creating your own work items is highly recommended and is fairly easy:
|
|
125
134
|
|
126
135
|
```ruby
|
127
136
|
|
128
|
-
require 'libis/workflow
|
137
|
+
require 'libis/workflow'
|
129
138
|
|
130
139
|
class MyWorkItem < ::Libis::Workflow::WorkItem
|
131
140
|
attr_accesor :name
|
@@ -137,13 +146,81 @@ Creating your own work items is highly recommended and is fairly easy:
|
|
137
146
|
end
|
138
147
|
```
|
139
148
|
|
140
|
-
|
149
|
+
or if a custom storage implementation is desired, a number of data items and methods require implementation:
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
|
153
|
+
require 'libis/workflow'
|
154
|
+
|
155
|
+
class MyWorkItem < MyStorageItem
|
156
|
+
include ::Libis::Workflow::Base::WorkItem
|
157
|
+
|
158
|
+
stored_attribute :parent
|
159
|
+
stored_attribute :items
|
160
|
+
stored_attribute :options
|
161
|
+
stored_attribute :properties
|
162
|
+
stored_attribute :log_history
|
163
|
+
stored_attribute :status_log
|
164
|
+
stored_attribute :summary
|
165
|
+
|
166
|
+
def initialize
|
167
|
+
self.parent = nil
|
168
|
+
self.items = []
|
169
|
+
self.options = {}
|
170
|
+
self.properties = {}
|
171
|
+
self.log_history = []
|
172
|
+
self.status_log = []
|
173
|
+
self.summary = {}
|
174
|
+
end
|
175
|
+
|
176
|
+
protected
|
177
|
+
|
178
|
+
def add_log_entry(msg)
|
179
|
+
self.log_history << msg.merge(c_at: ::Time.now)
|
180
|
+
end
|
181
|
+
|
182
|
+
def add_status_log(message, tasklist = nil)
|
183
|
+
self.status_log << { timestamp: ::Time.now, tasklist: tasklist, text: message }.cleanup
|
184
|
+
end
|
185
|
+
|
186
|
+
def status_label(status_entry)
|
187
|
+
"#{status_entry[:tasklist].last rescue nil}#{status_entry[:text] rescue nil}"
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
```
|
192
|
+
|
193
|
+
Work items that are file-based can derive from the ::Libis::Workflow::FileItem class:
|
141
194
|
|
142
195
|
```ruby
|
143
196
|
|
144
|
-
require 'libis/workflow
|
197
|
+
require 'libis/workflow'
|
198
|
+
|
199
|
+
class MyFileItem < ::Libis::Workflow::FileItem
|
145
200
|
|
146
|
-
|
201
|
+
def initialize(file)
|
202
|
+
filename = file
|
203
|
+
super
|
204
|
+
end
|
205
|
+
|
206
|
+
def filesize
|
207
|
+
properties[:size]
|
208
|
+
end
|
209
|
+
|
210
|
+
def fixity_check(checksum)
|
211
|
+
properties[:checksum] == checksum
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
```
|
216
|
+
|
217
|
+
or include the ::Libis::Workflow::Base::FileItem module:
|
218
|
+
|
219
|
+
```ruby
|
220
|
+
|
221
|
+
require 'libis/workflow'
|
222
|
+
|
223
|
+
class MyFileItem < MyWorkItem
|
147
224
|
include ::Libis::Workflow::FileItem
|
148
225
|
|
149
226
|
def initialize(file)
|
@@ -162,6 +239,8 @@ Work items that are file-based should also include the ::Libis::Workflow::FileIt
|
|
162
239
|
end
|
163
240
|
```
|
164
241
|
|
242
|
+
|
243
|
+
|
165
244
|
## Tasks
|
166
245
|
|
167
246
|
Tasks should inherit from ::Libis::Workflow::Task and specify the actions it wants to
|
@@ -172,69 +251,85 @@ perform on each work item:
|
|
172
251
|
class MyTask < ::Libis::Workflow::Task
|
173
252
|
|
174
253
|
def process_item(item)
|
175
|
-
item
|
254
|
+
if do_something(item)
|
255
|
+
info "Did something"
|
256
|
+
else
|
257
|
+
raise ::Libis::WorkflowError, "Something went wrong"
|
258
|
+
end
|
176
259
|
rescue Exception => e
|
177
|
-
|
260
|
+
error "Fatal problem, aborting"
|
261
|
+
raise ::Libis::WorkflowAbort, "Fatal problem"
|
262
|
+
ensure
|
263
|
+
item
|
178
264
|
end
|
179
265
|
|
180
266
|
end
|
181
267
|
```
|
182
268
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
269
|
+
As seen above, the task should define a method called process_item that takes one argument. The argument will be a
|
270
|
+
reference to the work item that it needs to perform an action on. The task has several option to progress after
|
271
|
+
performing its actions:
|
272
|
+
* return. This is considered a normal and successful operation result. If the item was replaced by a new item or if the
|
273
|
+
item tree has changed, it is recommended to return the new item. After a successful return the item's status will be
|
274
|
+
set to 'done' for the given task.
|
275
|
+
* raise a ::Libis::WorkflowError. Indicates that something went wrong during the processing of the item. The item's
|
276
|
+
status will be set to failed for the given task and the exception message will be printed in the error log. Processing
|
277
|
+
will continue with the next item. This action is recommended for temporary or recoverable errors.
|
278
|
+
* raise a ::Libis::WorkflowAbort. A severe and fatal error has occured. Processing will abort immediately and the
|
279
|
+
failure status will be escalated to all items up the item hierarchy. Due to the escalating behaviour, no message is
|
280
|
+
printed in the error log automatically, so it is up to the task to an appropriate log the error itself.
|
281
|
+
* raise any other Exception. Should be avoided, but if it happens nevertheless, it will cause the item to fail for the
|
282
|
+
given task and the exception message to be logged in the error log. It will attempt to process the other items.
|
283
|
+
|
284
|
+
### Controlling behavior with parameters
|
285
|
+
|
286
|
+
You have some options to control how the task will behave in special cases. These are controlled using parameters on
|
287
|
+
the task, which can be set (and fixed with the 'frozen' option) on the task, but can be configured at run-time with the
|
288
|
+
help of workflow input parameters and run options.
|
289
|
+
|
290
|
+
#### Performing an action on the work item and all child items recursively
|
291
|
+
|
292
|
+
With the 'recursive' parameter set to true, your task's process_item method will be called for the work item and then
|
293
|
+
once for each child and each child's children recursively.
|
193
294
|
|
194
|
-
|
295
|
+
#### Performing an action only on the child items, skipping the work item itself
|
195
296
|
|
196
|
-
|
197
|
-
|
198
|
-
|
297
|
+
The parameter 'subitems' decides if the item handed over to the task will be processed or if it will process only it's
|
298
|
+
child items. This will only work once, not recursively, but by organizing tasks hierarchically with 'subitems' set to
|
299
|
+
true, it is possible to make sure that only items on a certain hierarchy level are performed. Recommended for workflows
|
300
|
+
where a well-known and fixed hierarchical structure has to be processed selectively.
|
199
301
|
|
200
|
-
|
302
|
+
Alternatively the 'recursive' option can be set and the 'process_item' method could check for certain item types,
|
303
|
+
properties or hierarchy levels to decide to perform the operation. This approach is more flexible but harder to
|
304
|
+
understand unless well documented.
|
201
305
|
|
202
|
-
|
203
|
-
child items should be done in process_item as usual, but processing the parent item can be done either by defining a
|
204
|
-
pre_process method or a process method that ends with a 'super' call. Using this should be an exception as it is
|
205
|
-
recommended to create a seperate task to process the child work items.
|
306
|
+
#### Preventing any logging output from the task
|
206
307
|
|
207
|
-
|
308
|
+
Logging output can be blocked on a task-by-task basis by setting the 'quiet' parameter to true. Probably not usefull
|
309
|
+
except for the Analyzer task where the parameter is fixed to true. Logging output would otherwise intervene with the
|
310
|
+
log summary processing performed by the task.
|
208
311
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
nodes in the workflow definition tree are allowed to use the default implementation (by defining only 'name' and 'tasks'
|
215
|
-
value). See above on 'Workflow configuration' for more info.
|
312
|
+
#### Aborting the task whenever any item fails
|
313
|
+
|
314
|
+
When a task is so critical in the workflow process that any failure renders further processing useless, the parameter
|
315
|
+
'abort_on_error' can be turned on. Raising a ::Libis::WorkflowAbort exception would perform the same thing, but the
|
316
|
+
parameter makes the configuration more flexible.
|
216
317
|
|
217
|
-
|
318
|
+
#### Always running a task, even on items that failed in an earlier stage in the workflow
|
218
319
|
|
219
|
-
The
|
220
|
-
the
|
320
|
+
The opposite of aborting on error, the parameter 'always_run' can be set to true to force a task to process the items
|
321
|
+
even if the item has a failed status from a previous task. Note that this will cause the item's status to no longer be
|
322
|
+
failing until a task fails on the item again. The old failed status will be tracable in the status history.
|
221
323
|
|
222
|
-
|
223
|
-
|
224
|
-
|
324
|
+
The parameter only configures the task on which it is set. If the task is a subtask it will only be forced to run if
|
325
|
+
any of it's previous sibling tasks failed. In order to force the run, even if the item failed in another branch of the
|
326
|
+
task hiearchy, the parent tasks should have their 'always_run' parameter also set to true.
|
225
327
|
|
226
|
-
|
328
|
+
### Pre- and postprocessing
|
227
329
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
run due to a previous failure.
|
232
|
-
|
233
|
-
The items_fist option determines the processing order. If a task has multiple subtasks and the given workitem has
|
234
|
-
multiple subitems, setting the items_first option will cause it to take the first subitem, run the first subtask on it,
|
235
|
-
then the second subtask and so on. Next it will run the first, second, ... subtask on the second subitem and so on. If
|
236
|
-
the option is not set or set to false, the first subtask will run on each subitem, then the second subtask on each
|
237
|
-
subitem, and so on.
|
330
|
+
The default implementation of 'process' is to call 'pre_process' and then call 'process_item' on each child item,
|
331
|
+
followed by calling 'post_process'. The methods 'pre_process' and 'post_process' are no-operation methods by default,
|
332
|
+
but can be overwritten if needed.
|
238
333
|
|
239
334
|
### Convenience functions
|
240
335
|
|
@@ -260,6 +355,7 @@ stderr string.
|
|
260
355
|
#### names()
|
261
356
|
|
262
357
|
An array of strings with the hierarchical path of tasks leading to the current task. Can be usefull for log messages.
|
358
|
+
The method 'namepath' returns a '/' separated path of tasks.
|
263
359
|
|
264
360
|
#### (debug/info/warn/error/fatal)(message, *args)
|
265
361
|
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'digest'
|
4
|
+
|
5
|
+
require 'libis/workflow/base/work_item'
|
6
|
+
|
7
|
+
module Libis
|
8
|
+
module Workflow
|
9
|
+
module Base
|
10
|
+
|
11
|
+
# noinspection RubyResolve
|
12
|
+
module FileItem
|
13
|
+
include Libis::Workflow::Base::WorkItem
|
14
|
+
|
15
|
+
def filename
|
16
|
+
File.basename(self.properties[:filename]) || self.properties[:link]
|
17
|
+
end
|
18
|
+
|
19
|
+
def name
|
20
|
+
self.properties[:name] || self.filename
|
21
|
+
end
|
22
|
+
|
23
|
+
def filelist
|
24
|
+
(self.parent.filelist rescue Array.new).push(filename).compact
|
25
|
+
end
|
26
|
+
|
27
|
+
def filepath
|
28
|
+
self.filelist.join('/')
|
29
|
+
end
|
30
|
+
|
31
|
+
def fullpath
|
32
|
+
self.properties[:filename]
|
33
|
+
end
|
34
|
+
|
35
|
+
def filename=(name)
|
36
|
+
begin
|
37
|
+
stats = ::File.stat name
|
38
|
+
self.properties[:size] = stats.size
|
39
|
+
self.properties[:access_time] = stats.atime
|
40
|
+
self.properties[:modification_time] = stats.mtime
|
41
|
+
self.properties[:creation_time] = stats.ctime
|
42
|
+
self.properties[:mode] = stats.mode
|
43
|
+
self.properties[:uid] = stats.uid
|
44
|
+
self.properties[:gid] = stats.gid
|
45
|
+
set_checksum(:MD5, ::Digest::MD5.hexdigest(File.read(name))) if File.file?(name)
|
46
|
+
rescue
|
47
|
+
# ignored
|
48
|
+
end
|
49
|
+
self.properties[:filename] = name
|
50
|
+
end
|
51
|
+
|
52
|
+
def checksum(checksum_type)
|
53
|
+
self.properties[('checksum_' + checksum_type.to_s.downcase).to_sym]
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_checksum(checksum_type, value)
|
57
|
+
self.properties[('checksum_' + checksum_type.to_s.downcase).to_sym] = value
|
58
|
+
end
|
59
|
+
|
60
|
+
def link
|
61
|
+
self.properties[:link]
|
62
|
+
end
|
63
|
+
|
64
|
+
def link=(name)
|
65
|
+
self.properties[:link] = name
|
66
|
+
end
|
67
|
+
|
68
|
+
def set_info(info)
|
69
|
+
info.each do |k, v|
|
70
|
+
self.properties[k] = v
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def safe_name
|
75
|
+
self.name.to_s.gsub(/[^\w.-]/) { |s| '%%%02x' % s.ord }
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -2,23 +2,31 @@
|
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
4
|
|
5
|
-
require 'libis/workflow/
|
5
|
+
require 'libis/workflow/base/work_item'
|
6
6
|
|
7
7
|
module Libis
|
8
8
|
module Workflow
|
9
9
|
module Base
|
10
|
-
module Run
|
11
|
-
include ::Libis::Workflow::WorkItem
|
12
|
-
|
13
|
-
def start_date; raise RuntimeError.new "Method not implemented: #{caller[0]}"; end
|
14
|
-
def start_date=(_); raise RuntimeError.new "Method not implemented: #{caller[0]}"; end
|
15
10
|
|
16
|
-
|
17
|
-
|
11
|
+
# Base module for all workflow runs. It is created by an associated workflow when the workflow is executed.
|
12
|
+
#
|
13
|
+
# This module lacks the implementation for the data attributes. It functions as an interface that describes the
|
14
|
+
# common functionality regardless of the storage implementation. These attributes require some implementation:
|
15
|
+
#
|
16
|
+
# - start_date: [Time] the timestamp of the execution of the run
|
17
|
+
# - workflow: [Object] a reference to the Workflow this Run belongs to
|
18
|
+
#
|
19
|
+
# Note that ::Libis::Workflow::Base::WorkItem is a parent module and therefore requires implementation of the
|
20
|
+
# attributes of that module too.
|
21
|
+
#
|
22
|
+
# A simple in-memory implementation can be found in ::Libis::Workflow::Run
|
23
|
+
module Run
|
24
|
+
include ::Libis::Workflow::Base::WorkItem
|
18
25
|
|
19
|
-
|
26
|
+
attr_accessor :tasks
|
20
27
|
|
21
28
|
def work_dir
|
29
|
+
# noinspection RubyResolve
|
22
30
|
dir = File.join(Config.workdir, self.name)
|
23
31
|
FileUtils.mkpath dir unless Dir.exist?(dir)
|
24
32
|
dir
|
@@ -36,6 +44,9 @@ module Libis
|
|
36
44
|
self.name
|
37
45
|
end
|
38
46
|
|
47
|
+
# Execute the workflow.
|
48
|
+
# @param [Hash] opts a list with parameter name and value tuples that specify the values for the workflow input
|
49
|
+
# parameters.
|
39
50
|
def run(opts = {})
|
40
51
|
|
41
52
|
self.start_date = Time.now
|
@@ -48,6 +59,7 @@ module Libis
|
|
48
59
|
self.status = :STARTED
|
49
60
|
|
50
61
|
self.tasks.each do |task|
|
62
|
+
# note: do not return as we want to give any remaining task in the queue the oportunity to run
|
51
63
|
next if self.failed? and not task.parameter(:always_run)
|
52
64
|
task.run self
|
53
65
|
end
|