rbbt-util 5.19.37 → 5.20.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 137e4838f414d232714269ef64c04ba299fa3f62
4
- data.tar.gz: 7cc30b69428f3f33461d639c6657d101fb09547f
3
+ metadata.gz: 333a3110a30ab60b25c3e7a5acb5364c2b75cf87
4
+ data.tar.gz: 73610983c2f10ee9ec6cfcc3693e6569174a433d
5
5
  SHA512:
6
- metadata.gz: 6f901c235ed7ef31b1693b1d99282ad86f7f8f37c1b18e9e62a4c67adafa29e10d5fc3b53e12adba5803ce4571958401bd78a65723e1a9e17736e52a7acf755a
7
- data.tar.gz: 2aa36eb9d0a80795a230187894e1f05dd51b1125cf890cda3f740e8e66d1c0320f3f2637ac7d10e38b16698935cb313b3a5498283e7ccf26e1848df3c8620523
6
+ metadata.gz: 433fe181900362ba716a2fdaf9924a08458f2d75d15e41d0b86a9fcab8315c7dfbfa23998f114bfe08cdce03f057fd9af94a3721afdd9f732fd640f2f1789311
7
+ data.tar.gz: f3ff2dc3ff968917dce9851548c8cafd5c2a7e26666f25fc7be70da1de45a92c5e65c8ea95ac353eb841663f88c76fdf2b6500b5d7e9abab68975876c7bf0226
@@ -6,9 +6,8 @@ class WorkflowRESTClient
6
6
  def self.get_streams(inputs)
7
7
  new_inputs = {}
8
8
  inputs.each do |k,v|
9
- if Step === v or RemoteStep === v
10
- v.run
11
- new_inputs[k] = v.load
9
+ if Step === v
10
+ new_inputs[k] = TSV.get_stream v
12
11
  else
13
12
  new_inputs[k] = v
14
13
  end
@@ -16,12 +15,27 @@ class WorkflowRESTClient
16
15
  new_inputs
17
16
  end
18
17
 
18
+ def get_streams
19
+ @inputs = WorkflowRESTClient::RemoteStep.get_streams @inputs
20
+ end
21
+
19
22
 
20
23
  def initialize(base_url, task = nil, base_name = nil, inputs = nil, result_type = nil, result_description = nil, is_exec = false, stream_input = nil)
21
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
22
25
  @mutex = Mutex.new
23
26
  @stream_input = stream_input
24
- @inputs = RemoteStep.get_streams @inputs
27
+ #@inputs = RemoteStep.get_streams @inputs
28
+ end
29
+
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
25
39
  end
26
40
 
27
41
  def name
@@ -31,7 +45,7 @@ class WorkflowRESTClient
31
45
  end
32
46
 
33
47
  def task_name
34
- return task unless @url
48
+ return task if task
35
49
  init_job
36
50
  (Array === @url ? @url.first : @url).split("/")[-2]
37
51
  end
@@ -39,16 +53,16 @@ class WorkflowRESTClient
39
53
  def info(check_lock=false)
40
54
  @done = @info and @info[:status] and @info[:status].to_sym == :done
41
55
  @info = Persist.memory("RemoteSteps Info", :url => @url, :persist => !!@done) do
42
- init_job unless url
43
- info = WorkflowRESTClient.get_json(File.join(url, 'info'))
56
+ init_job unless @url
57
+ info = WorkflowRESTClient.get_json(File.join(@url, 'info'))
44
58
  info = WorkflowRESTClient.fix_hash(info)
45
59
  info[:status] = info[:status].to_sym if String === info[:status]
46
60
  info
47
61
  end
48
62
  end
49
-
63
+
50
64
  def status
51
- return nil if @url.nil?
65
+ return nil unless url or started?
52
66
  begin
53
67
  info[:status]
54
68
  ensure
@@ -56,6 +70,10 @@ class WorkflowRESTClient
56
70
  end
