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 +4 -4
- data/lib/rbbt/rest/client/step.rb +73 -24
- data/lib/rbbt/tsv/stream.rb +3 -2
- data/lib/rbbt/util/misc/exceptions.rb +13 -1
- data/lib/rbbt/util/misc/inspect.rb +2 -2
- data/lib/rbbt/util/misc/multipart_payload.rb +27 -23
- data/lib/rbbt/util/misc/pipes.rb +6 -5
- data/lib/rbbt/workflow/accessor.rb +4 -4
- data/lib/rbbt/workflow/step.rb +13 -5
- data/lib/rbbt/workflow/step/run.rb +139 -90
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 333a3110a30ab60b25c3e7a5acb5364c2b75cf87
|
4
|
+
data.tar.gz: 73610983c2f10ee9ec6cfcc3693e6569174a433d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
10
|
-
v
|
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
|
-
|
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
|
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
|
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
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
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
|
-
|
184
|
-
Log.debug{ "RestClient stream: #{
|
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
|
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
|
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
|
-
|
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
|
data/lib/rbbt/tsv/stream.rb
CHANGED
@@ -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 <
|
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
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
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
|
data/lib/rbbt/util/misc/pipes.rb
CHANGED
@@ -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(
|
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,
|
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(
|
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(
|
620
|
+
res = workflow.job(dep_task, jobname, _inputs)
|
621
621
|
res
|
622
622
|
when Step
|
623
623
|
dependency
|
data/lib/rbbt/workflow/step.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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 #{
|
16
|
-
STREAM_CACHE[
|
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 #{
|
35
|
+
Log.medium "Reopening file #{stream_key}"
|
20
36
|
Open.open(current.path)
|
21
37
|
else
|
22
|
-
|
23
|
-
Misc.
|
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
|
-
|
28
|
-
Misc.
|
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.
|
51
|
-
return
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
-
|
225
|
+
@seen.each do |dependency|
|
226
|
+
Step.prepare_for_execution(dependency)
|
152
227
|
end
|
153
228
|
|
154
|
-
|
155
|
-
|
229
|
+
pre_deps = []
|
230
|
+
last_deps = []
|
156
231
|
@seen.each do |dependency|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
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
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
239
|
+
else
|
240
|
+
pre_deps << dependency
|
241
|
+
end
|
242
|
+
end
|
184
243
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
244
|
+
pre_deps.each do |dependency|
|
245
|
+
dependency.dup_inputs
|
246
|
+
execute_dependency(dependency)
|
247
|
+
end
|
189
248
|
|
190
|
-
|
191
|
-
|
192
|
-
|
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
|
-
|
200
|
-
|
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.
|
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-
|
11
|
+
date: 2016-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|