rbbt-util 5.20.5 → 5.20.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 732f48d509a3d1292ceecf5001206984b5681829
4
- data.tar.gz: 54bad659a94eefc173f4c6d306f4bd78aca37ea9
3
+ metadata.gz: 5413d3d8418a3823e584e819c00d387d4f1cf756
4
+ data.tar.gz: 239e68cae4bb62da2e5db9a50e11e9e5fb916e2a
5
5
  SHA512:
6
- metadata.gz: b8ec9e618e757d8d308e2218c8dab1399bbe2dff8574d48063f07ce3391882b1fa95d78bbf84734b4e29122bda7a1868c650506e2ffe6c02e2e75e89de8254f2
7
- data.tar.gz: 06c02c802611a555db90e5bf6402aaec68c3a49b85aa8de3032b30b6e1cb9cea8936b0ba033a52c55e40784b6c2aabfcb487a14908f628519f86c69019458e02
6
+ metadata.gz: d646cab93661b4328ba21da388a7726064dc6ef1505e1bb8536f4d15ea53a9c9a307eb38454bca061ee3680e7b1b2b2c418e07d83d1c72fb813075cab9944176
7
+ data.tar.gz: f63f8e7912aa7dd295c44cdc344f780198baf553103cc7855beed580fba2cde5a0e0755138b59aac661fb1e1dd2212042bb949dc73d92bed5989922b4093a7c4
@@ -118,4 +118,34 @@ class WorkflowRESTClient
118
118
  end
119
119
  end
120
120
 
121
+ def self.stream_job(task_url, task_params, stream_input, cache_type = :exec)
122
+ require 'rbbt/util/misc/multipart_payload'
123
+ WorkflowRESTClient.capture_exception do
124
+ Log.debug{ "RestClient stream #{Process.pid}: #{ task_url } #{stream_input} #{cache_type} - #{Misc.fingerprint task_params}" }
125
+ res = RbbtMutiplartPayload.issue task_url, task_params, stream_input, nil, nil, true
126
+ type = res.gets
127
+ case type.strip
128
+ when "LOCATION"
129
+ @url = res.gets
130
+ @url.sub!(/\?.*/,'')
131
+ WorkflowRESTClient.get_raw(@url)
132
+ when /STREAM: (.*)/
133
+ @url = $1.strip
134
+ res.callback = Proc.new do
135
+ Log.medium "Done streaming result from #{@url}"
136
+ @done = true
137
+ end
138
+ res
139
+ when "BULK"
140
+ begin
141
+ res.read
142
+ ensure
143
+ @done = true
144
+ end
145
+ else
146
+ raise "What? " + type
147
+ end
148
+ end
149
+ end
150
+
121
151
  end
@@ -3,11 +3,39 @@ class WorkflowRESTClient
3
3
 
4
4
  attr_accessor :url, :base_url, :task, :base_name, :inputs, :result_type, :result_description, :is_exec, :stream_input
5
5
 
6
- def self.get_streams(inputs)
6
+ def initialize(base_url, task = nil, base_name = nil, inputs = nil, result_type = nil, result_description = nil, is_exec = false, stream_input = nil)
7
+ @base_url, @task, @base_name, @inputs, @result_type, @result_description, @is_exec, @stream_input = base_url, task, base_name, inputs, result_type, result_description, is_exec, stream_input
8
+ @mutex = Mutex.new
9
+ end
10
+
11
+ def run(noload = false)
12
+ @mutex.synchronize do
13
+ @result ||= begin
14
+ if @is_exec
15
+ exec(noload)
16
+ elsif noload == :stream
17
+ _run_job(:stream)
18
+ else
19
+ init_job
20
+ self.load
21
+ end
22
+ ensure
23
+ @started = true
24
+ end
25
+ end
26
+
27
+ return @result if noload == :stream
28
+ noload ? path + '?_format=raw' : @result
29
+ end
30
+
31
+
32
+ def self.get_streams(inputs, stream_input = nil)
7
33
  new_inputs = {}
8
34
  inputs.each do |k,v|
35
+ stream = stream_input.to_s == k.to_s
9
36
  if Step === v
10
- new_inputs[k] = TSV.get_stream v
37
+ v.run(true) and v.grace unless v.done? or v.streaming?
38
+ new_inputs[k] = (stream and (v.done? or v.streaming?)) ? TSV.get_stream(v) : v.path
11
39
  else
12
40
  new_inputs[k] = v
13
41
  end
@@ -16,26 +44,14 @@ class WorkflowRESTClient
16
44
  end
17
45
 
18
46
  def get_streams
19
- @inputs = WorkflowRESTClient::RemoteStep.get_streams @inputs
20
- end
21
-
22
-
23
- def initialize(base_url, task = nil, base_name = nil, inputs = nil, result_type = nil, result_description = nil, is_exec = false, stream_input = nil)
24
- @base_url, @task, @base_name, @inputs, @result_type, @result_description, @is_exec = base_url, task, base_name, inputs, result_type, result_description, is_exec
25
- @mutex = Mutex.new
26
- @stream_input = stream_input
27
- #@inputs = RemoteStep.get_streams @inputs
47
+ return if @inputs_done
48
+ @inputs = WorkflowRESTClient::RemoteStep.get_streams @inputs, @stream_input
49
+ @inputs_done = true
50
+ @inputs
28
51
  end
29
52
 
30
- def dup_inputs
31
- return if @dupped or ENV["RBBT_NO_STREAM"] == 'true'
32
- Log.low "Dupping inputs for remote #{path}"
33
- new_inputs = {}
34
- @inputs.each do |name,input|
35
- new_inputs[name] = Step.dup_stream input
36
- end
37
- @inputs = RemoteStep.get_streams new_inputs
38
- @dupped = true
53
+ def abort
54
+ #WorkflowRESTClient.get_json(File.join(@url, '?_update=abort')) if @url
39
55
  end