57
71
  end
58
72
 
73
+ def started?
74
+ @result != nil or @started
75
+ end
76
+
59
77
  def done?
60
78
  @done || status.to_s == 'done'
61
79
  end
@@ -68,9 +86,24 @@ class WorkflowRESTClient
68
86
  WorkflowRESTClient.get_raw(File.join(url, 'file', file))
69
87
  end
70
88
 
89
+ def get_stream
90
+ case @result
91
+ when IO
92
+ @result
93
+ when String
94
+ StringIO.new @result
95
+ else
96
+ nil
97
+ end
98
+ end
99
+
100
+ def grace
101
+ end
102
+
71
103
  #{{{ MANAGEMENT
72
-
104
+
73
105
  def init_job(cache_type = nil, other_params = {})
106
+ Log.stack caller
74
107
  cache_type = :asynchronous if cache_type.nil? and not @is_exec
75
108
  cache_type = :exec if cache_type.nil?
76
109
  @name ||= Persist.memory("RemoteSteps", :workflow => self, :task => task, :jobname => @name, :inputs => inputs, :cache_type => cache_type) do
@@ -108,6 +141,8 @@ class WorkflowRESTClient
108
141
  init_job
109
142
  self.load
110
143
  end
144
+ ensure
145
+ @started = true
111
146
  end
112
147
  end
113
148
 
@@ -116,11 +151,15 @@ class WorkflowRESTClient
116
151
  end
117
152
 
118
153
  def exec(noload = false)
119
- if noload == :stream
120
- _run_job(:exec)
121
- else
122
- exec_job
123
- end
154
+ @result ||= begin
155
+ if noload == :stream
156
+ _run_job(:exec)
157
+ else
158
+ exec_job
159
+ end
160
+ ensure
161
+ @started = true
162
+ end
124
163
  end
125
164
 
126
165
  def join
@@ -180,20 +219,29 @@ class WorkflowRESTClient
180
219
  def _stream_job(stream_input, cache_type = :exec)
181
220
  require 'rbbt/util/misc/multipart_payload'
182
221
  WorkflowRESTClient.capture_exception do
183
- url = URI.encode(File.join(base_url, task.to_s))
184
- Log.debug{ "RestClient stream: #{ url } #{stream_input} #{cache_type} - #{Misc.fingerprint inputs}" }
222
+ 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}" }
185
224
  task_params = inputs.merge(:_cache_type => cache_type, :jobname => base_name, :_format => [:string, :boolean, :tsv, :annotations].include?(result_type) ? :raw : :json)
186
- res = RbbtMutiplartPayload.issue url, task_params, :mutations, nil, nil, true
225
+ res = RbbtMutiplartPayload.issue task_url, task_params, stream_input, nil, nil, true
187
226
  type = res.gets
188
227
  case type.strip
189
228
  when "LOCATION"
190
- url = res.gets
191
- url.sub!(/\?.*/,'')
192
- WorkflowRESTClient.get_raw(url)
193
- when "STREAM"
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
194
238
  res
195
239
  when "BULK"
196
- res.read
240
+ begin
241
+ res.read
242
+ ensure
243
+ @done = true
244
+ end
197
245
  else
198
246
  raise "What? " + type
199
247
  end
@@ -206,7 +254,7 @@ class WorkflowRESTClient
206
254
  return _stream_job(stream_input, cache_type)
207
255
  end
208
256
  WorkflowRESTClient.capture_exception do
209
- url = URI.encode(File.join(base_url, task.to_s))
257
+ @url = URI.encode(File.join(base_url, task.to_s))
210
258
  task_params = inputs.merge(:_cache_type => cache_type, :jobname => base_name, :_format => [:string, :boolean, :tsv, :annotations].include?(result_type) ? :raw : :json)
211
259
 
212
260
  sout, sin = Misc.pipe
@@ -244,6 +292,7 @@ class WorkflowRESTClient
244
292
  def _restart
