rbbt-util 5.30.5 → 5.30.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aa5b1545b1a92199d163bf398ca973c6aa3d78ab37cc724b988e007c87824b3b
4
- data.tar.gz: 6cd3ce80ea589fb97a211ebe1d2973dd7c0d3f93b1ccefe10b9ecefbc77ff515
3
+ metadata.gz: 48bec783cd5a61ffb37cb7cd80379ed9c90bbcfd2cecdb756cff0f2efd6240ed
4
+ data.tar.gz: 9da9e93fc5c89be3ca8f57f87ca2808f298e6a300cd13dfff4dd602a2bf1b4b0
5
5
  SHA512:
6
- metadata.gz: d8246d2a2686cc38086800fb6c30949bba93c8e78b7feac220b710a4e80f66858f979c5ea41de0beb67aeefd29de045e2315c3b50128f448bfef521ce3d52e15
7
- data.tar.gz: 26559322cae3bfb736565e8da0c7e63c3b006c793ab5cda8ec37a04fabfa460001bae6d7da8164ccd310730b81553d1d3b5a1d14cee9e6929793329ce508ec59
6
+ metadata.gz: 23976e1fcc0a216a822fa19ec9f4510d87f5d19d334245f6cea87746d3b7b85cf3c41110ce2d36f3a793f6e5af1bd08ad2299ad0acb08f11efe711f3417da590
7
+ data.tar.gz: 2fe9f8dbea015d105076926f0407c1029a400f6eafce7f17edca075e4975ef5a4bd455f416cad4e2d4deadb2d7486988c00500687fc41352020ba71fa07a0f0c
@@ -8,7 +8,7 @@ module HPC
8
8
  task_name = job.overriden.to_s if Symbol === job.overriden
9
9
 
10
10
  defaults = rules["defaults"] || {}
11
- defaults.merge(rules[workflow]["defaults"] || {}) if rules[workflow]
11
+ defaults = defaults.merge(rules[workflow]["defaults"] || {}) if rules[workflow]
12
12
 
13
13
  job_rules = IndiferentHash.setup(defaults.dup)
14
14
 
@@ -53,62 +53,159 @@ module HPC
53
53
  job_rules
54
54
  end
55
55
 
56
- def self.get_job_dependencies(job, job_rules)
56
+ def self.get_job_dependencies(job, job_rules = nil)
57
57
  deps = job.dependencies || []
58
58
  deps += job.input_dependencies || []
59
59
  deps
60
60
  end
61
61
 
62
- def self.orchestrate_job(job, options, skip = false, seen = {})
63
- return if job.done?
64
- return unless job.path.split("/")[-4] == "jobs"
65
- seen[:orchestration_target_job] ||= job
66
-
67
- options.delete "recursive_clean"
68
- options.delete "clean_task"
69
- options.delete "clean"
70
- options.delete "tail"
71
- options.delete "printfile"
72
- options.delete "detach"
62
+ def self.get_recursive_job_dependencies(job)
63
+ deps = get_job_dependencies(job)
64
+ (deps + deps.collect{|dep| get_recursive_job_dependencies(dep) }).flatten
65
+ end
73
66
 
74
- rules = YAML.load(Open.read(options[:orchestration_rules])) if options[:orchestration_rules]
75
- rules ||= {}
76
- IndiferentHash.setup(rules)
67
+ def self.piggyback(job, job_rules, job_deps)
68
+ return false unless job_rules["skip"]
69
+ final_deps = job_deps - job_deps.collect{|dep| get_recursive_job_dependencies(dep)}.flatten.uniq
70
+ final_deps = final_deps.reject{|dep| dep.done? && dep.status == :noinfo }
71
+ return final_deps.first if final_deps.length == 1
72
+ return false
73
+ end
77
74
 
75
+ def self.get_chains(job, rules, chains = {})
78
76
  job_rules = self.job_rules(rules, job)
77
+ job_deps = get_job_dependencies(job)
78
+
79
+ input_deps = []
80
+ job.rec_dependencies.each do |dep|
81
+ input_deps.concat dep.input_dependencies
82
+ end
79
83
 
80
- deps = get_job_dependencies(job, job_rules)
84
+ job_deps.each do |dep|
85
+ input_deps.concat dep.input_dependencies
86
+ get_chains(dep, rules, chains)
87
+ end
81
88
 
