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