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.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/bin/rbbt +67 -90
- data/bin/rbbt_exec.rb +2 -2
- data/etc/app.d/base.rb +2 -2
- data/etc/app.d/semaphores.rb +3 -3
- data/lib/rbbt/annotations/annotated_array.rb +207 -207
- data/lib/rbbt/annotations/refactor.rb +27 -0
- data/lib/rbbt/annotations/util.rb +282 -282
- data/lib/rbbt/annotations.rb +343 -320
- data/lib/rbbt/association/database.rb +200 -225
- data/lib/rbbt/association/index.rb +294 -291
- data/lib/rbbt/association/item.rb +227 -227
- data/lib/rbbt/association/open.rb +35 -34
- data/lib/rbbt/association/util.rb +0 -169
- data/lib/rbbt/association.rb +2 -4
- data/lib/rbbt/entity/identifiers.rb +119 -118
- data/lib/rbbt/entity/refactor.rb +12 -0
- data/lib/rbbt/entity.rb +319 -315
- data/lib/rbbt/hpc/batch.rb +72 -53
- data/lib/rbbt/hpc/lsf.rb +2 -2
- data/lib/rbbt/hpc/orchestrate/batches.rb +2 -2
- data/lib/rbbt/hpc/orchestrate/chains.rb +25 -5
- data/lib/rbbt/hpc/orchestrate/rules.rb +2 -2
- data/lib/rbbt/hpc/orchestrate.rb +19 -13
- data/lib/rbbt/hpc/slurm.rb +18 -18
- data/lib/rbbt/knowledge_base/entity.rb +13 -5
- data/lib/rbbt/knowledge_base/query.rb +2 -2
- data/lib/rbbt/knowledge_base/registry.rb +32 -31
- data/lib/rbbt/knowledge_base/traverse.rb +1 -1
- data/lib/rbbt/knowledge_base.rb +1 -1
- data/lib/rbbt/monitor.rb +36 -25
- data/lib/rbbt/persist/refactor.rb +166 -0
- data/lib/rbbt/persist/tsv/tokyocabinet.rb +105 -105
- data/lib/rbbt/persist/tsv.rb +187 -185
- data/lib/rbbt/persist.rb +556 -551
- data/lib/rbbt/refactor.rb +20 -0
- data/lib/rbbt/resource/path/refactor.rb +178 -0
- data/lib/rbbt/resource/path.rb +317 -497
- data/lib/rbbt/resource/util.rb +0 -48
- data/lib/rbbt/resource.rb +3 -390
- data/lib/rbbt/tsv/accessor.rb +2 -838
- data/lib/rbbt/tsv/attach.rb +303 -299
- data/lib/rbbt/tsv/change_id.rb +244 -245
- data/lib/rbbt/tsv/csv.rb +87 -85
- data/lib/rbbt/tsv/dumper.rb +2 -100
- data/lib/rbbt/tsv/excel.rb +26 -24
- data/lib/rbbt/tsv/field_index.rb +4 -1
- data/lib/rbbt/tsv/filter.rb +3 -2
- data/lib/rbbt/tsv/index.rb +2 -284
- data/lib/rbbt/tsv/manipulate.rb +750 -747
- data/lib/rbbt/tsv/marshal.rb +3 -3
- data/lib/rbbt/tsv/matrix.rb +2 -2
- data/lib/rbbt/tsv/parallel/through.rb +2 -1
- data/lib/rbbt/tsv/parallel/traverse.rb +783 -781
- data/lib/rbbt/tsv/parser.rb +678 -678
- data/lib/rbbt/tsv/refactor.rb +195 -0
- data/lib/rbbt/tsv/stream.rb +253 -251
- data/lib/rbbt/tsv/util.rb +420 -420
- data/lib/rbbt/tsv.rb +210 -208
- data/lib/rbbt/util/R/eval.rb +4 -4
- data/lib/rbbt/util/R/plot.rb +62 -166
- data/lib/rbbt/util/R.rb +21 -18
- data/lib/rbbt/util/cmd.rb +2 -318
- data/lib/rbbt/util/color.rb +269 -269
- data/lib/rbbt/util/colorize.rb +89 -89
- data/lib/rbbt/util/concurrency/processes/refactor.rb +22 -0
- data/lib/rbbt/util/concurrency/processes/worker.rb +2 -2
- data/lib/rbbt/util/concurrency/processes.rb +389 -386
- data/lib/rbbt/util/config.rb +169 -167
- data/lib/rbbt/util/filecache.rb +1 -1
- data/lib/rbbt/util/iruby.rb +20 -0
- data/lib/rbbt/util/log/progress/report.rb +241 -241
- data/lib/rbbt/util/log/progress/util.rb +99 -99
- data/lib/rbbt/util/log/progress.rb +102 -102
- data/lib/rbbt/util/log/refactor.rb +49 -0
- data/lib/rbbt/util/log.rb +486 -532
- data/lib/rbbt/util/migrate.rb +2 -2
- data/lib/rbbt/util/misc/concurrent_stream.rb +248 -246
- data/lib/rbbt/util/misc/development.rb +12 -11
- data/lib/rbbt/util/misc/exceptions.rb +117 -112
- data/lib/rbbt/util/misc/format.rb +2 -230
- data/lib/rbbt/util/misc/indiferent_hash.rb +2 -107
- data/lib/rbbt/util/misc/inspect.rb +2 -476
- data/lib/rbbt/util/misc/lock.rb +109 -106
- data/lib/rbbt/util/misc/omics.rb +9 -1
- data/lib/rbbt/util/misc/pipes.rb +765 -793
- data/lib/rbbt/util/misc/refactor.rb +20 -0
- data/lib/rbbt/util/misc/ssw.rb +27 -17
- data/lib/rbbt/util/misc/system.rb +92 -105
- data/lib/rbbt/util/misc.rb +39 -20
- data/lib/rbbt/util/named_array/refactor.rb +4 -0
- data/lib/rbbt/util/named_array.rb +3 -220
- data/lib/rbbt/util/open/refactor.rb +7 -0
- data/lib/rbbt/util/open.rb +3 -857
- data/lib/rbbt/util/procpath.rb +6 -6
- data/lib/rbbt/util/python/paths.rb +27 -0
- data/lib/rbbt/util/python/run.rb +115 -0
- data/lib/rbbt/util/python/script.rb +110 -0
- data/lib/rbbt/util/python/util.rb +3 -3
- data/lib/rbbt/util/python.rb +22 -81
- data/lib/rbbt/util/semaphore.rb +152 -148
- data/lib/rbbt/util/simpleopt.rb +9 -8
- data/lib/rbbt/util/ssh/refactor.rb +19 -0
- data/lib/rbbt/util/ssh.rb +122 -118
- data/lib/rbbt/util/tar.rb +117 -115
- data/lib/rbbt/util/tmpfile.rb +69 -67
- data/lib/rbbt/util/version.rb +2 -0
- data/lib/rbbt/workflow/refactor/entity.rb +11 -0
- data/lib/rbbt/workflow/refactor/export.rb +66 -0
- data/lib/rbbt/workflow/refactor/inputs.rb +24 -0
- data/lib/rbbt/workflow/refactor/recursive.rb +64 -0
- data/lib/rbbt/workflow/refactor/task_info.rb +66 -0
- data/lib/rbbt/workflow/refactor.rb +150 -0
- data/lib/rbbt/workflow/remote_workflow/driver/rest.rb +1 -2
- data/lib/rbbt/workflow/remote_workflow/driver/ssh.rb +55 -32
- data/lib/rbbt/workflow/remote_workflow/remote_step/rest.rb +3 -1
- data/lib/rbbt/workflow/remote_workflow/remote_step/ssh.rb +14 -5
- data/lib/rbbt/workflow/remote_workflow/remote_step.rb +19 -7
- data/lib/rbbt/workflow/remote_workflow.rb +6 -1
- data/lib/rbbt/workflow/step/run.rb +766 -766
- data/lib/rbbt/workflow/step/save_load_inputs.rb +254 -254
- data/lib/rbbt/workflow/step.rb +2 -362
- data/lib/rbbt/workflow/task.rb +118 -118
- data/lib/rbbt/workflow/usage.rb +289 -287
- data/lib/rbbt/workflow/util/archive.rb +6 -5
- data/lib/rbbt/workflow/util/data.rb +1 -1
- data/lib/rbbt/workflow/util/orchestrator.rb +249 -246
- data/lib/rbbt/workflow/util/trace.rb +79 -44
- data/lib/rbbt/workflow.rb +4 -882
- data/lib/rbbt-util.rb +21 -13
- data/lib/rbbt.rb +16 -3
- data/python/rbbt/__init__.py +96 -4
- data/python/rbbt/workflow/remote.py +104 -0
- data/python/rbbt/workflow.py +64 -0
- data/python/test.py +10 -0
- data/share/Rlib/plot.R +37 -37
- data/share/Rlib/svg.R +22 -5
- data/share/install/software/lib/install_helpers +1 -1
- data/share/rbbt_commands/hpc/list +2 -3
- data/share/rbbt_commands/hpc/orchestrate +4 -4
- data/share/rbbt_commands/hpc/tail +2 -0
- data/share/rbbt_commands/hpc/task +10 -7
- data/share/rbbt_commands/lsf/list +2 -3
- data/share/rbbt_commands/lsf/orchestrate +4 -4
- data/share/rbbt_commands/lsf/tail +2 -0
- data/share/rbbt_commands/lsf/task +10 -7
- data/share/rbbt_commands/migrate +1 -1
- data/share/rbbt_commands/pbs/list +2 -3
- data/share/rbbt_commands/pbs/orchestrate +4 -4
- data/share/rbbt_commands/pbs/tail +2 -0
- data/share/rbbt_commands/pbs/task +10 -7
- data/share/rbbt_commands/resource/produce +8 -1
- data/share/rbbt_commands/slurm/list +2 -3
- data/share/rbbt_commands/slurm/orchestrate +4 -4
- data/share/rbbt_commands/slurm/tail +2 -0
- data/share/rbbt_commands/slurm/task +10 -7
- data/share/rbbt_commands/system/clean +5 -5
- data/share/rbbt_commands/system/status +5 -5
- data/share/rbbt_commands/tsv/get +2 -3
- data/share/rbbt_commands/tsv/info +10 -13
- data/share/rbbt_commands/tsv/keys +18 -14
- data/share/rbbt_commands/tsv/slice +2 -2
- data/share/rbbt_commands/tsv/transpose +6 -2
- data/share/rbbt_commands/workflow/info +20 -24
- data/share/rbbt_commands/workflow/list +1 -1
- data/share/rbbt_commands/workflow/prov +20 -13
- data/share/rbbt_commands/workflow/retry +43 -0
- data/share/rbbt_commands/workflow/server +12 -2
- data/share/rbbt_commands/workflow/task +80 -73
- data/share/rbbt_commands/workflow/write_info +26 -9
- data/share/software/opt/ssw/ssw.c +861 -0
- data/share/software/opt/ssw/ssw.h +130 -0
- data/share/workflow_config.ru +3 -3
- 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 =
|
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.
|
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.
|
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 =
|
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.
|
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,
|
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(
|
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
|
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
|
-
|
16
|
-
name,
|
17
|
-
|
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.
|
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
|
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.
|
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) >
|
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
|
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
|