82
- dep_ids = deps.collect do |dep|
83
- skip_dep = job_rules["chain_tasks"] &&
89
+ job_deps.select do |dep|
90
+ chained = job_rules["chain_tasks"] &&
84
91
  job_rules["chain_tasks"][job.workflow.to_s] && job_rules["chain_tasks"][job.workflow.to_s].include?(job.task_name.to_s) &&
85
92
  job_rules["chain_tasks"][dep.workflow.to_s] && job_rules["chain_tasks"][dep.workflow.to_s].include?(dep.task_name.to_s)
86
93
 
87
- deps = seen[dep.path] ||= self.orchestrate_job(dep, options, skip_dep, seen)
88
- if job.canfail_paths.include? dep.path
89
- [deps].flatten.compact.collect{|id| ['canfail', id] * ":"}
94
+ dep_skip = dep.done? && ! input_deps.include?(dep) && self.job_rules(rules, dep)["skip"]
95
+ chained || dep_skip
96
+ end.each do |dep|
97
+ chains[job] ||= []
98
+ chains[job] << dep
99
+ chains[job].concat chains[dep] if chains[dep]
100
+ end
101
+
102
+ chains
103
+ end
104
+
105
+ def self.workload(job, rules, chains, options, seen = nil)
106
+ return [] if job.done?
107
+ if seen.nil?
108
+ seen = {}
109
+ target_job = true
110
+ end
111
+
112
+ job_rules = self.job_rules(rules, job)
113
+ job_deps = get_job_dependencies(job)
114
+
115
+ chain = chains[job]
116
+ chain = chain.reject{|j| seen.include? j.path} if chain
117
+ chain = chain.reject{|dep| dep.done? } if chain
118
+ piggyback = piggyback(job, job_rules, job_deps)
119
+ dep_ids = job_deps.collect do |dep|
120
+ seen[dep.path] ||= nil if chain && chain.include?(dep) #&& ! job.input_dependencies.include?(dep)
121
+ next_options = IndiferentHash.setup(options.dup)
122
+ if piggyback and piggyback == dep
123
+ next_options[:piggyback] ||= []
124
+ next_options[:piggyback].push job
125
+ ids = workload(dep, rules, chains, next_options, seen)
90
126
  else
91
- deps
127
+ next_options.delete :piggyback
128
+ ids = workload(dep, rules, chains, next_options, seen)
92
129
  end
93
- end.flatten.compact.uniq
94
130
 
95
- skip = true if job_rules[:skip]
96
- return dep_ids if skip and seen[:orchestration_target_job] != job
131
+ ids = [ids].flatten.compact.collect{|id| ['canfail', id] * ":"} if job.canfail_paths.include? dep.path
132
+
133
+ seen[dep.path] = ids
134
+ ids
135
+ end.compact.flatten.uniq
136
+
137
+ return seen[job.path] || dep_ids if seen.include?(job.path)
138
+
139
+ if piggyback and seen[piggyback.path]
140
+ return seen[job.path] = seen[piggyback.path]
141
+ end
97
142
 
98
143
  job_rules.delete :chain_tasks
99
144
  job_rules.delete :tasks
100
145
  job_rules.delete :workflow
101
146
 
102
- config_keys = job_rules.delete(:config_keys)
103
147
 
104
148
  job_options = IndiferentHash.setup(options.merge(job_rules).merge(:slurm_dependencies => dep_ids))
105
149
  job_options.delete :orchestration_rules
150
+
151
+ config_keys = job_rules.delete(:config_keys)
106
152
  if config_keys
107
153
  config_keys.gsub!(/,\s+/,',')
108
154
  job_options[:config_keys] = job_options[:config_keys] ? config_keys + "," + job_options[:config_keys] : config_keys
109
155
  end
110
156
 