245
293
  @done = nil
246
294
  @name = nil
295
+ @started = nil
247
296
  new_inputs = {}
248
297
  inputs.each do |k,i|
249
298
  if File === i
@@ -69,7 +69,7 @@ module TSV
69
69
  if fix_flat and parser.type == :flat and parser.first_line
70
70
  parts = lines[-1].split("\t")
71
71
  lines[-1] = [parts[0], (parts[1..-1] || [])*"|"] * "\t"
72
- TSV.stream_flat2double(parser.stream).stream
72
+ TSV.stream_flat2double(parser.stream, :noheader => true).stream
73
73
  else
74
74
  parser.stream
75
75
  end
@@ -220,10 +220,11 @@ module TSV
220
220
  end
221
221
 
222
222
  def self.stream_flat2double(stream, options = {})
223
+ noheader = Misc.process_options options, :noheader
223
224
  parser = TSV::Parser.new TSV.get_stream(stream), :type => :flat
224
225
  dumper_options = parser.options.merge(options).merge(:type => :double)
225
226
  dumper = TSV::Dumper.new dumper_options
226
- dumper.init
227
+ dumper.init unless noheader
227
228
  TSV.traverse parser, :into => dumper do |key,values|
228
229
  key = key.first if Array === key
229
230
  values = [values] unless Array === values
@@ -8,7 +8,19 @@ class Aborted < Exception; end
8
8
 
9
9
  class RemoteServerError < Exception; end
10
10
 
11
- class DependencyError < Exception; end
11
+ class DependencyError < Aborted
12
+ def initialize(msg)
13
+ if defined? Step and Step === msg
14
+ step = msg
15
+ workflow = step.path.split("/")[-3]
16
+ new_msg = [workflow, step.short_path, step.messages.last] * " - "
17
+ new_msg = [step.path, step.messages.last] * ": "
18
+ super(new_msg)
19
+ else
20
+ super(msg)
21
+ end
22
+ end
23
+ end
12
24
 
13
25
  class KeepLocked < Exception
14
26
  attr_accessor :payload
@@ -28,7 +28,7 @@ module Misc
28
28
  when nil
29
29
  "nil"
30
30
  when (defined? Step and Step)
31
- obj.path || Misc.fingerprint([obj.task.name, obj.inputs])
31
+ "<Step:" << (obj.path || Misc.fingerprint([obj.task.name, obj.inputs])) << ">"
32
32
  when TrueClass
33
33
  "true"
34
34
  when FalseClass
@@ -53,7 +53,7 @@ module Misc
53
53
  if (length = obj.length) > 10
54
54
  "[#{length}--" << (obj.values_at(0,1, length / 2, -2, -1).collect{|e| fingerprint(e)} * ",") << "]"
55
55
  else
56
- "[" << (obj.collect{|e| fingerprint(e) } * ",") << "]"
56
+ "[" << (obj.collect{|e| fingerprint(e) } * ", ") << "]"
57
57
  end
58
58
  when (defined? TSV and TSV)
59
59
  obj.with_unnamed do
@@ -1,24 +1,30 @@
1
1
  require 'net/http'
2
2
  require 'rbbt-util'
3
3
 
4
- class Net::HTTPGenericRequest
5
- alias old_send_request_with_body_stream send_request_with_body_stream
6
-
7
- def send_request_with_body_stream(*args)
8
- if chunked?
9
- Thread.new do
10
- old_send_request_with_body_stream(*args)
11
- end
12
- else
13
- old_send_request_with_body_stream(*args)
14
- end
15
- end
16
- end
4
+ #class Net::HTTPGenericRequest
5
+ # alias old_send_request_with_body_stream send_request_with_body_stream
6
+ #
7
+ # def __send_request_with_body_stream(*args)
8
+ # begin
9
+ # pid = Process.fork do
10
+ # iii [:pre_chunk, Thread.current]
11
+ # return old_send_request_with_body_stream(*args)
12
+ # end
13
+ # Process.wait pid
14
+ # ensure
15
+ # iii [:pre_chunk_done, Thread.current]
16
+ # end
17
+ # end
18
+ #end
17
19
 
