scout-gear 10.7.1 → 10.7.3
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/.vimproject +50 -30
- data/VERSION +1 -1
- data/lib/scout/association/index.rb +5 -1
- data/lib/scout/association/item.rb +1 -1
- data/lib/scout/association.rb +46 -11
- data/lib/scout/entity/format.rb +9 -4
- data/lib/scout/entity/identifiers.rb +4 -4
- data/lib/scout/entity/named_array.rb +13 -0
- data/lib/scout/entity/property.rb +3 -1
- data/lib/scout/entity.rb +7 -4
- data/lib/scout/knowledge_base/enrichment.rb +9 -0
- data/lib/scout/knowledge_base/entity.rb +143 -0
- data/lib/scout/knowledge_base/list.rb +95 -0
- data/lib/scout/knowledge_base/query.rb +96 -0
- data/lib/scout/knowledge_base/registry.rb +173 -0
- data/lib/scout/knowledge_base/traverse.rb +329 -0
- data/lib/scout/knowledge_base.rb +91 -0
- data/lib/scout/persist/tsv/adapter/base.rb +13 -1
- data/lib/scout/persist/tsv.rb +2 -1
- data/lib/scout/tsv/annotation.rb +4 -4
- data/lib/scout/tsv/attach.rb +10 -2
- data/lib/scout/tsv/change_id.rb +3 -0
- data/lib/scout/tsv/dumper.rb +34 -30
- data/lib/scout/tsv/index.rb +0 -2
- data/lib/scout/tsv/open.rb +1 -0
- data/lib/scout/tsv/parser.rb +21 -10
- data/lib/scout/tsv/path.rb +8 -0
- data/lib/scout/tsv/stream.rb +17 -10
- data/lib/scout/tsv/traverse.rb +12 -2
- data/lib/scout/tsv/util/process.rb +4 -1
- data/lib/scout/tsv/util/select.rb +8 -2
- data/lib/scout/tsv/util/sort.rb +23 -15
- data/lib/scout/tsv/util.rb +11 -2
- data/lib/scout/tsv.rb +25 -11
- data/lib/scout/workflow/definition.rb +3 -3
- data/lib/scout/workflow/deployment/orchestrator.rb +8 -5
- data/lib/scout/workflow/step/dependencies.rb +35 -11
- data/lib/scout/workflow/step/file.rb +2 -1
- data/lib/scout/workflow/step/info.rb +23 -2
- data/lib/scout/workflow/step/load.rb +5 -3
- data/lib/scout/workflow/step/progress.rb +6 -0
- data/lib/scout/workflow/step/provenance.rb +1 -1
- data/lib/scout/workflow/step/status.rb +10 -4
- data/lib/scout/workflow/step.rb +32 -12
- data/lib/scout/workflow/task/dependencies.rb +33 -24
- data/lib/scout/workflow/task/inputs.rb +40 -12
- data/lib/scout/workflow/task.rb +22 -10
- data/lib/scout/workflow/usage.rb +2 -2
- data/lib/scout/workflow.rb +1 -1
- data/scout-gear.gemspec +28 -4
- data/scout_commands/kb/config +33 -0
- data/scout_commands/kb/entities +35 -0
- data/scout_commands/kb/list +39 -0
- data/scout_commands/kb/query +78 -0
- data/scout_commands/kb/register +44 -0
- data/scout_commands/kb/show +37 -0
- data/scout_commands/kb/traverse +66 -0
- data/test/data/person/brothers +1 -1
- data/test/scout/entity/test_identifiers.rb +3 -3
- data/test/scout/entity/test_named_array.rb +21 -0
- data/test/scout/knowledge_base/test_enrichment.rb +0 -0
- data/test/scout/knowledge_base/test_entity.rb +38 -0
- data/test/scout/knowledge_base/test_list.rb +40 -0
- data/test/scout/knowledge_base/test_query.rb +39 -0
- data/test/scout/knowledge_base/test_registry.rb +16 -0
- data/test/scout/knowledge_base/test_traverse.rb +245 -0
- data/test/scout/persist/test_tsv.rb +20 -0
- data/test/scout/persist/tsv/adapter/test_base.rb +20 -0
- data/test/scout/test_association.rb +17 -3
- data/test/scout/test_entity.rb +0 -15
- data/test/scout/test_knowledge_base.rb +27 -0
- data/test/scout/test_tsv.rb +40 -0
- data/test/scout/tsv/test_dumper.rb +24 -0
- data/test/scout/tsv/test_path.rb +24 -0
- data/test/scout/tsv/test_stream.rb +93 -0
- data/test/scout/tsv/test_traverse.rb +99 -0
- data/test/scout/tsv/test_util.rb +2 -0
- data/test/scout/tsv/util/test_select.rb +22 -0
- data/test/scout/tsv/util/test_sort.rb +24 -0
- data/test/scout/workflow/step/test_dependencies.rb +26 -0
- data/test/scout/workflow/step/test_info.rb +35 -0
- data/test/scout/workflow/task/test_dependencies.rb +67 -1
- data/test/scout/workflow/task/test_inputs.rb +24 -7
- data/test/scout/workflow/test_task.rb +36 -0
- data/test/scout/workflow/test_usage.rb +0 -1
- data/test/test_helper.rb +17 -0
- metadata +27 -3
data/lib/scout/tsv.rb
CHANGED
@@ -16,7 +16,8 @@ require_relative 'tsv/csv'
|
|
16
16
|
|
17
17
|
module TSV
|
18
18
|
extend Annotation
|
19
|
-
annotation :key_field, :fields, :type, :cast, :filename, :namespace, :unnamed, :identifiers, :serializer
|
19
|
+
annotation :key_field, :fields, :type, :cast, :filename, :namespace, :unnamed, :identifiers, :serializer, :entity_options
|
20
|
+
|
20
21
|
|
21
22
|
def self.str2options(str)
|
22
23
|
field_options,_sep, rest = str.partition("#")
|
@@ -34,7 +35,6 @@ module TSV
|
|
34
35
|
alias original_setup setup
|
35
36
|
|
36
37
|
def setup(obj, *rest, &block)
|
37
|
-
|
38
38
|
if rest.length == 1 && String === rest.first
|
39
39
|
options = TSV.str2options(rest.first)
|
40
40
|
if Array === obj
|
@@ -44,7 +44,7 @@ module TSV
|
|
44
44
|
when :single
|
45
45
|
nil
|
46
46
|
end
|
47
|
-
obj =
|
47
|
+
obj = IndiferentHash.array2hash(obj, default_value)
|
48
48
|
end
|
49
49
|
original_setup(obj, options, &block)
|
50
50
|
else
|
@@ -57,7 +57,7 @@ module TSV
|
|
57
57
|
when :single
|
58
58
|
nil
|
59
59
|
end
|
60
|
-
obj =
|
60
|
+
obj = IndiferentHash.array2hash(obj, default_value)
|
61
61
|
end
|
62
62
|
original_setup(obj, *rest, &block)
|
63
63
|
end
|
@@ -74,11 +74,17 @@ module TSV
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def self.open(file, options = {})
|
77
|
-
grep, invert_grep, nocache, monitor, entity_options = IndiferentHash.process_options options, :grep, :invert_grep, :nocache, :monitor, :entity_options
|
77
|
+
grep, invert_grep, fixed_grep, nocache, monitor, entity_options, unnamed, field = IndiferentHash.process_options options, :grep, :invert_grep, :fixed_grep, :nocache, :monitor, :entity_options, :unnamed, :field
|
78
|
+
|
79
|
+
if field and options[:field].nil?
|
80
|
+
options[:fields] = [field]
|
81
|
+
options[:type] ||= :single
|
82
|
+
end
|
78
83
|
|
79
84
|
persist_options = IndiferentHash.pull_keys options, :persist
|
80
85
|
persist_options = IndiferentHash.add_defaults persist_options, prefix: "TSV", type: :HDB, persist: false
|
81
86
|
persist_options[:data] ||= options[:data]
|
87
|
+
persist_options[:update] = options.delete(:update) if options.include?(:update)
|
82
88
|
|
83
89
|
file = StringIO.new file if String === file && ! (Path === file) && file.index("\n")
|
84
90
|
|
@@ -113,14 +119,22 @@ module TSV
|
|
113
119
|
end
|
114
120
|
|
115
121
|
tsv = if TSV::Parser === file
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
+
TSV.parse(file, **options)
|
123
|
+
else
|
124
|
+
options[:tsv_invert_grep] ||= invert_grep if invert_grep
|
125
|
+
Open.open(file, grep: grep, invert_grep: invert_grep, fixed_grep: fixed_grep, nocache: nocache) do |f|
|
126
|
+
TSV.parse(f, **options)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
if tsv.identifiers.nil? and Path === tsv.filename and tsv.filename.identifier_file_path
|
131
|
+
tsv.identifiers = tsv.filename.identifier_file_path.find if tsv.filename.identifier_file_path.exists?
|
122
132
|
end
|
123
133
|
|
134
|
+
tsv.unnamed = unnamed unless unnamed.nil?
|
135
|
+
|
136
|
+
tsv.entity_options = entity_options
|
137
|
+
|
124
138
|
tsv
|
125
139
|
end
|
126
140
|
end
|
@@ -164,9 +164,9 @@ module Workflow
|
|
164
164
|
Step.wait_for_jobs dependencies.select{|d| d.streaming? }
|
165
165
|
dep = dependencies.last
|
166
166
|
dep.join
|
167
|
-
raise dep.
|
167
|
+
raise dep.exception if dep.error?
|
168
168
|
raise Aborted, "Aborted dependency #{dep.path}" if dep.aborted?
|
169
|
-
|
169
|
+
merge_info type: dep.info[:type], task_alias: true
|
170
170
|
|
171
171
|
forget = config :forget_task_alias, "forget_task_alias"
|
172
172
|
forget = config :forget_dep_tasks, "forget_dep_tasks", :default => FORGET_TASK_ALIAS if forget.nil?
|
@@ -181,7 +181,7 @@ module Workflow
|
|
181
181
|
self.copy_linked_files_dir
|
182
182
|
self.dependencies = self.dependencies - [dep]
|
183
183
|
Open.rm_rf self.files_dir if Open.exist? self.files_dir
|
184
|
-
|
184
|
+
Open.link_dir dep.files_dir, self.files_dir if Open.exist?(dep.files_dir)
|
185
185
|
|
186
186
|
if dep.overriden?
|
187
187
|
Open.link dep.path, self.tmp_path
|
@@ -34,14 +34,16 @@ module Workflow
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def self.job_rules(rules, job)
|
37
|
+
IndiferentHash.setup(rules)
|
37
38
|
workflow = job.workflow.name
|
38
39
|
task_name = job.task_name.to_s
|
39
40
|
defaults = rules["defaults"] || {}
|
40
41
|
|
41
42
|
return IndiferentHash.setup(defaults) unless rules[workflow]
|
42
|
-
|
43
|
+
workflow_rules = IndiferentHash.setup(rules[workflow])
|
44
|
+
return IndiferentHash.setup(defaults) unless workflow_rules[task_name]
|
45
|
+
job_rules = IndiferentHash.setup(workflow_rules[task_name])
|
43
46
|
|
44
|
-
job_rules = IndiferentHash.setup(rules[workflow][task_name])
|
45
47
|
defaults.each{|k,v| job_rules[k] = v if job_rules[k].nil? } if defaults
|
46
48
|
job_rules
|
47
49
|
end
|
@@ -85,7 +87,7 @@ module Workflow
|
|
85
87
|
candidates = workload.
|
86
88
|
select{|k,v| v.empty? }.
|
87
89
|
collect{|k,v| k }.
|
88
|
-
reject{|k| k.done? || k.running? }
|
90
|
+
reject{|k| k.done? || k.running? || (k.error? && ! k.recoverable_error?) }
|
89
91
|
else
|
90
92
|
candidates = workload. #select{|k,v| Orchestrator.job_rules(rules, k) }.
|
91
93
|
select{|k,v| v.empty? }.
|
@@ -107,7 +109,7 @@ module Workflow
|
|
107
109
|
|
108
110
|
attr_accessor :available_resources, :resources_requested, :resources_used, :timer
|
109
111
|
|
110
|
-
def initialize(timer = 5, available_resources =
|
112
|
+
def initialize(timer = 5, available_resources = nil)
|
111
113
|
available_resources = {:cpus => Etc.nprocessors } if available_resources.nil?
|
112
114
|
@timer = timer
|
113
115
|
@available_resources = IndiferentHash.setup(available_resources)
|
@@ -192,7 +194,7 @@ module Workflow
|
|
192
194
|
workload = Orchestrator.workload(jobs)
|
193
195
|
all_jobs = workload.keys
|
194
196
|
|
195
|
-
all_jobs.each{|job| job.clean unless job.done? && job.updated? }
|
197
|
+
all_jobs.each{|job| job.clean unless (job.done? && job.updated?) || (job.error? && ! job.recoverable_error?) }
|
196
198
|
|
197
199
|
top_level_jobs = jobs.collect{|job| job.path }
|
198
200
|
failed_jobs = []
|
@@ -216,6 +218,7 @@ module Workflow
|
|
216
218
|
raise TryAgain
|
217
219
|
end
|
218
220
|
else
|
221
|
+
Log.warn "Non-recoverable error in #{job.path}"
|
219
222
|
next
|
220
223
|
end
|
221
224
|
ensure
|
@@ -1,20 +1,26 @@
|
|
1
1
|
class Step
|
2
2
|
def rec_dependencies(connected = false, seen = [])
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
@rec_dependencies = {}
|
4
|
+
@rec_dependencies[connected] ||= begin
|
5
|
+
direct_deps = []
|
6
|
+
dependencies.each do |dep|
|
7
|
+
next if seen.include? dep.path
|
8
|
+
next if connected && dep.done? && dep.updated?
|
9
|
+
direct_deps << dep
|
10
|
+
end if dependencies
|
11
|
+
seen.concat direct_deps.collect{|d| d.path }
|
12
|
+
seen.uniq!
|
13
|
+
direct_deps.inject(direct_deps){|acc,d| acc.concat(d.rec_dependencies(connected, seen)); acc }
|
14
|
+
direct_deps.uniq!
|
15
|
+
direct_deps
|
16
|
+
end
|
11
17
|
end
|
12
18
|
|
13
19
|
def recursive_inputs
|
14
20
|
recursive_inputs = NamedArray === inputs ? inputs.to_hash : {}
|
15
21
|
return recursive_inputs if dependencies.nil?
|
16
22
|
dependencies.inject(recursive_inputs) do |acc,dep|
|
17
|
-
acc.merge(
|
23
|
+
acc = dep.recursive_inputs.merge(acc)
|
18
24
|
end
|
19
25
|
end
|
20
26
|
|
@@ -41,6 +47,7 @@ class Step
|
|
41
47
|
end
|
42
48
|
|
43
49
|
next if dep.done?
|
50
|
+
next if dep.error? && ! dep.recoverable_error?
|
44
51
|
|
45
52
|
if dep.dependencies
|
46
53
|
dep.dependencies.each do |d|
|
@@ -72,9 +79,13 @@ class Step
|
|
72
79
|
def run_dependencies
|
73
80
|
all_dependencies.each do |dep|
|
74
81
|
next if dep.running? || dep.done?
|
82
|
+
next if dep.error? && ! dep.recoverable_error?
|
83
|
+
|
75
84
|
compute_options = compute[dep.path] if compute
|
76
85
|
compute_options = [] if compute_options.nil?
|
77
86
|
|
87
|
+
next if compute_options.include?(false)
|
88
|
+
|
78
89
|
stream = compute_options.include?(:stream)
|
79
90
|
stream = true unless ENV["SCOUT_EXPLICIT_STREAMING"] == 'true'
|
80
91
|
stream = :no_load if compute_options.include?(:produce)
|
@@ -95,12 +106,25 @@ class Step
|
|
95
106
|
all_dependencies.each{|dep| dep.abort if dep.running? }
|
96
107
|
end
|
97
108
|
|
98
|
-
def self.wait_for_jobs(jobs)
|
109
|
+
def self.wait_for_jobs(jobs, canfail=false)
|
99
110
|
threads = []
|
100
111
|
jobs.each do |job|
|
101
112
|
threads << Thread.new do
|
102
113
|
Thread.current.report_on_exception = false
|
103
|
-
|
114
|
+
begin
|
115
|
+
job.join
|
116
|
+
rescue Exception
|
117
|
+
case canfail
|
118
|
+
when TrueClass
|
119
|
+
next
|
120
|
+
else
|
121
|
+
if canfail === $!
|
122
|
+
next
|
123
|
+
else
|
124
|
+
raise $!
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
104
128
|
end
|
105
129
|
end
|
106
130
|
threads.each do |t|
|
@@ -7,6 +7,7 @@ class Step
|
|
7
7
|
else
|
8
8
|
Path.setup(dir)
|
9
9
|
end
|
10
|
+
dir = dir.find
|
10
11
|
dir.pkgdir = self
|
11
12
|
dir
|
12
13
|
end
|
@@ -34,7 +35,7 @@ class Step
|
|
34
35
|
begin
|
35
36
|
realpath = Open.realpath(self.files_dir)
|
36
37
|
Open.rm self.files_dir
|
37
|
-
Open.
|
38
|
+
Open.link_dir realpath, self.files_dir
|
38
39
|
rescue
|
39
40
|
Log.warn "Copy files_dir for #{self.workflow_short_path} failed: " + $!.message
|
40
41
|
end
|
@@ -24,7 +24,7 @@ class Step
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def save_info(info = nil)
|
27
|
-
Persist.save(info, info_file, SERIALIZER)
|
27
|
+
Persist.save(@info = info, info_file, SERIALIZER)
|
28
28
|
@info_load_time = Time.now
|
29
29
|
end
|
30
30
|
|
@@ -50,6 +50,15 @@ class Step
|
|
50
50
|
@info
|
51
51
|
end
|
52
52
|
|
53
|
+
def pid
|
54
|
+
info[:pid]
|
55
|
+
end
|
56
|
+
|
57
|
+
def pid=(pid)
|
58
|
+
set_info :pid, pid
|
59
|
+
end
|
60
|
+
|
61
|
+
|
53
62
|
def merge_info(new_info)
|
54
63
|
info = self.info
|
55
64
|
new_info.each do |key,value|
|
@@ -121,6 +130,7 @@ class Step
|
|
121
130
|
if message.nil?
|
122
131
|
Log.info [Log.color(:status, status, true), Log.color(:task, task_name, true), Log.color(:path, path)] * " "
|
123
132
|
else
|
133
|
+
message = Log.fingerprint(message.split("\n").first).sub(/^'/,'').sub(/'$/,'')
|
124
134
|
Log.info [Log.color(:status, status, true), Log.color(:task, task_name, true), message, Log.color(:path, path)] * " "
|
125
135
|
end
|
126
136
|
end
|
@@ -143,6 +153,10 @@ class Step
|
|
143
153
|
info[:messages]
|
144
154
|
end
|
145
155
|
|
156
|
+
def message(message)
|
157
|
+
merge_info :message => message
|
158
|
+
end
|
159
|
+
|
146
160
|
def status
|
147
161
|
info[:status].tap{|s| s.nil? ? s : s.to_sym }
|
148
162
|
end
|
@@ -165,7 +179,14 @@ class Step
|
|
165
179
|
end
|
166
180
|
|
167
181
|
def overriden_deps
|
168
|
-
|
182
|
+
dependencies.select{|d| d.overriden? }
|
183
|
+
end
|
184
|
+
|
185
|
+
def recursive_overriden_deps
|
186
|
+
overriden_deps = dependencies.select{|d|
|
187
|
+
d.overriden?
|
188
|
+
}
|
189
|
+
(overriden_deps + overriden_deps.collect{|d| d.recursive_overriden_deps }).flatten.uniq
|
169
190
|
end
|
170
191
|
|
171
192
|
def exception
|
@@ -4,9 +4,11 @@ class Step
|
|
4
4
|
Path.setup(path) unless Path === path
|
5
5
|
relocated = path.relocate
|
6
6
|
return relocated if Open.exists?(relocated)
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
if path.scan("/").length >= 2
|
8
|
+
subpath = path.split("/")[-3..-1] * "/"
|
9
|
+
relocated = Path.setup("var/jobs")[subpath]
|
10
|
+
return relocated if Open.exists?(relocated)
|
11
|
+
end
|
10
12
|
path
|
11
13
|
end
|
12
14
|
|
@@ -19,5 +19,11 @@ class Step
|
|
19
19
|
bar
|
20
20
|
end
|
21
21
|
end
|
22
|
+
|
23
|
+
def traverse(obj, desc: nil , **kwargs, &block)
|
24
|
+
desc = "Processing #{self.short_path}" if desc.nil?
|
25
|
+
kwargs[:bar] = self.progress_bar(desc) unless kwargs.include?(:bar)
|
26
|
+
TSV.traverse obj, **kwargs, &block
|
27
|
+
end
|
22
28
|
end
|
23
29
|
|
@@ -20,11 +20,17 @@ class Step
|
|
20
20
|
self.error? && ! (ScoutException === self.exception)
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
24
|
-
return false if self.error? && self.recoverable_error?
|
25
|
-
return true if self.done? && ! ENV["SCOUT_UPDATE"]
|
23
|
+
def newer_dependencies
|
26
24
|
newer = rec_dependencies.select{|dep| Path.newer?(self.path, dep.path) }
|
27
25
|
newer += input_dependencies.select{|dep| Path.newer?(self.path, dep.path) }
|
26
|
+
newer += rec_dependencies.collect{|dep| dep.input_dependencies }.flatten.select{|dep| Path.newer?(self.path, dep.path) }
|
27
|
+
newer
|
28
|
+
end
|
29
|
+
|
30
|
+
def updated?
|
31
|
+
return false if self.error? && self.recoverable_error?
|
32
|
+
return true if (self.done? || (self.error? && ! self.recoverable_error?)) && ! ENV["SCOUT_UPDATE"]
|
33
|
+
newer = newer_dependencies
|
28
34
|
|
29
35
|
Log.low "Newer deps found for #{Log.fingerprint self}: #{Log.fingerprint newer}" if newer.any?
|
30
36
|
newer.empty?
|
@@ -56,7 +62,7 @@ class Step
|
|
56
62
|
end
|
57
63
|
|
58
64
|
def canfail?
|
59
|
-
@compute && @compute.include?(:canfail)
|
65
|
+
@compute && @compute[self.path] && @compute[self.path].include?(:canfail)
|
60
66
|
end
|
61
67
|
|
62
68
|
def started?
|
data/lib/scout/workflow/step.rb
CHANGED
@@ -138,18 +138,32 @@ class Step
|
|
138
138
|
|
139
139
|
attr_reader :result
|
140
140
|
def run(stream = false)
|
141
|
+
case stream
|
142
|
+
when TrueClass, :stream
|
143
|
+
no_load = :stream
|
144
|
+
when :no_load
|
145
|
+
no_load = true
|
146
|
+
else
|
147
|
+
no_load = false
|
148
|
+
end
|
149
|
+
|
150
|
+
if done?
|
151
|
+
if no_load
|
152
|
+
if no_load == :stream
|
153
|
+
return self.stream
|
154
|
+
else
|
155
|
+
return self.path
|
156
|
+
end
|
157
|
+
else
|
158
|
+
return @result || self.load
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
|
141
163
|
return @result || self.load if done?
|
142
164
|
prepare_dependencies
|
143
165
|
begin
|
144
166
|
|
145
|
-
case stream
|
146
|
-
when TrueClass, :stream
|
147
|
-
no_load = :stream
|
148
|
-
when :no_load
|
149
|
-
no_load = true
|
150
|
-
else
|
151
|
-
no_load = false
|
152
|
-
end
|
153
167
|
|
154
168
|
@result = Persist.persist(name, type, :path => path, :tee_copies => tee_copies, no_load: no_load) do
|
155
169
|
input_names = (task.respond_to?(:inputs) && task.inputs) ? task.inputs.collect{|name,_| name} : []
|
@@ -206,6 +220,7 @@ class Step
|
|
206
220
|
end
|
207
221
|
|
208
222
|
@result.abort_callback = proc do |exception|
|
223
|
+
Open.rm self.path
|
209
224
|
if exception.nil? || Aborted === exception || Interrupt === exception
|
210
225
|
merge_info :status => :aborted, :end => Time.now
|
211
226
|
else
|
@@ -240,6 +255,7 @@ class Step
|
|
240
255
|
run(noload)
|
241
256
|
end
|
242
257
|
join
|
258
|
+
exit! 0
|
243
259
|
end
|
244
260
|
Process.detach pid
|
245
261
|
grace
|
@@ -350,6 +366,10 @@ class Step
|
|
350
366
|
|
351
367
|
def step(task_name)
|
352
368
|
task_name = task_name.to_sym
|
369
|
+
dependencies.each do |dep|
|
370
|
+
return dep if dep.task_name && dep.task_name.to_sym == task_name
|
371
|
+
return dep if dep.overriden_task && dep.overriden_task.to_sym == task_name
|
372
|
+
end
|
353
373
|
dependencies.each do |dep|
|
354
374
|
return dep if dep.task_name && dep.task_name.to_sym == task_name
|
355
375
|
return dep if dep.overriden_task && dep.overriden_task.to_sym == task_name
|
@@ -359,12 +379,12 @@ class Step
|
|
359
379
|
nil
|
360
380
|
end
|
361
381
|
|
362
|
-
def
|
363
|
-
Resource.identify
|
382
|
+
def identify_path
|
383
|
+
Resource.identify path
|
364
384
|
end
|
365
385
|
|
366
386
|
def digest_str
|
367
|
-
"Step: " +
|
387
|
+
"Step: " + identify_path
|
368
388
|
end
|
369
389
|
|
370
390
|
def fingerprint
|
@@ -373,7 +393,7 @@ class Step
|
|
373
393
|
|
374
394
|
def task_signature
|
375
395
|
workflow_name = String === workflow ? workflow : workflow.name
|
376
|
-
[
|
396
|
+
[workflow_name, task_name] * "#"
|
377
397
|
end
|
378
398
|
|
379
399
|
def alias?
|
@@ -9,22 +9,33 @@ module Task
|
|
9
9
|
load_dep = proc do |id, workflow, task, step_options, definition_options, dependencies|
|
10
10
|
task = step_options.delete(:task) if step_options.include?(:task)
|
11
11
|
workflow = step_options.delete(:workflow) if step_options.include?(:workflow)
|
12
|
-
|
13
|
-
|
12
|
+
|
13
|
+
step_id = id
|
14
|
+
step_id = step_options.delete(:jobname) if step_options.include?(:jobname)
|
15
|
+
step_id = nil if step_id == Task::DEFAULT_NAME
|
14
16
|
|
15
17
|
step_inputs = step_options.include?(:inputs)? step_options.delete(:inputs) : step_options
|
16
|
-
step_inputs = IndiferentHash.add_defaults step_inputs, definition_options
|
18
|
+
step_inputs = IndiferentHash.add_defaults step_inputs.dup, definition_options
|
17
19
|
|
18
20
|
resolved_inputs = {}
|
19
21
|
step_inputs.each do |k,v|
|
20
22
|
if Symbol === v
|
21
23
|
input_dep = dependencies.select{|d| d.task_name == v }.first
|
22
|
-
resolved_inputs[k] = input_dep
|
24
|
+
resolved_inputs[k] = if input_dep
|
25
|
+
input_dep
|
26
|
+
elsif provided_inputs.include?(v) && self.inputs.collect(&:first).include?(v)
|
27
|
+
provided_inputs[v]
|
28
|
+
elsif step_inputs.include?(v) && self.inputs.collect(&:first).include?(v)
|
29
|
+
step_inputs[v]
|
30
|
+
else
|
31
|
+
v
|
32
|
+
end
|
23
33
|
else
|
24
34
|
resolved_inputs[k] = v
|
25
35
|
end
|
26
36
|
end
|
27
|
-
|
37
|
+
|
38
|
+
job = workflow.job(task, step_id, resolved_inputs)
|
28
39
|
compute_options = definition_options[:compute] || []
|
29
40
|
compute_options = [compute_options] unless Array === compute_options
|
30
41
|
compute_options << :canfail if definition_options[:canfail]
|
@@ -33,26 +44,25 @@ module Task
|
|
33
44
|
compute[job.path] = compute_options if compute_options.any?
|
34
45
|
|
35
46
|
job.overriden = false if definition_options[:not_overriden]
|
47
|
+
job.compute = job.compute.nil? ? compute : job.compute.merge(compute)
|
36
48
|
|
37
49
|
[job, step_inputs]
|
38
50
|
end
|
39
51
|
|
40
52
|
# Helper function
|
41
|
-
|
53
|
+
filter_dep_non_default_inputs = proc do |dep,definition_options|
|
42
54
|
dep_non_default_inputs = dep.non_default_inputs
|
43
|
-
dep_non_default_inputs.select do |name|
|
44
|
-
step_inputs.include?(name)
|
45
|
-
end
|
46
55
|
dep_non_default_inputs.reject! do |name|
|
47
|
-
definition_options.include?(name)
|
48
|
-
(definition_options[name] != :placeholder || definition_options[name] != dep.inputs[name])
|
56
|
+
definition_options.include?(name)
|
49
57
|
end
|
50
58
|
|
51
59
|
dep_non_default_inputs
|
52
60
|
end
|
53
61
|
|
54
62
|
deps.each do |workflow,task,definition_options,block=nil|
|
55
|
-
definition_options
|
63
|
+
definition_options = definition_options.nil? ? {} : definition_options.dup
|
64
|
+
|
65
|
+
dep_id = definition_options.include?(:jobname) ? definition_options.delete(:jobname) : id
|
56
66
|
|
57
67
|
if provided_inputs.include?(overriden = [workflow.name, task] * "#")
|
58
68
|
dep = provided_inputs[overriden]
|
@@ -66,51 +76,50 @@ module Task
|
|
66
76
|
next
|
67
77
|
end
|
68
78
|
|
69
|
-
definition_options ||= {}
|
70
79
|
|
71
80
|
if block
|
72
|
-
fixed_provided_inputs = self.assign_inputs(provided_inputs).first.to_hash
|
73
|
-
self.inputs.each do |name,type,desc,value|
|
81
|
+
fixed_provided_inputs = self.assign_inputs(provided_inputs, dep_id).first.to_hash
|
82
|
+
self.inputs.each do |name,type,desc,value,options|
|
74
83
|
fixed_provided_inputs[name] = value unless fixed_provided_inputs.include?(name)
|
75
84
|
end
|
76
85
|
fixed_provided_inputs = IndiferentHash.add_defaults fixed_provided_inputs, provided_inputs
|
77
86
|
block_options = IndiferentHash.add_defaults definition_options.dup, fixed_provided_inputs
|
78
87
|
|
79
|
-
res = block.call
|
88
|
+
res = block.call dep_id, block_options, dependencies
|
80
89
|
|
81
90
|
case res
|
82
91
|
when Step
|
83
92
|
dep = res
|
84
93
|
dependencies << dep
|
85
|
-
dep_non_default_inputs =
|
94
|
+
dep_non_default_inputs = filter_dep_non_default_inputs.call(dep, definition_options)
|
86
95
|
non_default_inputs.concat(dep_non_default_inputs)
|
87
96
|
when Hash
|
88
97
|
step_options = block_options.merge(res)
|
89
|
-
dep, step_inputs = load_dep.call(
|
98
|
+
dep, step_inputs = load_dep.call(dep_id, workflow, task, step_options.dup, block_options, dependencies)
|
90
99
|
dependencies << dep
|
91
|
-
dep_non_default_inputs =
|
100
|
+
dep_non_default_inputs = filter_dep_non_default_inputs.call(dep, definition_options)
|
92
101
|
non_default_inputs.concat(dep_non_default_inputs)
|
93
102
|
when Array
|
94
103
|
res.each do |_res|
|
95
104
|
if Hash === _res
|
96
105
|
step_options = block_options.merge(_res)
|
97
|
-
dep, step_inputs = load_dep.call(
|
106
|
+
dep, step_inputs = load_dep.call(dep_id, workflow, task, step_options.dup, block_options, dependencies)
|
98
107
|
dependencies << dep
|
99
|
-
dep_non_default_inputs =
|
108
|
+
dep_non_default_inputs = filter_dep_non_default_inputs.call(dep, definition_options)
|
100
109
|
non_default_inputs.concat(dep_non_default_inputs)
|
101
110
|
else
|
102
111
|
dep = _res
|
103
112
|
dependencies << dep
|
104
|
-
dep_non_default_inputs =
|
113
|
+
dep_non_default_inputs = filter_dep_non_default_inputs.call(dep, definition_options)
|
105
114
|
non_default_inputs.concat(dep_non_default_inputs)
|
106
115
|
end
|
107
116
|
end
|
108
117
|
end
|
109
118
|
else
|
110
119
|
step_options = IndiferentHash.add_defaults definition_options.dup, provided_inputs
|
111
|
-
dep, step_inputs = load_dep.call(
|
120
|
+
dep, step_inputs = load_dep.call(dep_id, workflow, task, step_options, definition_options, dependencies)
|
112
121
|
dependencies << dep
|
113
|
-
dep_non_default_inputs =
|
122
|
+
dep_non_default_inputs = filter_dep_non_default_inputs.call(dep, definition_options)
|
114
123
|
non_default_inputs.concat(dep_non_default_inputs)
|
115
124
|
end
|
116
125
|
end
|