rbbt-util 5.28.11 → 5.28.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/lib/rbbt/hpc.rb +2 -2
- data/lib/rbbt/persist.rb +2 -2
- data/lib/rbbt/resource/path.rb +1 -1
- data/lib/rbbt/util/misc/indiferent_hash.rb +8 -0
- data/lib/rbbt/workflow/step.rb +3 -0
- data/lib/rbbt/workflow/step/accessor.rb +19 -9
- data/lib/rbbt/workflow/step/dependencies.rb +8 -2
- data/lib/rbbt/workflow/step/run.rb +22 -19
- data/share/rbbt_commands/workflow/info +12 -9
- data/test/rbbt/test_workflow.rb +32 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 889338e97d8b2f2467dcbbb7d7ecfb1a4904a317702c2b7c7164757efd1f55dc
|
|
4
|
+
data.tar.gz: 0e71e707ea5d0bab991aaf25f9dd5bf1d371d36ed6267694934aab92218ba293
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 173386b238dda5361b1c473c90708b783736f3726f868e86dd64f732d3e9474fc9987b133fdfc3d19538ccc19b31eb2f91ae29fa1fedaf150e5d46619ef69c76
|
|
7
|
+
data.tar.gz: 306f1058d7248387a7887bed09c4bd21541e6f52462de6b17d2d4b04bb73ebe4f0cdb3a9245e1a24f61fec252587d3b0669623d8544a6fc0d250eeebdad8c47e
|
data/lib/rbbt/hpc.rb
CHANGED
|
@@ -122,7 +122,7 @@ module Marenostrum
|
|
|
122
122
|
module load java
|
|
123
123
|
|
|
124
124
|
# Calculate max available memory
|
|
125
|
-
let "MAX_MEMORY=$SLURM_MEM_PER_CPU * $
|
|
125
|
+
let "MAX_MEMORY=$SLURM_MEM_PER_CPU * $SLURM_CPUS_PER_TASK"
|
|
126
126
|
EOF
|
|
127
127
|
|
|
128
128
|
|
|
@@ -172,7 +172,7 @@ cp ~/.rbbt/etc/environment $CONTAINER_DIR/.rbbt/etc/
|
|
|
172
172
|
# Set search_paths
|
|
173
173
|
echo "singularity: /singularity_opt/{PKGDIR}/{TOPLEVEL}/{SUBPATH}" > $CONTAINER_DIR/.rbbt/etc/search_paths
|
|
174
174
|
echo "rbbt_user: /home/rbbt/.rbbt/{TOPLEVEL}/{SUBPATH}" >> $CONTAINER_DIR/.rbbt/etc/search_paths
|
|
175
|
-
echo "
|
|
175
|
+
echo "outside_home: $CONTAINER_DIR/home/{TOPLEVEL}/{SUBPATH}" >> $CONTAINER_DIR/.rbbt/etc/search_paths
|
|
176
176
|
echo "group_projects: #{projects_group_dir}/{PKGDIR}/{TOPLEVEL}/{SUBPATH}" >> $CONTAINER_DIR/.rbbt/etc/search_paths
|
|
177
177
|
echo "group_scratch: #{scratch_group_dir}/{PKGDIR}/{TOPLEVEL}/{SUBPATH}" >> $CONTAINER_DIR/.rbbt/etc/search_paths
|
|
178
178
|
echo "user_projects: #{projects_group_dir}/#{user}/{PKGDIR}/{TOPLEVEL}/{SUBPATH}" >> $CONTAINER_DIR/.rbbt/etc/search_paths
|
data/lib/rbbt/persist.rb
CHANGED
|
@@ -31,8 +31,8 @@ module Persist
|
|
|
31
31
|
path = path.find if Path === path
|
|
32
32
|
file = file.find if Path === file
|
|
33
33
|
if by_link
|
|
34
|
-
patht = File.lstat(path).mtime
|
|
35
|
-
filet = File.lstat(file).mtime
|
|
34
|
+
patht = File.exists?(path) ? File.lstat(path).mtime : nil
|
|
35
|
+
filet = File.exists?(file) ? File.lstat(file).mtime : nil
|
|
36
36
|
else
|
|
37
37
|
patht = Open.mtime(path)
|
|
38
38
|
filet = Open.mtime(file)
|
data/lib/rbbt/resource/path.rb
CHANGED
data/lib/rbbt/workflow/step.rb
CHANGED
|
@@ -13,6 +13,8 @@ class Step
|
|
|
13
13
|
attr_accessor :relocated
|
|
14
14
|
attr_accessor :result, :mutex, :seen
|
|
15
15
|
|
|
16
|
+
RBBT_DEBUG_CLEAN = ENV["RBBT_DEBUG_CLEAN"] == 'true'
|
|
17
|
+
|
|
16
18
|
class << self
|
|
17
19
|
attr_accessor :lock_dir
|
|
18
20
|
|
|
@@ -454,6 +456,7 @@ class Step
|
|
|
454
456
|
status << "not running" if ! done? && ! running?
|
|
455
457
|
status.unshift " " if status.any?
|
|
456
458
|
Log.high "Cleaning step: #{path}#{status * " "}"
|
|
459
|
+
Log.stack caller if RBBT_DEBUG_CLEAN
|
|
457
460
|
abort if ! done? && running?
|
|
458
461
|
Step.clean(path)
|
|
459
462
|
self
|
|
@@ -8,6 +8,16 @@ class Step
|
|
|
8
8
|
end
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
def self.serialize_info(info)
|
|
12
|
+
info = info.clean_version if IndiferentHash === info
|
|
13
|
+
INFO_SERIALIZER.dump(info)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.load_serialized_info(io)
|
|
17
|
+
IndiferentHash.setup(INFO_SERIALIZER.load(io))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
|
|
11
21
|
def self.wait_for_jobs(jobs)
|
|
12
22
|
jobs = [jobs] if Step === jobs
|
|
13
23
|
begin
|
|
@@ -59,7 +69,7 @@ class Step
|
|
|
59
69
|
def self.step_info(path)
|
|
60
70
|
begin
|
|
61
71
|
Open.open(info_file(path), :mode => 'rb') do |f|
|
|
62
|
-
|
|
72
|
+
self.load_serialized_info(f)
|
|
63
73
|
end
|
|
64
74
|
rescue Exception
|
|
65
75
|
Log.exception $!
|
|
@@ -188,7 +198,7 @@ class Step
|
|
|
188
198
|
info_lock.lock if check_lock and false
|
|
189
199
|
begin
|
|
190
200
|
Open.open(info_file, :mode => 'rb') do |file|
|
|
191
|
-
|
|
201
|
+
Step.load_serialized_info(file)
|
|
192
202
|
end
|
|
193
203
|
ensure
|
|
194
204
|
info_lock.unlock if check_lock and false
|
|
@@ -204,7 +214,7 @@ class Step
|
|
|
204
214
|
Log.debug{"Error loading info file: " + info_file}
|
|
205
215
|
Log.exception $!
|
|
206
216
|
Open.rm info_file
|
|
207
|
-
Misc.sensiblewrite(info_file,
|
|
217
|
+
Misc.sensiblewrite(info_file, Step.serialize_info({:status => :error, :messages => ["Info file lost"]}))
|
|
208
218
|
raise $!
|
|
209
219
|
end
|
|
210
220
|
end
|
|
@@ -214,8 +224,8 @@ class Step
|
|
|
214
224
|
Open.lock(info_file, :lock => info_lock) do
|
|
215
225
|
i = {:status => :waiting, :pid => Process.pid, :path => path}
|
|
216
226
|
i[:dependencies] = dependencies.collect{|dep| [dep.task_name, dep.name, dep.path]} if dependencies
|
|
217
|
-
|
|
218
|
-
|
|
227
|
+
Misc.sensiblewrite(info_file, Step.serialize_info(i), :force => true, :lock => false)
|
|
228
|
+
@info_cache = IndiferentHash.setup(i)
|
|
219
229
|
@info_cache_time = Time.now
|
|
220
230
|
end
|
|
221
231
|
end
|
|
@@ -227,9 +237,9 @@ class Step
|
|
|
227
237
|
Open.lock(info_file, :lock => info_lock) do
|
|
228
238
|
i = info(false).dup
|
|
229
239
|
i[key] = value
|
|
240
|
+
dump = Step.serialize_info(i)
|
|
230
241
|
@info_cache = IndiferentHash.setup(i)
|
|
231
|
-
dump
|
|
232
|
-
Misc.sensiblewrite(info_file, dump, :force => true, :lock => false)
|
|
242
|
+
Misc.sensiblewrite(info_file, dump, :force => true, :lock => false) if Open.exists?(info_file)
|
|
233
243
|
@info_cache_time = Time.now
|
|
234
244
|
value
|
|
235
245
|
end
|
|
@@ -242,9 +252,9 @@ class Step
|
|
|
242
252
|
Open.lock(info_file, :lock => info_lock) do
|
|
243
253
|
i = info(false)
|
|
244
254
|
i.merge! hash
|
|
255
|
+
dump = Step.serialize_info(i)
|
|
245
256
|
@info_cache = IndiferentHash.setup(i)
|
|
246
|
-
dump
|
|
247
|
-
Misc.sensiblewrite(info_file, dump, :force => true, :lock => false)
|
|
257
|
+
Misc.sensiblewrite(info_file, dump, :force => true, :lock => false) if Open.exists?(info_file)
|
|
248
258
|
@info_cache_time = Time.now
|
|
249
259
|
value
|
|
250
260
|
end
|
|
@@ -92,7 +92,13 @@ class Step
|
|
|
92
92
|
(job.done? && job.dirty?) || (job.error? && job.dirty?) ||
|
|
93
93
|
(!(job.noinfo? || job.done? || job.error? || job.aborted? || job.running?))
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
if ! (job.resumable? && (job.updated? && ! job.dirty?))
|
|
96
|
+
Log.high "About to clean -- status: #{status}, present #{File.exists?(job.path)}, " +
|
|
97
|
+
%w(done? error? recoverable_error? noinfo? updated? dirty? aborted? running? resumable?).
|
|
98
|
+
collect{|v| [v, job.send(v)]*": "} * ", " if RBBT_DEBUG_CLEAN
|
|
99
|
+
|
|
100
|
+
job.clean
|
|
101
|
+
end
|
|
96
102
|
job.set_info :status, :cleaned
|
|
97
103
|
end
|
|
98
104
|
|
|
@@ -121,7 +127,7 @@ class Step
|
|
|
121
127
|
end
|
|
122
128
|
|
|
123
129
|
def input_dependencies
|
|
124
|
-
inputs.flatten.select{|i| Step === i}
|
|
130
|
+
(inputs.flatten.select{|i| Step === i} + inputs.flatten.select{|dep| Path === dep && Step === dep.resource}.collect{|dep| dep.resource})
|
|
125
131
|
end
|
|
126
132
|
|
|
127
133
|
|
|
@@ -112,7 +112,7 @@ class Step
|
|
|
112
112
|
end
|
|
113
113
|
|
|
114
114
|
def updatable?
|
|
115
|
-
(ENV["RBBT_UPDATE_ALL_JOBS"] == 'true' || ( ENV["RBBT_UPDATE"] == "true" && Open.exists?(info_file)) && status != :noinfo && ! (relocated? && done?))
|
|
115
|
+
(ENV["RBBT_UPDATE_ALL_JOBS"] == 'true' || ( ENV["RBBT_UPDATE"] == "true" && Open.exists?(info_file)) && status != :noinfo && ! (relocated? && done?)) || (ENV["RBBT_UPDATE"] && ! (done? && ! Open.exists?(info_file)))
|
|
116
116
|
end
|
|
117
117
|
|
|
118
118
|
def dependency_checks
|
|
@@ -128,7 +128,7 @@ class Step
|
|
|
128
128
|
end
|
|
129
129
|
|
|
130
130
|
def input_checks
|
|
131
|
-
inputs.select{|i| Step === i }.
|
|
131
|
+
(inputs.select{|i| Step === i } + inputs.select{|i| Path === i && Step === i.resource}.collect{|i| i.resource}).
|
|
132
132
|
select{|dependency| dependency.updatable? }
|
|
133
133
|
end
|
|
134
134
|
|
|
@@ -154,25 +154,28 @@ class Step
|
|
|
154
154
|
canfail_paths = self.canfail_paths
|
|
155
155
|
this_mtime = Open.mtime(self.path) if Open.exists?(self.path)
|
|
156
156
|
|
|
157
|
-
checks.
|
|
158
|
-
|
|
159
|
-
dep_done = dep.done?
|
|
157
|
+
outdated_time = checks.select{|dep| dep.updatable? && dep.done? && Persist.newer?(path, dep.path) }
|
|
158
|
+
outdated_dep = checks.reject{|dep| dep.done? || (dep.error? && ! dep.recoverable_error? && canfail_paths.include?(dep.path)) }
|
|
160
159
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
end
|
|
165
|
-
rescue
|
|
166
|
-
end
|
|
160
|
+
#checks.each do |dep|
|
|
161
|
+
# next unless dep.updatable?
|
|
162
|
+
# dep_done = dep.done?
|
|
167
163
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
164
|
+
# begin
|
|
165
|
+
# if this_mtime && dep_done && Open.exists?(dep.path) && (Open.mtime(dep.path) > this_mtime + 1)
|
|
166
|
+
# outdated_time << dep
|
|
167
|
+
# end
|
|
168
|
+
# rescue
|
|
169
|
+
# end
|
|
171
170
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
171
|
+
# # Is this pointless? this would mean some dep got updated after a later
|
|
172
|
+
# # dep but but before this one.
|
|
173
|
+
# #if (! dep.done? && ! canfail_paths.include?(dep.path)) || ! dep.updated?
|
|
174
|
+
|
|
175
|
+
# if (! dep_done && ! canfail_paths.include?(dep.path))
|
|
176
|
+
# outdated_dep << dep
|
|
177
|
+
# end
|
|
178
|
+
#end
|
|
176
179
|
|
|
177
180
|
Log.high "Some newer files found: #{Misc.fingerprint outdated_time}" if outdated_time.any?
|
|
178
181
|
Log.high "Some outdated files found: #{Misc.fingerprint outdated_dep}" if outdated_dep.any?
|
|
@@ -215,7 +218,7 @@ class Step
|
|
|
215
218
|
no_load = :stream if no_load
|
|
216
219
|
|
|
217
220
|
Open.write(pid_file, Process.pid.to_s) unless Open.exists?(path) or Open.exists?(pid_file)
|
|
218
|
-
result_type = @task.result_type
|
|
221
|
+
result_type = @task.result_type if @task
|
|
219
222
|
result_type = info[:result_type] if result_type.nil?
|
|
220
223
|
result = Persist.persist "Job", result_type, :file => path, :check => persist_checks, :no_load => no_load do
|
|
221
224
|
if Step === Step.log_relay_step and not self == Step.log_relay_step
|
|
@@ -17,6 +17,7 @@ $ rbbt workflow info <job-result>
|
|
|
17
17
|
-a--all Print all info entries
|
|
18
18
|
-r--recursive Print recursive input values
|
|
19
19
|
-o--original Print original object
|
|
20
|
+
-w--width* Screen width
|
|
20
21
|
EOF
|
|
21
22
|
|
|
22
23
|
SOPT.usage if options[:help]
|
|
@@ -24,6 +25,7 @@ SOPT.usage if options[:help]
|
|
|
24
25
|
file = ARGV.shift
|
|
25
26
|
all = options.delete :all
|
|
26
27
|
recursive = options.delete :recursive
|
|
28
|
+
width = (options.delete(:width) || 80).to_i
|
|
27
29
|
|
|
28
30
|
def get_step(file)
|
|
29
31
|
file = file.sub(/\.(info|files)/,'')
|
|
@@ -86,6 +88,7 @@ pid = info[:pid]
|
|
|
86
88
|
exception = info[:exception]
|
|
87
89
|
rest = info.keys - [:inputs, :dependencies, :status, :time_elapsed, :messages, :backtrace, :exception, :pid, :archived_info]
|
|
88
90
|
|
|
91
|
+
|
|
89
92
|
puts Log.color(:magenta, "File") << ": " << step.path
|
|
90
93
|
puts Log.color(:magenta, "Status") << ": " << status_msg(status) << ((step.aborted? || step.error?) && step.recoverable_error? ? " (recoverable)" : "" ) << (step.dirty? ? " (dirty)" : "")
|
|
91
94
|
puts Log.color(:magenta, "Pid") << ": " << pid_msg(pid, status.to_s == "done")
|
|
@@ -96,14 +99,14 @@ if inputs and inputs.any?
|
|
|
96
99
|
inputs.each do |input,value|
|
|
97
100
|
case value
|
|
98
101
|
when nil
|
|
99
|
-
puts Misc.format_definition_list_item(" " + input.to_s, 'nil',
|
|
102
|
+
puts Misc.format_definition_list_item(" " + input.to_s, 'nil', width, 20, :blue)
|
|
100
103
|
when Array
|
|
101
|
-
puts Misc.format_definition_list_item(" " + input.to_s, (value.length > 6 ? value[0..5]*"\n" << "\n" << "..." : value * "\n" ),
|
|
104
|
+
puts Misc.format_definition_list_item(" " + input.to_s, (value.length > 6 ? value[0..5]*"\n" << "\n" << "..." : value * "\n" ), width, 20, :blue)
|
|
102
105
|
when TrueClass, FalseClass
|
|
103
|
-
puts Misc.format_definition_list_item(" " + input.to_s, value.to_s,
|
|
106
|
+
puts Misc.format_definition_list_item(" " + input.to_s, value.to_s, width, 20, :blue)
|
|
104
107
|
else
|
|
105
108
|
text = value.to_s.split("\n")[0..5].compact * "\n\n"
|
|
106
|
-
puts Misc.format_definition_list_item(" " + input.to_s, text,
|
|
109
|
+
puts Misc.format_definition_list_item(" " + input.to_s, text, width, 20, :blue)
|
|
107
110
|
end
|
|
108
111
|
end
|
|
109
112
|
end
|
|
@@ -162,16 +165,16 @@ if recursive
|
|
|
162
165
|
inputs.each do |input,value|
|
|
163
166
|
case value
|
|
164
167
|
when nil
|
|
165
|
-
puts Misc.format_definition_list_item(" " << input.to_s, 'nil',
|
|
168
|
+
puts Misc.format_definition_list_item(" " << input.to_s, 'nil', width, 20, :blue)
|
|
166
169
|
when Array
|
|
167
|
-
puts Misc.format_definition_list_item(" " << input.to_s, (value.length > 6 ? (value[0..5])*"\n\n" << "\n\n" << "..." : value * "\n\n" ),
|
|
170
|
+
puts Misc.format_definition_list_item(" " << input.to_s, (value.length > 6 ? (value[0..5])*"\n\n" << "\n\n" << "..." : value * "\n\n" ), width, 20, :blue).gsub("\n\n","\n")
|
|
168
171
|
when TrueClass, FalseClass
|
|
169
|
-
puts Misc.format_definition_list_item(" " << input.to_s, value.to_s,
|
|
172
|
+
puts Misc.format_definition_list_item(" " << input.to_s, value.to_s, width, 20, :blue)
|
|
170
173
|
else
|
|
171
|
-
lines = value.to_s.split("\n").collect{|l| l.length >=
|
|
174
|
+
lines = value.to_s.split("\n").collect{|l| l.length >= width - 5 ? l[0..width - 5] + " ..." : l }
|
|
172
175
|
text = lines[0..5].compact * "\n\n"
|
|
173
176
|
text << "\n\n...\n\n" if lines.length > 6
|
|
174
|
-
puts Misc.format_definition_list_item(" " << input.to_s, text,
|
|
177
|
+
puts Misc.format_definition_list_item(" " << input.to_s, text, width, 20, :blue).gsub("\n\n","\n")
|
|
175
178
|
end
|
|
176
179
|
end
|
|
177
180
|
end
|
data/test/rbbt/test_workflow.rb
CHANGED
|
@@ -156,6 +156,15 @@ for this dependency
|
|
|
156
156
|
Open.read(file).reverse
|
|
157
157
|
end
|
|
158
158
|
|
|
159
|
+
task :create_file => :text do |file|
|
|
160
|
+
Open.write(file('a'), "A")
|
|
161
|
+
Open.write(file('b'), "B")
|
|
162
|
+
"DONE"
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
dep_task :reverse_step_file, TestWF, :reverse_file do |jobname, options, dependencies|
|
|
166
|
+
dep = dependencies.flatten.first
|
|
167
|
+
end
|
|
159
168
|
|
|
160
169
|
end
|
|
161
170
|
|
|
@@ -440,4 +449,27 @@ class TestWorkflow < Test::Unit::TestCase
|
|
|
440
449
|
end
|
|
441
450
|
end
|
|
442
451
|
end
|
|
452
|
+
|
|
453
|
+
def test_input_step_file_check
|
|
454
|
+
job = TestWF.job(:t3).recursive_clean
|
|
455
|
+
job.run
|
|
456
|
+
Misc.with_env "RBBT_UPDATE", 'true' do
|
|
457
|
+
assert job.checks.select{|d| d.task_name.to_s == "t1" }.any?
|
|
458
|
+
job = TestWF.job(:t3)
|
|
459
|
+
job.step(:t1).clean
|
|
460
|
+
assert job.checks.select{|d| d.task_name.to_s == "t1" }.empty?
|
|
461
|
+
job = TestWF.job(:t3).recursive_clean
|
|
462
|
+
job.run
|
|
463
|
+
assert job.checks.select{|d| d.task_name.to_s == "t1" }.any?
|
|
464
|
+
job = TestWF.job(:t3)
|
|
465
|
+
sleep 1
|
|
466
|
+
Open.touch job.step(:t1).path
|
|
467
|
+
Misc.with_env "RBBT_UPDATE", "false" do
|
|
468
|
+
assert job.updated?
|
|
469
|
+
end
|
|
470
|
+
Misc.with_env "RBBT_UPDATE", "true" do
|
|
471
|
+
assert ! job.updated?
|
|
472
|
+
end
|
|
473
|
+
end
|
|
474
|
+
end
|
|
443
475
|
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.28.
|
|
4
|
+
version: 5.28.12
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Miguel Vazquez
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
11
|
+
date: 2020-12-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rake
|