rbbt-util 5.26.157 → 5.26.158
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/lib/rbbt/util/misc/development.rb +7 -0
- data/lib/rbbt/workflow/remote_workflow/driver/rest.rb +230 -0
- data/lib/rbbt/workflow/remote_workflow/driver/ssh.rb +237 -0
- data/lib/rbbt/workflow/remote_workflow/driver.rb +75 -0
- data/lib/rbbt/workflow/remote_workflow/remote_step/rest.rb +148 -0
- data/lib/rbbt/workflow/remote_workflow/remote_step/ssh.rb +73 -0
- data/lib/rbbt/workflow/remote_workflow/remote_step.rb +329 -0
- data/lib/rbbt/workflow/{remote/client.rb → remote_workflow.rb} +9 -16
- data/lib/rbbt/workflow/util/archive.rb +2 -3
- data/lib/rbbt/workflow.rb +4 -4
- data/share/rbbt_commands/workflow/remote/add +28 -2
- data/share/rbbt_commands/workflow/task +4 -3
- data/test/rbbt/workflow/test_remote_workflow.rb +86 -0
- data/test/test_helper.rb +26 -23
- metadata +11 -14
- data/lib/rbbt/rest/client/adaptor.rb +0 -67
- data/lib/rbbt/rest/client/get.rb +0 -166
- data/lib/rbbt/rest/client/run.rb +0 -133
- data/lib/rbbt/rest/client/step.rb +0 -397
- data/lib/rbbt/rest/client.rb +0 -58
- data/lib/rbbt/workflow/remote/remote_step.rb +0 -324
- data/lib/rbbt/workflow/remote/rest/adaptor.rb +0 -161
- data/lib/rbbt/workflow/remote/rest/get.rb +0 -310
- data/lib/rbbt/workflow/remote/ssh/adaptor.rb +0 -61
- data/lib/rbbt/workflow/remote/ssh/driver.rb +0 -147
- data/lib/rbbt/workflow/remote/ssh/get.rb +0 -193
@@ -1,397 +0,0 @@
|
|
1
|
-
class WorkflowRESTClient
|
2
|
-
|
3
|
-
def self.__prepare_inputs_for_restclient(inputs)
|
4
|
-
inputs.each do |k,v|
|
5
|
-
if v.respond_to? :path and not v.respond_to? :original_filename
|
6
|
-
class << v
|
7
|
-
def original_filename
|
8
|
-
File.expand_path(path)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
if Array === v and v.empty?
|
14
|
-
inputs[k] = "EMPTY_ARRAY"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
class RemoteStep < Step
|
20
|
-
|
21
|
-
attr_accessor :url, :base_url, :task, :base_name, :inputs, :result_type, :result_description, :is_exec, :is_stream, :stream_input
|
22
|
-
|
23
|
-
def initialize(base_url, task = nil, base_name = nil, inputs = nil, result_type = nil, result_description = nil, is_exec = false, is_stream = false, stream_input = nil)
|
24
|
-
@base_url, @task, @base_name, @inputs, @result_type, @result_description, @is_exec, @is_stream, @stream_input = base_url, task, base_name, inputs, result_type, result_description, is_exec, is_stream, stream_input
|
25
|
-
@base_url = "http://" << @base_url unless @base_url =~ /^https?:\/\//
|
26
|
-
@mutex = Mutex.new
|
27
|
-
end
|
28
|
-
|
29
|
-
def clean_name
|
30
|
-
@base_name
|
31
|
-
end
|
32
|
-
|
33
|
-
def run(no_load = false)
|
34
|
-
no_load = @is_stream ? :stream : true if no_load
|
35
|
-
|
36
|
-
@mutex.synchronize do
|
37
|
-
@result ||= begin
|
38
|
-
if @is_exec
|
39
|
-
exec(no_load)
|
40
|
-
elsif no_load == :stream
|
41
|
-
_run_job(:stream)
|
42
|
-
elsif no_load
|
43
|
-
init_job
|
44
|
-
nil
|
45
|
-
else
|
46
|
-
init_job
|
47
|
-
join
|
48
|
-
self.load
|
49
|
-
end
|
50
|
-
ensure
|
51
|
-
@started = true
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
return @result if no_load == :stream
|
56
|
-
no_load ? Misc.add_GET_param(path, "_format", "raw") : @result
|
57
|
-
end
|
58
|
-
|
59
|
-
|
60
|
-
def self.get_streams(inputs, stream_input = nil)
|
61
|
-
new_inputs = {}
|
62
|
-
inputs.each do |k,v|
|
63
|
-
stream = stream_input.to_s == k.to_s
|
64
|
-
if Step === v
|
65
|
-
unless (v.done? or v.streaming?) # or RestClient::Step === v)
|
66
|
-
v.run(true) and v.grace
|
67
|
-
end
|
68
|
-
|
69
|
-
begin
|
70
|
-
if stream
|
71
|
-
new_inputs[k] = TSV.get_stream(v)
|
72
|
-
else
|
73
|
-
new_inputs[k] = v.load
|
74
|
-
end
|
75
|
-
rescue Exception
|
76
|
-
raise $!
|
77
|
-
end
|
78
|
-
else
|
79
|
-
new_inputs[k] = v
|
80
|
-
end
|
81
|
-
end
|
82
|
-
new_inputs
|
83
|
-
end
|
84
|
-
|
85
|
-
def get_streams
|
86
|
-
return if @inputs_done
|
87
|
-
@inputs = WorkflowRESTClient::RemoteStep.get_streams @inputs, @stream_input
|
88
|
-
@inputs_done = true
|
89
|
-
@inputs
|
90
|
-
end
|
91
|
-
|
92
|
-
def abort
|
93
|
-
return self if status == :done
|
94
|
-
WorkflowRESTClient.get_json(@url + '?_update=abort') if @url and @name
|
95
|
-
self
|
96
|
-
end
|
97
|
-
|
98
|
-
def dup_inputs
|
99
|
-
return if @dupped or ENV["RBBT_NO_STREAM"] == 'true'
|
100
|
-
Log.low "Dupping inputs for #{path}"
|
101
|
-
dupped_inputs = {}
|
102
|
-
@inputs.collect do |k,input|
|
103
|
-
dupped_inputs[k] = Step.dup_stream input
|
104
|
-
end
|
105
|
-
@inputs = dupped_inputs
|
106
|
-
@dupped = true
|
107
|
-
end
|
108
|
-
|
109
|
-
def name
|
110
|
-
return nil if @is_exec
|
111
|
-
return @path if @url.nil?
|
112
|
-
(Array === @url ? @url.first : @url).split("/").last
|
113
|
-
end
|
114
|
-
|
115
|
-
def name=(name)
|
116
|
-
@url = [base_url,task, name] * "/"
|
117
|
-
end
|
118
|
-
|
119
|
-
def task_name
|
120
|
-
return task if task
|
121
|
-
init_job
|
122
|
-
(Array === @url ? @url.first : @url).split("/")[-2]
|
123
|
-
end
|
124
|
-
|
125
|
-
def nopid?
|
126
|
-
false
|
127
|
-
end
|
128
|
-
|
129
|
-
def info(check_lock=false)
|
130
|
-
@done = @info && @info[:status] && @info[:status].to_sym == :done
|
131
|
-
|
132
|
-
if !@done && (@last_info_time.nil? || (Time.now - @last_info_time) > 0.5)
|
133
|
-
update = true
|
134
|
-
else
|
135
|
-
update = false
|
136
|
-
end
|
137
|
-
|
138
|
-
@info = Persist.memory("RemoteSteps Info", :url => @url, :persist => true, :update => update) do
|
139
|
-
@last_info_time = Time.now
|
140
|
-
init_job unless @url
|
141
|
-
info = WorkflowRESTClient.get_json(File.join(@url, 'info'))
|
142
|
-
info = WorkflowRESTClient.fix_hash(info)
|
143
|
-
info[:status] = info[:status].to_sym if String === info[:status]
|
144
|
-
info
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
def status
|
149
|
-
return :done if @done
|
150
|
-
return nil unless url or started?
|
151
|
-
#return :streaming if @streaming
|
152
|
-
begin
|
153
|
-
status = info[:status]
|
154
|
-
@done = true if status and status.to_sym == :done
|
155
|
-
status
|
156
|
-
rescue
|
157
|
-
nil
|
158
|
-
ensure
|
159
|
-
@info = nil
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
def started?
|
164
|
-
@result != nil || @started || @streaming
|
165
|
-
end
|
166
|
-
|
167
|
-
def done?
|
168
|
-
init_job unless @url
|
169
|
-
@done || status.to_s == 'done' || status.to_s == 'noinfo'
|
170
|
-
end
|
171
|
-
|
172
|
-
def files
|
173
|
-
WorkflowRESTClient.get_json(File.join(url, 'files'))
|
174
|
-
end
|
175
|
-
|
176
|
-
def file(file)
|
177
|
-
WorkflowRESTClient.get_raw(File.join(url, 'file', file))
|
178
|
-
end
|
179
|
-
|
180
|
-
def get_stream
|
181
|
-
case @result
|
182
|
-
when IO
|
183
|
-
@result
|
184
|
-
when String
|
185
|
-
StringIO.new @result
|
186
|
-
else
|
187
|
-
nil
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
def grace
|
192
|
-
produce unless @started
|
193
|
-
sleep 0.1 unless started?
|
194
|
-
sleep 0.5 unless started?
|
195
|
-
sleep 1 unless started?
|
196
|
-
while not (done? or started?)
|
197
|
-
sleep 1
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
#{{{ MANAGEMENT
|
202
|
-
|
203
|
-
def init_job(cache_type = nil, other_params = {})
|
204
|
-
cache_type = :asynchronous if cache_type.nil? and not @is_exec
|
205
|
-
cache_type = :exec if cache_type.nil?
|
206
|
-
@last_info_time = nil
|
207
|
-
@done = false
|
208
|
-
get_streams
|
209
|
-
@name ||= Persist.memory("RemoteSteps", :workflow => self, :task => task, :jobname => @name, :inputs => inputs, :cache_type => cache_type) do
|
210
|
-
Misc.insist do
|
211
|
-
WorkflowRESTClient.post_jobname(File.join(base_url, task.to_s), inputs.merge(other_params).merge(:jobname => @name||@base_name, :_cache_type => cache_type))
|
212
|
-
end
|
213
|
-
end
|
214
|
-
if Open.remote? @name
|
215
|
-
@url = @name
|
216
|
-
@name = File.basename(@name)
|
217
|
-
else
|
218
|
-
@url = File.join(base_url, task.to_s, @name)
|
219
|
-
end
|
220
|
-
self
|
221
|
-
end
|
222
|
-
|
223
|
-
|
224
|
-
def fork(noload=false, semaphore=nil)
|
225
|
-
init_job(:asynchronous)
|
226
|
-
end
|
227
|
-
|
228
|
-
def running?
|
229
|
-
! %w(done error aborted noinfo).include? status.to_s
|
230
|
-
end
|
231
|
-
|
232
|
-
def path
|
233
|
-
if @url
|
234
|
-
Misc.add_GET_param(@url, "_format", "raw")
|
235
|
-
else
|
236
|
-
[base_url, task, @base_name + '-' + Misc.fingerprint(inputs)] * "/"
|
237
|
-
end
|
238
|
-
end
|
239
|
-
|
240
|
-
def exec(noload = false)
|
241
|
-
@result ||= begin
|
242
|
-
if noload == :stream
|
243
|
-
_run_job(:exec)
|
244
|
-
else
|
245
|
-
exec_job
|
246
|
-
end
|
247
|
-
ensure
|
248
|
-
@started = true
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
def join
|
253
|
-
init_job unless @url
|
254
|
-
Log.debug{ "Joining RestClient: #{path}" }
|
255
|
-
if IO === @result
|
256
|
-
res = @result
|
257
|
-
@result = nil
|
258
|
-
Misc.consume_stream(res, true)
|
259
|
-
end
|
260
|
-
|
261
|
-
if not (self.done? || self.aborted? || self.error?)
|
262
|
-
self.info
|
263
|
-
return self if self.done? || self.aborted? || self.error?
|
264
|
-
sleep 0.2 unless self.done? || self.aborted? || self.error?
|
265
|
-
sleep 1 unless self.done? || self.aborted? || self.error?
|
266
|
-
while not (self.done? || self.aborted? || self.error?)
|
267
|
-
sleep 3
|
268
|
-
end
|
269
|
-
end
|
270
|
-
|
271
|
-
self
|
272
|
-
end
|
273
|
-
|
274
|
-
def get
|
275
|
-
params ||= {}
|
276
|
-
params = params.merge(:_format => [:string, :boolean, :tsv, :annotations,:array].include?(result_type.to_sym) ? :raw : :json )
|
277
|
-
Misc.insist 3, rand(2) + 1 do
|
278
|
-
begin
|
279
|
-
init_job if url.nil?
|
280
|
-
WorkflowRESTClient.get_raw(url, params)
|
281
|
-
rescue
|
282
|
-
Log.exception $!
|
283
|
-
raise $!
|
284
|
-
end
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
def load_res(res, result_type = nil)
|
289
|
-
stream = true if res.respond_to? :read
|
290
|
-
join unless stream
|
291
|
-
result_type ||= self.result_type
|
292
|
-
case result_type
|
293
|
-
when :string
|
294
|
-
stream ? res.read : res
|
295
|
-
when :boolean
|
296
|
-
(stream ? res.read : res) == 'true'
|
297
|
-
when :tsv
|
298
|
-
if stream
|
299
|
-
TSV.open(res, :monitor => true)
|
300
|
-
else
|
301
|
-
TSV.open(StringIO.new(res))
|
302
|
-
end
|
303
|
-
when :annotations
|
304
|
-
if stream
|
305
|
-
Annotated.load_tsv(TSV.open(res))
|
306
|
-
else
|
307
|
-
Annotated.load_tsv(TSV.open(StringIO.new(res)))
|
308
|
-
end
|
309
|
-
when :array
|
310
|
-
(stream ? res.read : res).split("\n")
|
311
|
-
res.split("\n")
|
312
|
-
else
|
313
|
-
json_text = if IO === res
|
314
|
-
res.read
|
315
|
-
else
|
316
|
-
res
|
317
|
-
end
|
318
|
-
begin
|
319
|
-
JSON.parse json_text
|
320
|
-
rescue
|
321
|
-
case
|
322
|
-
when json_text =~ /^\d+$/
|
323
|
-
json_text.to_i
|
324
|
-
when json_text =~ /^\d+\.\d/
|
325
|
-
json_text.to_f
|
326
|
-
else
|
327
|
-
raise $!
|
328
|
-
end
|
329
|
-
end
|
330
|
-
end
|
331
|
-
end
|
332
|
-
|
333
|
-
def load
|
334
|
-
params = {}
|
335
|
-
join unless done? or streaming?
|
336
|
-
raise get_exception if error? or aborted?
|
337
|
-
load_res get
|
338
|
-
end
|
339
|
-
|
340
|
-
def exec_job
|
341
|
-
res = _run_job(:exec)
|
342
|
-
load_res res, result_type == :array ? :json : result_type
|
343
|
-
end
|
344
|
-
|
345
|
-
def _restart
|
346
|
-
@done = nil
|
347
|
-
@name = nil
|
348
|
-
@started = nil
|
349
|
-
@aborted = nil
|
350
|
-
new_inputs = {}
|
351
|
-
inputs.each do |k,i|
|
352
|
-
if File === i
|
353
|
-
new_inputs[k] = File.open(i.path)
|
354
|
-
else
|
355
|
-
new_inputs[k] = i
|
356
|
-
end
|
357
|
-
end
|
358
|
-
@inputs = new_inputs
|
359
|
-
@info = nil
|
360
|
-
end
|
361
|
-
|
362
|
-
def recursive_clean
|
363
|
-
Log.warn "Not doing recursive cleans"
|
364
|
-
return
|
365
|
-
begin
|
366
|
-
_restart
|
367
|
-
params = {:_update => :recursive_clean}
|
368
|
-
WorkflowRESTClient.get_raw(url, params)
|
369
|
-
rescue Exception
|
370
|
-
Log.exception $!
|
371
|
-
end
|
372
|
-
self
|
373
|
-
end
|
374
|
-
|
375
|
-
def _clean
|
376
|
-
begin
|
377
|
-
_restart
|
378
|
-
params = {:_update => :clean}
|
379
|
-
WorkflowRESTClient.clean_url(url, params) if @url
|
380
|
-
rescue Exception
|
381
|
-
Log.exception $!
|
382
|
-
end
|
383
|
-
end
|
384
|
-
|
385
|
-
def clean
|
386
|
-
init_job
|
387
|
-
_clean
|
388
|
-
self
|
389
|
-
end
|
390
|
-
|
391
|
-
def input_checks
|
392
|
-
[]
|
393
|
-
end
|
394
|
-
end
|
395
|
-
end
|
396
|
-
|
397
|
-
require 'rbbt/rest/client/run'
|
data/lib/rbbt/rest/client.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'rest_client'
|
2
|
-
require 'json'
|
3
|
-
require 'rbbt/workflow'
|
4
|
-
require 'rbbt/workflow/step'
|
5
|
-
require 'rbbt/util/misc'
|
6
|
-
|
7
|
-
require 'rbbt/rest/client/get'
|
8
|
-
require 'rbbt/rest/client/adaptor'
|
9
|
-
require 'rbbt/rest/client/step'
|
10
|
-
|
11
|
-
class WorkflowRESTClient
|
12
|
-
include Workflow
|
13
|
-
|
14
|
-
attr_accessor :url, :name, :exec_exports, :synchronous_exports, :asynchronous_exports, :stream_exports
|
15
|
-
|
16
|
-
def initialize(url, name)
|
17
|
-
Log.debug{ "Loading remote workflow #{ name }: #{ url }" }
|
18
|
-
@url, @name = url, name
|
19
|
-
init_remote_tasks
|
20
|
-
end
|
21
|
-
|
22
|
-
def to_s
|
23
|
-
name
|
24
|
-
end
|
25
|
-
|
26
|
-
def job(task, name, inputs)
|
27
|
-
task_info = task_info(task)
|
28
|
-
fixed_inputs = {}
|
29
|
-
input_types = task_info[:input_types]
|
30
|
-
|
31
|
-
inputs.each do |k,v|
|
32
|
-
k = k.to_sym
|
33
|
-
if TSV === v
|
34
|
-
fixed_inputs[k] = v.to_s
|
35
|
-
else
|
36
|
-
next if input_types[k].nil?
|
37
|
-
case input_types[k].to_sym
|
38
|
-
when :tsv, :array, :file, :text
|
39
|
-
fixed_inputs[k] = (String === v and Open.exists?(v)) ? Open.open(v) : v
|
40
|
-
else
|
41
|
-
fixed_inputs[k] = v
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
stream_input = @can_stream ? task_info(task)[:input_options].select{|k,o| o[:stream] }.collect{|k,o| k }.first : nil
|
47
|
-
RemoteStep.new(url, task, name, fixed_inputs, task_info[:result_type], task_info[:result_description], @exec_exports.include?(task), @stream_exports.include?(task), stream_input)
|
48
|
-
end
|
49
|
-
|
50
|
-
def load_id(id)
|
51
|
-
task, name = id.split("/")
|
52
|
-
step = RemoteStep.new url, task, nil
|
53
|
-
step.name = name
|
54
|
-
step.result_type = task_info(task)[:result_type]
|
55
|
-
step.result_description = task_info(task)[:result_description]
|
56
|
-
step
|
57
|
-
end
|
58
|
-
end
|