rbbt-util 5.13.2 → 5.13.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 52c2b4f2b6f065da491646388575b22ffccddee4
4
- data.tar.gz: 48c8543fb121288f15a998bf4ce0237e56bdc2a8
3
+ metadata.gz: 715d410e93dddd02e14dd6d04f31917470c10b3d
4
+ data.tar.gz: 473271c8efe67c3465b204078d228618bedbc327
5
5
  SHA512:
6
- metadata.gz: b218fc2960eb7f021d8628fa08b5363362efdc6bbf4b04ea1002140dcdf93dd7556f39f6265d77c8d35c3c234a0ecedcfe94197499ea080c663249d748ef963e
7
- data.tar.gz: 3562d3fb1ccbf97705e4923642814b2c4519942c89dcfc97d9cc74802a220e32c338f2bfce65d689dffc0b35e99982f817236a75b67a0ebc8faeda7b5b516024
6
+ metadata.gz: 3412998c1d2dce774a3d3a6a41428ab4506a6de2480b73be70890ae97d62be4285d1854881f6af92a551098c93e7b2dc62aaa8867a199e9ad26b3d991a213667
7
+ data.tar.gz: fb333f016809936f1ab2a928934683a3759a16d5ff3238e088535a7802f62566a732bfc7e7b0e3a7d638ebaa978b6dad6856ef2f3d5795f068213c5c14751e3a
data/lib/rbbt/persist.rb CHANGED
@@ -202,7 +202,6 @@ module Persist
202
202
  rescue Aborted
203
203
  Log.warn "Persist stream thread aborted: #{ Log.color :blue, path }"
204
204
  file.abort if file.respond_to? :abort
205
- parent.raise $!
206
205
  rescue Exception
207
206
  Log.warn "Persist stream thread exception: #{ Log.color :blue, path }"
208
207
  file.abort if file.respond_to? :abort
@@ -284,7 +283,7 @@ module Persist
284
283
  res = tee_stream(res, path, type, res.respond_to?(:callback)? res.callback : nil)
285
284
  ConcurrentStream.setup res do
286
285
  begin
287
- lockfile.unlock if lockfile.locked?
286
+ lockfile.unlock if File.exists? lockfile.path and lockfile.locked?
288
287
  rescue
289
288
  Log.exception $!
290
289
  Log.warn "Lockfile exception: " << $!.message
@@ -292,7 +291,7 @@ module Persist
292
291
  end
293
292
  res.abort_callback = Proc.new do
294
293
  begin
295
- lockfile.unlock if lockfile.locked?
294
+ lockfile.unlock if File.exists? lockfile.path and lockfile.locked?
296
295
  rescue
297
296
  Log.exception $!
298
297
  Log.warn "Lockfile exception: " << $!.message
@@ -303,7 +302,7 @@ module Persist
303
302
  res = tee_stream(res.stream, path, type, res.respond_to?(:callback)? res.callback : nil)
304
303
  ConcurrentStream.setup res do
305
304
  begin
306
- lockfile.unlock if lockfile.locked?
305
+ lockfile.unlock if File.exists? lockfile.path and lockfile.locked?
307
306
  rescue
308
307
  Log.exception $!
309
308
  Log.warn "Lockfile exception: " << $!.message
@@ -311,7 +310,7 @@ module Persist
311
310
  end
312
311
  res.abort_callback = Proc.new do
313
312
  begin
314
- lockfile.unlock if lockfile.locked?
313
+ lockfile.unlock if File.exists? lockfile.path and lockfile.locked?
315
314
  rescue
316
315
  Log.exception $!
317
316
  Log.warn "Lockfile exception: " << $!.message
@@ -10,7 +10,29 @@ module TSV
10
10
  end
11
11
  end
12
12
 
13
+ def self.guess_max(obj)
14
+ begin
15
+ case obj
16
+ when Step
17
+ if obj.done?
18
+ CMD.cmd("wc -l '#{obj.path.find}'").read.to_i
19
+ else
20
+ nil
21
+ end
22
+ when Array, Hash
23
+ obj.size
24
+ when File
25
+ CMD.cmd("wc -l '#{obj.filename}'").read.to_i
26
+ when Path
27
+ CMD.cmd("wc -l '#{obj.find}'").read.to_i
28
+ end
29
+ rescue
30
+ nil
31
+ end
32
+ end
33
+
13
34
  def self.stream_name(obj)
35
+ return "nil" if obj.nil?
14
36
  filename_obj = obj.respond_to?(:filename) ? obj.filename : nil
15
37
  filename_obj ||= obj.respond_to?(:path) ? obj.path : nil
16
38
  stream_obj = obj_stream(obj) || obj
@@ -149,7 +171,6 @@ module TSV
149
171
 
150
172
  Log.medium "Traversing #{stream_name(obj)} #{Log.color :green, "->"} #{stream_name(options[:into])}"
151
173
  begin
152
- sleep 1
153
174
  case obj
154
175
  when TSV
155
176
  traverse_tsv(obj, options, &block)
@@ -173,7 +194,6 @@ module TSV
173
194
  end
174
195
  rescue Aborted
