rbbt-util 5.13.2 → 5.13.3

Sign up to get free protection for your applications and to get access to all the features.
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