rbbt-util 5.33.0 → 5.33.1
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/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
|