libis-workflow 2.0.beta.9 → 2.0.beta.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|