175
196
  obj.abort if obj.respond_to? :abort
176
- raise $!
177
197
  rescue Exception
178
198
  obj.abort if obj.respond_to? :abort
179
199
  raise $!
@@ -216,20 +236,28 @@ module TSV
216
236
  Log.warn "IOError traversing #{stream_name(obj)}: #{$!.message}"
217
237
  stream = obj_stream(obj)
218
238
  stream.abort if stream and stream.respond_to? :abort
239
+ stream = obj_stream(options[:into])
240
+ stream.abort if stream.respond_to? :abort
219
241
  raise $!
220
242
  rescue Errno::EPIPE
221
243
  Log.warn "Pipe closed while traversing #{stream_name(obj)}: #{$!.message}"
244
+ stream = obj_stream(obj)
245
+ stream.abort if stream and stream.respond_to? :abort
246
+ stream = obj_stream(options[:into])
247
+ stream.abort if stream.respond_to? :abort
222
248
  raise $!
223
249
  rescue Aborted
224
250
  Log.warn "Aborted traversing #{stream_name(obj)}"
225
251
  stream = obj_stream(obj)
226
252
  stream.abort if stream and stream.respond_to? :abort
227
- raise $!
253
+ stream = obj_stream(options[:into])
254
+ stream.abort if stream.respond_to? :abort
228
255
  rescue Exception
229
256
  Log.warn "Exception traversing #{stream_name(obj)}"
230
- Log.exception $!
231
257
  stream = obj_stream(obj)
232
258
  stream.abort if stream and stream.respond_to? :abort
259
+ stream = obj_stream(options[:into])
260
+ stream.abort if stream.respond_to? :abort
233
261
  raise $!
234
262
  end
235
263
  end
@@ -263,40 +291,38 @@ module TSV
263
291
  def self.traverse_cpus(num, obj, options, &block)
264
292
  begin
265
293
  callback, cleanup, join = Misc.process_options options, :callback, :cleanup, :join
266
- q = RbbtProcessQueue.new num, cleanup, join
267
294
 
268
- q.callback &callback
269
- q.init &block
295
+ begin
296
+ q = RbbtProcessQueue.new num, cleanup, join
297
+ q.callback &callback
298
+ q.init &block
270
299
 
271
- thread = Thread.new do
272
300
  traverse_obj(obj, options) do |*p|
273
301
  q.process *p
274
302
  end
275
- end
276
-
277
- begin
278
- thread.join
279
- rescue
303
+ rescue Aborted, Errno::EPIPE
304
+ Log.warn "Aborted"
305
+ rescue Exception
306
+ Log.exception $!
280
307
  raise $!
308
+ ensure
309
+ q.join
281
310
  end
282
311
  rescue Interrupt, Aborted
283
- Log.warn "Aborted traversal in CPUs for #{stream_name(obj) || Misc.fingerprint(obj)}"
312
+ Log.warn "Aborted traversal in CPUs for #{stream_name(obj) || Misc.fingerprint(obj)}: #{$!.backtrace*","}"
313
+ q.abort
284
314
  stream = obj_stream(obj)
285
315
  stream.abort if stream.respond_to? :abort
286
316
  stream = obj_stream(options[:into])
287
317
  stream.abort if stream.respond_to? :abort
288
- q.abort
289
- raise $!
318
+ raise "Traversal aborted"
290
319
  rescue Exception
291
- Log.warn "Exception during traversal in CPUs for #{stream_name(obj) || Misc.fingerprint(obj)}"
320
+ Log.warn "Exception during traversal in CPUs for #{stream_name(obj) || Misc.fingerprint(obj)}: #{$!.message}"
292
321
  stream = obj_stream(obj)
293
322
  stream.abort if stream.respond_to? :abort
294
323
  stream = obj_stream(options[:into])
295
324
  stream.abort if stream.respond_to? :abort
296
- q.abort
297
325
  raise $!
298
- ensure
299
- q.join
300
326
  end
301
327
  end
302
328
 
@@ -326,8 +352,15 @@ module TSV
326
352
  store << value
327
353
  end
328
354
  true
329
- rescue
330
- raise "Error storing into #{store.inspect}: #{$!.message}"
355
+ rescue Aborted, Interrupt
356
+ Log.warn "Aborted storing into #{Misc.fingerprint store}: #{$!.message}"
357
+ stream = obj_stream(store)
358
+ stream.abort if stream.respond_to? :abort
359
+ rescue Exception
360
+ stream = obj_stream(store)
361
+ stream.abort if stream.respond_to? :abort
362
+ Log.exception $!
363
+ raise $!
331
364
  end
332
365
  end
333
366
 
@@ -423,15 +456,16 @@ module TSV
423
456
 
424
457
  bar = Misc.process_options options, :bar
425
458
  bar ||= Misc.process_options options, :progress
459
+ max = guess_max(obj)
426
460
  options[:bar] = case bar
427
461
  when String
428
- Log::ProgressBar.new_bar(nil, {:desc => bar})
462
+ Log::ProgressBar.new_bar(max, {:desc => bar})
429
463
  when TrueClass
430
- Log::ProgressBar.new_bar(nil, nil)
464
+ Log::ProgressBar.new_bar(max, nil)
431
465
  when Fixnum
432
466
  Log::ProgressBar.new_bar(bar)
433
467
  when Hash
434
- max = Misc.process_options bar, :max
468
+ max = Misc.process_options(bar, :max) || max
435
469
  Log::ProgressBar.new_bar(max, bar)
436
470
  else
437
471
  bar
@@ -448,10 +482,10 @@ module TSV
448
482
  begin
449
483
  store_into into, e
450
484
  rescue Aborted
451
- raise $!
485
+ Log.warn "Aborted callback #{stream_name(obj)} #{Log.color :green, "->"} #{stream_name(options[:into])}"
452
486
  rescue Exception
487
+ Log.warn "Exception callback #{stream_name(obj)} #{Log.color :green, "->"} #{stream_name(options[:into])}"
453
488
  Log.exception $!
454
- raise $!
455
489
  ensure
456
490
  bar.tick if bar
457
491
  end
@@ -537,12 +537,11 @@ module TSV
537
537
  break
538
538
  rescue Errno::EPIPE
539
539
  Log.error "Pipe closed while parsing #{Misc.fingerprint stream}: #{$!.message}"
540
+ stream.abort if stream.respond_to? :abort
540
541
  raise $!
541
542
  rescue Exception
542
543
  Log.error "Exception parsing #{Misc.fingerprint stream}: #{$!.message}"
543
- Log.exception $!
544
544
  stream.abort if stream.respond_to? :abort
545
- stream.join if stream.respond_to? :join
546
545
  raise $!
547
546
  end
548
547
  end
@@ -130,7 +130,7 @@ module TSV
130
130
  end
131
131
  if line.nil?
132
132
  stream = streams[i]
133
- #stream.join if stream.respond_to? :join
133
+ stream.join if stream.respond_to? :join
134
134
  keys[i] = nil
135
135
  parts[i] = nil
136
136
  else
@@ -146,12 +146,13 @@ module TSV
146
146
  sin.puts [min, str*sep] * sep
147
147
  end
148
148
  streams.each do |stream|
149
- #stream.join if stream.respond_to? :join
149
+ stream.join if stream.respond_to? :join
150
150
  end
151
- rescue
152
- Log.exception $!
151
+ rescue Exception
153
152
  streams.each do |stream|
154
- stream.abort if stream.respond_to? :abort
153
+ Thread.new do
154
+ stream.abort if stream.respond_to? :abort
155
+ end
155
156
  end
156
157
  raise $!
157
158
  end
@@ -29,11 +29,14 @@ class RbbtProcessQueue
29
29
  @callback.call p
30
30
  end
31
31
  rescue Aborted
32
- parent.raise $!
32
+ Log.warn "Callback thread aborted"
33
+ @process_monitor.raise Aborted.new
34
+ raise $!
33
35
  rescue ClosedStream
34
36
  rescue Exception
35
- Log.warn "Callback thread exception"
36
- parent.raise $!
37
+ Log.warn "Callback thread exception: #{$!.message}"
38
+ @process_monitor.raise $!
39
+ raise $!
37
40
  ensure
38
41
  @callback_queue.sread.close unless @callback_queue.sread.closed?
39
42
  end
@@ -56,14 +59,14 @@ class RbbtProcessQueue
56
59
  @processes.shift
57
60
  end
58
61
  rescue Aborted
62
+ Log.warn "Aborting process monitor"
59
63
  @processes.each{|p| p.abort }
60
64
  @processes.each{|p| p.join }
61
- Log.warn "Process monitor aborted"
62
65
  rescue Exception
63
66
  Log.warn "Process monitor exception: #{$!.message}"
64
67
  @processes.each{|p| p.abort }
65
- @callback_thread.raise $! if @callback_thread
66
- parent.raise $!
68
+ @callback_thread.raise $! if @callback_thread and @callback_thread.alive?
69
+ raise $!
67
70
  end
68
71
  end
69
72
  end
@@ -71,22 +74,25 @@ class RbbtProcessQueue
71
74
  def close_callback
72
75
  begin
73
76
  @callback_queue.push ClosedStream.new if @callback_thread.alive?
74
- rescue
77
+ rescue Exception
75
78
  Log.warn "Error closing callback: #{$!.message}"
76
79
  end
77
- @callback_thread.join if @callback_thread.alive?
80
+ @callback_thread.join #if @callback_thread.alive?
78
81
  end
79
82
 
80
83
  def join
81
- @processes.length.times do
82
- @queue.push ClosedStream.new
83
- end if @process_monitor.alive?
84
+ begin
85
+ @processes.length.times do
86
+ @queue.push ClosedStream.new
87
+ end if @process_monitor.alive?
88
+ rescue Exception
89
+ end
84
90
 
85
91
  begin
86
92
  @process_monitor.join
87
93
  close_callback if @callback
88
94
  rescue Exception
89
- Log.exception $!
95
+ Log.error "Exception joining queue: #{$!.message}"
90
96
  raise $!
91
97
  ensure
92
98
  @queue.swrite.close unless @queue.swrite.closed?
@@ -113,7 +119,11 @@ class RbbtProcessQueue
113
119
  end
114
120
 
115
121
  def process(*e)
116
- @queue.push e
122
+ begin
123
+ @queue.push e
124
+ rescue Errno::EPIPE
125
+ raise Aborted
126
+ end
117
127
  end
118
128
 
119
129
  def self.each(list, num = 3, &block)
@@ -35,7 +35,6 @@ class RbbtProcessQueue
35
35
  Log.warn "Worker #{Process.pid} aborted"
36
36
  Kernel.exit! -1
37
37
  rescue Exception
38
- Log.exception $!
39
38
  @callback_queue.push($!) if @callback_queue
40
39
  Kernel.exit! -1
41
40
  ensure
@@ -45,10 +44,7 @@ class RbbtProcessQueue
45
44
  end
46
45
 
47
46
  def join
48
- begin
49
- joined_pid = Process.waitpid @pid
50
- rescue
51
- end
47
+ joined_pid = Process.waitpid @pid
52
48
  end
53
49
 
54
50
  def abort
@@ -103,7 +103,10 @@ module Log
103
103
  end
104
104
 
105
105
  def thr
106
- @last_report = Time.now if @last_report == -1
106
+ if @last_report == -1
107
+ @last_report = Time.now
108
+ return thr
109
+ end
107
110
  time = Time.now - @last_report
108
111
  time = 0.000001 if time == 0
109
112
  thr = (@current / time).to_i
@@ -140,6 +143,10 @@ module Log
140
143
  indicator
141
144
  end
142
145
 
146
+ def msg
147
+ @max ? report_msg : throughput_msg
148
+ end
149
+
143
150
  def print(io, str)
144
151
  LOG_MUTEX.synchronize do
145
152
  STDERR.print str
@@ -153,9 +160,9 @@ module Log
153
160
  # original line. Everything is printed to stderr.
154
161
  def report(io = STDERR)
155
162
  if Log::LAST != "progress"
156
- Log::ProgressBar.cleanup_bars
157
- print(io, Log.color(:yellow, "== Progress"))
158
- (BARS.length-1).times{print(io, "\n")}
163
+ Log::LAST.replace "progress"
164
+ length = Log::ProgressBar.cleanup_bars
165
+ length.times{print(io, "\n")}
159
166
  end
160
167
  print(io, up_lines(@depth) << report_msg << down_lines(@depth)) if severity >= Log.severity
161
168
  @last_report = Time.now if @last_report == -1
@@ -163,9 +170,9 @@ module Log
163
170
 
164
171
  def throughput(io = STDERR)
165
172
  if Log::LAST != "progress"
166
- Log::ProgressBar.cleanup_bars
167
- print(io, Log.color(:yellow, "== Progress"))
168
- (BARS.length-1).times{print(io, "\n")}
173
+ Log::LAST.replace "progress"
174
+ length = Log::ProgressBar.cleanup_bars
175
+ length.times{print(io, "\n")}
169
176
  end
170
177
  print(io, up_lines(@depth) << throughput_msg << down_lines(@depth)) if severity >= Log.severity
171
178
  @last_report = Time.now
@@ -173,6 +180,11 @@ module Log
173
180
  end
174
181
 
175
182
  def done
183
+ if Log::LAST != "progress"
184
+ Log::LAST.replace "progress"
185
+ length = Log::ProgressBar.cleanup_bars
186
+ length.times{print(io, "\n")}
187
+ end
176
188
  print(io, up_lines(@depth) << Log.color(:magenta, @desc) << Log.color(:green, " DONE") << down_lines(@depth)) if severity >= Log.severity
177
189
  end
178
190
 
@@ -193,22 +205,22 @@ module Log
193
205
  REMOVE.each do |bar|
194
206
  index = BARS.index bar
195
207
  if index
196
- (index..BARS.length-1).each do |pos|
197
- bar = BARS[pos]
198
- bar.depth = pos - 1
199
- BARS[pos-1] = bar
200
- end
201
- BARS.pop
208
+ BARS.delete_at index
209
+ BARS.each_with_index do |bar,i|
210
+ bar.depth = i
211
+ end
202
212
  end
203
213
  end
204
214
  REMOVE.clear
215
+ BARS.length
205
216
  end
206
217
  end
207
218
 
208
219
  def self.remove_bar(bar)
220
+ bar.done unless bar.max
209
221
  BAR_MUTEX.synchronize do
210
- bar.done unless bar.max
211
222
  REMOVE << bar
223
+ Log::LAST.replace "remove"
212
224
  end
213
225
  end
214
226
 
@@ -220,7 +232,7 @@ module Log
220
232
  rescue KeepBar
221
233
  keep = true
222
234
  ensure
223
- remove_bar(bar) unless bar
235
+ remove_bar(bar) if bar
224
236
  end
225
237
  end
226
238
  end
@@ -1,5 +1,5 @@
1
1
  module ConcurrentStream
2
- attr_accessor :threads, :pids, :callback, :abort_callback, :filename, :joined, :autojoin
2
+ attr_accessor :threads, :pids, :callback, :abort_callback, :filename, :joined, :aborted, :autojoin
3
3
 