40
56
 
41
57
  def name
@@ -63,8 +79,12 @@ class WorkflowRESTClient
63
79
 
64
80
  def status
65
81
  return nil unless url or started?
82
+ return :done if @done
83
+ return :streaming if @streaming
66
84
  begin
67
- info[:status]
85
+ status = info[:status]
86
+ @done = true if status and status.to_sym == :done
87
+ status
68
88
  ensure
69
89
  @info = nil
70
90
  end
@@ -103,9 +123,9 @@ class WorkflowRESTClient
103
123
  #{{{ MANAGEMENT
104
124
 
105
125
  def init_job(cache_type = nil, other_params = {})
106
- Log.stack caller
107
126
  cache_type = :asynchronous if cache_type.nil? and not @is_exec
108
127
  cache_type = :exec if cache_type.nil?
128
+ get_streams
109
129
  @name ||= Persist.memory("RemoteSteps", :workflow => self, :task => task, :jobname => @name, :inputs => inputs, :cache_type => cache_type) do
110
130
  WorkflowRESTClient.post_jobname(File.join(base_url, task.to_s), inputs.merge(other_params).merge(:jobname => @name||@base_name, :_cache_type => cache_type))
111
131
  end
@@ -130,26 +150,6 @@ class WorkflowRESTClient
130
150
  end
131
151
  end
132
152
 
133
- def run(noload = false)
134
- @mutex.synchronize do
135
- @result ||= begin
136
- if @is_exec
137
- exec(noload)
138
- elsif noload == :stream
139
- _run_job(:stream)
140
- else
141
- init_job
142
- self.load
143
- end
144
- ensure
145
- @started = true
146
- end
147
- end
148
-
149
- return @result if noload == :stream
150
- noload ? path + '?_format=raw' : @result
151
- end
152
-
153
153
  def exec(noload = false)
154
154
  @result ||= begin
155
155
  if noload == :stream
@@ -163,6 +163,11 @@ class WorkflowRESTClient
163
163
  end
164
164
 
165
165
  def join
166
+ if IO === @result
167
+ res = @result
168
+ @result = nil
169
+ Misc.consume_stream(res, true)
170
+ end
166
171
  sleep 0.2 unless self.done?
167
172
  sleep 1 unless self.done?
168
173
  sleep 3 while not self.done?
@@ -216,43 +221,26 @@ class WorkflowRESTClient
216
221
  load_res get
217
222
  end
218
223
 
219
- def _stream_job(stream_input, cache_type = :exec)
220
- require 'rbbt/util/misc/multipart_payload'
221
- WorkflowRESTClient.capture_exception do
224
+ def _run_job(cache_type = :async)
225
+ get_streams
226
+ if cache_type == :stream or cache_type == :exec and stream_input
222
227
  task_url = URI.encode(File.join(base_url, task.to_s))
223
- Log.debug{ "RestClient stream: #{ task_url } #{stream_input} #{cache_type} - #{Misc.fingerprint inputs}" }
224
228
  task_params = inputs.merge(:_cache_type => cache_type, :jobname => base_name, :_format => [:string, :boolean, :tsv, :annotations].include?(result_type) ? :raw : :json)
225
- res = RbbtMutiplartPayload.issue task_url, task_params, stream_input, nil, nil, true
226
- type = res.gets
227
- case type.strip
228
- when "LOCATION"
229
- @url = res.gets
230
- @url.sub!(/\?.*/,'')
231
- WorkflowRESTClient.get_raw(@url)
232
- when /STREAM: (.*)/
233
- @url = $1.strip
234
- ConcurrentStream.setup(res)
235
- res.callback = Proc.new do
236
- @done = true
237
- end
238
- res
239
- when "BULK"
240
- begin
241
- res.read
242
- ensure
229
+ @streaming = true
230
+ io = WorkflowRESTClient.stream_job(task_url, task_params, stream_input, cache_type)
231
+ if IO === io
232
+ ConcurrentStream.setup(io)
233
+ io.add_callback do
243
234
  @done = true
235
+ @streaming = false
244
236
  end
245
237
  else
246
- raise "What? " + type
238
+ @done = true
239
+ @streaming = false
247
240
  end
241
+ return io
248
242
  end
249
- end
250
243
 
251
- def _run_job(cache_type = :async)
252
- #if cache_type == :stream and stream_input
253
- if cache_type == :stream or cache_type == :exec and stream_input
254
- return _stream_job(stream_input, cache_type)
255
- end
256
244
  WorkflowRESTClient.capture_exception do
257
245
  @url = URI.encode(File.join(base_url, task.to_s))
258
246
  task_params = inputs.merge(:_cache_type => cache_type, :jobname => base_name, :_format => [:string, :boolean, :tsv, :annotations].include?(result_type) ? :raw : :json)
@@ -262,7 +250,7 @@ class WorkflowRESTClient
262
250
  sin.write c
263
251
  end
264
252
 
265
- Thread.new do
253
+ post_thread = Thread.new do
266
254
  bl = lambda do |rok|
267
255
  rok.read_body do |c,_a, _b|
268
256
  sin.write c
@@ -270,17 +258,20 @@ class WorkflowRESTClient
270
258
  sin.close
271
259
  end
272
260
 
261
+ Log.debug{ "RestClient execute: #{ url } - #{Misc.fingerprint task_params}" }
273
262
  RestClient::Request.execute(:method => :post, :url => url, :payload => task_params, :block_response => bl)
274
263
  end
275
264
 
276
265
  reader = Zlib::GzipReader.new(sout)
