rbbt-util 5.19.37 → 5.20.0

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: 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