4
4
  def self.setup(stream, options = {}, &block)
5
5
  threads, pids, callback, filename, autojoin = Misc.process_options options, :threads, :pids, :callback, :filename, :autojoin
@@ -46,6 +46,10 @@ module ConcurrentStream
46
46
  @joined
47
47
  end
48
48
 
49
+ def aborted?
50
+ @aborted
51
+ end
52
+
49
53
  def join_threads
50
54
  if @threads and @threads.any?
51
55
  @threads.each do |t|
@@ -97,11 +101,16 @@ module ConcurrentStream
97
101
  end
98
102
 
99
103
  def abort
100
- abort_threads
101
- abort_pids
102
- @abort_callback.call if @abort_callback
103
- @abort_callback = nil
104
- @callback = nil
104
+ return if @aborted
105
+ begin
106
+ abort_threads
107
+ abort_pids
108
+ @abort_callback.call if @abort_callback
109
+ ensure
110
+ @abort_callback = nil
111
+ @callback = nil
112
+ @aborted = true
113
+ end
105
114
  end
106
115
 
107
116
  def super(*args)
@@ -47,8 +47,9 @@ module Misc
47
47
  lockfile.unlock if lockfile.locked?
48
48
  raise $!
49
49
  ensure
50
- if unlock and lockfile.locked?
51
- lockfile.unlock
50
+ if unlock
51
+ lockfile.unlock if lockfile.locked?
52
+ FileUtils.rm lock_path if File.exists? lock_path
52
53
  end
53
54
  end
54
55
 
@@ -73,45 +73,6 @@ module Misc
73
73
  sout
74
74
  end
75
75
 
76
- #def self.tee_stream_fork(stream)
77
- # stream_out1, stream_in1 = Misc.pipe
78
- # stream_out2, stream_in2 = Misc.pipe
79
-
80
- # splitter_pid = Process.fork do
81
- # Misc.purge_pipes(stream_in1, stream_in2)
82
- # stream_out1.close
83
- # stream_out2.close
84
- # begin
85
- # filename = stream.respond_to?(:filename)? stream.filename : nil
86
- # skip1 = skip2 = false
87
- # while block = stream.read(2048)
88
- # begin stream_in1.write block; rescue Exception; Log.exception $!; skip1 = true end unless skip1
89
- # begin stream_in2.write block; rescue Exception; Log.exception $!; skip2 = true end unless skip2
90
- # end
91
- # raise "Error writing in stream_in1" if skip1
92
- # raise "Error writing in stream_in2" if skip2
93
- # stream.join if stream.respond_to? :join
94
- # stream_in1.close
95
- # stream_in2.close
96
- # rescue Aborted
97
- # stream.abort if stream.respond_to? :abort
98
- # raise $!
99
- # rescue IOError
100
- # Log.exception $!
101
- # rescue Exception
102
- # Log.exception $!
103
- # end
104
- # end
105
- # stream.close
106
- # stream_in1.close
107
- # stream_in2.close
108
-
109
- # ConcurrentStream.setup stream_out1, :pids => [splitter_pid]
110
- # ConcurrentStream.setup stream_out2, :pids => [splitter_pid]
111
-
112
- # [stream_out1, stream_out2]
113
- #end
114
-
115
76
  def self.tee_stream_thread(stream)
116
77
  stream_out1, stream_in1 = Misc.pipe
117
78
  stream_out2, stream_in2 = Misc.pipe
@@ -139,11 +100,14 @@ module Misc
139
100
  stream_in2.close unless stream_in2.closed?
140
101
  stream.join if stream.respond_to? :join
141
102
  rescue Aborted, Interrupt
142
- Log.warn("Tee stream #{Misc.fingerprint stream} Aborted");
143
- stream.abort if stream.respond_to? :abort
103
+ begin
104
+ stream.abort if stream.respond_to? :abort
105
+ rescue
106
+ Log.exception $!
107
+ end
144
108
  rescue Exception
145
109
  Log.exception $!
146
- parent.raise $!
110
+ stream.abort if stream.respond_to? :abort
147
111
  end
148
112
  end
149
113
 
@@ -186,14 +150,17 @@ module Misc
186
150
  else
187
151
  begin
188
152
  while block = io.read(2048)
189
- return if io.eof?
190
- Thread.pass
153
+ #return if io.eof?
154
+ #Thread.pass
191
155
  end
192
156
  io.join if io.respond_to? :join
193
- rescue IOError
194
- rescue
195
- Log.warn "Exception consuming stream: #{io.inspect}"
157
+ rescue Aborted
158
+ Log.warn "Consume stream aborted #{Misc.fingerprint io}"
196
159
  io.abort if io.respond_to? :abort
160
+ rescue Exception
161
+ Log.warn "Exception consuming stream: #{Misc.fingerprint io}: #{$!.message}"
162
+ io.abort if io.respond_to? :abort
163
+ raise $!
197
164
  end
198
165
  end
199
166
  end
@@ -244,11 +211,10 @@ module Misc
244
211
  rescue Aborted
245
212
  Log.warn "Aborted sensiblewrite -- #{ Log.reset << Log.color(:blue, path) }"
246
213
  content.abort if content.respond_to? :abort
247
- content.join if content.respond_to? :join
214
+ Open.rm_f path if File.exists? path
248
215
  rescue Exception
249
216
  Log.warn "Exception in sensiblewrite: #{$!.message} -- #{ Log.color :blue, path }"
250
217
  content.abort if content.respond_to? :abort
251
- content.join if content.respond_to? :join
252
218
  Open.rm_f path if File.exists? path
253
219
  raise $!
254
220
  ensure
data/lib/rbbt/workflow.rb CHANGED
@@ -7,6 +7,8 @@ require 'rbbt/workflow/examples'
7
7
 
8
8
  module Workflow
9
9
 
10
+ STEP_CACHE = {}
11
+
10
12
  class TaskNotFoundException < Exception
11
13
  def initialize(workflow, task = nil)
12
14
  if task
@@ -184,7 +186,7 @@ module Workflow
184
186
  end
185
187
 
186
188
  def step_cache
187
- @step_cache ||= {}
189
+ @step_cache ||= Workflow::STEP_CACHE
188
190
  end
189
191
 
190
192
 
@@ -236,7 +238,7 @@ module Workflow
236
238
  step_path = step_path.call if Proc === step_path
237
239
  persist = input_values.nil? ? false : true
238
240
  key = Path === step_path ? step_path.find : step_path
239
- step = Persist.memory("Step", :key => key, :repo => step_cache, :persist => persist ) do
241
+ step = Persist.memory("Step", :key => key, :repo => step_cache, :persist => persist) do
240
242
  step = Step.new step_path, task, input_values, dependencies
241
243
 
242
244
  helpers.each do |name, block|
@@ -244,8 +246,8 @@ module Workflow
244
246
  define_method name, &block
245
247
  end
246
248
  end
247
- step
248
249
 
250
+ step
249
251
  end
250
252
 
251
253
  step.task ||= task
@@ -71,23 +71,24 @@ class Step
71
71
  case
72
72
  when IO === value
73
73
  begin
74
- case @task.result_type
75
- when :array
76
- array = []
77
- while line = value.gets
78
- array << line.strip
79
- end
80
- array
81
- when :tsv
82
- TSV.open(value)
83
- else
84
- value.read
85
- end
74
+ res = case @task.result_type
75
+ when :array
76
+ array = []
77
+ while line = value.gets
78
+ array << line.strip
79
+ end
80
+ array
81
+ when :tsv
82
+ TSV.open(value)
83
+ else
84
+ value.read
85
+ end
86
+ value.join if value.respond_to? :join
87
+ res
86
88
  rescue Exception
87
89
  value.abort if value.respond_to? :abort
88
- ensure
89
- value.join if value.respond_to? :join
90
- value.close unless value.closed?
90
+ self.abort
91
+ raise $!
91
92
  end
92
93
  when (not defined? Entity or description.nil? or not Entity.formats.include? description)
93
94
  value
@@ -1,6 +1,6 @@
1
1
  class Step
2
2
 
3
- attr_reader :stream, :dupped
3
+ attr_reader :stream, :dupped, :saved_stream
4
4
 
5
5
  STREAM_CACHE = {}
6
6
  STREAM_CACHE_MUTEX = Mutex.new
@@ -67,7 +67,7 @@ class Step
67
67
  @mutex.synchronize do
68
68
  begin
69
69
  if IO === @result
70
- @result
70
+ @saved_stream = @result
71
71
  else
72
72
  nil
73
73
  end
@@ -146,15 +146,23 @@ class Step
146
146
  unless dependency.result or dependency.done?
147
147
  dependency.run(true)
148
148
  end
149
- rescue Aborted, Interrupt
149
+ rescue Aborted
150
150
  backtrace = $!.backtrace
151
151
  set_info :backtrace, backtrace
152
152
  log(:error, "Aborted dependency #{Log.color :yellow, dependency.task.name.to_s}")
153
+ self.abort
154
+ raise $!
155
+ rescue Interrupt
156
+ backtrace = $!.backtrace
157
+ set_info :backtrace, backtrace
158
+ log(:error, "Interrupted dependency #{Log.color :yellow, dependency.task.name.to_s}")
159
+ self.abort
153
160
  raise $!
154
161
  rescue Exception
155
162
  backtrace = $!.backtrace
156
163
  set_info :backtrace, backtrace
157
164
  log(:error, "Exception processing dependency #{Log.color :yellow, dependency.task.name.to_s} -- #{$!.class}: #{$!.message}")
165
+ self.abort
158
166
  raise $!
159
167
  end
160
168
  end
@@ -163,8 +171,8 @@ class Step
163
171
  def run(no_load = false)
164
172
  result = nil
165
173
 
166
- begin
167
- @mutex.synchronize do
174
+ @mutex.synchronize do
175
+ begin
168
176
  no_load = no_load ? :stream : false
169
177
  result = Persist.persist "Job", @task.result_type, :file => path, :check => checks, :no_load => no_load do |lockfile|
170
178
  if Step === Step.log_relay_step and not self == Step.log_relay_step