18
20
  module RbbtMutiplartPayload
19
21
  BOUNDARY = "Rbbt_Param_Stream"
20
22
  EOL = "\r\n"
21
23
 
24
+ def self.mutex
25
+ @mutex ||= Mutex.new
26
+ end
27
+
22
28
  def self.input_header(name, filename = nil)
23
29
 
24
30
  if filename
@@ -43,9 +49,6 @@ module RbbtMutiplartPayload
43
49
  header = input_header(name, filename)
44
50
  io.write "--" + BOUNDARY + EOL + header + EOL + EOL
45
51
 
46
- #while c = content.read(1024)
47
- # io.write c
48
- #end
49
52
  while line = content.gets
50
53
  io.puts line
51
54
  end
@@ -59,9 +62,6 @@ module RbbtMutiplartPayload
59
62
  end
60
63
 
61
64
  def self.post_data_stream(inputs = nil, stream_input = nil, stream_io = nil, stream_filename = nil)
62
- #sout, sin = Misc.pipe
63
-
64
- #Thread.new do
65
65
  Misc.open_pipe do |sin|
66
66
  inputs.each do |input,content|
67
67
  input = input.to_s
@@ -86,6 +86,7 @@ module RbbtMutiplartPayload
86
86
 
87
87
  RbbtMutiplartPayload.add_stream(sin, stream_input.to_s, stream_io, stream_filename) if stream_input
88
88
  RbbtMutiplartPayload.close_stream(sin)
89
+
89
90
  sin.close unless sin.closed?
90
91
  end
91
92
  end
@@ -105,7 +106,7 @@ module RbbtMutiplartPayload
105
106
  when File
106
107
  inputs[stream_input].path
107
108
  else
108
- 'file'
109
+ 'file-rand-' + rand(10000000).to_s
109
110
  end
110
111
  end
111
112
 
@@ -120,14 +121,17 @@ module RbbtMutiplartPayload
120
121
  req.body = sout.read
121
122
  end
122
123
 
123
- Misc.open_pipe do |sin|
124
+ Misc.open_pipe(true) do |sin|
125
+ sleep rand(10).to_f / 5
124
126
  Net::HTTP.start(uri.hostname, uri.port) do |http|
125
127
  http.request(req) do |res|
128
+ url_path = res["RBBT-STREAMING-JOB-URL"]
126
129
  if Net::HTTPRedirection === res
127
130
  sin.puts "LOCATION" if report_type
128
131
  sin.write res["location"]
129
- elsif stream_input
130
- sin.puts "STREAM" if report_type
132
+ elsif stream_input and url_path
133
+ url = URI::HTTP.build(:host => uri.hostname, :post => uri.port, :path => url_path)
134
+ sin.puts "STREAM: #{url.to_s}" if report_type
131
135
  res.read_body do |c|
132
136
  sin.write c
133
137
  end
@@ -77,6 +77,7 @@ module Misc
77
77
  Log.medium "Aborted open_pipe: #{$!.message}"
78
78
  rescue Exception
79
79
  Log.medium "Exception in open_pipe: #{$!.message}"
80
+ Log.exception $!
80
81
  parent.raise $!
81
82
  raise $!
82
83
  end
@@ -90,14 +91,12 @@ module Misc
90
91
  stream_out1, stream_in1 = Misc.pipe
91
92
  stream_out2, stream_in2 = Misc.pipe
92
93
 
93
- #if ConcurrentStream === stream
94
- # stream.annotate stream_out1
95
- #end
96
-
97
94
  splitter_thread = Thread.new(Thread.current) do |parent|
98
95
  begin
96
+
99
97
  skip1 = skip2 = false
100
- while block = stream.read(2048)
98
+ while block = stream.read(1024)
99
+
101
100
  begin
102
101
  stream_in1.write block;
103
102
  rescue IOError
@@ -111,7 +110,9 @@ module Misc
111
110
  Log.medium("Tee stream 2 #{Misc.fingerprint stream} IOError: #{$!.message}");
112
111
  skip2 = true
113
112
  end unless skip2
113
+
114
114
  end
115
+
115
116
  stream_in1.close unless stream_in1.closed?
116
117
  stream.join if stream.respond_to? :join
117
118
  stream_in2.close unless stream_in2.closed?
@@ -585,7 +585,7 @@ module Workflow
585
585
  dependencies.each do |dependency|
586
586
  real_dependencies << case dependency
587
587
  when Array
588
- workflow, task, options = dependency
588
+ workflow, dep_task, options = dependency
589
589
 
590
590
  _inputs = IndiferentHash.setup(inputs.dup)
591
591
  options.each{|i,v|
@@ -595,9 +595,9 @@ module Workflow
595
595
  rec_dependency = all_d.select{|d| d.task_name.to_sym == v }.first
596
596
 
597
597
  if rec_dependency.nil?
598
- _inputs[i] = v
598
+ _inputs[i] = v unless _inputs.include? i
599
599
  else
600
- input_options = workflow.task_info(task)[:input_options][i] || {}
600
+ input_options = workflow.task_info(dep_task)[:input_options][i] || {}
601
601
  if input_options[:stream]
602
602
  #rec_dependency.run(true).grace unless rec_dependency.done? or rec_dependency.running?
603
603
  _inputs[i] = rec_dependency
@@ -617,7 +617,7 @@ module Workflow
617
617
  end
618
618
  } if options
619
619
 
620
- res = workflow.job(task, jobname, _inputs)
620
+ res = workflow.job(dep_task, jobname, _inputs)
621
621
  res
622
622
  when Step
623
623
  dependency
@@ -203,11 +203,8 @@ class Step
203
203
  info_file = Step.info_file path
204
204
  pid_file = Step.pid_file path
205
205
  files_dir = Step.files_dir path
206
+
206
207
  if Open.exists?(path) or Open.exists?(pid_file)
207
- begin
208
- self.abort if self.running?
209
- rescue Exception
210
- end
211
208
 
212
209
  @result = nil
213
210
  @pid = nil
@@ -224,6 +221,8 @@ class Step
224
221
  end
225
222
 
226
223
  def clean
224
+ Log.medium "Cleaning step: #{path}"
225
+ abort if not done? and running?
227
226
  Step.clean(path)
228
227
  self
229
228
  end
@@ -250,7 +249,16 @@ class Step
250
249
  rec_dependencies.each do |step|
251
250
  if Open.exists?(step.info_file)
252
251
  step.clean
253
- else
252
+ end
253
+ end
254
+ self
255
+ end
256
+
257
+ def recursive_clean
258
+ clean
259
+ dependencies.each do |step|
260
+ if Open.exists?(step.info_file)
261
+ step.recursive_clean
254
262
  end
255
263
  end
256
264
  self
@@ -1,31 +1,55 @@
1
1
  class Step
2
2
 
3
- attr_reader :stream, :dupped, :saved_stream
3
+ attr_reader :stream, :dupped, :saved_stream, :inputs
4
4
 
5
5
  STREAM_CACHE = {}
6
6
  STREAM_CACHE_MUTEX = Mutex.new
7
+ def self.purge_stream_cache
8
+ Log.medium "Purging dup. stream cache"
9
+ STREAM_CACHE_MUTEX.synchronize do
10
+ #STREAM_CACHE.collect{|k,s|
11
+ # next
12
+ # Thread.new do
13
+ # Misc.consume_stream s
14
+ # end
15
+ #}
16
+ STREAM_CACHE.clear
17
+ end
18
+ end
19
+
7
20
  def self.dup_stream(stream)
8
21
  case stream
9
- when IO, File
10
- return stream if stream.closed?
22
+ when IO, File, Step
23
+ return stream if stream.respond_to?(:closed?) and stream.closed?
24
+ return stream if stream.respond_to?(:done?) and stream.done?
11
25
 
12
26
  STREAM_CACHE_MUTEX.synchronize do
13
- case current = STREAM_CACHE[stream]
27
+ stream_key = Misc.fingerprint(stream)
28
+ current = STREAM_CACHE[stream_key]
29
+ case current
14
30
  when nil
15
- Log.medium "Not duplicating stream #{ Misc.fingerprint(stream) }"
16
- STREAM_CACHE[stream] = stream
31
+ Log.medium "Not duplicating stream #{stream_key}"
32
+ STREAM_CACHE[stream_key] = stream
17
33
  when File
18
34
  if Open.exists? current.path
19
- Log.medium "Reopening file #{ Misc.fingerprint(current) }"
35
+ Log.medium "Reopening file #{stream_key}"
20
36
  Open.open(current.path)
21
37
  else
22
- Log.medium "Duplicating file #{ Misc.fingerprint(current) } #{current.inspect}"
23
- Misc.dup_stream(current)
38
+ new = Misc.dup_stream(current)
39
+ Log.medium "Duplicating file #{stream_key} #{current.inspect} => #{Misc.fingerprint(new)}"
40
+ new
24
41
  end
25
-
42
+ when Step
43
+ job = current
44
+ current = job.result
45
+ new = Misc.dup_stream(current)
46
+ job.result = current
47
+ Log.medium "Duplicating step #{stream_key} #{current.inspect} => #{Misc.fingerprint(new)}"
48
+ new
26
49
  else
27
- Log.medium "Duplicating stream #{ Misc.fingerprint(stream) }"
28
- Misc.dup_stream(current)
50
+ new = Misc.dup_stream(current)
51
+ Log.medium "Duplicating stream #{stream_key} #{ Misc.fingerprint(stream) } => #{Misc.fingerprint(new)}"
52
+ new
29
53
  end
30
54
  end
31
55
  when TSV::Dumper#, TSV::Parser
@@ -47,20 +71,86 @@ class Step
47
71
  end
48
72
  end
49
73
 
50
- def self.purge_stream_cache
51
- return
52
- STREAM_CACHE_MUTEX.synchronize do
53
- STREAM_CACHE.collect{|k,s|
54
- Thread.new do
55
- Misc.consume_stream s
56
- end
57
- }
58
- STREAM_CACHE.clear
74
+ def self.prepare_for_execution(job)
75
+ return if (job.done? and not job.dirty?) or
76
+ (job.streaming? and job.running?) or
77
+ (defined? WorkflowRESTClient and WorkflowRESTClient::RemoteStep === job and not (job.error? or job.aborted?))
78
+
79
+ job.clean if job.aborted? or (job.started? and not job.running? and not job.error?)
80
+
81
+ raise DependencyError, job if job.error?
82
+ end
83
+
84
+ def execute_dependency(dependency)
85
+ task_name = self.task_name
86
+ begin
87
+
88
+ if dependency.done?
89
+ Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task_name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} done -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
90
+ return
91
+ end
92
+
93
+ if not dependency.started?
94
+ Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task_name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} starting -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
95
+ dependency.run(:stream)
96
+ raise TryAgain
97
+ end
98
+
99
+ dependency.grace
100
+
101
+ if dependency.aborted?
102
+ Log.warn "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task_name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} aborted (clean and retry) -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
103
+ dependency.clean
104
+ raise TryAgain
105
+ end
106
+
107
+ if dependency.error?
108
+ Log.error "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task_name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} error -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
109
+ raise DependencyError, [dependency.path, dependency.messages.last] * ": " if dependency.error?
110
+ end
111
+
112
+ if dependency.streaming?
113
+ Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task_name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} streaming -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
114
+ return
115
+ end
116
+
117
+ begin
118
+ Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task_name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} joining -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
119
+ dependency.join
120
+ raise TryAgain unless dependency.done?
121
+ Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task_name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} joined -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
122
+ rescue Aborted
123
+ raise TryAgain
124
+ end
125
+
126
+ rescue TryAgain
127
+ retry
128
+ rescue Aborted
129
+ Log.error "Aborted dep. #{Log.color :red, dependency.task_name.to_s}"
130
+ raise $!
131
+ rescue Interrupt
132
+ Log.error "Interrupted while in dep. #{Log.color :red, dependency.task_name.to_s}"
133
+ raise $!
134
+ rescue Exception
135
+ Log.error "Exception in dep. #{ Log.color :red, dependency.task_name.to_s }"
136
+ Log.exception $!
137
+ raise $!
138
+ end
139
+ end
140
+
141
+ def dup_inputs
142
+ return if @dupped or ENV["RBBT_NO_STREAM"] == 'true'
143
+ Log.low "Dupping inputs for #{path}"
144
+ dupped_inputs = @inputs.collect do |input|
145
+ Step.dup_stream input
59
146
  end
