rbbt-util 5.33.0 → 5.33.1
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/orchestrate/batches.rb +7 -0
- data/lib/rbbt/hpc/orchestrate.rb +23 -1
- data/lib/rbbt/util/misc/exceptions.rb +15 -3
- data/lib/rbbt/workflow/step/dependencies.rb +22 -3
- data/lib/rbbt/workflow/step/info.rb +1 -1
- data/lib/rbbt/workflow/step/run.rb +3 -2
- data/lib/rbbt/workflow/util/orchestrator.rb +8 -4
- data/lib/rbbt/workflow.rb +3 -5
- data/share/rbbt_commands/workflow/task +13 -3
- 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: 70ba4440be0bdca6f80b4aa78393ca4fbec5dbc8d8a1cc72b6393e73127b5340
|
4
|
+
data.tar.gz: 42021bd242233b5e4e3a268c27291953d84c8bad85b87d8feaf6389685f043bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6a229aa39440cf3b0b42a505e32c699d791d8dd1e1328f42cd6500c947560b0d9343312080af78475a6f4835077e53c029d862e9d4c90addd84408925754b50
|
7
|
+
data.tar.gz: e31505e92ca6425095a90bdcd8fe95d435c8435bc929dcb1c0c77083a1286439c952d7a98af1091664fcee7a57ba3f86b99258a84958714d630ab4a3678f1ee3
|
@@ -80,6 +80,13 @@ module HPC
|
|
80
80
|
batches.each do |batch|
|
81
81
|
jobs = batch[:jobs]
|
82
82
|
all_deps = jobs.collect{|d| job_dependencies(d) }.flatten.uniq
|
83
|
+
|
84
|
+
minimum = all_deps
|
85
|
+
all_deps.each do |dep|
|
86
|
+
minimum -= job_dependencies(dep)
|
87
|
+
end
|
88
|
+
|
89
|
+
all_deps = minimum
|
83
90
|
deps = all_deps.collect do |d|
|
84
91
|
(batches - [batch]).select{|batch| batch[:jobs].collect(&:path).include? d.path }
|
85
92
|
end.flatten.uniq
|
data/lib/rbbt/hpc/orchestrate.rb
CHANGED
@@ -26,7 +26,29 @@ module HPC
|
|
26
26
|
raise "No batch without unmet dependencies" if top.nil?
|
27
27
|
batches.delete top
|
28
28
|
job_options = options.merge(top[:rules])
|
29
|
-
|
29
|
+
|
30
|
+
if top[:deps].nil?
|
31
|
+
batch_dependencies = []
|
32
|
+
else
|
33
|
+
top_jobs = top[:jobs]
|
34
|
+
|
35
|
+
batch_dependencies = top[:deps].collect{|d|
|
36
|
+
target = d[:top_level]
|
37
|
+
canfail = false
|
38
|
+
|
39
|
+
top_jobs.each do |job|
|
40
|
+
canfail = true if job.canfail_paths.include?(target.path)
|
41
|
+
end
|
42
|
+
|
43
|
+
if canfail
|
44
|
+
'canfail:' + batch_ids[d].to_s
|
45
|
+
else
|
46
|
+
batch_ids[d].to_s
|
47
|
+
end
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
job_options.merge!(:batch_dependencies => batch_dependencies )
|
30
52
|
job_options.merge!(:manifest => top[:jobs].collect{|d| d.task_signature })
|
31
53
|
|
32
54
|
if options[:dry_run]
|
@@ -32,8 +32,6 @@ class DependencyError < Aborted
|
|
32
32
|
def initialize(msg)
|
33
33
|
if defined? Step and Step === msg
|
34
34
|
step = msg
|
35
|
-
workflow = step.path.split("/")[-3]
|
36
|
-
new_msg = [workflow, step.short_path, step.messages.last] * " - "
|
37
35
|
new_msg = [step.path, step.messages.last] * ": "
|
38
36
|
super(new_msg)
|
39
37
|
else
|
@@ -42,6 +40,21 @@ class DependencyError < Aborted
|
|
42
40
|
end
|
43
41
|
end
|
44
42
|
|
43
|
+
class DependencyRbbtException < RbbtException
|
44
|
+
def initialize(msg)
|
45
|
+
if defined? Step and Step === msg
|
46
|
+
step = msg
|
47
|
+
|
48
|
+
new_msg = nil
|
49
|
+
new_msg = [step.path, step.messages.last] * ": "
|
50
|
+
|
51
|
+
super(new_msg)
|
52
|
+
else
|
53
|
+
super(msg)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
45
58
|
class DontClose < Exception; end
|
46
59
|
|
47
60
|
class KeepLocked < Exception
|
@@ -64,4 +77,3 @@ class StopInsist < Exception
|
|
64
77
|
@exception = exception
|
65
78
|
end
|
66
79
|
end
|
67
|
-
|
@@ -107,7 +107,26 @@ class Step
|
|
107
107
|
canfail = ComputeDependency === job && job.canfail?
|
108
108
|
end
|
109
109
|
|
110
|
-
|
110
|
+
raise_dependency_error(job) if job.error? and not canfail
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.raise_dependency_error(job)
|
114
|
+
begin
|
115
|
+
if job.get_exception
|
116
|
+
klass = job.get_exception.class
|
117
|
+
else
|
118
|
+
klass = Kernel.const_get(info[:exception][:class])
|
119
|
+
end
|
120
|
+
rescue
|
121
|
+
Log.exception $!
|
122
|
+
raise DependencyError, job
|
123
|
+
end
|
124
|
+
|
125
|
+
if (klass <= RbbtException)
|
126
|
+
raise DependencyRbbtException, job
|
127
|
+
else
|
128
|
+
raise DependencyError, job
|
129
|
+
end
|
111
130
|
end
|
112
131
|
|
113
132
|
def log_dependency_exec(dependency, action)
|
@@ -169,7 +188,7 @@ class Step
|
|
169
188
|
|
170
189
|
if dependency.error?
|
171
190
|
log_dependency_exec(dependency, :error)
|
172
|
-
|
191
|
+
raise_dependency_error dependency
|
173
192
|
end
|
174
193
|
|
175
194
|
if dependency.streaming?
|
@@ -368,7 +387,7 @@ class Step
|
|
368
387
|
seen_paths << step.path
|
369
388
|
begin
|
370
389
|
Step.prepare_for_execution(step) unless step == self
|
371
|
-
rescue DependencyError
|
390
|
+
rescue DependencyError, DependencyRbbtException
|
372
391
|
raise $! unless canfail_paths.include? step.path
|
373
392
|
end
|
374
393
|
next unless step.dependencies and step.dependencies.any?
|
@@ -437,7 +437,7 @@ class Step
|
|
437
437
|
end
|
438
438
|
end # END SYNC
|
439
439
|
res
|
440
|
-
rescue DependencyError
|
440
|
+
rescue DependencyError, DependencyRbbtException
|
441
441
|
exception $!
|
442
442
|
rescue LockInterrupted
|
443
443
|
raise $!
|
@@ -484,7 +484,7 @@ class Step
|
|
484
484
|
if dofork
|
485
485
|
fork(true) unless started?
|
486
486
|
|
487
|
-
join unless done?
|
487
|
+
join unless done? or dofork == :nowait
|
488
488
|
else
|
489
489
|
run(true) unless started?
|
490
490
|
|
@@ -496,6 +496,7 @@ class Step
|
|
496
496
|
|
497
497
|
def fork(no_load = false, semaphore = nil)
|
498
498
|
raise "Can not fork: Step is waiting for proces #{@pid} to finish" if not @pid.nil? and not Process.pid == @pid and Misc.pid_exists?(@pid) and not done? and info[:forked]
|
499
|
+
Log.debug "Fork to run #{self.path}"
|
499
500
|
sout, sin = Misc.pipe if no_load == :stream
|
500
501
|
@pid = Process.fork do
|
501
502
|
Signal.trap(:TERM) do
|
@@ -71,6 +71,7 @@ module Workflow
|
|
71
71
|
|
72
72
|
default_resources.each{|k,v| resources[k] ||= v } if default_resources
|
73
73
|
|
74
|
+
resources = {:cpus => 1} if resources.empty?
|
74
75
|
resources
|
75
76
|
end
|
76
77
|
|
@@ -107,7 +108,8 @@ module Workflow
|
|
107
108
|
|
108
109
|
attr_accessor :available_resources, :resources_requested, :resources_used, :timer
|
109
110
|
|
110
|
-
def initialize(timer = 5, available_resources =
|
111
|
+
def initialize(timer = 5, available_resources = nil)
|
112
|
+
available_resources = {:cpus => Etc.nprocessors } if available_resources.nil?
|
111
113
|
@timer = timer
|
112
114
|
@available_resources = IndiferentHash.setup(available_resources)
|
113
115
|
@resources_requested = IndiferentHash.setup({})
|
@@ -155,7 +157,7 @@ module Workflow
|
|
155
157
|
log = job_rules[:log] if job_rules
|
156
158
|
log = Log.severity if log.nil?
|
157
159
|
Log.with_severity log do
|
158
|
-
job.produce(false,
|
160
|
+
job.produce(false, :nowait)
|
159
161
|
end
|
160
162
|
end
|
161
163
|
end
|
@@ -202,6 +204,7 @@ module Workflow
|
|
202
204
|
when (job.error? || job.aborted?)
|
203
205
|
begin
|
204
206
|
if job.recoverable_error?
|
207
|
+
iif [:CLEAN, job, job.status, job.info[:exception]]
|
205
208
|
job.clean
|
206
209
|
raise TryAgain
|
207
210
|
else
|
@@ -228,8 +231,9 @@ module Workflow
|
|
228
231
|
|
229
232
|
new_workload = {}
|
230
233
|
workload.each do |k,v|
|
231
|
-
next if k.done?
|
232
|
-
new_workload[k] = v.reject{|d| d.done? || (d.error? && ! d.recoverable_error?)}
|
234
|
+
next if k.done? || k.error? || k.aborted?
|
235
|
+
#new_workload[k] = v.reject{|d| d.done? || ((d.error? || d.aborted?) && ! d.recoverable_error?)}
|
236
|
+
new_workload[k] = v.reject{|d| d.done? || d.error? || d.aborted?}
|
233
237
|
end
|
234
238
|
workload = new_workload
|
235
239
|
sleep timer
|
data/lib/rbbt/workflow.rb
CHANGED
@@ -423,7 +423,7 @@ module Workflow
|
|
423
423
|
|
424
424
|
# jobname => true sets the value of the input to the name of the job
|
425
425
|
if task.input_options
|
426
|
-
jobname_input = task.input_options.select{|i,o| o[:jobname]}.collect{|i,o| i }.first
|
426
|
+
jobname_input = task.input_options.select{|i,o| o[:jobname] }.collect{|i,o| i }.first
|
427
427
|
else
|
428
428
|
jobname_input = nil
|
429
429
|
end
|
@@ -476,14 +476,14 @@ module Workflow
|
|
476
476
|
end
|
477
477
|
end
|
478
478
|
|
479
|
+
input_values = task.take_input_values(inputs)
|
479
480
|
if real_inputs.empty? && Workflow::TAG != :inputs && ! overriden
|
480
481
|
step_path = step_path taskname, jobname, [], [], extension
|
481
|
-
input_values = task.take_input_values(inputs)
|
482
482
|
else
|
483
|
-
input_values = task.take_input_values(inputs)
|
484
483
|
step_path = step_path taskname, jobname, input_values, dependencies, extension
|
485
484
|
end
|
486
485
|
|
486
|
+
|
487
487
|
job = get_job_step step_path, task, input_values, dependencies
|
488
488
|
job.workflow = self
|
489
489
|
job.clean_name = jobname
|
@@ -503,8 +503,6 @@ module Workflow
|
|
503
503
|
|
504
504
|
def _job(taskname, jobname = nil, inputs = {})
|
505
505
|
|
506
|
-
_inputs = IndiferentHash.setup(inputs.dup)
|
507
|
-
|
508
506
|
task_info = task_info(taskname)
|
509
507
|
task_inputs = task_info[:inputs]
|
510
508
|
persist_inputs = inputs.values_at(*task_inputs)
|
@@ -191,7 +191,7 @@ The `recursive_clean` cleans all the job dependency steps recursively.
|
|
191
191
|
-rcl--recursive_clean Clean the last step and its dependencies to recompute the job completely
|
192
192
|
-uaj--update_all_jobs Consider all dependencies when checking for updates, even when they have no info files
|
193
193
|
--fork Run job asyncronously and monitor progress. It monitors detached processes as well
|
194
|
-
--orchestrate Run the job through the orchestrator
|
194
|
+
--orchestrate* Run the job through the orchestrator
|
195
195
|
--detach Run job asyncronously and detach process
|
196
196
|
--exec Run job with no persistence
|
197
197
|
-O--output* Save job result into file
|
@@ -441,7 +441,17 @@ begin
|
|
441
441
|
job.fork
|
442
442
|
elsif options[:orchestrate]
|
443
443
|
require 'rbbt/workflow/util/orchestrator'
|
444
|
-
|
444
|
+
rules = case options[:orchestrate]
|
445
|
+
when 'none', 'open', 'default'
|
446
|
+
nil
|
447
|
+
else
|
448
|
+
YAML.parse(Open.read(options[:orchestrate]))
|
449
|
+
end
|
450
|
+
if rules
|
451
|
+
Workflow::Orchestrator.process rules, job
|
452
|
+
else
|
453
|
+
Workflow::Orchestrator.process job
|
454
|
+
end unless job.done?
|
445
455
|
else
|
446
456
|
job.run(:stream)
|
447
457
|
res = job
|
@@ -577,10 +587,10 @@ when Step
|
|
577
587
|
elsif detach
|
578
588
|
exit! 0
|
579
589
|
else
|
590
|
+
res.join
|
580
591
|
if %w(float integer string boolean).include?(res.result_type.to_s)
|
581
592
|
out.puts res.load
|
582
593
|
else
|
583
|
-
res.join
|
584
594
|
Open.open(res.path, :mode => 'rb') do |io|
|
585
595
|
Misc.consume_stream(io, false, out)
|
586
596
|
end if Open.exist?(res.path) || Open.remote?(res.path) || Open.ssh?(res.path)
|
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.33.
|
4
|
+
version: 5.33.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miguel Vazquez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-02-
|
11
|
+
date: 2022-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|