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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a6b198e57fe73c0e36e7aea6164bafd1a8a97d10b3a992f17d0ba6dc531a3c7
4
- data.tar.gz: 5aa8b8753fc88d5de6fa8f6db31b9b71a57ee5dcc86380041582a4985984f749
3
+ metadata.gz: 70ba4440be0bdca6f80b4aa78393ca4fbec5dbc8d8a1cc72b6393e73127b5340
4
+ data.tar.gz: 42021bd242233b5e4e3a268c27291953d84c8bad85b87d8feaf6389685f043bf
5
5
  SHA512:
6
- metadata.gz: a61b6e6671803d73b7993b2de9c6cf16d4f463ddd04f9378b54c77a00eb7292b4e817eea14cce81704fe3f2640d38ede202a3928d293ab1fe7e0e67fa87a35b0
7
- data.tar.gz: d41b1477aab34bfc08610602a3e333a5701edb58d9fa10ecf24436659c4e996bb000ceccb20bbcba1f153ec4e888264ae47ab28689b9e2879601da0b7822e831
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
@@ -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
- job_options.merge!(:batch_dependencies => top[:deps].nil? ? [] : top[:deps].collect{|d| batch_ids[d] })
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
- raise DependencyError, job if job.error? and not canfail
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
- raise DependencyError, [dependency.path, dependency.messages.last] * ": " if dependency.error?
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?
@@ -285,7 +285,7 @@ class Step
285
285
  begin
286
286
  return true unless info[:exception]
287
287
  klass = Kernel.const_get(info[:exception][:class])
288
- ! (klass <= RbbtException)
288
+ ! (klass <= RbbtException )
289
289
  rescue Exception
290
290
  true
291
291
  end
@@ -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, true)
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
- Workflow::Orchestrator.process job
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.0
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-18 00:00:00.000000000 Z
11
+ date: 2022-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake