rbbt-util 5.23.16 → 5.23.17
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/util/concurrency/processes.rb +1 -0
- data/lib/rbbt/util/concurrency/processes/worker.rb +5 -3
- data/lib/rbbt/util/log/progress/report.rb +0 -1
- data/lib/rbbt/util/misc/pipes.rb +3 -3
- data/lib/rbbt/workflow/accessor.rb +7 -4
- data/lib/rbbt/workflow/step/run.rb +162 -165
- data/share/rbbt_commands/workflow/prov +1 -1
- 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: b741d19f2b817da6421a86a354264aabedae4397
|
4
|
+
data.tar.gz: 5003c159ae149e9a1660acfa939080c3895b08d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f14b692b30f79dfd99d859c66d2a51313d83f3f1e704bb08a7a89baa0c69aacdadaf331a998c48958f066c73f8eecc050216c23de774c23461070ca3d3c5e9a
|
7
|
+
data.tar.gz: 6755c1770e04c17b779f63d22649230018d0480fad203fe56033a295d75f0989d63c97fffeee0a1c70b031ce27186d5cbaa05c22be1eeff42500cab170813e0c
|
@@ -27,9 +27,9 @@ class RbbtProcessQueue
|
|
27
27
|
@stop = true
|
28
28
|
}
|
29
29
|
|
30
|
-
@abort = false
|
31
30
|
Signal.trap(20){
|
32
|
-
|
31
|
+
Log.high "Worker #{Process.pid} signaled to abort"
|
32
|
+
Kernel.exit! -1
|
33
33
|
}
|
34
34
|
|
35
35
|
loop do
|
@@ -63,6 +63,7 @@ class RbbtProcessQueue
|
|
63
63
|
Log.high "Worker #{Process.pid} leaving"
|
64
64
|
rescue Exception
|
65
65
|
Log.high "Worker #{Process.pid} had exception: #{$!.message}"
|
66
|
+
Log.exception $!
|
66
67
|
begin
|
67
68
|
@callback_queue.push($!) if @callback_queue
|
68
69
|
rescue
|
@@ -144,6 +145,7 @@ class RbbtProcessQueue
|
|
144
145
|
}
|
145
146
|
|
146
147
|
Signal.trap(20){
|
148
|
+
Log.high "Killing respawned process #{@current}"
|
147
149
|
begin
|
148
150
|
Process.kill 20, @current if @current
|
149
151
|
rescue Errno::ESRCH, Errno::ECHILD
|
@@ -181,7 +183,7 @@ class RbbtProcessQueue
|
|
181
183
|
end
|
182
184
|
|
183
185
|
if status
|
184
|
-
Log.high "Worker respawner
|
186
|
+
Log.high "Worker #{@current} (respawner #{Process.pid} ) completed with status #{status}"
|
185
187
|
Kernel.exit! status.to_i >> 8
|
186
188
|
else
|
187
189
|
Kernel.exit! -1
|
data/lib/rbbt/util/misc/pipes.rb
CHANGED
@@ -411,9 +411,6 @@ module Misc
|
|
411
411
|
FileUtils.touch path if File.exist? path
|
412
412
|
content.join if content.respond_to? :join and not (content.respond_to?(:joined?) and content.joined?)
|
413
413
|
|
414
|
-
if Lockfile === lock_options[:lock] and lock_options[:lock].locked?
|
415
|
-
lock_options[:lock].unlock
|
416
|
-
end
|
417
414
|
Open.notify_write(path)
|
418
415
|
rescue Aborted
|
419
416
|
Log.medium "Aborted sensiblewrite -- #{ Log.reset << Log.color(:blue, path) }"
|
@@ -430,6 +427,9 @@ module Misc
|
|
430
427
|
raise $!
|
431
428
|
ensure
|
432
429
|
FileUtils.rm_f tmp_path if File.exist? tmp_path
|
430
|
+
if Lockfile === lock_options[:lock] and lock_options[:lock].locked?
|
431
|
+
lock_options[:lock].unlock
|
432
|
+
end
|
433
433
|
end
|
434
434
|
end
|
435
435
|
end
|
@@ -112,6 +112,7 @@ class Step
|
|
112
112
|
end
|
113
113
|
|
114
114
|
def status_lock
|
115
|
+
return @mutex
|
115
116
|
@status_lock = begin
|
116
117
|
path = Persist.persistence_path(info_file + '.status.lock', {:dir => Step.lock_dir})
|
117
118
|
Lockfile.new path, :refresh => false, :dont_use_lock_id => true
|
@@ -411,6 +412,7 @@ class Step
|
|
411
412
|
end
|
412
413
|
|
413
414
|
if dirty_files.any?
|
415
|
+
Log.low "Some dirty files found for #{self.path}: #{Misc.fingerprint dirty_files}"
|
414
416
|
true
|
415
417
|
else
|
416
418
|
! self.updated?
|
@@ -429,21 +431,22 @@ class Step
|
|
429
431
|
status == :noinfo
|
430
432
|
end
|
431
433
|
|
432
|
-
def running?
|
434
|
+
def running?
|
435
|
+
return false if ! (started? || status == :ending)
|
433
436
|
pid = info[:pid]
|
434
437
|
return nil if pid.nil?
|
435
438
|
|
436
|
-
return false if done? or error? or aborted?
|
439
|
+
return false if done? or error? or aborted?
|
437
440
|
|
438
441
|
if Misc.pid_exists?(pid)
|
439
442
|
pid
|
440
443
|
else
|
441
|
-
|
444
|
+
done? or error? or aborted?
|
442
445
|
end
|
443
446
|
end
|
444
447
|
|
445
448
|
def stalled?
|
446
|
-
started? && ! (done? ||
|
449
|
+
started? && ! (done? || running? || done? || error? || aborted?)
|
447
450
|
end
|
448
451
|
|
449
452
|
def missing?
|
@@ -182,204 +182,203 @@ class Step
|
|
182
182
|
res = @mutex.synchronize do
|
183
183
|
no_load = :stream if no_load
|
184
184
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
end
|
185
|
+
Open.write(pid_file, Process.pid.to_s) unless Open.exists?(path) or Open.exists?(pid_file)
|
186
|
+
result = Persist.persist "Job", @task.result_type, :file => path, :check => checks.collect{|dep| dep.path}, :no_load => no_load do
|
187
|
+
if Step === Step.log_relay_step and not self == Step.log_relay_step
|
188
|
+
relay_log(Step.log_relay_step) unless self.respond_to? :relay_step and self.relay_step
|
189
|
+
end
|
191
190
|
|
192
|
-
|
191
|
+
Open.write(pid_file, Process.pid.to_s) unless Open.exists? pid_file
|
193
192
|
|
194
|
-
|
195
|
-
|
193
|
+
@exec = false
|
194
|
+
init_info
|
196
195
|
|
197
|
-
|
196
|
+
log :setup, "#{Log.color :green, "Setup"} step #{Log.color :yellow, task.name.to_s || ""}"
|
198
197
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
198
|
+
merge_info({
|
199
|
+
:issued => (issue_time = Time.now),
|
200
|
+
:name => name,
|
201
|
+
:clean_name => clean_name,
|
202
|
+
:workflow => (@workflow || @task.workflow).to_s,
|
203
|
+
:task_name => @task.name,
|
204
|
+
:result_type => @task.result_type,
|
205
|
+
:result_description => @task.result_description,
|
206
|
+
:dependencies => dependencies.collect{|dep| [dep.task_name, dep.name, dep.path]}
|
207
|
+
})
|
209
208
|
|
210
209
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
210
|
+
begin
|
211
|
+
run_dependencies
|
212
|
+
rescue Exception
|
213
|
+
FileUtils.rm pid_file if File.exist?(pid_file)
|
214
|
+
stop_dependencies
|
215
|
+
raise $!
|
216
|
+
end
|
217
|
+
|
218
|
+
new_inputs = []
|
219
|
+
@inputs.each_with_index do |input,i|
|
220
|
+
name = @task.inputs[i]
|
221
|
+
type = @task.input_types[name]
|
222
|
+
|
223
|
+
if type == :directory
|
224
|
+
directory_inputs = file('directory_inputs')
|
225
|
+
input_source = directory_inputs['.source'][name].find
|
226
|
+
input_dir = directory_inputs[name].find
|
218
227
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
case input
|
230
|
-
when Path
|
231
|
-
if input.directory?
|
232
|
-
new_inputs << input
|
233
|
-
else
|
234
|
-
input.open do |io|
|
235
|
-
begin
|
236
|
-
Misc.untar(io, input_source)
|
237
|
-
rescue
|
238
|
-
raise ParameterException, "Error unpackaging tar directory input '#{name}':\n\n#{$!.message}"
|
239
|
-
end
|
228
|
+
case input
|
229
|
+
when Path
|
230
|
+
if input.directory?
|
231
|
+
new_inputs << input
|
232
|
+
else
|
233
|
+
input.open do |io|
|
234
|
+
begin
|
235
|
+
Misc.untar(io, input_source)
|
236
|
+
rescue
|
237
|
+
raise ParameterException, "Error unpackaging tar directory input '#{name}':\n\n#{$!.message}"
|
240
238
|
end
|
241
|
-
tar_1 = input_source.glob("*")
|
242
|
-
raise ParameterException, "When using tar.gz files for directories, the directory must be the single first level entry" if tar_1.length != 1
|
243
|
-
FileUtils.ln_s Misc.path_relative_to(directory_inputs, tar_1.first), input_dir
|
244
|
-
new_inputs << input_dir
|
245
|
-
end
|
246
|
-
when File, IO, Tempfile
|
247
|
-
begin
|
248
|
-
Misc.untar(Open.gunzip(input), input_source)
|
249
|
-
rescue
|
250
|
-
raise ParameterException, "Error unpackaging tar directory input '#{name}':\n\n#{$!.message}"
|
251
239
|
end
|
252
240
|
tar_1 = input_source.glob("*")
|
253
241
|
raise ParameterException, "When using tar.gz files for directories, the directory must be the single first level entry" if tar_1.length != 1
|
254
242
|
FileUtils.ln_s Misc.path_relative_to(directory_inputs, tar_1.first), input_dir
|
255
243
|
new_inputs << input_dir
|
256
|
-
else
|
257
|
-
raise ParameterException, "Format of directory input '#{name}' not understood: #{Misc.fingerprint input}"
|
258
244
|
end
|
245
|
+
when File, IO, Tempfile
|
246
|
+
begin
|
247
|
+
Misc.untar(Open.gunzip(input), input_source)
|
248
|
+
rescue
|
249
|
+
raise ParameterException, "Error unpackaging tar directory input '#{name}':\n\n#{$!.message}"
|
250
|
+
end
|
251
|
+
tar_1 = input_source.glob("*")
|
252
|
+
raise ParameterException, "When using tar.gz files for directories, the directory must be the single first level entry" if tar_1.length != 1
|
253
|
+
FileUtils.ln_s Misc.path_relative_to(directory_inputs, tar_1.first), input_dir
|
254
|
+
new_inputs << input_dir
|
259
255
|
else
|
260
|
-
|
256
|
+
raise ParameterException, "Format of directory input '#{name}' not understood: #{Misc.fingerprint input}"
|
261
257
|
end
|
262
|
-
|
258
|
+
else
|
259
|
+
new_inputs << input
|
260
|
+
end
|
261
|
+
end if @inputs
|
263
262
|
|
264
|
-
|
263
|
+
@inputs = new_inputs if @inputs
|
265
264
|
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
end
|
265
|
+
if not task.inputs.nil?
|
266
|
+
info_inputs = @inputs.collect do |i|
|
267
|
+
if Path === i
|
268
|
+
i.to_s
|
269
|
+
else
|
270
|
+
i
|
273
271
|
end
|
274
|
-
set_info :inputs, Misc.remove_long_items(Misc.zip2hash(task.inputs, info_inputs))
|
275
272
|
end
|
273
|
+
set_info :inputs, Misc.remove_long_items(Misc.zip2hash(task.inputs, info_inputs))
|
274
|
+
end
|
276
275
|
|
277
|
-
|
278
|
-
|
276
|
+
set_info :started, (start_time = Time.now)
|
277
|
+
log :started, "Starting step #{Log.color :yellow, task.name.to_s || ""}"
|
279
278
|
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
279
|
+
begin
|
280
|
+
result = _exec
|
281
|
+
rescue Aborted, Interrupt
|
282
|
+
log(:aborted, "Aborted")
|
283
|
+
raise $!
|
284
|
+
rescue Exception
|
285
|
+
backtrace = $!.backtrace
|
286
|
+
|
287
|
+
# HACK: This fixes an strange behaviour in 1.9.3 where some
|
288
|
+
# backtrace strings are coded in ASCII-8BIT
|
289
|
+
backtrace.each{|l| l.force_encoding("UTF-8")} if String.instance_methods.include? :force_encoding
|
290
|
+
set_info :backtrace, backtrace
|
291
|
+
log(:error, "#{$!.class}: #{$!.message}")
|
292
|
+
stop_dependencies
|
293
|
+
raise $!
|
294
|
+
end
|
296
295
|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
296
|
+
if not no_load or ENV["RBBT_NO_STREAM"] == "true"
|
297
|
+
result = prepare_result result, @task.description, info if IO === result
|
298
|
+
result = prepare_result result.stream, @task.description, info if TSV::Dumper === result
|
299
|
+
end
|
301
300
|
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
end
|
319
|
-
end
|
320
|
-
begin
|
321
|
-
status = self.status
|
322
|
-
if status != :done and status != :error and status != :aborted
|
323
|
-
Misc.insist do
|
324
|
-
merge_info({
|
325
|
-
:done => (done_time = Time.now),
|
326
|
-
:total_time_elapsed => (total_time_elapsed = done_time - issue_time),
|
327
|
-
:time_elapsed => (time_elapsed = done_time - start_time)
|
328
|
-
})
|
329
|
-
log :done, "Completed step #{Log.color :yellow, task.name.to_s || ""} in #{time_elapsed.to_i}+#{(total_time_elapsed - time_elapsed).to_i} sec."
|
330
|
-
end
|
331
|
-
end
|
332
|
-
rescue
|
333
|
-
Log.exception $!
|
334
|
-
ensure
|
335
|
-
Step.purge_stream_cache
|
336
|
-
set_info :pid, nil
|
337
|
-
FileUtils.rm pid_file if File.exist?(pid_file)
|
301
|
+
stream = case result
|
302
|
+
when IO
|
303
|
+
result
|
304
|
+
when TSV::Dumper
|
305
|
+
result.stream
|
306
|
+
end
|
307
|
+
|
308
|
+
if stream
|
309
|
+
log :streaming, "Streaming step #{Log.color :yellow, task.name.to_s || ""}"
|
310
|
+
|
311
|
+
callback = Proc.new do
|
312
|
+
if AbortedStream === stream
|
313
|
+
if stream.exception
|
314
|
+
raise stream.exception
|
315
|
+
else
|
316
|
+
raise Aborted
|
338
317
|
end
|
339
318
|
end
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
319
|
+
begin
|
320
|
+
status = self.status
|
321
|
+
if status != :done and status != :error and status != :aborted
|
322
|
+
Misc.insist do
|
323
|
+
merge_info({
|
324
|
+
:done => (done_time = Time.now),
|
325
|
+
:total_time_elapsed => (total_time_elapsed = done_time - issue_time),
|
326
|
+
:time_elapsed => (time_elapsed = done_time - start_time)
|
327
|
+
})
|
328
|
+
log :done, "Completed step #{Log.color :yellow, task.name.to_s || ""} in #{time_elapsed.to_i}+#{(total_time_elapsed - time_elapsed).to_i} sec."
|
347
329
|
end
|
348
|
-
_clean_finished
|
349
|
-
rescue
|
350
|
-
stop_dependencies
|
351
|
-
set_info :pid, nil
|
352
|
-
FileUtils.rm pid_file if File.exist?(pid_file)
|
353
330
|
end
|
331
|
+
rescue
|
332
|
+
Log.exception $!
|
333
|
+
ensure
|
334
|
+
Step.purge_stream_cache
|
335
|
+
set_info :pid, nil
|
336
|
+
FileUtils.rm pid_file if File.exist?(pid_file)
|
354
337
|
end
|
338
|
+
end
|
355
339
|
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
340
|
+
abort_callback = Proc.new do |exception|
|
341
|
+
begin
|
342
|
+
if exception
|
343
|
+
self.exception exception
|
344
|
+
else
|
345
|
+
log :aborted, "#{Log.color :red, "Aborted"} step #{Log.color :yellow, task.name.to_s || ""}" if status == :streaming
|
346
|
+
end
|
361
347
|
_clean_finished
|
362
|
-
|
348
|
+
rescue
|
349
|
+
stop_dependencies
|
350
|
+
set_info :pid, nil
|
351
|
+
FileUtils.rm pid_file if File.exist?(pid_file)
|
363
352
|
end
|
364
|
-
else
|
365
|
-
merge_info({
|
366
|
-
:done => (done_time = Time.now),
|
367
|
-
:total_time_elapsed => (total_time_elapsed = done_time - issue_time),
|
368
|
-
:time_elapsed => (time_elapsed = done_time - start_time)
|
369
|
-
})
|
370
|
-
log :ending
|
371
|
-
Step.purge_stream_cache
|
372
|
-
FileUtils.rm pid_file if File.exist?(pid_file)
|
373
353
|
end
|
374
354
|
|
375
|
-
|
355
|
+
ConcurrentStream.setup stream, :callback => callback, :abort_callback => abort_callback
|
376
356
|
|
377
|
-
if
|
378
|
-
|
357
|
+
if AbortedStream === stream
|
358
|
+
exception = stream.exception || Aborted.new("Aborted stream: #{Misc.fingerprint stream}")
|
359
|
+
self.exception exception
|
360
|
+
_clean_finished
|
361
|
+
raise exception
|
379
362
|
end
|
380
|
-
|
363
|
+
else
|
364
|
+
merge_info({
|
365
|
+
:done => (done_time = Time.now),
|
366
|
+
:total_time_elapsed => (total_time_elapsed = done_time - issue_time),
|
367
|
+
:time_elapsed => (time_elapsed = done_time - start_time)
|
368
|
+
})
|
369
|
+
log :ending
|
370
|
+
Step.purge_stream_cache
|
371
|
+
FileUtils.rm pid_file if File.exist?(pid_file)
|
381
372
|
end
|
382
|
-
|
373
|
+
|
374
|
+
set_info :dependencies, dependencies.collect{|dep| [dep.task_name, dep.name, dep.path]}
|
375
|
+
|
376
|
+
if result.nil? && File.exists?(self.tmp_path) && ! File.exists?(self.path)
|
377
|
+
FileUtils.mv self.tmp_path, self.path
|
378
|
+
end
|
379
|
+
result
|
380
|
+
end # END PERSIST
|
381
|
+
log :done, "Completed step #{Log.color :yellow, task.name.to_s || ""} in #{time_elapsed.to_i}+#{(total_time_elapsed - time_elapsed).to_i} sec." unless stream or time_elapsed.nil?
|
383
382
|
|
384
383
|
if no_load
|
385
384
|
@result ||= result
|
@@ -388,8 +387,7 @@ class Step
|
|
388
387
|
Step.purge_stream_cache
|
389
388
|
@result = prepare_result result, @task.result_description
|
390
389
|
end
|
391
|
-
end
|
392
|
-
log :done, "Completed step #{Log.color :yellow, task.name.to_s || ""} in #{time_elapsed.to_i}+#{(total_time_elapsed - time_elapsed).to_i} sec." unless stream or time_elapsed.nil?
|
390
|
+
end # END SYNC
|
393
391
|
res
|
394
392
|
rescue DependencyError
|
395
393
|
exception $!
|
@@ -409,9 +407,8 @@ class Step
|
|
409
407
|
def produce(force=false, dofork=false)
|
410
408
|
return self if done? and not dirty?
|
411
409
|
|
412
|
-
|
413
410
|
self.status_lock.synchronize do
|
414
|
-
if error?
|
411
|
+
if error? || aborted? || stalled?
|
415
412
|
if stalled?
|
416
413
|
Log.warn "Aborting stalled job #{self.path}"
|
417
414
|
abort
|
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.23.
|
4
|
+
version: 5.23.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miguel Vazquez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|