rbbt-util 5.26.157 → 5.26.158

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,324 +0,0 @@
1
- class WorkflowRemoteClient
2
- class RemoteStep < Step
3
-
4
- attr_accessor :url, :base_url, :task, :base_name, :inputs, :result_type, :result_description, :is_exec, :is_stream, :stream_input
5
-
6
- def initialize(base_url, task = nil, base_name = nil, inputs = nil, result_type = nil, result_description = nil, is_exec = false, is_stream = false, stream_input = nil)
7
- @base_url, @task, @base_name, @inputs, @result_type, @result_description, @is_exec, @is_stream, @stream_input = base_url, task, base_name, inputs, result_type, result_description, is_exec, is_stream, stream_input
8
- @base_url = "http://" << @base_url unless @base_url =~ /^[a-z]+:\/\//
9
- @mutex = Mutex.new
10
- rest = base_url.include?('ssh:') ? false : true
11
-
12
- if rest
13
- @adaptor = WorkflowRESTClient
14
- else
15
- @adaptor = WorkflowSSHClient
16
- end
17
-
18
- self.extend @adaptor
19
- end
20
-
21
- def clean_name
22
- @base_name
23
- end
24
-
25
- def cache_file
26
- digest = Misc.obj2digest([base_url, task, base_name, inputs])
27
- Rbbt.var.cache.REST[[task, clean_name, digest] * "."].find
28
- end
29
-
30
- def cache_files
31
- Dir.glob(cache_file + '.*')
32
- end
33
-
34
- def run(no_load = false)
35
- no_load = @is_stream ? :stream : true if no_load
36
-
37
- @result ||= @mutex.synchronize do
38
- begin
39
- if @is_exec
40
- exec(no_load)
41
- elsif no_load == :stream
42
- _run_job(:stream)
43
- elsif no_load
44
- init_job
45
- nil
46
- else
47
- if ! done?
48
- init_job
49
- join
50
- end
51
- self.load
52
- end
53
- ensure
54
- @started = true
55
- end
56
- end
57
-
58
- return @result if no_load == :stream
59
- no_load ? Misc.add_GET_param(path, "_format", "raw") : @result
60
- end
61
-
62
-
63
- def self.get_streams(inputs, stream_input = nil)
64
- new_inputs = {}
65
- inputs.each do |k,v|
66
- stream = stream_input.to_s == k.to_s
67
- if Step === v
68
- unless (v.done? or v.streaming?) # or RestClient::Step === v)
69
- v.run(true) and v.grace
70
- end
71
-
72
- begin
73
- if stream
74
- new_inputs[k] = TSV.get_stream(v)
75
- else
76
- new_inputs[k] = v.load
77
- end
78
- rescue Exception
79
- raise $!
80
- end
81
- else
82
- new_inputs[k] = v
83
- end
84
- end
85
- new_inputs
86
- end
87
-
88
- def get_streams
89
- return if @inputs_done
90
- @inputs = RemoteStep.get_streams @inputs, @stream_input
91
- @inputs_done = true
92
- @inputs
93
- end
94
-
95
- def dup_inputs
96
- return if @dupped or ENV["RBBT_NO_STREAM"] == 'true'
97
- Log.low "Dupping inputs for #{path}"
98
- dupped_inputs = {}
99
- @inputs.collect do |k,input|
100
- dupped_inputs[k] = Step.dup_stream input
101
- end
102
- @inputs = dupped_inputs
103
- @dupped = true
104
- end
105
-
106
- def name
107
- return nil if @is_exec
108
- return @path if @url.nil?
109
- (Array === @url ? @url.first : @url).split("/").last
110
- end
111
-
112
- def name=(name)
113
- @url = [base_url,task, name] * "/"
114
- end
115
-
116
- def task_name
117
- return task if task
118
- init_job
119
- (Array === @url ? @url.first : @url).split("/")[-2]
120
- end
121
-
122
- def nopid?
123
- false
124
- end
125
-
126
- def info(check_lock=false)
127
- @done = @info && @info[:status] && (@info[:status].to_sym == :done || @info[:status].to_sym == :error)
128
-
129
- if !@done && (@last_info_time.nil? || (Time.now - @last_info_time) > 0.5)
130
- update = true
131
- else
132
- update = false
133
- end
134
-
135
- @info = Persist.memory("RemoteSteps Info", :url => @url, :persist => true, :update => update) do
136
- @last_info_time = Time.now
137
- init_job unless @url
138
- info = @adaptor.get_json(File.join(@url, 'info'))
139
- info = @adaptor.fix_hash(info)
140
- info[:status] = info[:status].to_sym if String === info[:status]
141
- info
142
- end
143
- @info
144
- end
145
-
146
- def status
147
- return :done if @done
148
- return nil unless url or started?
149
- #return :streaming if @streaming
150
- begin
151
- status = info[:status]
152
- @done = true if status and status.to_sym == :done
153
- status
154
- rescue
155
- nil
156
- ensure
157
- @info = nil
158
- end
159
- end
160
-
161
- def started?
162
- @result != nil || @started || @streaming
163
- end
164
-
165
- def done?
166
- return true if cache_files.any?
167
- init_job unless @url
168
- @done || status.to_s == 'done' || status.to_s == 'noinfo'
169
- end
170
-
171
- def files
172
- @adaptor.get_json(File.join(url, 'files'))
173
- end
174
-
175
- def file(file)
176
- @adaptor.get_raw(File.join(url, 'file', file))
177
- end
178
-
179
- def get_stream
180
- case @result
181
- when IO
182
- @result
183
- when String
184
- StringIO.new @result
185
- else
186
- nil
187
- end
188
- end
189
-
190
- def grace
191
- produce unless @started
192
- sleep 0.1 unless started?
193
- sleep 0.5 unless started?
194
- sleep 1 unless started?
195
- while not (done? or started?)
196
- sleep 1
197
- end
198
- end
199
-
200
- #{{{ MANAGEMENT
201
-
202
-
203
- def path
204
- if @url
205
- Misc.add_GET_param(@url, "_format", "raw")
206
- elsif @base_name
207
- [base_url, task, @base_name + '-' + Misc.fingerprint(inputs)] * "/"
208
- else
209
- nil
210
- end
211
- end
212
-
213
- def fork(noload=false, semaphore=nil)
214
- init_job(:asynchronous)
215
- end
216
-
217
- def running?
218
- ! %w(done error aborted noinfo).include? status.to_s
219
- end
220
-
221
- def exec(noload = false)
222
- @result ||= begin
223
- if noload == :stream
224
- _run_job(:exec)
225
- else
226
- exec_job
227
- end
228
- ensure
229
- @started = true
230
- end
231
- end
232
-
233
- def join
234
- return true if cache_files.any?
235
- init_job unless @url
236
- Log.debug{ "Joining RestClient: #{path}" }
237
- if IO === @result
238
- res = @result
239
- @result = nil
240
- Misc.consume_stream(res, true)
241
- end
242
-
243
- if not (self.done? || self.aborted? || self.error?)
244
- self.info
245
- return self if self.done? || self.aborted? || self.error?
246
- sleep 0.2 unless self.done? || self.aborted? || self.error?
247
- sleep 1 unless self.done? || self.aborted? || self.error?
248
- while not (self.done? || self.aborted? || self.error?)
249
- sleep 3
250
- end
251
- end
252
-
253
- self
254
- end
255
-
256
- def load_res(res, result_type = nil)
257
-
258
- stream = true if res.respond_to? :read
259
- join unless stream
260
- result_type ||= self.result_type
261
-
262
- case result_type.to_sym
263
- when :string
264
- stream ? res.read : res
265
- when :boolean
266
- (stream ? res.read : res) == 'true'
267
- when :tsv
268
- if stream
269
- TSV.open(res, :monitor => true)
270
- else
271
- TSV.open(StringIO.new(res))
272
- end
273
- when :annotations
274
- if stream
275
- Annotated.load_tsv(TSV.open(res))
276
- else
277
- Annotated.load_tsv(TSV.open(StringIO.new(res)))
278
- end
279
- when :array
280
- (stream ? res.read : res).split("\n")
281
- else
282
- json_text = if IO === res
283
- res.read
284
- else
285
- res
286
- end
287
- begin
288
- JSON.parse json_text
289
- rescue
290
- case
291
- when json_text =~ /^\d+$/
292
- json_text.to_i
293
- when json_text =~ /^\d+\.\d/
294
- json_text.to_f
295
- else
296
- raise $!
297
- end
298
- end
299
- end
300
- end
301
-
302
- def _restart
303
- @done = nil
304
- @name = nil
305
- @started = nil
306
- @aborted = nil
307
- new_inputs = {}
308
- inputs.each do |k,i|
309
- if File === i
310
- new_inputs[k] = File.open(i.path)
311
- else
312
- new_inputs[k] = i
313
- end
314
- end
315
- @inputs = new_inputs
316
- @info = nil
317
- end
318
-
319
- def input_checks
320
- []
321
- end
322
-
323
- end
324
- end
@@ -1,161 +0,0 @@
1
- require 'rest-client'
2
-
3
- module WorkflowRESTClient
4
- def self.__prepare_inputs_for_restclient(inputs)
5
- inputs.each do |k,v|
6
- if v.respond_to? :path and not v.respond_to? :original_filename
7
- class << v
8
- def original_filename
9
- File.expand_path(path)
10
- end
11
- end
12
- end
13
-
14
- if Array === v and v.empty?
15
- inputs[k] = "EMPTY_ARRAY"
16
- end
17
- end
18
- end
19
-
20
- def workflow_description
21
- WorkflowRESTClient.get_raw(File.join(url, 'description'))
22
- end
23
-
24
- def documentation
25
- @documention ||= IndiferentHash.setup(WorkflowRESTClient.get_json(File.join(url, "documentation"),{}))
26
- end
27
-
28
- def self.task_info(url, task)
29
- @@task_info ||= {}
30
-
31
- key = [url, task] * "#"
32
- @@task_info[key] ||= begin
33
- task_info = WorkflowRESTClient.get_json(File.join(url, task.to_s, 'info'))
34
- task_info = WorkflowRESTClient.fix_hash(task_info)
35
-
36
- task_info[:result_type] = task_info[:result_type].to_sym
37
- task_info[:export] = task_info[:export].to_sym
38
- task_info[:input_types] = WorkflowRESTClient.fix_hash(task_info[:input_types], true)
39
- task_info[:inputs] = task_info[:inputs].collect{|input| input.to_sym }
40
-
41
- @@task_info[key] = task_info
42
- end
43
- end
44
-
45
- def task_info(task)
46
- WorkflowRESTClient.task_info(url, task)
47
- end
48
-
49
- def exported_tasks
50
- (@asynchronous_exports + @synchronous_exports + @exec_exports).compact.flatten
51
- end
52
-
53
- def tasks
54
- @tasks ||= Hash.new do |hash,task_name|
55
- info = task_info(task_name)
56
- task = Task.setup info do |*args|
57
- raise "This is a remote task"
58
- end
59
- task.name = task_name.to_sym
60
- hash[task_name] = task
61
- end
62
- end
63
-
64
- def load_tasks
65
- exported_tasks.each{|name| tasks[name]}
66
- nil
67
- end
68
-
69
- def task_dependencies
70
- @task_dependencies ||= Hash.new do |hash,task|
71
- hash[task] = if exported_tasks.include? task
72
- WorkflowRESTClient.get_json(File.join(url, task.to_s, 'dependencies'))
73
- else
74
- []
75
- end
76
- end
77
- end
78
-
79
- def init_remote_tasks
80
- task_exports = WorkflowRESTClient.get_json(url)
81
- @asynchronous_exports = (task_exports["asynchronous"] || []).collect{|task| task.to_sym }
82
- @synchronous_exports = (task_exports["synchronous"] || []).collect{|task| task.to_sym }
83
- @exec_exports = (task_exports["exec"] || []).collect{|task| task.to_sym }
84
- @stream_exports = (task_exports["stream"] || []).collect{|task| task.to_sym }
85
- @can_stream = task_exports["can_stream"]
86
- end
87
-
88
- def self.execute_job(base_url, task, task_params, cache_type)
89
- self.capture_exception do
90
- task_url = URI.encode(File.join(base_url, task.to_s))
91
-
92
- sout, sin = Misc.pipe
93
-
94
- post_thread = Thread.new(Thread.current) do |parent|
95
- bl = lambda do |rok|
96
- if Net::HTTPOK === rok
97
- _url = rok["RBBT-STREAMING-JOB-URL"]
98
- @url = File.join(task_url, File.basename(_url)) if _url
99
- rok.read_body do |c,_a, _b|
100
- sin.write c
101
- end
102
- sin.close
103
- else
104
- err = StringIO.new
105
- rok.read_body do |c,_a, _b|
106
- err.write c
107
- end
108
- text = begin
109
- reader = Zlib::GzipReader.new(err)
110
- reader.read
111
- rescue
112
- err.rewind
113
- err.read
114
- end
115
- ne = @adaptor.parse_exception text
116
- case ne
117
- when String
118
- parent.raise e.class, ne
119
- when Exception
120
- parent.raise ne
121
- else
122
- parent.raise "Error in RestClient: " << rok.message
123
- end
124
- end
125
- end
126
-
127
- task_params.each do |k,v|
128
- task_params[k] = v.read if IO === v
129
- end
130
-
131
- Log.debug{ "RestClient execute: #{ task_url } - #{Misc.fingerprint task_params}" }
132
- RestClient::Request.execute(:method => :post, :url => task_url, :payload => task_params, :block_response => bl)
133
- end
134
-
135
- # It seems like now response body are now decoded by Net::HTTP after 2.1
136
- # https://github.com/rest-client/rest-client/blob/cf3e5a115bcdb8f3344aeac0e45b44d67fac1a42/history.md
137
- decode = Gem.loaded_specs["rest-client"].version < Gem::Version.create('2.1')
138
- if decode
139
- reader = Zlib::GzipReader.new(sout)
140
- res_io = Misc.open_pipe do |sin|
141
- while c = reader.read(Misc::BLOCK_SIZE)
142
- sin.write c
143
- end
144
- sin.close
145
- @done = true
146
- end
147
- ConcurrentStream.setup(res_io, :threads => [post_thread]) do
148
- @done = true
149
- @streaming = false
150
- end
151
- else
152
- ConcurrentStream.setup(sout, :threads => [post_thread]) do
153
- @done = true
154
- @streaming = false
155
- end
156
- end
157
-
158
- end
159
- end
160
-
161
- end