147
+ @inputs.replace dupped_inputs
148
+ @dupped = true
60
149
  end
61
150
 
62
151
  def get_stream
63
152
  @mutex.synchronize do
153
+ Log.low "Getting stream from #{path} #{!@saved_stream}"
64
154
  begin
65
155
  return nil if @saved_stream
66
156
  if IO === @result
@@ -72,13 +162,6 @@ class Step
72
162
  end
73
163
  end
74
164
 
75
- def dup_inputs
76
- return if @dupped or ENV["RBBT_NO_STREAM"] == 'true'
77
- @inputs = @inputs.collect do |input|
78
- Step.dup_stream input
79
- end
80
- @dupped = true
81
- end
82
165
 
83
166
  def _exec
84
167
  @exec = true if @exec.nil?
@@ -98,7 +181,7 @@ class Step
98
181
  def checks
99
182
  rec_dependencies.collect{|dependency| (defined? WorkflowRESTClient and WorkflowRESTClient::RemoteStep === dependency) ? nil : dependency.path }.compact.uniq
100
183
  end
101
-
184
+
102
185
 
103
186
  def kill_children
104
187
  begin
@@ -138,77 +221,39 @@ class Step
138
221
  return if @seen.empty?
139
222
 
140
223
  log :dependencies, "#{Log.color :magenta, "Dependencies"} for step #{Log.color :yellow, task.name.to_s || ""}"
141
- dupping = []
142
- @seen.each do |dependency|
143
- next if (dependency.done? and not dependency.dirty?) or
144
- (dependency.streaming? and dependency.running?) or
145
- (defined? WorkflowRESTClient and WorkflowRESTClient::RemoteStep === dependency and not (dependency.error? or dependency.aborted?))
146
-
147
- dependency.clean if dependency.aborted? or (dependency.started? and not dependency.running? and not dependency.error?)
148
-
149
- raise DependencyError, [dependency.short_path, dependency.messages.last] * ": " if dependency.error?
150
224
 
151
- dupping << dependency unless dependencies.include? dependency
225
+ @seen.each do |dependency|
226
+ Step.prepare_for_execution(dependency)
152
227
  end
153
228
 
154
- dupping.each{|dep| dep.dup_inputs}
155
-
229
+ pre_deps = []
230
+ last_deps = []
156
231
  @seen.each do |dependency|
