rbbt-util 5.19.34 → 5.19.35
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/etc/app.d/requires.rb +5 -1
- data/lib/rbbt/rest/client/step.rb +52 -11
- data/lib/rbbt/tsv/parallel/traverse.rb +2 -0
- data/lib/rbbt/tsv/parser.rb +9 -0
- data/lib/rbbt/tsv/stream.rb +9 -5
- data/lib/rbbt/util/docker.rb +10 -2
- data/lib/rbbt/util/log/progress.rb +1 -1
- data/lib/rbbt/util/misc/pipes.rb +26 -6
- data/lib/rbbt/workflow/accessor.rb +15 -2
- data/share/Rlib/util.R +26 -2
- data/share/rbbt_commands/study/task +8 -2
- data/share/rbbt_commands/workflow/server +4 -4
- data/share/rbbt_commands/workflow/task +22 -4
- data/test/rbbt/tsv/test_stream.rb +0 -1
- data/test/rbbt/util/misc/test_pipes.rb +17 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71c4c5187485430e7ea4977a2a46002f2a5caa81
|
4
|
+
data.tar.gz: 60e13741b32e65b17e63621a0dcdd021b467b2ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70760328e15502ce16d06483def0e5d6c7ee75d20d33e7891666e2a10c8cebb275a5a277be0afd0810fdecfa99f3d27ee48ddf93335b52caa94f629102fac250
|
7
|
+
data.tar.gz: 7310fddb61cc783289304aabd83b77bf47b2666d1f31ba90a7d15c91b701016b3272d2d2a7503b8b3697fd62a56278e420be3caf81efdfcf3f18c6bf629e138f
|
data/etc/app.d/requires.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'excon'
|
1
2
|
class WorkflowRESTClient
|
2
3
|
class RemoteStep < Step
|
3
4
|
|
@@ -89,18 +90,25 @@ class WorkflowRESTClient
|
|
89
90
|
@mutex.synchronize do
|
90
91
|
@result ||= begin
|
91
92
|
if @is_exec
|
92
|
-
|
93
|
+
exec(noload)
|
94
|
+
elsif noload == :stream
|
95
|
+
_run_job(:stream)
|
93
96
|
else
|
94
97
|
init_job
|
95
98
|
self.load
|
96
99
|
end
|
97
100
|
end
|
98
101
|
end
|
102
|
+
return @result if noload == :stream
|
99
103
|
noload ? path + '?_format=raw' : @result
|
100
104
|
end
|
101
105
|
|
102
|
-
def exec(
|
103
|
-
|
106
|
+
def exec(noload = false)
|
107
|
+
if noload == :stream
|
108
|
+
_run_job(:exec)
|
109
|
+
else
|
110
|
+
exec_job
|
111
|
+
end
|
104
112
|
end
|
105
113
|
|
106
114
|
def join
|
@@ -124,18 +132,28 @@ class WorkflowRESTClient
|
|
124
132
|
end
|
125
133
|
|
126
134
|
def load_res(res, result_type = nil)
|
127
|
-
|
135
|
+
stream = true if res.respond_to? :read
|
136
|
+
join unless stream
|
128
137
|
result_type ||= self.result_type
|
129
138
|
case result_type
|
130
139
|
when :string
|
131
|
-
res
|
140
|
+
stream ? res.read : res
|
132
141
|
when :boolean
|
133
|
-
res ==
|
142
|
+
(stream ? res.read : res) == 'true'
|
134
143
|
when :tsv
|
135
|
-
|
144
|
+
if stream
|
145
|
+
TSV.open(res, :monitor => true)
|
146
|
+
else
|
147
|
+
TSV.open(StringIO.new(res))
|
148
|
+
end
|
136
149
|
when :annotations
|
137
|
-
|
150
|
+
if stream
|
151
|
+
Annotated.load_tsv(TSV.open(res))
|
152
|
+
else
|
153
|
+
Annotated.load_tsv(TSV.open(StringIO.new(res)))
|
154
|
+
end
|
138
155
|
when :array
|
156
|
+
(stream ? res.read : res).split("\n")
|
139
157
|
res.split("\n")
|
140
158
|
else
|
141
159
|
JSON.parse res
|
@@ -147,10 +165,33 @@ class WorkflowRESTClient
|
|
147
165
|
load_res get
|
148
166
|
end
|
149
167
|
|
150
|
-
def
|
151
|
-
|
152
|
-
|
168
|
+
def _run_job(cache_type = :async)
|
169
|
+
WorkflowRESTClient.capture_exception do
|
170
|
+
url = URI.encode(File.join(base_url, task.to_s))
|
171
|
+
task_params = inputs.merge(:_cache_type => cache_type, :jobname => base_name, :_format => [:string, :boolean, :tsv, :annotations].include?(result_type) ? :raw : :json)
|
172
|
+
|
173
|
+
sout, sin = Misc.pipe
|
174
|
+
streamer = lambda do |c|
|
175
|
+
sin.write c
|
176
|
+
end
|
177
|
+
|
178
|
+
Thread.new do
|
179
|
+
bl = lambda do |rok|
|
180
|
+
rok.read_body do |c,_a, _b|
|
181
|
+
sin.write c
|
182
|
+
end
|
183
|
+
sin.close
|
184
|
+
end
|
185
|
+
|
186
|
+
RestClient::Request.execute(:method => :post, :url => url, :payload => task_params, :block_response => bl)
|
187
|
+
end
|
188
|
+
|
189
|
+
Zlib::GzipReader.new(sout)
|
153
190
|
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def exec_job
|
194
|
+
res = _run_job(:exec)
|
154
195
|
load_res res, result_type == :array ? :json : result_type
|
155
196
|
end
|
156
197
|
|
data/lib/rbbt/tsv/parser.rb
CHANGED
@@ -554,6 +554,15 @@ module TSV
|
|
554
554
|
|
555
555
|
progress_monitor.bytes = true
|
556
556
|
progress_monitor.max = size unless size.to_i == 0
|
557
|
+
elsif monitor
|
558
|
+
desc = "Parsing Stream"
|
559
|
+
step = 100
|
560
|
+
size = nil
|
561
|
+
if Hash === monitor
|
562
|
+
desc = monitor[:desc] if monitor.include? :desc
|
563
|
+
step = monitor[:step] if monitor.include? :step
|
564
|
+
end
|
565
|
+
progress_monitor = Log::ProgressBar.new_bar(size, :desc => desc, :bytes => true)
|
557
566
|
end
|
558
567
|
|
559
568
|
# parser
|
data/lib/rbbt/tsv/stream.rb
CHANGED
@@ -1,18 +1,21 @@
|
|
1
1
|
require 'rbbt/tsv/dumper'
|
2
2
|
module TSV
|
3
3
|
|
4
|
-
def self.collapse_stream(input, options = {})
|
5
|
-
options = Misc.add_defaults options, :sep => "\t"
|
4
|
+
def self.collapse_stream(input, options = {}, &block)
|
5
|
+
options = Misc.add_defaults options, :sep => "\t", :header_hash => '#', :uniq => true
|
6
6
|
input_stream = TSV.get_stream input
|
7
7
|
|
8
|
-
|
8
|
+
header_hash = options[:header_hash]
|
9
|
+
cmd_args = options[:uniq] ? "-u" : nil
|
10
|
+
|
11
|
+
sorted_input_stream = Misc.sort_stream input_stream, header_hash, cmd_args
|
9
12
|
|
10
13
|
parser = TSV::Parser.new sorted_input_stream, options.dup
|
11
14
|
dumper = TSV::Dumper.new parser
|
12
15
|
header = TSV.header_lines(parser.key_field, parser.fields, parser.options)
|
13
16
|
dumper.close_in
|
14
17
|
dumper.close_out
|
15
|
-
dumper.stream = Misc.collapse_stream parser.stream, parser.first_line, parser.sep, header
|
18
|
+
dumper.stream = Misc.collapse_stream parser.stream, parser.first_line, parser.sep, header, &block
|
16
19
|
dumper
|
17
20
|
end
|
18
21
|
|
@@ -65,7 +68,7 @@ module TSV
|
|
65
68
|
|
66
69
|
if fix_flat and parser.type == :flat and parser.first_line
|
67
70
|
parts = lines[-1].split("\t")
|
68
|
-
lines[-1] = [parts[0], parts[1..-1]*"|"] * "\t"
|
71
|
+
lines[-1] = [parts[0], (parts[1..-1] || [])*"|"] * "\t"
|
69
72
|
TSV.stream_flat2double(parser.stream).stream
|
70
73
|
else
|
71
74
|
parser.stream
|
@@ -220,6 +223,7 @@ module TSV
|
|
220
223
|
parser = TSV::Parser.new TSV.get_stream(stream), :type => :flat
|
221
224
|
dumper_options = parser.options.merge(options).merge(:type => :double)
|
222
225
|
dumper = TSV::Dumper.new dumper_options
|
226
|
+
dumper.init
|
223
227
|
TSV.traverse parser, :into => dumper do |key,values|
|
224
228
|
key = key.first if Array === key
|
225
229
|
values = [values] unless Array === values
|
data/lib/rbbt/util/docker.rb
CHANGED
@@ -20,7 +20,11 @@ module Docker
|
|
20
20
|
when File
|
21
21
|
FileUtils.cp obj.filename, directory[name]
|
22
22
|
when IO
|
23
|
-
|
23
|
+
begin
|
24
|
+
Open.write(directory[name], obj)
|
25
|
+
ensure
|
26
|
+
obj.join if obj.respond_to?(:join) and not obj.joined?
|
27
|
+
end
|
24
28
|
when String
|
25
29
|
if obj.length < 256 and File.exists?(obj)
|
26
30
|
FileUtils.cp obj, directory[name]
|
@@ -39,7 +43,11 @@ module Docker
|
|
39
43
|
when File
|
40
44
|
FileUtils.cp obj.filename, tmpfile[name]
|
41
45
|
when IO
|
42
|
-
|
46
|
+
begin
|
47
|
+
Open.write(tmpfile[name], obj)
|
48
|
+
ensure
|
49
|
+
obj.join if obj.respond_to?(:join) and not obj.joined?
|
50
|
+
end
|
43
51
|
when String
|
44
52
|
if obj.length < 256 and File.exists?(obj)
|
45
53
|
FileUtils.cp obj, tmpfile[name]
|
data/lib/rbbt/util/misc/pipes.rb
CHANGED
@@ -159,7 +159,7 @@ module Misc
|
|
159
159
|
str
|
160
160
|
end
|
161
161
|
|
162
|
-
def self.consume_stream(io, in_thread = false, into = nil)
|
162
|
+
def self.consume_stream(io, in_thread = false, into = nil, into_close = true)
|
163
163
|
return if Path === io
|
164
164
|
return unless io.respond_to? :read
|
165
165
|
if io.respond_to? :closed? and io.closed?
|
@@ -169,10 +169,15 @@ module Misc
|
|
169
169
|
|
170
170
|
if in_thread
|
171
171
|
Thread.new do
|
172
|
-
consume_stream(io, false)
|
172
|
+
consume_stream(io, false, into, into_close)
|
173
173
|
end
|
174
174
|
else
|
175
|
-
|
175
|
+
if into
|
176
|
+
Log.medium "Consuming stream #{Misc.fingerprint io} -> #{Misc.fingerprint into}"
|
177
|
+
else
|
178
|
+
Log.medium "Consuming stream #{Misc.fingerprint io}"
|
179
|
+
end
|
180
|
+
|
176
181
|
begin
|
177
182
|
into = into.find if Path === into
|
178
183
|
into = Open.open(into, :mode => 'w') if String === into
|
@@ -182,6 +187,8 @@ module Misc
|
|
182
187
|
end
|
183
188
|
io.join if io.respond_to? :join
|
184
189
|
io.close unless io.closed?
|
190
|
+
into.close if into and into_close and not into.closed?
|
191
|
+
into.join if into and into_close and into.respond_to?(:joined?) and not into.joined?
|
185
192
|
rescue Aborted
|
186
193
|
Log.medium "Consume stream aborted #{Misc.fingerprint io}"
|
187
194
|
io.abort if io.respond_to? :abort
|
@@ -344,7 +351,7 @@ module Misc
|
|
344
351
|
end
|
345
352
|
end
|
346
353
|
|
347
|
-
def self.collapse_stream(s, line = nil, sep = "\t", header = nil)
|
354
|
+
def self.collapse_stream(s, line = nil, sep = "\t", header = nil, &block)
|
348
355
|
sep ||= "\t"
|
349
356
|
Misc.open_pipe do |sin|
|
350
357
|
sin.puts header if header
|
@@ -371,15 +378,28 @@ module Misc
|
|
371
378
|
(parts.length..current_parts.length-1).to_a.each do |pos|
|
372
379
|
current_parts[pos] = current_parts[pos] << "|" << ""
|
373
380
|
end
|
381
|
+
when current_key.nil?
|
382
|
+
current_key = key
|
383
|
+
current_parts = parts
|
374
384
|
when current_key != key
|
375
|
-
|
385
|
+
if block_given?
|
386
|
+
res = block.call(current_parts)
|
387
|
+
sin.puts [current_key, res] * sep
|
388
|
+
else
|
389
|
+
sin.puts [current_key, current_parts].flatten * sep
|
390
|
+
end
|
376
391
|
current_key = key
|
377
392
|
current_parts = parts
|
378
393
|
end
|
379
394
|
line = s.gets
|
380
395
|
end
|
381
396
|
|
382
|
-
|
397
|
+
if block_given?
|
398
|
+
res = block.call(current_parts)
|
399
|
+
sin.puts [current_key, res] * sep
|
400
|
+
else
|
401
|
+
sin.puts [current_key, current_parts].flatten * sep
|
402
|
+
end unless current_key.nil?
|
383
403
|
end
|
384
404
|
end
|
385
405
|
end
|
@@ -242,7 +242,13 @@ class Step
|
|
242
242
|
Step.log_progress(status, options, file(:progress), &block)
|
243
243
|
end
|
244
244
|
|
245
|
-
def progress_bar(msg = "Progress", options =
|
245
|
+
def progress_bar(msg = "Progress", options = nil)
|
246
|
+
if Hash === msg and options.nil?
|
247
|
+
options = msg
|
248
|
+
msg = nil
|
249
|
+
end
|
250
|
+
options = {} if options.nil?
|
251
|
+
|
246
252
|
max = options[:max]
|
247
253
|
Log::ProgressBar.new_bar(max, {:desc => msg, :file => file(:progress)}.merge(options))
|
248
254
|
end
|
@@ -565,7 +571,14 @@ module Workflow
|
|
565
571
|
#rec_dependency.run(true).grace unless rec_dependency.done? or rec_dependency.running?
|
566
572
|
_inputs[i] = rec_dependency
|
567
573
|
else
|
568
|
-
|
574
|
+
rec_dependency.abort if rec_dependency.streaming? and not rec_dependency.running?
|
575
|
+
rec_dependency.clean if rec_dependency.error? or rec_dependency.aborted?
|
576
|
+
if rec_dependency.streaming? and rec_dependency.running?
|
577
|
+
_inputs[i] = rec_dependency.join.load
|
578
|
+
else
|
579
|
+
rec_dependency.run(true).join
|
580
|
+
_inputs[i] = rec_dependency.load
|
581
|
+
end
|
569
582
|
end
|
570
583
|
end
|
571
584
|
else
|
data/share/Rlib/util.R
CHANGED
@@ -18,8 +18,8 @@ rbbt.ruby <- function(code, load = TRUE, flat = FALSE, type = 'tsv', ...){
|
|
18
18
|
return(data)
|
19
19
|
}
|
20
20
|
|
21
|
-
if(type == 'list'){
|
22
|
-
data = scan(file, ...)
|
21
|
+
if(type == 'list' || type == 'array'){
|
22
|
+
data = scan(file, what='string', sep="\n", ...)
|
23
23
|
return(data);
|
24
24
|
}
|
25
25
|
|
@@ -33,6 +33,30 @@ rbbt.ruby <- function(code, load = TRUE, flat = FALSE, type = 'tsv', ...){
|
|
33
33
|
}
|
34
34
|
}
|
35
35
|
|
36
|
+
rbbt.job <- function(workflow, task, load=TRUE, flat = FALSE, type = 'tsv', jobname="R.Default", code='', ...){
|
37
|
+
|
38
|
+
str = "require 'rbbt/workflow'"
|
39
|
+
|
40
|
+
str = paste(str, code, sep="\n")
|
41
|
+
|
42
|
+
str = paste(str, paste("Workflow.require_workflow '", workflow, "'", sep=""), sep="\n")
|
43
|
+
|
44
|
+
args_list = list(...)
|
45
|
+
args_strs = c()
|
46
|
+
for (input in names(args_list)){
|
47
|
+
value = args_list[[input]]
|
48
|
+
if (!is.numeric(value)){
|
49
|
+
value = paste("'", value, "'", sep="")
|
50
|
+
}
|
51
|
+
args_strs = c(args_strs, paste(":",input,' => ',value, sep=""))
|
52
|
+
}
|
53
|
+
|
54
|
+
args_str = paste(args_strs, sep=",")
|
55
|
+
str = paste(str, paste(workflow, '.job(:', task, ", '", jobname, "', ", args_str,').produce.path', sep=""), sep="\n")
|
56
|
+
cat(str)
|
57
|
+
rbbt.ruby(str, load, flat, type)
|
58
|
+
}
|
59
|
+
|
36
60
|
rbbt.ruby.substitutions <- function(script, substitutions = list(), ...){
|
37
61
|
|
38
62
|
for (keyword in names(substitutions)){
|
@@ -203,7 +203,7 @@ if do_fork
|
|
203
203
|
end
|
204
204
|
raise job.messages.last if job.error?
|
205
205
|
else
|
206
|
-
res = job.run(
|
206
|
+
res = job.run(:stream)
|
207
207
|
end
|
208
208
|
|
209
209
|
if options.delete(:printname)
|
@@ -216,7 +216,13 @@ end
|
|
216
216
|
if Step === res
|
217
217
|
puts Open.read(res.path) if File.exists? res.path
|
218
218
|
else
|
219
|
-
|
219
|
+
if res.respond_to? :gets
|
220
|
+
while line = res.gets
|
221
|
+
puts line
|
222
|
+
end
|
223
|
+
else
|
224
|
+
puts res
|
225
|
+
end
|
220
226
|
end
|
221
227
|
|
222
228
|
exit 0
|
@@ -67,10 +67,6 @@ app.use Rack::Deflater
|
|
67
67
|
|
68
68
|
load Rbbt.etc['app.d/resources.rb'].find
|
69
69
|
|
70
|
-
load Rbbt.etc['app.d/requires.rb'].find
|
71
|
-
|
72
|
-
load Rbbt.etc['app.d/entities.rb'].find
|
73
|
-
|
74
70
|
app.class_eval do
|
75
71
|
eval Rbbt.etc['app.d/finder.rb'].read
|
76
72
|
end
|
@@ -83,6 +79,10 @@ if options[:workflows]
|
|
83
79
|
end
|
84
80
|
end
|
85
81
|
|
82
|
+
load Rbbt.etc['app.d/requires.rb'].find
|
83
|
+
|
84
|
+
load Rbbt.etc['app.d/entities.rb'].find
|
85
|
+
|
86
86
|
|
87
87
|
if options[:views] and not options[:views].empty?
|
88
88
|
Sinatra::RbbtRESTMain.add_resource_path(Path.setup(options[:views]), true)
|
@@ -302,8 +302,12 @@ begin
|
|
302
302
|
end
|
303
303
|
|
304
304
|
if do_exec or (job.respond_to?(:is_exec) and job.is_exec)
|
305
|
-
res = job.exec(
|
305
|
+
res = job.exec(:stream)
|
306
306
|
case
|
307
|
+
when res.respond_to?(:gets)
|
308
|
+
while block = res.read(2048)
|
309
|
+
out.write block
|
310
|
+
end
|
307
311
|
when Array === res
|
308
312
|
out.puts res * "\n"
|
309
313
|
when TSV === res
|
@@ -331,7 +335,7 @@ begin
|
|
331
335
|
|
332
336
|
job.fork
|
333
337
|
else
|
334
|
-
job.run(
|
338
|
+
job.run(:stream)
|
335
339
|
res = job
|
336
340
|
end
|
337
341
|
|
@@ -427,9 +431,23 @@ end
|
|
427
431
|
|
428
432
|
case res
|
429
433
|
when (defined?(WorkflowRESTClient) and WorkflowRESTClient::RemoteStep)
|
430
|
-
|
434
|
+
res = job.result
|
435
|
+
if res.respond_to? :gets
|
436
|
+
while block = res.read(2048) do
|
437
|
+
out.write block
|
438
|
+
end #unless io.closed?
|
439
|
+
res.join if res.respond_to? :join
|
440
|
+
else
|
441
|
+
puts res.to_s
|
442
|
+
end
|
431
443
|
when Step
|
432
|
-
if
|
444
|
+
if step.streaming?
|
445
|
+
io = res.get_stream
|
446
|
+
while block = io.read(2048) do
|
447
|
+
out.write block
|
448
|
+
end #unless io.closed?
|
449
|
+
io.join if io.respond_to? :join
|
450
|
+
elsif IO === res.result
|
433
451
|
begin
|
434
452
|
io = res.get_stream
|
435
453
|
while block = io.read(2048) do
|
@@ -193,7 +193,6 @@ row2 AAA
|
|
193
193
|
s1 = StringIO.new text1
|
194
194
|
s2 = StringIO.new text2
|
195
195
|
tsv = TSV.open TSV.paste_streams([s1,s2], :sep => " ", :type => :double, :sort => false, :same_fields => true)
|
196
|
-
ppp tsv.to_s
|
197
196
|
assert_equal "Row", tsv.key_field
|
198
197
|
assert_equal ["AA", "AAA"], tsv["row2"][0]
|
199
198
|
end
|
@@ -19,6 +19,23 @@ row2 aa bb cc
|
|
19
19
|
assert_equal ["BB", "bb"], tsv["row2"][1]
|
20
20
|
end
|
21
21
|
|
22
|
+
def test_collapse_sum
|
23
|
+
text=<<-EOF
|
24
|
+
row1 12
|
25
|
+
row1 4
|
26
|
+
row2 10
|
27
|
+
row2 6
|
28
|
+
EOF
|
29
|
+
|
30
|
+
s = StringIO.new text
|
31
|
+
stream = Misc.collapse_stream(s,nil, " ") do |parts|
|
32
|
+
next nil if parts.empty?
|
33
|
+
parts.first.split("|").collect{|p| p.to_f}.inject(0){|acc,e| acc += e}.to_s
|
34
|
+
end
|
35
|
+
tsv = TSV.open stream, :sep => " "
|
36
|
+
ppp tsv.to_s
|
37
|
+
end
|
38
|
+
|
22
39
|
def test_collapse_stream_gap
|
23
40
|
text=<<-EOF
|
24
41
|
row2 AA BB
|
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.19.
|
4
|
+
version: 5.19.35
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miguel Vazquez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-04-
|
11
|
+
date: 2016-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|