111
- run_job(job, job_options)
157
+ if options[:piggyback]
158
+ manifest = options[:piggyback].uniq
159
+ manifest += [job]
160
+ manifest.concat chain if chain
161
+
162
+ job = options[:piggyback].first
163
+
164
+ job_rules = self.job_rules(rules, job)
165
+ new_config_keys = self.job_rules(rules, job)[:config_keys]
166
+ if new_config_keys
167
+ new_config_keys = new_config_keys.gsub(/,\s+/,',')
168
+ job_options[:config_keys] = job_options[:config_keys] ? new_config_keys + "," + job_options[:config_keys] : new_config_keys
169
+ end
170
+
171
+ job_options.delete :piggyback
172
+ else
173
+ manifest = [job]
174
+ manifest.concat chain if chain
175
+ end
176
+
177
+ manifest.uniq!
178
+
179
+ job_options[:manifest] = manifest.collect{|j| j.task_signature }
180
+
181
+ job_options[:config_keys] = job_options[:config_keys].split(",").uniq * "," if job_options[:config_keys]
182
+
183
+ if options[:dry_run]
184
+ puts Log.color(:magenta, "Manifest: ") + Log.color(:blue, job_options[:manifest] * ", ") + " - tasks: #{job_options[:task_cpus] || 1} - time: #{job_options[:time]} - config: #{job_options[:config_keys]}"
185
+ puts Log.color(:yellow, "Deps: ") + Log.color(:blue, job_options[:slurm_dependencies]*", ")
186
+ job_options[:manifest].first
187
+ else
188
+ run_job(job, job_options)
189
+ end
112
190
  end
191
+
192
+
193
+ def self.orchestrate_job(job, options)
194
+ options.delete "recursive_clean"
195
+ options.delete "clean_task"
196
+ options.delete "clean"
197
+ options.delete "tail"
198
+ options.delete "printfile"
199
+ options.delete "detach"
200
+
201
+ rules = YAML.load(Open.read(options[:orchestration_rules])) if options[:orchestration_rules]
202
+ rules ||= {}
203
+ IndiferentHash.setup(rules)
204
+
205
+ chains = get_chains(job, rules)
206
+
207
+ workload(job, rules, chains, options)
208
+ end
209
+
113
210
  end
114
211
  end
@@ -21,6 +21,8 @@ module HPC
21
21
  exclusive = options.delete :exclusive
22
22
  highmem = options.delete :highmem
23
23
 
24
+ manifest = options.delete :manifest
25
+
24
26
  queue = options.delete(:queue) || Rbbt::Config.get('queue', :slurm_queue, :slurm, :SLURM, :default => 'bsc_ls')
25
27
  task_cpus = options.delete(:task_cpus) || 1
26
28
  nodes = options.delete(:nodes) || 1
@@ -258,6 +260,10 @@ EOF
258
260
  workflow write_info --recursive --force=false --check_pid "$step_path" slurm_job $SLURM_JOB_ID
259
261
  EOF
260
262
 
263
+ header +=<<-EOF if manifest
264
+ #MANIFEST: #{manifest * ", "}
265
+ EOF
266
+
261
267
  header +=<<-EOF
262
268
  #CMD: #{rbbt_cmd}
263
269
  EOF
data/lib/rbbt/persist.rb CHANGED
@@ -349,7 +349,7 @@ module Persist
349
349
 
350
350
  Open.notify_write(path)
351
351
 
352
- return path if persist_options[:no_load]
352
+ return path if persist_options[:no_load] || type == :path
353
353
 
354
354
  res
355
355
  end
@@ -218,7 +218,14 @@ module Path
218
218
 
219
219
  else
220
220
  where = where.to_sym
221
- raise "Did not recognize the 'where' tag: #{where}. Options: #{paths.keys}" unless paths.include? where
221
+
222
+ if paths.include? where
223
+ path = paths[where]
224
+ elsif where.to_s.include?("/")
225
+ path = where.to_s
226
+ else
227
+ raise "Did not recognize the 'where' tag: #{where}. Options: #{paths.keys}" unless paths.include? where
228
+ end
222
229
 
223
230
  if where == :lib
224
231
  libdir = @libdir || Path.caller_lib_dir(caller_lib) || "NOLIBDIR"
@@ -227,7 +234,6 @@ module Path
227
234
  end
228
235
 
229
236
  pwd = FileUtils.pwd
230
- path = paths[where]
231
237
  path = File.join(path, "{PATH}") unless path.include? "PATH}" or path.include? "{BASENAME}"
232
238
  path = path.
233
239
  sub('{PKGDIR}', pkgdir).
@@ -717,7 +717,7 @@ module TSV
717
717
  def transpose(key_field = "Unkown ID")
718
718
  case type
719
719
  when :single, :flat
720
- transpose_list self.to_list, key_field
720
+ self.to_list.transpose_list key_field
721
721
  when :list
722
722
  transpose_list key_field