157
- next unless dependencies.include? dependency
158
-
159
- begin
160
-
161
- if dependency.done?
162
- Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task.name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} done -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
163
- next
164
- end
165
-
166
- if not dependency.started?
167
- Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task.name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} starting -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
168
- dependency.run(:stream)
169
- raise TryAgain
170
- end
171
-
172
- dependency.grace
173
-
174
- if dependency.aborted?
175
- Log.warn "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task.name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} aborted (clean and retry) -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
176
- dependency.clean
177
- raise TryAgain
232
+ if dependencies.include? dependency
233
+ if dependency.inputs.flatten.select{|i| Step === i}.any?
234
+ last_deps << dependency
235
+ else
236
+ pre_deps << dependency
178
237
  end
179
238
 
180
- if dependency.error?
181
- Log.error "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task.name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} error -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
182
- raise DependencyError, [dependency.path, dependency.messages.last] * ": " if dependency.error?
183
- end
239
+ else
240
+ pre_deps << dependency
241
+ end
242
+ end
184
243
 
185
- if dependency.streaming?
186
- Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task.name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} streaming -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
187
- next
188
- end
244
+ pre_deps.each do |dependency|
245
+ dependency.dup_inputs
246
+ execute_dependency(dependency)
247
+ end
189
248
 
190
- begin
191
- Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task.name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} joining -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
192
- dependency.join
193
- raise TryAgain unless dependency.done?
194
- Log.info "#{Log.color :cyan, "dependency"} #{Log.color :yellow, task.name.to_s || ""} => #{Log.color :yellow, dependency.task_name.to_s || ""} joined -- #{Log.color :blue, dependency.path} -- #{Log.color :yellow, self.short_path}"
195
- rescue Aborted
196
- raise TryAgain
197
- end
249
+ last_deps.each do |dependency|
250
+ dependency.dup_inputs
251
+ end
198
252
 
199
- rescue TryAgain
200
- retry
201
- rescue Aborted
202
- Log.error "Aborted dep. #{Log.color :red, dependency.task_name.to_s}"
203
- raise $!
204
- rescue Interrupt
205
- Log.error "Interrupted while in dep. #{Log.color :red, dependency.task_name.to_s}"
206
- raise $!
207
- rescue Exception
208
- Log.error "Exception in dep. #{ Log.color :red, dependency.task_name.to_s }"
209
- raise $!
210
- end
253
+ last_deps.each do |dependency|
254
+ execute_dependency(dependency)
211
255
  end
256
+
212
257
  end
213
258
 
214
259
  def run(no_load = false)
@@ -243,6 +288,7 @@ class Step
243
288
  stop_dependencies
244
289
  raise $!
245
290
  end
291
+
246
292
  set_info :dependencies, dependencies.collect{|dep| [dep.task_name, dep.name, dep.path]}
247
293
 
248
294
  set_info :inputs, Misc.remove_long_items(Misc.zip2hash(task.inputs, @inputs)) unless task.inputs.nil?
@@ -295,6 +341,7 @@ class Step
295
341
  Log.exception $!
296
342
  ensure
297
343
  join
344
+ Step.purge_stream_cache
298
345
  FileUtils.rm pid_file if File.exists?(pid_file)
299
346
  end
300
347
  end
@@ -312,6 +359,7 @@ class Step
312
359
  set_info :total_time_elapsed, (total_time_elapsed = done_time - issue_time)
313
360
  set_info :time_elapsed, (time_elapsed = done_time - start_time)
314
361
  log :done, "#{Log.color :magenta, "Completed"} step #{Log.color :yellow, task.name.to_s || ""} in #{time_elapsed.to_i}+#{(total_time_elapsed - time_elapsed).to_i} sec."
362
+ Step.purge_stream_cache
315
363
  FileUtils.rm pid_file if File.exists?(pid_file)
316
364
  end
317
365
 
@@ -322,6 +370,7 @@ class Step
322
370
  @result ||= result
323
371
  self
324
372
  else
373
+ Step.purge_stream_cache
325
374
  @result = prepare_result result, @task.result_description
326
375
  end
327
376
  end
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.37
4
+ version: 5.20.0
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-05-13 00:00:00.000000000 Z
11
+ date: 2016-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake