rbbt-util 5.26.157 → 5.26.158

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.
@@ -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