723
723
  when :double
@@ -90,6 +90,8 @@ module Rbbt::Config
90
90
  options = tokens.pop if Hash === tokens.last
91
91
  default = options.nil? ? nil : options[:default]
92
92
 
93
+ tokens = ["key:" + key] if tokens.empty?
94
+
93
95
  tokens = tokens.flatten
94
96
  file, _sep, line = caller.reject{|l|
95
97
  l =~ /rbbt\/(?:resource\.rb|workflow\.rb)/ or
@@ -106,7 +108,6 @@ module Rbbt::Config
106
108
 
107
109
  entries = CACHE[key.to_s]
108
110
  priorities = {}
109
- tokens = tokens + ["key:" << key.to_s]
110
111
  tokens.each do |token|
111
112
  token_prio = match entries, token.to_s
112
113
  token_prio.each do |prio, values|
@@ -145,7 +146,6 @@ module Rbbt::Config
145
146
  Rbbt::Config.load_file(Rbbt.etc.config_profile[config].find)
146
147
  else
147
148
  key, value, *tokens = config.split(/\s/)
148
- tokens = ['key:' << key << '::0'] if tokens.empty?
149
149
  tokens = tokens.collect do |tok|
150
150
  tok, _sep, prio = tok.partition("::")
151
151
  prio = "0" if prio.nil? or prio.empty?
data/lib/rbbt/workflow.rb CHANGED
@@ -379,7 +379,7 @@ module Workflow
379
379
  has_overriden_inputs = false
380
380
 
381
381
  inputs.each do |k,v|
382
- has_overriden_inputs = true if String === k and k.include? "#"
382
+ #has_overriden_inputs = true if String === k and k.include? "#"
383
383
  next unless (task_inputs.include?(k.to_sym) or task_inputs.include?(k.to_s))
384
384
  default = all_defaults[k]
385
385
  next if default == v
@@ -382,8 +382,8 @@ module Workflow
382
382
  else
383
383
  task_info = d[:workflow].task_info(d[:task])
384
384
 
385
- inputs = assign_dep_inputs({}, options.merge(d[:inputs] || {}), real_dependencies, task_info)
386
- d[:workflow]._job(d[:task], d[:jobname], inputs)
385
+ _inputs = assign_dep_inputs({}, options.merge(d[:inputs] || {}), real_dependencies, task_info)
386
+ d[:workflow]._job(d[:task], d[:jobname], _inputs)
387
387
  end
388
388
  end
389
389
  ComputeDependency.setup(d, compute) if compute
@@ -400,8 +400,8 @@ module Workflow
400
400
  setup_override_dependency(value, dep[:workflow], dep[:task])
401
401
  else
402
402
  task_info = (dep[:task] && dep[:workflow]) ? dep[:workflow].task_info(dep[:task]) : nil
403
- inputs = assign_dep_inputs({}, dep[:inputs], real_dependencies, task_info)
404
- dep = dep[:workflow]._job(dep[:task], dep[:jobname], inputs)
403
+ _inputs = assign_dep_inputs({}, dep[:inputs], real_dependencies, task_info)
404
+ dep = dep[:workflow]._job(dep[:task], dep[:jobname], _inputs)
405
405
  end
406
406
  end
407
407
  end
@@ -79,9 +79,10 @@ module Workflow
79
79
  dep = dependencies.last.join
80
80
  raise dep.get_exception if dep.error?
81
81
  set_info :result_type, dep.info[:result_type]
82
- forget = config :forget_dep_tasks, :forget_dep_tasks, :default => FORGET_DEP_TASKS
82
+ forget = config :forget_dep_tasks, "key:forget_dep_tasks", :default => FORGET_DEP_TASKS
83
83
  if forget
84
- remove = config :remove_dep_tasks, :remove_dep_tasks, :default => REMOVE_DEP_TASKS
84
+ remove = config :remove_dep_tasks, "key:remove_dep_tasks", :default => REMOVE_DEP_TASKS
85
+
85
86
  self.archive_deps
86
87
  self.copy_files_dir
87
88
  self.dependencies = self.dependencies - [dep]
@@ -92,7 +93,10 @@ module Workflow
92
93
  when 'true'
93
94
  dep.clean
94
95
  when 'recursive'
95
- dep.recursive_clean
96
+ dep.rec_dependencies.each do |d|
97
+ d.clean unless config(:remove_dep, d.task_signature, d.task_name, d.workflow.to_s, :default => true).to_s == 'false'
98
+ end
99
+ dep.clean unless config(:remove_dep, dep.task_signature, dep.task_name, dep.workflow.to_s, :default => true).to_s == 'false'
96
100
  end
97
101
  else
98
102
  if Open.exists?(dep.files_dir)
@@ -315,6 +315,11 @@ class RemoteStep < Step
315
315
  end
316
316
  end
317
317
 
318
+ def workflow_short_path
319
+ init_job unless @url
320
+ [@base_url, @task, @name] * "/"
321
+ end
322
+
318
323
  def short_path
319
324
  init_job unless @url
320
325
  [@task, @name] * "/"
@@ -114,9 +114,13 @@ class Step
114
114
 
115
115
  def copy_files_dir
116
116
  if File.symlink?(self.files_dir)
117
- realpath = Open.realpath(self.files_dir)
118
- Open.rm self.files_dir
119
- Open.cp realpath, self.files_dir
117
+ begin
118
+ realpath = Open.realpath(self.files_dir)
119
+ Open.rm self.files_dir
120
+ Open.cp realpath, self.files_dir
121
+ rescue
122
+ Log.warn "Copy files_dir for #{self.workflow_short_path}: " + $!.message
123
+ end
120
124
  end
121
125
  end
122
126
 
@@ -465,7 +469,10 @@ class Step
465
469
  self
466
470
  end
467
471
 
468
- def rec_dependencies(need_run = false, seen = [])
472
+ #connected = true means that dependency searching ends when a result is done
473
+ #but dependencies are absent, meanining that the file could have been dropped
474
+ #in
475
+ def rec_dependencies(connected = false, seen = [])
469
476
 
470
477
  # A step result with no info_file means that it was manually
471
478
  # placed. In that case, do not consider its dependencies
@@ -480,9 +487,9 @@ class Step
480
487
  #next if self.done? && Open.exists?(info_file) && info[:dependencies] && info[:dependencies].select{|task,name,path| path == step.path }.empty?
481
488
  next if archived_deps.include? step.path
482
489
  next if seen.include? step.path
483
- next if self.done? && need_run && ! updatable?
490
+ next if self.done? && connected && ! updatable?
484
491
 
485
- r = step.rec_dependencies(need_run, new_dependencies.collect{|d| d.path})
492
+ r = step.rec_dependencies(connected, new_dependencies.collect{|d| d.path})
486
493
  new_dependencies.concat r
487
494
  new_dependencies << step
488
495
  }