277
- Misc.open_pipe do |sin|
278
- while c = reader.read(1015)
266
+ res_io = Misc.open_pipe do |sin|
267
+ while c = reader.read(Misc::BLOCK_SIZE)
279
268
  sin.write c
280
269
  end
281
270
  sin.close
282
271
  @done = true
283
272
  end
273
+
274
+ ConcurrentStream.setup(res_io, :threads => [post_thread])
284
275
  end
285
276
  end
286
277
 
@@ -305,6 +296,7 @@ class WorkflowRESTClient
305
296
  end
306
297
 
307
298
  def recursive_clean
299
+ return
308
300
  begin
309
301
  params = {:_update => :recursive_clean}
310
302
  init_job(nil, params)
@@ -317,6 +309,7 @@ class WorkflowRESTClient
317
309
  end
318
310
 
319
311
  def clean
312
+ return
320
313
  begin
321
314
  params = {:_update => :clean}
322
315
  init_job(nil, params)
@@ -54,8 +54,8 @@ module TSV
54
54
 
55
55
  def self.stream_name(obj)
56
56
  return "nil" if obj.nil?
57
- filename_obj = obj.respond_to?(:filename) ? obj.filename : nil
58
- filename_obj ||= obj.respond_to?(:path) ? obj.path : nil
57
+ #filename_obj = obj.respond_to?(:filename) ? obj.filename : nil
58
+ #filename_obj ||= obj.respond_to?(:path) ? obj.path : nil
59
59
  stream_obj = obj_stream(obj) || obj
60
60
  obj.class.to_s << "-" << Misc.fingerprint(stream_obj)
61
61
  end
@@ -223,7 +223,8 @@ module TSV
223
223
  options[:type] = :single
224
224
  end
225
225
 
226
- Log.medium{"Traversing #{stream_name(obj)} #{Log.color :green, "->"} #{stream_name(options[:into])}"}
226
+ name = stream_name(obj)
227
+ Log.medium{"Traversing #{name} #{Log.color :green, "->"} #{stream_name(options[:into])}"}
227
228
  begin
228
229
  case obj
229
230
  when TSV
data/lib/rbbt/util/log.rb CHANGED
@@ -156,9 +156,7 @@ module Log
156
156
 
157
157
  sev_str = severity.to_s
158
158
 
159
- #prefix = time << "[" << color(severity) << sev_str << color(0)<<"]"
160
159
  prefix = time << color(severity) << "[" << sev_str << "]" << color(0)
161
- #prefix = color(severity) << time << color(0) << "[" << sev_str << "]"
162
160
  message = "" << highlight << message << color(0) if severity >= INFO
163
161
  str = prefix << " " << message
164
162
 
@@ -318,6 +318,42 @@ module Misc
318
318
  end
319
319
  end
320
320
 
321
+ def self.bootstrap_in_threads(elems, num = :current, options = {}, &block)
322
+ IndiferentHash.setup options
323
+ num = :current if num.nil?
324
+ threads = case num
325
+ when :current
326
+ 10
327
+ when String
328
+ num.to_i
329
+ when Integer
330
+ if num < 100
331
+ num
332
+ else
333
+ 32000 / num
334
+ end
335
+ else
336
+ raise "Parameter 'num' not understood: #{Misc.fingerprint num}"
337
+ end
338
+
339
+
340
+ options = Misc.add_defaults options, :respawn => true, :threads => threads
341
+ options = Misc.add_defaults options, :bar => "Bootstrap in #{ options[:threads] } threads: #{ Misc.fingerprint Annotated.purge(elems) }"
342
+
343
+ index = (0..elems.length-1).to_a.collect{|v| v.to_s }
344
+ TSV.traverse index, options do |pos|
345
+ elem = elems[pos.to_i]
346
+ elems.annotate elem if elems.respond_to? :annotate
347
+ begin
348
+ res = yield elem
349
+ rescue Interrupt
350
+ Log.warn "Process #{Process.pid} was aborted"
351
+ raise $!
352
+ end
353
+ res = nil unless options[:into]
354
+ res
355
+ end
356
+ end
321
357
  def self.memory_use(pid=nil)
322
358
  `ps -o rss -p #{pid || $$}`.strip.split.last.to_i
323
359
  end
@@ -229,7 +229,7 @@ module Misc
229
229
  when (defined? Step and Step)
230
230
  "<Step #{obj.path}>"
231
231
  else
232
- if obj.respond_to? :filename
232
+ if obj.respond_to? :filename and obj.filename
233
233
  "<IO:" << obj.filename << ">"
234
234
  else
235
235
  obj_ins = obj.inspect
@@ -54,13 +54,12 @@ module RbbtMutiplartPayload
54
54
  io.write c
55
55
  end
56
56
  rescue EOFError
57
+ io.write "\r\n"
57
58
  end
58
- content.close
59
59
  end
60
60
 
61
61
  def self.close_stream(io)
62
62
  io.write "--" + BOUNDARY + "--" + EOL + EOL
63
- io.close
64
63
  end
65
64
 
66
65
  def self.post_data_stream(inputs = nil, stream_input = nil, stream_io = nil, stream_filename = nil)
@@ -88,16 +87,12 @@ module RbbtMutiplartPayload
88
87
 
89
88
  RbbtMutiplartPayload.add_stream(sin, stream_input.to_s, stream_io, stream_filename) if stream_input
90
89
  RbbtMutiplartPayload.close_stream(sin)
91
-
92
- sin.close unless sin.closed?
93
90
  end
94
91
  end
95
92
 
96
93
  def self.issue(url, inputs = nil, stream_input = nil, stream_io = nil, stream_filename = nil, report_type = false)
97
94
 
98
95
  uri = URI(url)
99
- req = Net::HTTP::Post.new(uri.path)
100
-
101
96
  IndiferentHash.setup(inputs)
102
97
 
103
98
  if stream_input
@@ -112,37 +107,47 @@ module RbbtMutiplartPayload
112
107
  end
113
108
  end
114
109
 
115
- sout = RbbtMutiplartPayload.post_data_stream inputs, stream_input, stream_io, stream_filename
110
+ post_data_stream = RbbtMutiplartPayload.post_data_stream inputs, stream_input, stream_io, stream_filename
116
111
 
112
+ jobname = inputs["jobname"]
113
+
114
+ req = Net::HTTP::Post.new(uri.path)
117
115
  if stream_input
118
116
  req.content_type = "multipart/form-data; boundary=" + RbbtMutiplartPayload::BOUNDARY + '; stream=' + stream_input.to_s
119
- req.body_stream = sout
120
- req.add_field "Transfer-Encoding", "chunked"
117
+ req.body_stream = post_data_stream
121
118
  else
122
119
  req.content_type = "multipart/form-data; boundary=" + RbbtMutiplartPayload::BOUNDARY
123
- req.body = sout.read
120
+ req.body = post_data_stream.read
124
121
  end
125
122
 
123
+ req.add_field "Transfer-Encoding", 'chunked'
124
+ req.add_field "RBBT_ID", (jobname || "No name")
126
125
  Misc.open_pipe do |sin|
127
126
  Net::HTTP.start(uri.hostname, uri.port) do |http|
128
127
  http.request(req) do |res|
129
- url_path = res["RBBT-STREAMING-JOB-URL"]
130
- if Net::HTTPRedirection === res
131
- sin.puts "LOCATION" if report_type
132
- sin.write res["location"]
133
- elsif stream_input and url_path
134
- url = URI::HTTP.build(:host => uri.hostname, :post => uri.port, :path => url_path)
135
- sin.puts "STREAM: #{url.to_s}" if report_type
136
- res.read_body do |c|
137
- sin.write c
128
+ if Net::HTTPSuccess === res
129
+ url_path = res["RBBT-STREAMING-JOB-URL"]
130
+ if Net::HTTPRedirection === res
131
+ Log.medium "Response recieved REDIRECT: #{ url_path }"
132
+ sin.puts "LOCATION" if report_type
133
+ sin.write res["location"]
134
+ elsif stream_input and url_path
135
+ Log.medium "Response recieved STREAM: #{ url_path }"
136
+ url = URI::HTTP.build(:host => uri.hostname, :post => uri.port, :path => url_path)
137
+ sin.puts "STREAM: #{url.to_s}" if report_type
138
+ Log.medium "Read body: #{ url_path }"
139
+ res.read_body(sin)
140
+ Log.medium "Read body DONE: #{ url_path }"
141
+ else
142
+ Log.medium "Response recieved BULK: #{ url_path }"
143
+ sin.puts "BULK" if report_type
144
+ sin.write res.body
138
145
  end
139
146
  else
140
- sin.puts "BULK" if report_type
141
- sin.write res.body
147
+ raise "Error: #{res.code}"
142
148
  end
143
149
  end
144
150
  end
145
151
  end
146
152
  end
147
-
148
153
  end
@@ -54,27 +54,32 @@ module Misc
54
54
  sout, sin = Misc.pipe
55
55
 
56
56
  if do_fork
57
+
57
58
  parent_pid = Process.pid
58
59
  pid = Process.fork {
59
60
  purge_pipes(sin)
60
61
  sout.close
61
62
  begin
63
+
62
64
  yield sin
63
65
  sin.close if close and not sin.closed?
64
- rescue
66
+
67
+ rescue Exception
65
68
  Log.exception $!
66
69
  Process.kill :INT, parent_pid
67
70
  Kernel.exit! -1
68
71
  end
69
72
  Kernel.exit! 0
70
73
  }
71
- sin.close
74
+
72
75
  ConcurrentStream.setup sout, :pids => [pid]
73
76
  else
74
77
  thread = Thread.new(Thread.current) do |parent|
75
78
  begin
79
+
76
80
  yield sin
77
81
  sin.close if close and not sin.closed?
82
+
78
83
  rescue Aborted
79
84
  Log.medium "Aborted open_pipe: #{$!.message}"
80
85
  rescue Exception
@@ -83,8 +88,10 @@ module Misc
83
88
  raise $!
84
89
  end
85
90
  end
91
+
86
92
  ConcurrentStream.setup sout, :threads => [thread]
87
93
  end
94
+
88
95
  sout
89
96
  end
90
97
 
@@ -147,6 +154,8 @@ module Misc
147
154
  out_pipes << sout
148
155
  end
149
156
 
157
+ filename = stream.filename if stream.respond_to? :filename
158
+
150
159
  splitter_thread = Thread.new(Thread.current) do |parent|
151
160
  begin
152
161
 
@@ -156,9 +165,9 @@ module Misc
156
165
 
157
166
  in_pipes.each_with_index do |sin,i|
158
167
  begin
159
- sin.write block;
168
+ sin.write block
160
169
  rescue IOError
161
- Log.medium("Tee stream #{i} #{Misc.fingerprint stream} IOError: #{$!.message}");
170
+ Log.error("Tee stream #{i} #{Misc.fingerprint stream} IOError: #{$!.message}");
162
171
  skip[i] = true
163
172
  end unless skip[i]
164
173
  end
@@ -169,6 +178,7 @@ module Misc
169
178
  in_pipes.each do |sin|
170
179
  sin.close unless sin.closed?
171
180
  end
181
+
172
182
  stream.join if stream.respond_to? :join
173
183
  rescue Aborted, Interrupt
174
184
  stream.abort if stream.respond_to? :abort
@@ -188,7 +198,7 @@ module Misc
188
198
  end
189
199
 
190
200
  out_pipes.each do |sout|
191
- ConcurrentStream.setup sout, :threads => splitter_thread
201
+ ConcurrentStream.setup sout, :threads => splitter_thread, :filename => filename
192
202
  end
193
203
 
194
204
  out_pipes
@@ -205,13 +215,15 @@ module Misc
205
215
  stream.clear
206
216
  end
207
217
  tee1, *rest = Misc.tee_stream stream_dup, num + 1
208
- stream.reopen(tee1)
209
218
  rest
210
219
  end
211
220
 
221
+ def Misc.dup_stream (stream)
222
+ dup_stream_multiple(stream, 1).first
223
+ end
224
+
212
225
  class << self
213
226
  alias tee_stream tee_stream_thread_multiple
214
- alias dup_stream dup_stream_multiple
215
227
  end
216
228
 
217
229
  def self.read_full_stream(io)
@@ -254,8 +266,8 @@ module Misc
254
266
  io.sync = true
255
267
 
256
268
  begin
257
- while block = io.readpartial(BLOCK_SIZE)
258
- into << block if into
269
+ while c = io.readpartial(BLOCK_SIZE)
270
+ into << c if into
259
271
  end
260
272
  rescue EOFError
261
273
  end
@@ -79,7 +79,7 @@ class Step
79
79
 
80
80
  job.clean if job.error? or job.aborted? or (job.started? and not job.running? and not job.error?)
81
81
 
82
- job.dup_inputs
82
+ job.dup_inputs unless job.done? or job.started?
83
83
 
84
84
  raise DependencyError, job if job.error?
85
85
  end
@@ -157,64 +157,18 @@ class Step
157
157
  end
158
158
  end
159
159
 
160
- #def consolidate_dependencies(path_deps = {})
161
- # return false if @consolidated or dependencies.nil? or dependencies.empty?
162
- # consolidated_deps = dependencies.collect do |dep|
163
- # dep.consolidate_dependencies(path_deps)
164
- # path = dep.path
165
- # path_deps[path] ||= dep
166
- # end
167
- # dependencies.replace consolidated_deps
168
- # @consolidated = true
169
- #end
170
-
171
- #def prepare_dependencies
172
- # dep_step = {}
173
-
174
- # all_deps = rec_dependencies + [self]
175
-
176
- # seen_paths = Set.new
177
- # all_deps.uniq.each do |step|
178
- # next if seen_paths.include? step.path
179
- # Step.prepare_for_execution(step)
180
- # seen_paths << step.path
181
- # step.dependencies.each do |step_dep|
182
- # dep_step[step_dep.path] ||= []
183
- # dep_step[step_dep.path] << step_dep
184
- # end
185
- # end
186
-
187
- # seen_paths = Set.new
188
- # rec_dependencies.uniq.each do |step|
189
- # next if seen_paths.include? step.path
190
- # = {} seen_paths << step.path
191
- # execute_dependency(step)
192
- # if step.streaming? and step.result
193
- # if dep_step[step.path] and dep_step[step.path].length > 1
194
- # stream = step.result
195
- # other_steps = dep_step[step.path] - [step]
196
- # copies = Misc.dup_stream_multiple(stream, other_steps.length)
197
- # other_steps.zip(copies).each do |other,dupped_stream|
198
- # other.instance_variable_set(:@result, dupped_stream)
199
- # end
200
- # end
201
- # end
202
- # end
203
-
204
- # Step.purge_stream_cache
205
- #end
206
-
207
160
  def execute_and_dup(step, dep_step, log = true)
208
161
  dup = step.result.nil?
209
162
  execute_dependency(step, log)
210
163
  if dup and step.streaming? and not step.result.nil?
211
164
  if dep_step[step.path] and dep_step[step.path].length > 1
212
165
  stream = step.result
213
- other_steps = dep_step[step.path] - [step]
214
- copies = Misc.dup_stream_multiple(stream, other_steps.length)
166
+ other_steps = dep_step[step.path]
167
+ return unless other_steps.length > 1
168
+ copies = Misc.tee_stream_thread_multiple(stream, other_steps.length)
215
169
  log_dependency_exec(step, "duplicating #{copies.length}")
216
170
  other_steps.zip(copies).each do |other,dupped_stream|
217
- other.instance_variable_set(:@result, dupped_stream)
171
+ other.instance_variable_set("@result", dupped_stream)
218
172
  end
219
173
  end
220
174
  end
@@ -233,10 +187,10 @@ class Step
233
187
  end
234
188
  when :bootstrap
235
189
  cpus = rest.nil? ? nil : rest.first
236
- cpus = 30 if cpus.nil?
190
+ cpus = 5 if cpus.nil?
237
191
  cpus = list.length / 2 if cpus > list.length / 2
238
192
 
239
- Misc.bootstrap(list, cpus, :bar => "Bootstrapping dependencies for #{path}", :_respawn => :always) do |dep|
193
+ Misc.bootstrap(list, cpus, :bar => "Bootstrapping dependencies for #{path}", :respawn => :always) do |dep|
240
194
  dep.produce
241
195
  nil
242
196
  end
@@ -280,7 +234,7 @@ class Step
280
234
  dep_step[step_dep.path] << step_dep
281
235
  end
282
236
  end
283
-
237
+
284
238
  self.dup_inputs
285
239
 
286
240
  required_dep_paths = []
@@ -325,18 +279,18 @@ class Step
325
279
  execute_and_dup(step, dep_step, false)
326
280
  end
327
281
 
328
- Log.medium "Computing pre dependencies: #{Misc.fingerprint(compute_pre_deps)} - #{Log.color :blue, self.path}" if pre_deps.any?
282
+ Log.medium "Computing pre dependencies: #{Misc.fingerprint(compute_pre_deps)} - #{Log.color :blue, self.path}" if compute_pre_deps.any?
329
283
  compute_pre_deps.each do |type,list|
330
284
  run_compute_dependencies(type, list, dep_step)
331
285
  end
332
286
 
333
- Log.medium "Processing last dependencies: #{Misc.fingerprint(last_deps)} - #{Log.color :blue, self.path}" if pre_deps.any?
287
+ Log.medium "Processing last dependencies: #{Misc.fingerprint(last_deps)} - #{Log.color :blue, self.path}" if last_deps.any?
334
288
  last_deps.each do |step|
335
289
  next if compute_deps.include? step
336
290
  execute_and_dup(step, dep_step)
337
291
  end
338
292
 
339
- Log.medium "Computing last dependencies: #{Misc.fingerprint(compute_last_deps)} - #{Log.color :blue, self.path}" if pre_deps.any?
293
+ Log.medium "Computing last dependencies: #{Misc.fingerprint(compute_last_deps)} - #{Log.color :blue, self.path}" if compute_last_deps.any?
340
294
  compute_last_deps.each do |type,list|
341
295
  run_compute_dependencies(type, list, dep_step)
342
296
  end
@@ -350,108 +304,4 @@ class Step
350
304
  kill_children
351
305
  end
352
306
 
353
- #def run_dependencies
354
- # @seen ||= []
355
- # seen_paths ||= Set.new
356
- #
357
- # consolidate_dependencies
358
- # dependencies.uniq.each do |dependency|
359
- # dependency_path = dependency.path
360
- # next if seen_paths.include? dependency_path
361
- # @seen.concat dependency.rec_dependencies
362
- # seen_paths.union(dependency.rec_dependencies.collect{|d| d.path})
363
- # @seen << dependency
364
- # seen_paths << dependency_path
365
- # end
366
-
367
- # @seen.uniq!
368
- # @seen.delete self
369
-
370
- # return if @seen.empty?
371
-
372
- # log :dependencies, "#{Log.color :magenta, "Dependencies"} for step #{Log.color :yellow, task.name.to_s || ""}"
373
-
374
- # @seen.each do |dependency|
375
- # Step.prepare_for_execution(dependency)
376
- # end
377
-
378
- # pre_deps = []
379
- # compute_pre_deps = {}
380
- # last_deps = []
381
- # compute_last_deps = {}
382
- # @seen.each do |dependency|
383
- # if dependencies.include?(dependency) and dependency.inputs.flatten.select{|i| Step === i}.any?
384
- # if ComputeDependency === dependency
385
- # compute_last_deps[dependency.compute] ||= []
386
- # compute_last_deps[dependency.compute] << dependency
387
- # else
388
- # last_deps << dependency
389
- # end
390
- # else
391
- # if ComputeDependency === dependency
392
- # compute_pre_deps[dependency.compute] ||= []
393
- # compute_pre_deps[dependency.compute] << dependency
394
- # else
395
- # pre_deps << dependency if dependencies.include?(dependency)
396
- # end
397
- # end
398
- # end
399
-
400
- # pre_deps.each do |dependency|
401
- # dependency.dup_inputs
402
- # execute_dependency(dependency)
403
- # end
404
-
405
- # compute_pre_deps.each do |type,list|
406
- # if Array === type
407
- # type, *rest = type
408
- # end
409
-
410
- # case type
411
- # when :bootstrap
412
- # cpus = rest.nil? ? nil : rest.first
413
- # cpus = 10 if cpus.nil?
414
-
415
- # list.each do |dependency|
416
- # dependency.dup_inputs
417
- # end
418
-
419
- # Misc.bootstrap(list, cpus, :bar => "Bootstrapping dependencies for #{path}", :_respawn => :always) do |dep|
420
- # dep.produce
421
- # nil
422
- # end
423
- # else
424
- # list.each do |dependency|
425
- # dependency.dup_inputs
426
- # execute_dependency(dependency)
427
- # end
428
- # end
429
- # end
430
-
431
- # last_deps.each do |dependency|
432
- # dependency.dup_inputs
433
- # end
434
-
435
- # last_deps.each do |dependency|
436
- # execute_dependency(dependency)
437
- # end
438
-
439
- # compute_last_deps.each do |type,list|
440
- # case type
441
- # when :_bootstrap
442
- # list.each do |dependency|
443
- # dependency.dup_inputs
444
- # end
445
- # Misc.bootstrap(list, 3, :bar => "Boostrapping dependencies for #{path}", :respawn => :always) do |dependency|
446
- # dependency.produce
447
- # nil
448
- # end
449
- # else
450
- # list.each do |dependency|
451
- # dependency.dup_inputs
452
- # execute_dependency(dependency)
453
- # end
454
- # end
455
- # end
456
- #end
457
307
  end
@@ -6,7 +6,7 @@ class Step
6
6
 
7
7
  def get_stream
8
8
  @mutex.synchronize do
9
- Log.low "Getting stream from #{path} #{!@saved_stream} [#{object_id}]"
9
+ Log.low "Getting stream from #{path} #{!@saved_stream} [#{object_id}-#{Misc.fingerprint(@result)}]"
10
10
  begin
11
11
  return nil if @saved_stream
12
12
  if IO === @result
@@ -113,7 +113,6 @@ class Step
113
113
  :clean_name => clean_name,
114
114
  })
115
115
 
116
- dup_inputs
117
116
  begin
118
117
  run_dependencies
119
118
  rescue Exception
@@ -125,8 +125,8 @@ if recursive
125
125
 
126
126
  while deps.any? do
127
127
  dep = deps.shift
128
- inputs = inputs.merge(dep.info[:inputs])
129
- deps.concat dep.info[:dependencies].collect{|v| get_step v.last }
128
+ inputs = inputs.merge(dep.info[:inputs] || {})
129
+ deps.concat (dep.info[:dependencies] || []).collect{|v| get_step v.last }
130
130
  end
131
131
 
132
132
  inputs.each do |input,value|
@@ -40,8 +40,6 @@ def status_msg(status)
40
40
  :yellow
41
41
  when :done
42
42
  :green
43
- else
44
- nil
45
43
  end
46
44
  Log.color(color, status)
47
45
  end
@@ -64,7 +64,7 @@ TmpFile.with_file do |app_dir|
64
64
  ENV["RBBT_VIEWS_DIR"] = options[:views] if options.include?(:views)
65
65
 
66
66
  if options[:stream]
67
- raise "No streaming available for any server other than puma" unless options[:server] == 'puma'
67
+ raise "No streaming available for any server other than puma" unless true or options[:server].include? 'puma'
68
68
  ENV["RBBT_WORKFLOW_TASK_STREAM"] = 'true'
69
69
  end
70
70
 
@@ -81,9 +81,10 @@ TmpFile.with_file do |app_dir|
81
81
 
82
82
  case server
83
83
  when 'unicorn'
84
- `unicorn -c #{ Rbbt.share['unicorn.rb'].find } '#{config_ru_file}' -p #{options[:port] || "2887"}`
84
+ `env RBBT_LOG=#{Log.severity.to_s} unicorn -c #{ Rbbt.share['unicorn.rb'].find } '#{config_ru_file}' -p #{options[:port] || "2887"}`
85
85
  when 'puma_alt'
86
- `puma '#{config_ru_file}' -p #{options[:Port] || "2887"} -w 3 -t 8:32 --preload`
86
+ #`puma '#{config_ru_file}' -p #{options[:Port] || "2887"} -w 3 -t 8:32 --preload`
87
+ `env RBBT_LOG=#{Log.severity.to_s} puma '#{config_ru_file}' -p #{options[:Port] || "2887"} -w 20 -t 10:160 --preload`
87
88
  else
88
89
  options[:config] = config_ru_file
89
90
  Rack::Server.start(options)
