rbbt-util 5.28.11 → 5.28.12
Sign up to get free protection for your applications and to get access to all the features.
- 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
|