rbbt-util 5.19.34 → 5.19.35
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/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
|