@@ -154,14 +154,24 @@ class Step
154
154
  @name ||= path.sub(/.*\/#{Regexp.quote task_name.to_s}\/(.*)/, '\1')
155
155
  end
156
156
 
157
+
157
158
  def short_path
158
159
  [task_name, name] * "/"
159
160
  end
160
161
 
162
+ def workflow_short_path
163
+ return short_path unless workflow
164
+ workflow.to_s + "#" + short_path
165
+ end
166
+
161
167
  def task_name
162
168
  @task_name ||= task.name
163
169
  end
164
170
 
171
+ def task_signature
172
+ [workflow.to_s, task_name] * "#"
173
+ end
174
+
165
175
  # {{{ INFO
166
176
 
167
177
  def info_file
@@ -456,7 +466,7 @@ class Step
456
466
  end
457
467
 
458
468
  def dirty_files
459
- rec_dependencies = self.rec_dependencies
469
+ rec_dependencies = self.rec_dependencies(true)
460
470
  return [] if rec_dependencies.empty?
461
471
  canfail_paths = self.canfail_paths
462
472
 
@@ -112,23 +112,27 @@ 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?)) || (ENV["RBBT_UPDATE"] && ! (done? && ! Open.exists?(info_file)))
115
+ return true if ENV["RBBT_UPDATE_ALL_JOBS"] == 'true'
116
+ return false unless ENV["RBBT_UPDATE"] == "true"
117
+ return false unless Open.exists?(info_file)
118
+ return true if status != :noinfo && ! (relocated? && done?)
119
+ false
116
120
  end
117
121
 
118
122
  def dependency_checks
119
123
  return [] if ENV["RBBT_UPDATE"] != "true"
120
124
 
