rbbt-util 5.32.16 → 5.32.21
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/lib/rbbt/hpc/slurm.rb +1 -0
- data/lib/rbbt/resource/path.rb +6 -6
- data/lib/rbbt/tsv/parallel/traverse.rb +1 -1
- data/lib/rbbt/util/log.rb +15 -4
- data/lib/rbbt/util/misc/inspect.rb +3 -1
- data/lib/rbbt/util/open.rb +1 -0
- data/lib/rbbt/workflow.rb +43 -1
- data/lib/rbbt/workflow/accessor.rb +15 -242
- data/lib/rbbt/workflow/definition.rb +7 -4
- data/lib/rbbt/workflow/dependencies.rb +196 -0
- data/lib/rbbt/workflow/step.rb +4 -184
- data/lib/rbbt/workflow/step/accessor.rb +1 -311
- data/lib/rbbt/workflow/step/dependencies.rb +75 -3
- data/lib/rbbt/workflow/step/info.rb +294 -0
- data/lib/rbbt/workflow/step/status.rb +146 -0
- data/lib/rbbt/workflow/usage.rb +4 -2
- data/lib/rbbt/workflow/util/orchestrator.rb +1 -1
- data/lib/rbbt/workflow/util/provenance.rb +16 -4
- data/share/rbbt_commands/system/clean +1 -0
- data/share/rbbt_commands/workflow/prov +1 -1
- metadata +5 -2
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
class Step
|
|
2
|
+
def self.clean(path)
|
|
3
|
+
info_file = Step.info_file path
|
|
4
|
+
pid_file = Step.pid_file path
|
|
5
|
+
md5_file = Step.md5_file path
|
|
6
|
+
files_dir = Step.files_dir path
|
|
7
|
+
tmp_path = Step.tmp_path path
|
|
8
|
+
|
|
9
|
+
if ! (Open.writable?(path) && Open.writable?(info_file))
|
|
10
|
+
Log.warn "Could not clean #{path}: not writable"
|
|
11
|
+
return
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
if ENV["RBBT_DEBUG_CLEAN"] == 'true'
|
|
15
|
+
raise "DO NOT CLEAN"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
if (Open.exists?(path) or Open.broken_link?(path)) or Open.exists?(pid_file) or Open.exists?(info_file) or Open.exists?(files_dir) or Open.broken_link?(files_dir)
|
|
19
|
+
|
|
20
|
+
@result = nil
|
|
21
|
+
@pid = nil
|
|
22
|
+
|
|
23
|
+
Misc.insist do
|
|
24
|
+
Open.rm info_file if Open.exists?(info_file)
|
|
25
|
+
Open.rm md5_file if Open.exists?(md5_file)
|
|
26
|
+
Open.rm path if (Open.exists?(path) || Open.broken_link?(path))
|
|
27
|
+
Open.rm_rf files_dir if Open.exists?(files_dir) || Open.broken_link?(files_dir)
|
|
28
|
+
Open.rm pid_file if Open.exists?(pid_file)
|
|
29
|
+
Open.rm tmp_path if Open.exists?(tmp_path)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def clean
|
|
35
|
+
if ! Open.exists?(info_file)
|
|
36
|
+
Log.high "Refusing to clean step with no .info file: #{path}"
|
|
37
|
+
return self
|
|
38
|
+
end
|
|
39
|
+
status = []
|
|
40
|
+
status << "dirty" if done? && dirty?
|
|
41
|
+
status << "not running" if ! done? && ! running?
|
|
42
|
+
status.unshift " " if status.any?
|
|
43
|
+
Log.high "Cleaning step: #{path}#{status * " "}"
|
|
44
|
+
Log.stack caller if RBBT_DEBUG_CLEAN
|
|
45
|
+
abort if ! done? && running?
|
|
46
|
+
Step.clean(path)
|
|
47
|
+
@done = false
|
|
48
|
+
self
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def resumable?
|
|
52
|
+
(task && task.resumable) || status == :waiting || status == :cleaned
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def started?
|
|
56
|
+
Open.exists?(path) or (Open.exists?(pid_file) && Open.exists?(info_file))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def waiting?
|
|
60
|
+
Open.exists?(info_file) and not started?
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def dirty_files
|
|
64
|
+
rec_dependencies = self.rec_dependencies(true)
|
|
65
|
+
return [] if rec_dependencies.empty?
|
|
66
|
+
canfail_paths = self.canfail_paths
|
|
67
|
+
|
|
68
|
+
dirty_files = rec_dependencies.reject{|dep|
|
|
69
|
+
(defined?(WorkflowRemoteClient) && WorkflowRemoteClient::RemoteStep === dep) ||
|
|
70
|
+
! Open.exists?(dep.info_file) ||
|
|
71
|
+
(dep.path && (Open.exists?(dep.path) || Open.remote?(dep.path))) ||
|
|
72
|
+
((dep.error? || dep.aborted?) && (! dep.recoverable_error? || canfail_paths.include?(dep.path)))
|
|
73
|
+
}
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def dirty?
|
|
77
|
+
return true if Open.exists?(pid_file) && ! ( Open.exists?(info_file) || done? )
|
|
78
|
+
return false unless done? || status == :done
|
|
79
|
+
return false unless ENV["RBBT_UPDATE"] == "true"
|
|
80
|
+
|
|
81
|
+
status = self.status
|
|
82
|
+
|
|
83
|
+
if done? and not (status == :done or status == :ending or status == :producing) and not status == :noinfo
|
|
84
|
+
return true
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
if status == :done and not done?
|
|
88
|
+
return true
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
if dirty_files.any?
|
|
92
|
+
Log.low "Some dirty files found for #{self.path}: #{Misc.fingerprint dirty_files}"
|
|
93
|
+
true
|
|
94
|
+
else
|
|
95
|
+
! self.updated?
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def done?
|
|
100
|
+
@done ||= path and Open.exists? path
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def streaming?
|
|
104
|
+
(IO === @result) or (not @saved_stream.nil?) or status == :streaming
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def noinfo?
|
|
108
|
+
status == :noinfo
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def running?
|
|
112
|
+
return false if ! (started? || status == :ending)
|
|
113
|
+
return nil unless Open.exist?(self.pid_file)
|
|
114
|
+
pid = Open.read(self.pid_file).to_i
|
|
115
|
+
|
|
116
|
+
return false if done? or error? or aborted?
|
|
117
|
+
|
|
118
|
+
if Misc.pid_exists?(pid)
|
|
119
|
+
pid
|
|
120
|
+
else
|
|
121
|
+
done? or error? or aborted?
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def stalled?
|
|
126
|
+
started? && ! (done? || running? || done? || error? || aborted?)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def missing?
|
|
130
|
+
status == :done && ! Open.exists?(path)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def error?
|
|
134
|
+
status == :error
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def nopid?
|
|
138
|
+
! Open.exists?(pid_file) && ! (status.nil? || status == :aborted || status == :done || status == :error || status == :cleaned)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def aborted?
|
|
142
|
+
status = self.status
|
|
143
|
+
status == :aborted || ((status != :ending && status != :dependencies && status != :cleaned && status != :noinfo && status != :setup && status != :noinfo && status != :waiting) && nopid?)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
end
|
data/lib/rbbt/workflow/usage.rb
CHANGED
|
@@ -67,11 +67,13 @@ end
|
|
|
67
67
|
|
|
68
68
|
module Workflow
|
|
69
69
|
|
|
70
|
-
def dep_tree(name)
|
|
70
|
+
def dep_tree(name, seen = [])
|
|
71
71
|
@dep_tree ||= {}
|
|
72
72
|
@dep_tree[name] ||= begin
|
|
73
73
|
dep_tree = {}
|
|
74
74
|
self.task_dependencies[name.to_sym].reverse.each do |dep|
|
|
75
|
+
next if seen.include? dep
|
|
76
|
+
seen << dep
|
|
75
77
|
dep = dep.first if Array === dep && dep.length == 1
|
|
76
78
|
dep = dep.dependency if DependencyBlock === dep
|
|
77
79
|
|
|
@@ -87,7 +89,7 @@ module Workflow
|
|
|
87
89
|
|
|
88
90
|
key = [workflow, task]
|
|
89
91
|
|
|
90
|
-
dep_tree[key] = workflow.dep_tree(task)
|
|
92
|
+
dep_tree[key] = workflow.dep_tree(task, seen)
|
|
91
93
|
end if name && self.task_dependencies[name.to_sym]
|
|
92
94
|
dep_tree
|
|
93
95
|
end
|
|
@@ -81,7 +81,7 @@ module Workflow
|
|
|
81
81
|
def self.candidates(workload, rules)
|
|
82
82
|
if rules.empty?
|
|
83
83
|
candidates = workload.select{|k,v| v.empty? }.
|
|
84
|
-
collect{|k,v| k}.
|
|
84
|
+
collect{|k,v| k }.
|
|
85
85
|
reject{|k| k.done? }
|
|
86
86
|
else
|
|
87
87
|
candidates = workload. #select{|k,v| Orchestrator.job_rules(rules, k) }.
|
|
@@ -47,6 +47,8 @@ class Step
|
|
|
47
47
|
if input.nil? || input.empty?
|
|
48
48
|
input_str = nil
|
|
49
49
|
else
|
|
50
|
+
input = input.reject{|dep,name| (input & dep.dependencies.collect{|d| [d,name]}).any? }
|
|
51
|
+
input = input.reject{|dep,name| (input & dep.input_dependencies.collect{|d| [d,name]}).any? }
|
|
50
52
|
input_str = Log.color(:magenta, "-> ") + input.collect{|dep,name| Log.color(:yellow, dep.task_name.to_s) + ":" + Log.color(:yellow, name) }.uniq * " "
|
|
51
53
|
end
|
|
52
54
|
|
|
@@ -91,21 +93,28 @@ class Step
|
|
|
91
93
|
status = :unsync if status == :done and not Open.exist?(path)
|
|
92
94
|
status = :notfound if status == :noinfo and not Open.exist?(path)
|
|
93
95
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
+
|
|
97
|
+
this_step_msg = prov_report_msg(status, name, path, info, input)
|
|
96
98
|
|
|
97
99
|
input_dependencies = {}
|
|
98
100
|
step.dependencies.each do |dep|
|
|
99
101
|
if dep.input_dependencies.any?
|
|
100
102
|
dep.input_dependencies.each do |id|
|
|
101
|
-
input_name = dep.
|
|
103
|
+
input_name = dep.recursive_inputs.fields.zip(dep.recursive_inputs).select{|f,d|
|
|
104
|
+
d == id || (String === d && d.start_with?(id.files_dir)) || (Array === d && d.include?(id))
|
|
105
|
+
}.last.first
|
|
102
106
|
input_dependencies[id] ||= []
|
|
103
107
|
input_dependencies[id] << [dep, input_name]
|
|
104
108
|
end
|
|
105
109
|
end
|
|
106
110
|
end
|
|
107
111
|
|
|
108
|
-
|
|
112
|
+
str = ""
|
|
113
|
+
str = " " * offset + this_step_msg if ENV["RBBT_ORIGINAL_STACK"] == 'true'
|
|
114
|
+
|
|
115
|
+
step.dependencies.dup.tap{|l|
|
|
116
|
+
l.reverse! if ENV["RBBT_ORIGINAL_STACK"] == 'true'
|
|
117
|
+
}.each do |dep|
|
|
109
118
|
path = dep.path
|
|
110
119
|
new = ! seen.include?(path)
|
|
111
120
|
if new
|
|
@@ -126,6 +135,9 @@ class Step
|
|
|
126
135
|
end
|
|
127
136
|
end
|
|
128
137
|
end if step.dependencies
|
|
138
|
+
|
|
139
|
+
str += (" " * offset) + this_step_msg unless ENV["RBBT_ORIGINAL_STACK"] == 'true'
|
|
140
|
+
|
|
129
141
|
str
|
|
130
142
|
end
|
|
131
143
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rbbt-util
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.32.
|
|
4
|
+
version: 5.32.21
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Miguel Vazquez
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-07-
|
|
11
|
+
date: 2021-07-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rake
|
|
@@ -322,6 +322,7 @@ files:
|
|
|
322
322
|
- lib/rbbt/workflow/accessor.rb
|
|
323
323
|
- lib/rbbt/workflow/annotate.rb
|
|
324
324
|
- lib/rbbt/workflow/definition.rb
|
|
325
|
+
- lib/rbbt/workflow/dependencies.rb
|
|
325
326
|
- lib/rbbt/workflow/doc.rb
|
|
326
327
|
- lib/rbbt/workflow/examples.rb
|
|
327
328
|
- lib/rbbt/workflow/integration/ansible.rb
|
|
@@ -339,8 +340,10 @@ files:
|
|
|
339
340
|
- lib/rbbt/workflow/step.rb
|
|
340
341
|
- lib/rbbt/workflow/step/accessor.rb
|
|
341
342
|
- lib/rbbt/workflow/step/dependencies.rb
|
|
343
|
+
- lib/rbbt/workflow/step/info.rb
|
|
342
344
|
- lib/rbbt/workflow/step/prepare.rb
|
|
343
345
|
- lib/rbbt/workflow/step/run.rb
|
|
346
|
+
- lib/rbbt/workflow/step/status.rb
|
|
344
347
|
- lib/rbbt/workflow/task.rb
|
|
345
348
|
- lib/rbbt/workflow/usage.rb
|
|
346
349
|
- lib/rbbt/workflow/util/archive.rb
|