@@ -0,0 +1,202 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../../..', 'test_helper.rb')
2
+ require 'rbbt/util/misc/multipart_payload'
3
+
4
+ class TestMultipartPayload < Test::Unit::TestCase
5
+
6
+ URL='http://localhost:2887/Echo'
7
+ def _test_post_data_stream
8
+ content =<<-EOF
9
+ Line 1
10
+ Line 2
11
+ Line 3
12
+ END
13
+ EOF
14
+ mutipart =<<-EOF
15
+ --Rbbt_Param_Stream<>
16
+ Content-Disposition: form-data; name="input1"<>
17
+ Content-Transfer-Encoding: binary<>
18
+ Content-Type: text/plain<>
19
+ <>
20
+ Input1<>
21
+ --Rbbt_Param_Stream<>
22
+ Content-Disposition: form-data; name="input2"<>
23
+ Content-Transfer-Encoding: binary<>
24
+ Content-Type: text/plain<>
25
+ <>
26
+ Input2<>
27
+ --Rbbt_Param_Stream<>
28
+ Content-Disposition: form-data; name="stream_input"<>
29
+ Content-Transfer-Encoding: binary<>
30
+ Content-Type: text/plain<>
31
+ <>
32
+ Line 1
33
+ Line 2
34
+ Line 3
35
+ END
36
+ <>
37
+ --Rbbt_Param_Stream--<>
38
+ <>
39
+ EOF
40
+ TmpFile.with_file(content) do |tmpfile|
41
+ inputs = {}
42
+ stream_input = :stream_input
43
+ inputs[:input1] = "Input1"
44
+ inputs[:input2] = "Input2"
45
+ inputs[:stream_input] = Open.open(tmpfile)
46
+
47
+ post_data_stream = RbbtMutiplartPayload.post_data_stream(inputs, stream_input, inputs[stream_input])
48
+ assert_equal mutipart, post_data_stream.read.gsub(/\r\n/,"<>\n")
49
+ end
50
+ end
51
+
52
+ def _test_issue
53
+ content =<<-EOF
54
+ Line 1
55
+ Line 2
56
+ Line 3
57
+ END
58
+ EOF
59
+ mutipart =<<-EOF
60
+ --Rbbt_Param_Stream<>
61
+ Content-Disposition: form-data; name="input1"<>
62
+ Content-Transfer-Encoding: binary<>
63
+ Content-Type: text/plain<>
64
+ <>
65
+ Input1<>
66
+ --Rbbt_Param_Stream<>
67
+ Content-Disposition: form-data; name="input2"<>
68
+ Content-Transfer-Encoding: binary<>
69
+ Content-Type: text/plain<>
70
+ <>
71
+ Input2<>
72
+ --Rbbt_Param_Stream<>
73
+ Content-Disposition: form-data; name="stream_input"; filename="FILENAME"<>
74
+ Content-Transfer-Encoding: binary<>
75
+ Content-Type: text/plain<>
76
+ <>
77
+ Line 1
78
+ Line 2
79
+ Line 3
80
+ END
81
+ <>
82
+ --Rbbt_Param_Stream--<>
83
+ <>
84
+ DONE_PARAM_STREAM
85
+ EOF
86
+ inputs = {}
87
+ #mutipart.gsub!('<>',"\r")
88
+ stream_input = :stream_input
89
+ inputs[:input1] = "Input1"
90
+ inputs[:input2] = "Input2"
91
+ num = 50
92
+ cpus = 1
93
+ TmpFile.with_file(content) do |tmpfile|
94
+ inputs = inputs.dup
95
+ inputs[:stream_input] = File.open(tmpfile)
96
+
97
+ io = RbbtMutiplartPayload.issue(URL, inputs, stream_input)
98
+ assert_equal mutipart.sub("FILENAME", tmpfile).force_encoding("ASCII"), io.read.gsub(/\r\n/,"<>\n")
99
+ end
100
+ end
101
+
102
+ def _test_issue_multiple
103
+ content =<<-EOF
104
+ Line 1
105
+ Line 2
106
+ Line 3
107
+ END
108
+ EOF
109
+ mutipart =<<-EOF
110
+ --Rbbt_Param_Stream<>
111
+ Content-Disposition: form-data; name="input1"<>
112
+ Content-Transfer-Encoding: binary<>
113
+ Content-Type: text/plain<>
114
+ <>
115
+ Input1<>
116
+ --Rbbt_Param_Stream<>
117
+ Content-Disposition: form-data; name="input2"<>
118
+ Content-Transfer-Encoding: binary<>
119
+ Content-Type: text/plain<>
120
+ <>
121
+ Input2<>
122
+ --Rbbt_Param_Stream<>
123
+ Content-Disposition: form-data; name="stream_input"; filename="FILENAME"<>
124
+ Content-Transfer-Encoding: binary<>
125
+ Content-Type: text/plain<>
126
+ <>
127
+ Line 1
128
+ Line 2
129
+ Line 3
130
+ END
131
+ <>
132
+ --Rbbt_Param_Stream--<>
133
+ <>
134
+ DONE_PARAM_STREAM
135
+ EOF
136
+ inputs = {}
137
+ stream_input = :stream_input
138
+ inputs[:input1] = "Input1"
139
+ inputs[:input2] = "Input2"
140
+ num = 100
141
+ cpus = 10
142
+ Misc.bootstrap((0..num-1).to_a, cpus) do |n|
143
+ TmpFile.with_file(content) do |tmpfile|
144
+ inputs = inputs.dup
145
+ inputs[:stream_input] = File.open(tmpfile)
146
+
147
+ io = RbbtMutiplartPayload.issue(URL, inputs, stream_input)
148
+ str = io.read
149
+ assert_equal mutipart.sub("FILENAME", tmpfile).force_encoding("ASCII"), str.gsub(/\r\n/,"<>\n")
150
+ end
151
+ end
152
+ end
153
+
154
+ def _test_raw
155
+ mutipart =<<-EOF
156
+ --Rbbt_Param_Stream<>
157
+ Content-Disposition: form-data; name="input1"<>
158
+ Content-Transfer-Encoding: binary<>
159
+ Content-Type: text/plain<>
160
+ <>
161
+ Input1<>
162
+ --Rbbt_Param_Stream<>
163
+ Content-Disposition: form-data; name="input2"<>
164
+ Content-Transfer-Encoding: binary<>
165
+ Content-Type: text/plain<>
166
+ <>
167
+ Input2<>
168
+ --Rbbt_Param_Stream<>
169
+ Content-Disposition: form-data; name="stream_input"; filename="FILENAME"<>
170
+ Content-Transfer-Encoding: binary<>
171
+ Content-Type: text/plain<>
172
+ <>
173
+ Line 1
174
+ Line 2
175
+ Line 3
176
+ END
177
+ <>
178
+ --Rbbt_Param_Stream--<>
179
+ <>
180
+ EOF
181
+ mutipart.gsub!('<>',"\r")
182
+ inputs = {}
183
+ stream_input = :stream_input
184
+ inputs[:input1] = "Input1"
185
+ inputs[:input2] = "Input2"
186
+ num = 50
187
+ cpus = 1
188
+ Log.severity = 0
189
+ Misc.bootstrap((0..num-1).to_a, cpus) do |n|
190
+ puts mutipart
191
+ TmpFile.with_file(mutipart, false) do |tmpfile|
192
+ inputs = inputs.dup
193
+ inputs[:stream_input] = File.open(tmpfile)
194
+
195
+ puts "wget '#{URL}' --post-file #{ tmpfile } -O -"
196
+ io = CMD.cmd("wget '#{URL}' --post-file #{ tmpfile } -O -", :pipe => true)
197
+ assert_equal mutipart, io.read
198
+ end
199
+ end
200
+ end
201
+ end
202
+
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.20.5
4
+ version: 5.20.6
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-06-01 00:00:00.000000000 Z
11
+ date: 2016-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -432,6 +432,7 @@ files:
432
432
  - test/rbbt/util/log/test_progress.rb
433
433
  - test/rbbt/util/misc/test_bgzf.rb
434
434
  - test/rbbt/util/misc/test_lock.rb
435
+ - test/rbbt/util/misc/test_multipart_payload.rb
435
436
  - test/rbbt/util/misc/test_pipes.rb
436
437
  - test/rbbt/util/simpleopt/test_get.rb
437
438
  - test/rbbt/util/simpleopt/test_parse.rb
@@ -491,6 +492,7 @@ test_files:
491
492
  - test/rbbt/util/test_log.rb
492
493
  - test/rbbt/util/test_open.rb
493
494
  - test/rbbt/util/misc/test_lock.rb
495
+ - test/rbbt/util/misc/test_multipart_payload.rb
494
496
  - test/rbbt/util/misc/test_bgzf.rb
495
497
  - test/rbbt/util/misc/test_pipes.rb
496
498
  - test/rbbt/util/test_concurrency.rb