121
- rec_dependencies.
125
+ rec_dependencies(true).
122
126
  reject{|dependency| (defined?(WorkflowRemoteClient) && WorkflowRemoteClient::RemoteStep === dependency) || Open.remote?(dependency.path) }.
123
127
  reject{|dependency| dependency.error? }.
124
128
  #select{|dependency| Open.exists?(dependency.path) || ((Open.exists?(dependency.info_file) && (dependency.status == :cleaned) || dependency.status == :waiting)) }.
125
- select{|dependency| dependency.updatable? }.
129
+ #select{|dependency| dependency.updatable? }.
126
130
  collect{|dependency| Workflow.relocate_dependency(self, dependency)}
127
131
  end
128
132
 
129
133
  def input_checks
130
- (inputs.select{|i| Step === i } + inputs.select{|i| Path === i && Step === i.resource}.collect{|i| i.resource}).
131
- select{|dependency| dependency.updatable? }
134
+ (inputs.select{|i| Step === i } + inputs.select{|i| Path === i && Step === i.resource}.collect{|i| i.resource})
135
+ #select{|dependency| dependency.updatable? }
132
136
  end
133
137
 
134
138
  def checks
@@ -153,7 +157,8 @@ class Step
153
157
  canfail_paths = self.canfail_paths
154
158
  this_mtime = Open.mtime(self.path) if Open.exists?(self.path)
155
159
 
156
- outdated_time = checks.select{|dep| dep.updatable? && dep.done? && Persist.newer?(path, dep.path) }
160
+ #outdated_time = checks.select{|dep| dep.updatable? && dep.done? && Persist.newer?(path, dep.path) }
161
+ outdated_time = checks.select{|dep| dep.done? && Persist.newer?(path, dep.path) }
157
162
  outdated_dep = checks.reject{|dep| dep.done? || (dep.error? && ! dep.recoverable_error? && canfail_paths.include?(dep.path)) }
158
163
 
159
164
  #checks.each do |dep|
@@ -21,7 +21,7 @@ module Task
21
21
 
22
22
  selects = []
23
23
  if inputs.any?
24
- inputs.zip(input_types.values_at(*inputs)).select{|i,t| t.to_sym == :select and input_options[i][:select_options] }.each{|i,t| selects << [i, input_options[i][:select_options]] }
24
+ inputs.zip(input_types.values_at(*inputs)).select{|i,t| t.to_sym == :select && input_options[i] && input_options[i][:select_options] }.each{|i,t| selects << [i, input_options[i][:select_options]] }
25
25
  puts SOPT.input_doc(inputs, input_types, input_descriptions, input_defaults, true)
26
26
  puts
27
27
  end
@@ -51,7 +51,7 @@ class Step
51
51
  end
52
52
  end
53
53
 
54
- def self.job_files_for_archive(files, recursive = false)
54
+ def self.job_files_for_archive(files, recursive = false, skip_overriden = false)
55
55
  job_files = Set.new
56
56
 
57
57
  jobs = files.collect do |file|
@@ -65,6 +65,8 @@ class Step
65
65
 
66
66
  jobs.each do |step|
67
67
  next unless File.exists?(step.path)
68
+ next if skip_overriden && step.overriden
69
+
68
70
  job_files << step.path
69
71
  job_files << step.info_file if File.exists?(step.info_file)
70
72
  job_files << Step.md5_file(step.path) if File.exists?(Step.md5_file step.path)
@@ -258,9 +260,9 @@ puts resource[path].find(search_path)
258
260
  end
259
261
  end
260
262
 
261
- def self.purge(path, recursive = false)
263
+ def self.purge(path, recursive = false, skip_overriden = true)
262
264
  path = [path] if String === path
263
- job_files = job_files_for_archive path, recursive
265
+ job_files = job_files_for_archive path, recursive, skip_overriden
264
266
 
265
267
  job_files.each do |file|
266
268
  begin
@@ -91,7 +91,14 @@ class Step
91
91
  if expand_repeats
92
92
  str << Log.color(:green, Log.uncolor(prov_report(dep, offset+1, task)))
93
93
  else
94
- str << Log.color(:green, " " * (offset + 1) + Log.uncolor(prov_report_msg(dep.status, dep.info[:name], dep.path, dep.info)))
94
+ info = dep.info || {}
95
+ status = info[:status] || :missing
96
+ status = "remote" if Open.remote?(path) || Open.ssh?(path)
97
+ name = info[:name] || File.basename(path)
98
+ status = :unsync if status == :done and not Open.exist?(path)
99
+ status = :notfound if status == :noinfo and not Open.exist?(path)
100
+
101
+ str << Log.color(status == :notfound ? :blue : :green, " " * (offset + 1) + Log.uncolor(prov_report_msg(status, name, path, info)))
95
102
  end
96
103
  end
97
104
  end if step.dependencies
data/share/Rlib/util.R CHANGED
@@ -484,7 +484,7 @@ rbbt.model.inpute <- function(data, formula, ...){
484
484
  data
485
485
  }
486
486
 
487
- rbbt.tsv.melt <- function(tsv, variable = NULL, value = NULL, key.field = NULL){
487
+ rbbt.tsv.melt <- function(tsv, variable = NULL, value = NULL, key.field = NULL, ...){
488
488
  rbbt.require('reshape2')
489
489
  if (is.null(key.field)){ key.field = attributes(data)$key.field;}
490
490
  if (is.null(key.field)){ key.field = "ID" }
@@ -494,7 +494,7 @@ rbbt.tsv.melt <- function(tsv, variable = NULL, value = NULL, key.field = NULL){
494
494
 
495
495
  tsv[key.field] = rownames(tsv)
496
496
 
497
- m <- melt(tsv)
497
+ m <- melt(tsv, id.vars=c(key.field), ...)
498
498
 
499
499
  names(m) <- c(key.field, variable, value)
500
500
 
@@ -784,6 +784,12 @@ rbbt.plot.venn <- function(data, a=NULL, category=NULL, fill=NULL, ...) {
784
784
  return(out)
785
785
  }
786
786
 
787
+ rbbt.plot.upset <- function(data, variable = NULL, ...){
788
+ rbbt.require('UpSetR')
789
+ data[data == TRUE] = 1
790
+ return(upset(data, ...))
791
+ }
792
+
787
793
  rbbt.plot.pca <- function(data, center = TRUE, scale. = TRUE, ...) {
788
794
  rbbt.require('vqv/ggbiplot')
789
795
  data <- rbbt.impute(data)
@@ -70,6 +70,13 @@ workdir.glob("**/command.slurm").sort_by{|f| File.mtime(f)}.each do |fcmd|
70
70
  cmd = nil
71
71
  end
72
72
 
73
+ if m = Open.read(fcmd).match(/#MANIFEST: (.*)/)
74
+ manifest = m[1]
75
+ else
76
+ manifest = nil
77
+ end
78
+
79
+
73
80
  if m = Open.read(fcmd).match(/# Run command\n(.*?)\n/im)
74
81
  exe = m[1].sub('step_path=$(','')
75
82
  else
@@ -145,6 +152,7 @@ workdir.glob("**/command.slurm").sort_by{|f| File.mtime(f)}.each do |fcmd|
145
152
  puts Log.color :blue, dir
146
153
  puts Log.color(:magenta, "Creation: ") << File.mtime(File.join(dir, 'command.slurm')).to_s
147
154
  puts Log.color(:magenta, "Started: ") << File.ctime(File.join(dir, 'std.err')).to_s if File.exist?(File.join(dir, 'std.err'))
155
+ puts Log.color(:magenta, "Manifest: ") << Log.color(:yellow, manifest)
148
156
  puts Log.color(:magenta, "Done: ") << File.mtime(File.join(dir, 'exit.status')).to_s if File.exist?(File.join(dir, 'exit.status'))
149
157
  puts Log.color(:magenta, "Exec: ") << (exe || "Missing")
150
158
  puts Log.color(:magenta, "CMD: ") << (Log.color(:yellow, cmd) || "Missing")
@@ -16,6 +16,8 @@ $ rbbt workflow server [options] <Workflow>
16
16
  -B--Bind* Bind IP
17
17
  -p--port* TCP port
18
18
  -s--server* Server type: thin, webrick, unicorn, etc
19
+ -w--workers* Number of workers for cluster mode (puma)
20
+ -so--server_options* Additional options for server (e.g. option1=value1;option2=value2)
19
21
  -f--finder Start server with finder functionality
20
22
  -RS--Rserve_session* Rserve session to use, otherwise start new one
21
23
  -wd--workdir* Change the working directory of the workflow
@@ -32,7 +34,6 @@ $ rbbt workflow server [options] <Workflow>
32
34
  --export_synchronous* Export workflow tasks as synchronous
33
35
  --export_exec* Export workflow tasks as exec
34
36
  --export_stream* Export workflow tasks as stream
35
- --options* Additional options for server (e.g. option1=value1;option2=value2)
36
37
  EOF
37
38
 
38
39
  if options[:help]
@@ -108,20 +109,24 @@ TmpFile.with_file do |app_dir|
108
109
  config_ru_file = File.exist?('./workflow_config.ru') ? './workflow_config.ru' : Rbbt.share['workflow_config.ru'].find
109
110
 
110
111
 
111
- if options[:options]
112
- options[:options].split(";").each do |pair|
112
+ if options[:server_options]
113
+ options[:server_options].split(";").each do |pair|
113
114
  name, _sep, value = pair.partition("=")
114
115
  name = name[1..-1].to_sym if name[0] == ':'
116
+ value = value.to_i if value =~ /^\d+$/
117
+ value = true if value == "true"
118
+ value = false if value == "false"
115
119
  options[name] = value
116
120
  end
121
+ options.delete :server_options
117
122
  end
118
123
 
119
124
  case server
120
125
  when 'unicorn'
121
126
  `env RBBT_LOG=#{Log.severity.to_s} unicorn -c #{ Rbbt.share['unicorn.rb'].find } '#{config_ru_file}' -p #{options[:Port] || "2887"}`
122
- when 'puma_alt'
127
+ when 'puma_production'
123
128
  #`puma '#{config_ru_file}' -p #{options[:Port] || "2887"} -w 3 -t 8:32 --preload`
124
- `env RBBT_LOG=#{Log.severity.to_s} puma '#{config_ru_file}' -p #{options[:Port] || "2887"} -w 20 -t 10:160 --preload`
129
+ CMD.cmd_log("env RBBT_LOG=#{Log.severity.to_s} puma '#{config_ru_file}' -p #{options[:Port] || "2887"} -w 20 -t 10:160 --preload")
125
130
  else
126
131
  options[:config] = config_ru_file
127
132
 
@@ -5,8 +5,9 @@ class TestConfig < Test::Unit::TestCase
5
5
  def setup
6
6
  Rbbt::Config.set({:cpus => 30}, :test_config, :test)
7
7
  Rbbt::Config.set(:cpus, 5, "slow::2", :test)
8
- Rbbt::Config.set({:token => "token"}, "token", "key:token")
8
+ Rbbt::Config.set({:token => "token"}, "token")
9
9
  Rbbt::Config.set(:notoken, "no_token")
10
+ Rbbt::Config.set({:emptytoken => "empty"})
10
11
  end
11
12
 
12
13
  def test_simple
@@ -19,8 +20,12 @@ class TestConfig < Test::Unit::TestCase
19
20
 
20
21
  def test_simple_no_token
21
22
  assert_equal "token", Rbbt::Config.get("token", "token")
22
- assert_equal "token", Rbbt::Config.get("token")
23
- assert_equal "no_token", Rbbt::Config.get("notoken")
23
+ assert_equal "no_token", Rbbt::Config.get("notoken", "key:notoken")
24
+ assert_equal 'token', Rbbt::Config.get("token", "key:token")
25
+ assert_equal 'token', Rbbt::Config.get("token")
26
+ assert_equal nil, Rbbt::Config.get("token", "someotherthing")
27
+ assert_equal "default_token", Rbbt::Config.get("token", 'unknown', :default => 'default_token')
28
+ assert_equal 'empty', Rbbt::Config.get("emptytoken", 'key:emptytoken')
24
29
  end
25
30
 
26
31
  def test_prio
@@ -54,6 +59,11 @@ class TestConfig < Test::Unit::TestCase
54
59
  assert_equal "V1", Rbbt::Config.get('key', 'token1', 'token2')
55
60
  end
56
61
 
62
+ def test_default
63
+ Rbbt::Config.add_entry 'key', 'V1', 'token1'
64
+ assert_equal "V3", Rbbt::Config.get('key', 'token2', :default => 'V3')
65
+ end
66
+
57
67
 
58
68
  end
59
69
 
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.30.5
4
+ version: 5.30.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Vazquez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-07 00:00:00.000000000 Z
11
+ date: 2021-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake