rbbt-util 5.44.1 → 6.0.4

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.
Files changed (175) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/bin/rbbt +67 -90
  4. data/bin/rbbt_exec.rb +2 -2
  5. data/etc/app.d/base.rb +2 -2
  6. data/etc/app.d/semaphores.rb +3 -3
  7. data/lib/rbbt/annotations/annotated_array.rb +207 -207
  8. data/lib/rbbt/annotations/refactor.rb +27 -0
  9. data/lib/rbbt/annotations/util.rb +282 -282
  10. data/lib/rbbt/annotations.rb +343 -320
  11. data/lib/rbbt/association/database.rb +200 -225
  12. data/lib/rbbt/association/index.rb +294 -291
  13. data/lib/rbbt/association/item.rb +227 -227
  14. data/lib/rbbt/association/open.rb +35 -34
  15. data/lib/rbbt/association/util.rb +0 -169
  16. data/lib/rbbt/association.rb +2 -4
  17. data/lib/rbbt/entity/identifiers.rb +119 -118
  18. data/lib/rbbt/entity/refactor.rb +12 -0
  19. data/lib/rbbt/entity.rb +319 -315
  20. data/lib/rbbt/hpc/batch.rb +72 -53
  21. data/lib/rbbt/hpc/lsf.rb +2 -2
  22. data/lib/rbbt/hpc/orchestrate/batches.rb +2 -2
  23. data/lib/rbbt/hpc/orchestrate/chains.rb +25 -5
  24. data/lib/rbbt/hpc/orchestrate/rules.rb +2 -2
  25. data/lib/rbbt/hpc/orchestrate.rb +19 -13
  26. data/lib/rbbt/hpc/slurm.rb +18 -18
  27. data/lib/rbbt/knowledge_base/entity.rb +13 -5
  28. data/lib/rbbt/knowledge_base/query.rb +2 -2
  29. data/lib/rbbt/knowledge_base/registry.rb +32 -31
  30. data/lib/rbbt/knowledge_base/traverse.rb +1 -1
  31. data/lib/rbbt/knowledge_base.rb +1 -1
  32. data/lib/rbbt/monitor.rb +36 -25
  33. data/lib/rbbt/persist/refactor.rb +166 -0
  34. data/lib/rbbt/persist/tsv/tokyocabinet.rb +105 -105
  35. data/lib/rbbt/persist/tsv.rb +187 -185
  36. data/lib/rbbt/persist.rb +556 -551
  37. data/lib/rbbt/refactor.rb +20 -0
  38. data/lib/rbbt/resource/path/refactor.rb +178 -0
  39. data/lib/rbbt/resource/path.rb +317 -497
  40. data/lib/rbbt/resource/util.rb +0 -48
  41. data/lib/rbbt/resource.rb +3 -390
  42. data/lib/rbbt/tsv/accessor.rb +2 -838
  43. data/lib/rbbt/tsv/attach.rb +303 -299
  44. data/lib/rbbt/tsv/change_id.rb +244 -245
  45. data/lib/rbbt/tsv/csv.rb +87 -85
  46. data/lib/rbbt/tsv/dumper.rb +2 -100
  47. data/lib/rbbt/tsv/excel.rb +26 -24
  48. data/lib/rbbt/tsv/field_index.rb +4 -1
  49. data/lib/rbbt/tsv/filter.rb +3 -2
  50. data/lib/rbbt/tsv/index.rb +2 -284
  51. data/lib/rbbt/tsv/manipulate.rb +750 -747
  52. data/lib/rbbt/tsv/marshal.rb +3 -3
  53. data/lib/rbbt/tsv/matrix.rb +2 -2
  54. data/lib/rbbt/tsv/parallel/through.rb +2 -1
  55. data/lib/rbbt/tsv/parallel/traverse.rb +783 -781
  56. data/lib/rbbt/tsv/parser.rb +678 -678
  57. data/lib/rbbt/tsv/refactor.rb +195 -0
  58. data/lib/rbbt/tsv/stream.rb +253 -251
  59. data/lib/rbbt/tsv/util.rb +420 -420
  60. data/lib/rbbt/tsv.rb +210 -208
  61. data/lib/rbbt/util/R/eval.rb +4 -4
  62. data/lib/rbbt/util/R/plot.rb +62 -166
  63. data/lib/rbbt/util/R.rb +21 -18
  64. data/lib/rbbt/util/cmd.rb +2 -318
  65. data/lib/rbbt/util/color.rb +269 -269
  66. data/lib/rbbt/util/colorize.rb +89 -89
  67. data/lib/rbbt/util/concurrency/processes/refactor.rb +22 -0
  68. data/lib/rbbt/util/concurrency/processes/worker.rb +2 -2
  69. data/lib/rbbt/util/concurrency/processes.rb +389 -386
  70. data/lib/rbbt/util/config.rb +169 -167
  71. data/lib/rbbt/util/filecache.rb +1 -1
  72. data/lib/rbbt/util/iruby.rb +20 -0
  73. data/lib/rbbt/util/log/progress/report.rb +241 -241
  74. data/lib/rbbt/util/log/progress/util.rb +99 -99
  75. data/lib/rbbt/util/log/progress.rb +102 -102
  76. data/lib/rbbt/util/log/refactor.rb +49 -0
  77. data/lib/rbbt/util/log.rb +486 -532
  78. data/lib/rbbt/util/migrate.rb +2 -2
  79. data/lib/rbbt/util/misc/concurrent_stream.rb +248 -246
  80. data/lib/rbbt/util/misc/development.rb +12 -11
  81. data/lib/rbbt/util/misc/exceptions.rb +117 -112
  82. data/lib/rbbt/util/misc/format.rb +2 -230
  83. data/lib/rbbt/util/misc/indiferent_hash.rb +2 -107
  84. data/lib/rbbt/util/misc/inspect.rb +2 -476
  85. data/lib/rbbt/util/misc/lock.rb +109 -106
  86. data/lib/rbbt/util/misc/omics.rb +9 -1
  87. data/lib/rbbt/util/misc/pipes.rb +765 -793
  88. data/lib/rbbt/util/misc/refactor.rb +20 -0
  89. data/lib/rbbt/util/misc/ssw.rb +27 -17
  90. data/lib/rbbt/util/misc/system.rb +92 -105
  91. data/lib/rbbt/util/misc.rb +39 -20
  92. data/lib/rbbt/util/named_array/refactor.rb +4 -0
  93. data/lib/rbbt/util/named_array.rb +3 -220
  94. data/lib/rbbt/util/open/refactor.rb +7 -0
  95. data/lib/rbbt/util/open.rb +3 -857
  96. data/lib/rbbt/util/procpath.rb +6 -6
  97. data/lib/rbbt/util/python/paths.rb +27 -0
  98. data/lib/rbbt/util/python/run.rb +115 -0
  99. data/lib/rbbt/util/python/script.rb +110 -0
  100. data/lib/rbbt/util/python/util.rb +3 -3
  101. data/lib/rbbt/util/python.rb +22 -81
  102. data/lib/rbbt/util/semaphore.rb +152 -148
  103. data/lib/rbbt/util/simpleopt.rb +9 -8
  104. data/lib/rbbt/util/ssh/refactor.rb +19 -0
  105. data/lib/rbbt/util/ssh.rb +122 -118
  106. data/lib/rbbt/util/tar.rb +117 -115
  107. data/lib/rbbt/util/tmpfile.rb +69 -67
  108. data/lib/rbbt/util/version.rb +2 -0
  109. data/lib/rbbt/workflow/refactor/entity.rb +11 -0
  110. data/lib/rbbt/workflow/refactor/export.rb +66 -0
  111. data/lib/rbbt/workflow/refactor/inputs.rb +24 -0
  112. data/lib/rbbt/workflow/refactor/recursive.rb +64 -0
  113. data/lib/rbbt/workflow/refactor/task_info.rb +66 -0
  114. data/lib/rbbt/workflow/refactor.rb +150 -0
  115. data/lib/rbbt/workflow/remote_workflow/driver/rest.rb +1 -2
  116. data/lib/rbbt/workflow/remote_workflow/driver/ssh.rb +55 -32
  117. data/lib/rbbt/workflow/remote_workflow/remote_step/rest.rb +3 -1
  118. data/lib/rbbt/workflow/remote_workflow/remote_step/ssh.rb +14 -5
  119. data/lib/rbbt/workflow/remote_workflow/remote_step.rb +19 -7
  120. data/lib/rbbt/workflow/remote_workflow.rb +6 -1
  121. data/lib/rbbt/workflow/step/run.rb +766 -766
  122. data/lib/rbbt/workflow/step/save_load_inputs.rb +254 -254
  123. data/lib/rbbt/workflow/step.rb +2 -362
  124. data/lib/rbbt/workflow/task.rb +118 -118
  125. data/lib/rbbt/workflow/usage.rb +289 -287
  126. data/lib/rbbt/workflow/util/archive.rb +6 -5
  127. data/lib/rbbt/workflow/util/data.rb +1 -1
  128. data/lib/rbbt/workflow/util/orchestrator.rb +249 -246
  129. data/lib/rbbt/workflow/util/trace.rb +79 -44
  130. data/lib/rbbt/workflow.rb +4 -882
  131. data/lib/rbbt-util.rb +21 -13
  132. data/lib/rbbt.rb +16 -3
  133. data/python/rbbt/__init__.py +96 -4
  134. data/python/rbbt/workflow/remote.py +104 -0
  135. data/python/rbbt/workflow.py +64 -0
  136. data/python/test.py +10 -0
  137. data/share/Rlib/plot.R +37 -37
  138. data/share/Rlib/svg.R +22 -5
  139. data/share/install/software/lib/install_helpers +1 -1
  140. data/share/rbbt_commands/hpc/list +2 -3
  141. data/share/rbbt_commands/hpc/orchestrate +4 -4
  142. data/share/rbbt_commands/hpc/tail +2 -0
  143. data/share/rbbt_commands/hpc/task +10 -7
  144. data/share/rbbt_commands/lsf/list +2 -3
  145. data/share/rbbt_commands/lsf/orchestrate +4 -4
  146. data/share/rbbt_commands/lsf/tail +2 -0
  147. data/share/rbbt_commands/lsf/task +10 -7
  148. data/share/rbbt_commands/migrate +1 -1
  149. data/share/rbbt_commands/pbs/list +2 -3
  150. data/share/rbbt_commands/pbs/orchestrate +4 -4
  151. data/share/rbbt_commands/pbs/tail +2 -0
  152. data/share/rbbt_commands/pbs/task +10 -7
  153. data/share/rbbt_commands/resource/produce +8 -1
  154. data/share/rbbt_commands/slurm/list +2 -3
  155. data/share/rbbt_commands/slurm/orchestrate +4 -4
  156. data/share/rbbt_commands/slurm/tail +2 -0
  157. data/share/rbbt_commands/slurm/task +10 -7
  158. data/share/rbbt_commands/system/clean +5 -5
  159. data/share/rbbt_commands/system/status +5 -5
  160. data/share/rbbt_commands/tsv/get +2 -3
  161. data/share/rbbt_commands/tsv/info +10 -13
  162. data/share/rbbt_commands/tsv/keys +18 -14
  163. data/share/rbbt_commands/tsv/slice +2 -2
  164. data/share/rbbt_commands/tsv/transpose +6 -2
  165. data/share/rbbt_commands/workflow/info +20 -24
  166. data/share/rbbt_commands/workflow/list +1 -1
  167. data/share/rbbt_commands/workflow/prov +20 -13
  168. data/share/rbbt_commands/workflow/retry +43 -0
  169. data/share/rbbt_commands/workflow/server +12 -2
  170. data/share/rbbt_commands/workflow/task +80 -73
  171. data/share/rbbt_commands/workflow/write_info +26 -9
  172. data/share/software/opt/ssw/ssw.c +861 -0
  173. data/share/software/opt/ssw/ssw.h +130 -0
  174. data/share/workflow_config.ru +3 -3
  175. metadata +45 -6
@@ -0,0 +1,150 @@
1
+ require_relative 'refactor/inputs'
2
+ require_relative 'refactor/entity'
3
+
4
+ class Step
5
+ alias get_stream stream
6
+ alias old_exec exec
7
+
8
+ def exec(noload = false)
9
+ old_exec
10
+ end
11
+
12
+ def self.md5_file(path)
13
+ path.nil? ? nil : path + '.md5'
14
+ end
15
+
16
+ def md5_file
17
+ Step.md5_file(path)
18
+ end
19
+
20
+ alias real_inputs non_default_inputs
21
+
22
+ def reset_info(info = {})
23
+ if ENV["BATCH_SYSTEM"]
24
+ info = info.dup
25
+ info[:batch_system] = ENV["BATCH_SYSTEM"]
26
+ info[:batch_job] = ENV["BATCH_JOB_ID"]
27
+ end
28
+ save_info(info)
29
+ end
30
+ end
31
+
32
+ module Workflow
33
+ alias workdir= directory=
34
+
35
+ def resumable
36
+ Log.warn "RESUMABLE MOCKED"
37
+ end
38
+
39
+ DEFAULT_NAME = Task::DEFAULT_NAME
40
+
41
+ end
42
+
43
+ module ComputeDependency
44
+ attr_accessor :compute
45
+ def self.setup(dep, value)
46
+ dep.extend ComputeDependency
47
+ dep.compute = value
48
+ end
49
+
50
+ def canfail?
51
+ compute == :canfail || (Array === compute && compute.include?(:canfail))
52
+ end
53
+ end
54
+
55
+ class Step
56
+
57
+ def soft_grace
58
+ sleep 1 until Open.exists?(info_file)
59
+ end
60
+ end
61
+
62
+ Rbbt.relay_module_method Workflow, :load_step, Step, :load
63
+ Rbbt.relay_module_method Workflow, :fast_load_step, Step, :load
64
+
65
+ module Workflow
66
+ attr_accessor :remote_tasks
67
+ def remote_tasks
68
+ @remote_tasks ||= {}
69
+ end
70
+ def task_for(path)
71
+ parts = path.split("/")
72
+ if parts.include?(self.to_s)
73
+ parts[parts.index(self.to_s) + 1]
74
+ else
75
+ parts[-2]
76
+ end
77
+ end
78
+
79
+ def fast_load_id(id)
80
+ path = if Path === directory
81
+ directory[id].find
82
+ else
83
+ File.join(directory, id)
84
+ end
85
+ task = task_for path
86
+ return remote_tasks[task].load_id(id) if remote_tasks && remote_tasks.include?(task)
87
+ return Workflow.fast_load_step path
88
+ end
89
+
90
+ alias load_id fast_load_id
91
+
92
+ class << self
93
+ alias original_require_workflow require_workflow
94
+
95
+ def require_remote_workflow(wf_name, url)
96
+ require 'rbbt/workflow/remote_workflow'
97
+ eval "Object::#{wf_name.split("+").first} = RemoteWorkflow.new '#{ url }', '#{wf_name}'"
98
+ end
99
+
100
+ def require_workflow(wf_name, force_local = true)
101
+ if Open.remote?(wf_name) or Open.ssh?(wf_name)
102
+ url = wf_name
103
+
104
+ if Open.ssh?(wf_name)
105
+ wf_name = File.basename(url.split(":").last)
106
+ else
107
+ wf_name = File.basename(url)
108
+ end
109
+
110
+ begin
111
+ return require_remote_workflow(wf_name, url)
112
+ ensure
113
+ Log.debug{"Workflow #{ wf_name } loaded remotely: #{ url }"}
114
+ end
115
+ end
116
+
117
+ original_require_workflow(wf_name)
118
+ end
119
+ end
120
+ end
121
+
122
+ module Workflow
123
+ class << self
124
+ def workflow_dir
125
+ @workflow_dir ||
126
+ ENV["RBBT_WORKFLOW_DIR"] ||
127
+ begin
128
+ workflow_dir_config = Path.setup("etc/workflow_dir")
129
+ if workflow_dir_config.exists?
130
+ Path.setup(workflow_dir_config.read.strip)
131
+ else
132
+ Path.setup('workflows').find(:user)
133
+ end
134
+ end
135
+ end
136
+
137
+ def workflow_repo
138
+ @workflow_repo ||
139
+ ENV["RBBT_WORKFLOW_REPO"] ||
140
+ begin
141
+ workflow_repo_config = Path.setup("etc/workflow_repo")
142
+ if workflow_repo_config.exists?
143
+ workflow_repo_config.read.strip
144
+ else
145
+ 'https://github.com/Rbbt-Workflows/'
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
@@ -146,7 +146,6 @@ class RemoteWorkflow
146
146
  task_info = RemoteWorkflow::REST.get_json(File.join(url, task.to_s, 'info'))
147
147
  task_info = RemoteWorkflow.fix_hash(task_info)
148
148
 
149
- task_info[:result_type] = task_info[:result_type].to_sym
150
149
  task_info[:export] = task_info[:export].to_sym
151
150
  task_info[:input_types] = RemoteWorkflow.fix_hash(task_info[:input_types], true)
152
151
  task_info[:inputs] = task_info[:inputs].collect{|input| input.to_sym }
@@ -248,7 +247,6 @@ class RemoteWorkflow
248
247
  end
249
248
  end
250
249
 
251
-
252
250
  def task_info(task)
253
251
  RemoteWorkflow::REST.task_info(url, task)
254
252
  end
@@ -260,6 +258,7 @@ class RemoteWorkflow
260
258
  @exec_exports = (task_exports["exec"] || []).collect{|task| task.to_sym }
261
259
  @stream_exports = (task_exports["stream"] || []).collect{|task| task.to_sym }
262
260
  @can_stream = task_exports["can_stream"]
261
+ (@asynchronous_exports + @synchronous_exports + @exec_exports).uniq.each do |e| tasks[e] end
263
262
  end
264
263
  end
265
264
  end
@@ -80,7 +80,7 @@ res = job_info = job.info
80
80
  script =<<-EOF
81
81
  jobname = #{jobname.nil? ? 'nil' : "'#{jobname}'"}
82
82
  path = File.join(ENV["HOME"], '.rbbt/tmp/tmp-ssh_job_inputs/#{inputs_id}')
83
- job_inputs = Workflow.load_inputs(path, task_info[:inputs], task_info[:input_types])
83
+ job_inputs = wf.tasks[task].load_inputs(path)
84
84
  job = wf.job(task, jobname, job_inputs)
85
85
  EOF
86
86
  script
@@ -199,28 +199,6 @@ job.clean
199
199
  end
200
200
  end
201
201
 
202
- #def self.relay_old(workflow, task, jobname, inputs, server, options = {})
203
- # options = Misc.add_defaults options, :search_path => 'user'
204
- # search_path = options[:search_path]
205
-
206
- # job = workflow.job(task, jobname, inputs)
207
-
208
- # job.dependencies.each do |dep|
209
- # dep.produce
210
- # end
211
-
212
- # override_dependencies = job.dependencies.collect{|dep| [dep.workflow.to_s, dep.task_name.to_s] * "#" << "=" << Rbbt.identify(dep.path)}
213
-
214
- # job.dependencies.each do |dep|
215
- # Step.migrate(dep.path, search_path, :target => server)
216
- # end
217
-
218
- # remote = RemoteWorkflow.new("ssh://#{server}:#{workflow.to_s}", "#{workflow.to_s}")
219
- # rjob = remote.job(task, jobname, {})
220
- # rjob.override_dependencies = override_dependencies
221
- # rjob.run
222
- #end
223
-
224
202
  def self.upload_dependencies(job_list, server, search_path = 'user', produce_dependencies = false)
225
203
  server, path = parse_url(server) if server =~ /^ssh:\/\//
226
204
 
@@ -229,13 +207,22 @@ job.clean
229
207
  all_deps = {}
230
208
  if produce_dependencies
231
209
  job_list.each do |job|
232
- job.dependencies.each do |dep|
210
+ job.all_dependencies.each do |dep|
233
211
  all_deps[dep] ||= []
234
212
  all_deps[dep] << job
235
213
  end
236
214
  end
237
215
  end
238
216
 
217
+ job_list.each do |job|
218
+ job.dependencies.
219
+ select{|dep| dep.overriden? }.
220
+ each do |dep|
221
+ all_deps[dep] ||= []
222
+ all_deps[dep] << job
223
+ end
224
+ end
225
+
239
226
  job_list.each do |job|
240
227
  job.input_dependencies.each do |dep|
241
228
  all_deps[dep] ||= []
@@ -246,13 +233,16 @@ job.clean
246
233
  missing_deps = []
247
234
  all_deps.each do |dep,jobs|
248
235
  next if dep.done?
236
+ next if job_list.include?(dep)
249
237
  Log.medium "Producing #{dep.workflow}:#{dep.short_path} dependency for #{Misc.fingerprint jobs}"
250
- dep.run(true)
238
+ dep.produce
251
239
  missing_deps << dep
252
240
  end if produce_dependencies
241
+
253
242
  Step.wait_for_jobs missing_deps
254
243
 
255
- migrate_dependencies = all_deps.keys.collect{|d| [d] + d.rec_dependencies + d.input_dependencies }.flatten.select{|d| d.done? }.collect{|d| d.path }
244
+ #migrate_dependencies = all_deps.keys.collect{|d| [d] + d.rec_dependencies + d.input_dependencies }.flatten.select{|d| d.done? }.collect{|d| d.path }
245
+ migrate_dependencies = all_deps.keys.collect{|d| [d] + d.input_dependencies }.flatten.select{|d| d.done? }.collect{|d| d.path }
256
246
  Log.low "Migrating #{migrate_dependencies.length} dependencies from #{Misc.fingerprint job_list} to #{ server }"
257
247
  Step.migrate(migrate_dependencies, search_path, :target => server) if migrate_dependencies.any?
258
248
  end
@@ -283,7 +273,13 @@ job.clean
283
273
  upload_dependencies(job, server, search_path, options[:produce_dependencies])
284
274
  rjob = remote_workflow.job(job.task_name.to_s, job.clean_name, inputs)
285
275
 
286
- override_dependencies = job.rec_dependencies.select{|dep| dep.done? }.collect{|dep| [dep.workflow.to_s, dep.task_name.to_s] * "#" << "=" << Rbbt.identify(dep.path)}
276
+ override_dependencies = {}
277
+ job.rec_dependencies.
278
+ select{|dep| dep.done? }.
279
+ collect{|dep|
280
+ override_dependencies[[dep.overriden_workflow.to_s, dep.overriden_task.to_s] * "#"] = dep
281
+ }
282
+
287
283
  rjob.override_dependencies = override_dependencies
288
284
 
289
285
  rjob.run_type = run_type
@@ -311,18 +307,29 @@ job.clean
311
307
 
312
308
  workflow_name = job.workflow.to_s
313
309
  remote_workflow = RemoteWorkflow.new("ssh://#{server}:#{workflow_name}", "#{workflow_name}")
314
- inputs = IndiferentHash.setup(job.recursive_inputs.to_hash).slice(*job.real_inputs.map{|i| i.to_s})
310
+ inputs = IndiferentHash.setup(job.recursive_inputs.to_hash).slice(*job.non_default_inputs.map{|i| i.to_s})
315
311
  Log.medium "Relaying dependency #{job.workflow}:#{job.short_path} to #{server} (#{inputs.keys * ", "})"
316
312
 
317
- rjob = remote_workflow.job(job.task_name.to_s, job.clean_name, inputs)
313
+ rjob = remote_workflow.job(job.task_name.to_s, job.clean_name, job.provided_inputs)
314
+
315
+ override_dependencies = {}
316
+ job.rec_dependencies.
317
+ select{|dep| dep.done? }.
318
+ collect{|dep|
319
+ dep_key = if dep.overriden_workflow
320
+ [dep.overriden_workflow.to_s, dep.overriden_task.to_s] * "#"
321
+ else
322
+ [dep.workflow.to_s, dep.task_name.to_s] * "#"
323
+ end
324
+ override_dependencies[dep_key] ||= dep
325
+ }
318
326
 
319
- override_dependencies = job.rec_dependencies.select{|dep| dep.done? }.collect{|dep| [dep.workflow.to_s, dep.task_name.to_s] * "#" << "=" << Rbbt.identify(dep.path)}
320
327
  rjob.override_dependencies = override_dependencies
321
328
 
322
329
  rjob.run_type = run_type
323
330
  rjob.batch_options = batch_options || {}
324
331
 
325
- rjob.run(true)
332
+ rjob.run(:noload)
326
333
 
327
334
  [rjob, job]
328
335
  end
@@ -349,7 +356,6 @@ job.clean
349
356
 
350
357
  def documentation
351
358
  @documention ||= IndiferentHash.setup(RemoteWorkflow::SSH.get_json(File.join(url, "documentation")))
352
- @documention
353
359
  end
354
360
 
355
361
  def task_info(task)
@@ -382,6 +388,23 @@ job.clean
382
388
  end
383
389
  end
384
390
 
391
+ def tasks
392
+ @tasks ||= begin
393
+ tasks = Hash.new do |hash,task_name|
394
+ raise Workflow::TaskNotFoundException, "Task #{task_name} not found in workflow #{self.to_s}" unless @task_info.include?(task_name)
395
+ info = @task_info[task_name]
396
+ task = Task.setup info do |*args|
397
+ raise "This is a remote task"
398
+ end
399
+ task.name = task_name.to_sym
400
+ hash[task_name] = task
401
+ end
402
+
403
+ @task_info.keys.each{|k| tasks[k] }
404
+ tasks
405
+ end
406
+ end
407
+
385
408
  def task_dependencies
386
409
  @task_dependencies ||= Hash.new do |hash,task|
387
410
  hash[task] = if exported_tasks.include? task
@@ -1,6 +1,8 @@
1
1
  class RemoteStep
2
2
  module REST
3
3
 
4
+ DEFAULT_REFRESH_TIME = 2
5
+
4
6
  def get
5
7
  params ||= {}
6
8
  params = params.merge(:_format => [:string, :boolean, :tsv, :annotations, :array].include?(result_type.to_sym) ? :raw : :json )
@@ -20,7 +22,7 @@ class RemoteStep
20
22
  def load
21
23
  params = {}
22
24
  join unless done? or streaming?
23
- raise get_exception if error? or aborted?
25
+ raise exception if error? or aborted?
24
26
  load_res get
25
27
  end
26
28
 
@@ -1,5 +1,8 @@
1
1
  class RemoteStep
2
2
  module SSH
3
+
4
+ DEFAULT_REFRESH_TIME = 2
5
+
3
6
  attr_accessor :override_dependencies, :run_type, :batch_options, :produce_dependencies
4
7
 
5
8
  def init_job(cache_type = nil, other_params = {})
@@ -12,9 +15,15 @@ class RemoteStep
12
15
  @input_id ||= "inputs-" << rand(100000).to_s
13
16
 
14
17
  if override_dependencies && override_dependencies.any?
15
- override_dependencies.each do |od|
16
- name, _sep, value = od.partition("=")
17
- inputs[name] = value
18
+ if Hash === override_dependencies
19
+ override_dependencies.each do |name,dep|
20
+ inputs[name] = dep
21
+ end
22
+ else
23
+ override_dependencies.each do |od|
24
+ name, _sep, value = od.partition("=")
25
+ inputs[name] = value
26
+ end
18
27
  end
19
28
  end
20
29
 
@@ -84,7 +93,7 @@ class RemoteStep
84
93
  while ! (done? || error? || aborted?)
85
94
  sleep 1
86
95
  end
87
- raise self.get_exception if error?
96
+ raise self.exception if error?
88
97
  self
89
98
  end
90
99
 
@@ -97,7 +106,7 @@ class RemoteStep
97
106
  issue
98
107
  else
99
108
  produce
100
- self.load unless args.first
109
+ self.load unless stream
101
110
  end
102
111
  end
103
112
 
@@ -2,10 +2,10 @@ require 'rbbt/workflow'
2
2
 
3
3
  class RemoteStep < Step
4
4
 
5
- attr_accessor :url, :base_url, :task, :base_name, :inputs, :input_types, :result_type, :result_description, :is_exec, :is_stream, :stream_input, :started
5
+ attr_accessor :url, :base_url, :task, :base_name, :inputs, :input_types, :result_type, :result_description, :is_exec, :is_stream, :stream_input, :started, :refresh_time
6
6
 
7
- def initialize(base_url, task = nil, base_name = nil, inputs = nil, input_types = nil, result_type = nil, result_description = nil, is_exec = false, is_stream = false, stream_input = nil)
8
- @base_url, @task, @base_name, @inputs, @input_types, @result_type, @result_description, @is_exec, @is_stream, @stream_input = base_url, task, base_name, inputs, input_types, result_type, result_description, is_exec, is_stream, stream_input
7
+ def initialize(base_url, task = nil, base_name = nil, inputs = nil, input_types = nil, result_type = nil, result_description = nil, is_exec = false, is_stream = false, stream_input = nil, refresh_time = nil)
8
+ @base_url, @task, @base_name, @inputs, @input_types, @result_type, @result_description, @is_exec, @is_stream, @stream_input, @refresh_time = base_url, task, base_name, inputs, input_types, result_type, result_description, is_exec, is_stream, stream_input, refresh_time
9
9
  @base_url = "http://" << @base_url unless @base_url =~ /^[a-z]+:\/\//
10
10
  @mutex = Mutex.new
11
11
  rest = base_url.include?('ssh:') ? false : true
@@ -13,9 +13,11 @@ class RemoteStep < Step
13
13
  if rest
14
14
  @adaptor = RemoteWorkflow::REST
15
15
  self.extend RemoteStep::REST
16
+ @refresh_time ||= Rbbt::Config.get(:remote_refresh_time, :refresh_time, :ssh_refresh_time, :ssh, :SSH, :default => RemoteStep::REST::DEFAULT_REFRESH_TIME)
16
17
  else
17
18
  @adaptor = RemoteWorkflow::SSH
18
19
  self.extend RemoteStep::SSH
20
+ @refresh_time ||= Rbbt::Config.get(:remote_refresh_time, :refresh_time, :rest_refresh_time, :rest, :REST, :default => RemoteStep::SSH::DEFAULT_REFRESH_TIME)
19
21
  end
20
22
 
21
23
  end
@@ -26,7 +28,7 @@ class RemoteStep < Step
26
28
 
27
29
  def cache_file
28
30
  begin
29
- digest = Misc.obj2digest([base_url, task.to_s, base_name, inputs])
31
+ digest = Misc.digest([base_url, task.to_s, base_name, inputs])
30
32
  Rbbt.var.cache.REST[task.to_s][[clean_name, digest].compact * "."].find
31
33
  rescue
32
34
  Log.exception $!
@@ -134,7 +136,7 @@ class RemoteStep < Step
134
136
  return {:status => :waiting } unless started?
135
137
  @done = @info && @info[:status] && (@info[:status].to_sym == :done || @info[:status].to_sym == :error)
136
138
 
137
- if !@done && (@last_info_time.nil? || (Time.now - @last_info_time) > 0.5)
139
+ if !@done && (@last_info_time.nil? || (Time.now - @last_info_time) > @refresh_time)
138
140
  update = true
139
141
  else
140
142
  update = false
@@ -163,8 +165,8 @@ class RemoteStep < Step
163
165
  begin
164
166
  status = info[:status]
165
167
  @done = true if status and status.to_sym == :done
166
- Log.low "RemoteStep status '#{status}' #{self.url}"
167
- status
168
+ Log.low "RemoteStep status '#{status}' #{self.url}" if @status != status
169
+ @status = status
168
170
  rescue
169
171
  Log.exception $!
170
172
  nil
@@ -258,6 +260,14 @@ class RemoteStep < Step
258
260
  Misc.consume_stream(res, true)
259
261
  end
260
262
 
263
+ case @adaptor
264
+ when RemoteWorkflow::REST
265
+ max_tries = Scout::Config.get :max_tries, :remote_step, :rest, :default => nil
266
+ when RemoteWorkflow::SSH
267
+ max_tries = Scout::Config.get :max_tries, :remote_step, :ssh, :default => 10
268
+ end
269
+
270
+ times = 0
261
271
  if not (self.done? || self.aborted? || self.error?)
262
272
  self.info
263
273
  return self if self.done? || self.aborted? || self.error?
@@ -265,6 +275,8 @@ class RemoteStep < Step
265
275
  sleep 1 unless self.done? || self.aborted? || self.error?
266
276
  while not (self.done? || self.aborted? || self.error?)
267
277
  sleep 3
278
+ raise "Max tries reached while waiting for remote job: #{Log.fingerprint self}" if times > max_tries
279
+ times += 1
268
280
  end
269
281
  end
270
282
 
@@ -1,4 +1,5 @@
1
1
  require 'rbbt/workflow'
2
+ require 'rbbt/tsv'
2
3
  class RemoteWorkflow
3
4
  include Workflow
4
5
 
@@ -23,7 +24,7 @@ class RemoteWorkflow
23
24
  name
24
25
  end
25
26
 
26
- def __job(task, name = nil, inputs = {})
27
+ def remote_job(task, name = nil, inputs = {})
27
28
  task_info = task_info(task)
28
29
  fixed_inputs = {}
29
30
  input_types = IndiferentHash.setup(task_info[:input_types])
@@ -32,6 +33,8 @@ class RemoteWorkflow
32
33
  k = k.to_sym
33
34
  if TSV === v
34
35
  fixed_inputs[k] = v.to_s
36
+ elsif Path === v && Path.step_file?(v)
37
+ fixed_inputs[k] = v.identify
35
38
  else
36
39
  next if input_types[k].nil?
37
40
  case input_types[k].to_sym
@@ -49,6 +52,8 @@ class RemoteWorkflow
49
52
  step
50
53
  end
51
54
 
55
+ alias job remote_job
56
+
52
57
  def load_id(id)
53
58
  task, name = id.split("/")
54
59
  step = RemoteStep.new url, task, nil