@@ -198,19 +206,18 @@ class Step
198
206
  begin
199
207
  result = _exec
200
208
  rescue Aborted
209
+ stop_dependencies
201
210
  log(:error, "Aborted")
202
-
203
- kill_children
204
211
  raise $!
205
212
  rescue Exception
206
213
  backtrace = $!.backtrace
207
214
 
208
215
  # HACK: This fixes an strange behaviour in 1.9.3 where some
209
216
  # backtrace strings are coded in ASCII-8BIT
210
- kill_children
211
217
  set_info :backtrace, backtrace
212
218
  log(:error, "#{$!.class}: #{$!.message}")
213
219
  backtrace.each{|l| l.force_encoding("UTF-8")} if String.instance_methods.include? :force_encoding
220
+ stop_dependencies
214
221
  raise $!
215
222
  end
216
223
 
@@ -260,13 +267,9 @@ class Step
260
267
  end
261
268
  result.stream.abort_callback = Proc.new do
262
269
  begin
263
- log :error, "#{Log.color :red, "ERROR -- streamming aborted"} #{Log.color :yellow, task.name.to_s || ""} [#{Process.pid}] -- #{path}" if status == :streaming
264
270
  stop_dependencies
265
- abort_stream
266
- rescue
267
- Log.exception $!
268
- ensure
269
- join
271
+ log :error, "#{Log.color :red, "ERROR -- streamming aborted"} #{Log.color :yellow, task.name.to_s || ""} [#{Process.pid}] -- #{path}" if status == :streaming
272
+ rescue Exception
270
273
  end
271
274
  end
272
275
  else
@@ -284,9 +287,9 @@ class Step
284
287
  else
285
288
  @result = prepare_result result, @task.result_description
286
289
  end
290
+ rescue Exception
291
+ self.abort
287
292
  end
288
- ensure
289
- join unless no_load
290
293
  end
291
294
  end
292
295
 
@@ -300,7 +303,7 @@ class Step
300
303
  res = run true
301
304
  rescue Aborted
302
305
  Log.debug{"Forked process aborted: #{path}"}
303
- log :aborted, "Aborted"
306
+ log :aborted, "Job aborted (#{Process.pid})"
304
307
  raise $!
305
308
  rescue Exception
306
309
  Log.debug("Exception '#{$!.message}' caught on forked process: #{path}")
@@ -340,11 +343,15 @@ class Step
340
343
 
341
344
  def stop_dependencies
342
345
  dependencies.each do |dep|
346
+ Log.warn "Stoping #{Misc.fingerprint dep}"
343
347
  begin
344
- dep.abort unless dep.done? or dep.error? or dep.aborted?
348
+ dep.abort unless dep.done?
349
+ rescue Exception
350
+ Log.exception $!
345
351
  rescue Aborted
346
352
  end
347
353
  end
354
+ kill_children
348
355
  end
349
356
 
350
357
  def abort_pid
@@ -371,27 +378,42 @@ class Step
371
378
 
372
379
  def abort_stream
373
380
  stream = get_stream if @result
374
- stream ||= @stream
375
- if stream and stream.respond_to? :abort
376
- Log.medium "Aborting stream #{stream.inspect} -- #{Log.color :blue, path}"
381
+ stream ||= @saved_stream
382
+ if stream and stream.respond_to? :abort and not stream.aborted?
377
383
  begin
384
+ Log.medium "Aborting job stream #{stream.inspect} -- #{Log.color :blue, path}"
378
385
  stream.abort
386
+ Log.medium "Aborted job stream #{stream.inspect} -- #{Log.color :blue, path}"
387
+ #stream.close unless stream.closed?
379
388
  rescue Aborted
389
+ Log.medium "Aborting job stream #{stream.inspect} ABORTED RETRY -- #{Log.color :blue, path}"
390
+ retry
380
391
  end
381
392
  end
382
393
  end
383
394
 
384
395
  def abort
396
+ return if @aborted
385
397
  Log.medium{"#{Log.color :red, "Aborting"} #{Log.color :blue, path}"}
386
398
  begin
387
- abort_pid
388
399
  stop_dependencies
400
+ @aborted = true
389
401
  abort_stream
390
- rescue
402
+ abort_pid
403
+ rescue Aborted
404
+ Log.medium{"#{Log.color :red, "Aborting ABORTED RETRY"} #{Log.color :blue, path}"}
405
+ retry
406
+ rescue Exception
391
407
  Log.exception $!
392
408
  ensure
393
- log(:aborted, "Job aborted")
409
+ @aborted = true
410
+ begin
411
+ log(:aborted, "Job aborted")
412
+ rescue Exception
413
+ Log.exception $!
414
+ end
394
415
  end
416
+ Log.medium{"#{Log.color :red, "Aborted"} #{Log.color :blue, path}"}
395
417
  end
396
418
 
397
419
  def join_stream
@@ -401,9 +423,9 @@ class Step
401
423
  Misc.consume_stream stream
402
424
  stream.join if stream.respond_to? :join
403
425
  rescue Exception
404
- stream.abort if stream.respond_to? :abort
405
426
  self.abort
406
427
  raise $!
428
+ #stream.abort if stream.respond_to? :abort
407
429
  end
408
430
  end
409
431
  end
@@ -13,27 +13,33 @@ def run_task(workflow, task, name)
13
13
  ARGV.replace([workflow.to_s, task, '--load_inputs', example_dir, '--jobname', name,'-pf'] + $saved_args)
14
14
 
15
15
  path = nil
16
+ success = nil
16
17
  TmpFile.with_file do |res|
17
18
  Open.open(res, :mode => 'w') do |file|
18
19
  @pid = Process.fork{
19
20
  STDOUT.reopen res
20
21
  load Rbbt.share.rbbt_commands.workflow.task.find
21
22
  }
22
- file.close
23
23
  Signal.trap(:INT) do
24
24
  begin
25
25
  Process.kill "INT", @pid
26
26
  ensure
27
- exit -1
27
+ Kernel.exit! -1
28
28
  end
29
29
  end
30
- Process.wait @pid
30
+ file.close
31
+ begin
32
+ p,s = Process.waitpid2 @pid
33
+ success = s.success?
34
+ rescue Errno::ECHILD
35
+ success = true
36
+ end
31
37
  end
32
38
  path = Open.read(res).strip if File.exists? res
33
39
  end
34
40
  path = "NO RESULT" if path.nil? or path.empty?
35
41
 
36
- if $?.success?
42
+ if success
37
43
  Log.info "#{Log.color :green, "SUCCESS"} #{Log.color :magenta, workflow.to_s}##{Log.color :yellow, task} -- #{Log.color :cyan, name}"
38
44
  return [path, true]
39
45
  else
@@ -60,14 +66,15 @@ workflow = Workflow.require_workflow workflow
60
66
  tasks = task ? [task] : workflow.libdir.examples.glob('*').collect{|file| File.basename file }
61
67
 
62
68
  task_result = {}
63
- tasks.each do |task|
69
+ TSV.traverse tasks, :threads => 5 do |task|
64
70
  names = name ? [name] : workflow.libdir.examples[task].glob('*').collect{|file| File.basename file }
65
- names.each do |name|
71
+ TSV.traverse names, :threads => 5 do |name|
66
72
  success = run_task workflow, task, name
67
73
  task_result[[task, name]] = success
68
74
  end
69
75
  end
70
76
 
77
+
71
78
  task_result.each do |code,res|
72
79
  task, name = code
73
80
  path, success = res
@@ -309,14 +309,6 @@ begin
309
309
  exit 0
310
310
  end
311
311
 
312
- Signal.trap(:INT) do
313
- begin
314
- job.abort if job.info[:pid] == job.pid
315
- rescue
316
- end
317
- exit 0
318
- end
319
-
320
312
  job.fork
321
313
  else
322
314
  job.run(true)
@@ -407,6 +399,7 @@ if options.delete(:list_job_files)
407
399
  end
408
400
 
409
401
  if job_file = options.delete(:job_file)
402
+ job.join
410
403
  file = job.file(job_file)
411
404
  out.puts Path === file ? file.read : file
412
405
  exit 0
@@ -2,6 +2,8 @@ require File.join(File.expand_path(File.dirname(__FILE__)), '../../..', 'test_he
2
2
  require 'rbbt/tsv'
3
3
  require 'rbbt/tsv/parallel'
4
4
 
5
+ class StopException < StandardError; end
6
+
5
7
  class TestTSVParallelThrough < Test::Unit::TestCase
6
8
 
7
9
  def _test_traverse_tsv
@@ -307,16 +309,16 @@ class TestTSVParallelThrough < Test::Unit::TestCase
307
309
  head = 2_000
308
310
  cpus = 2
309
311
 
310
-
311
- 3.times do
312
+ 20.times do
313
+ Log.info Log.color :red, "TRAVERSE EXCEPTION"
312
314
  stream = Organism.identifiers("Hsa/jun2011").open
313
315
  dumper = TSV::Dumper.new Organism.identifiers("Hsa/jun2011").tsv_options
314
316
  dumper.init
315
317
 
316
- assert_raise do
318
+ assert_raise StopException do
317
319
  TSV.traverse stream, :head => head, :cpus => cpus, :into => dumper do |k,v|
318
320
  k = k.first
319
- raise "STOP" if rand(100) < 1
321
+ raise StopException if rand(100) < 1
320
322
  [k,v]
321
323
  end
322
324
  stream = dumper.stream
@@ -35,7 +35,7 @@ class TestProgress < Test::Unit::TestCase
35
35
  bar.tick
36
36
  sleep 0.3
37
37
  end
38
- Log.debug "Done progress"
38
+ #Log.debug "Done progress"
39
39
  assert bar.history.length > 0
40
40
  end
41
41
  end
@@ -46,7 +46,7 @@ class TestProgress < Test::Unit::TestCase
46
46
  bar.tick
47
47
  sleep 0.2
48
48
  end
49
- Log.debug "Done progress"
49
+ #Log.debug "Done progress"
50
50
  assert bar.history.length > 0
51
51
  end
52
52
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbbt-util
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.13.2
4
+ version: 5.13.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Vazquez