rbbt-util 5.13.1 → 5.13.2

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.
@@ -80,20 +80,6 @@ module TSV
80
80
  end
81
81
  end
82
82
 
83
- def self.get_stream(file, open_options = {})
84
- case
85
- when Path === file
86
- file.open(open_options)
87
- when file.respond_to?(:gets)
88
- file.rewind if file.respond_to?(:rewind) and file.eof?
89
- file
90
- when String === file
91
- Open.open(file, open_options)
92
- else
93
- raise "Cannot get stream from: #{file.inspect}"
94
- end
95
- end
96
-
97
83
  def self.get_stream(file, open_options = {})
98
84
  case file
99
85
  when Path
@@ -108,8 +94,14 @@ module TSV
108
94
  raise "Could not open file given by String: #{Misc.fingerprint file}" unless Open.remote?(file) or File.exists? file
109
95
  Open.open(file, open_options)
110
96
  when (defined? Step and Step)
97
+ file.grace
111
98
  stream = file.get_stream
112
- stream || get_stream(file.join.path)
99
+ if stream
100
+ stream
101
+ else
102
+ file.join
103
+ get_stream(file.path)
104
+ end
113
105
  when TSV::Dumper
114
106
  file.stream
115
107
  when Array
@@ -29,10 +29,10 @@ class RbbtProcessQueue
29
29
  @callback.call p
30
30
  end
31
31
  rescue Aborted
32
- Log.error "Callback thread aborted"
32
+ parent.raise $!
33
33
  rescue ClosedStream
34
34
  rescue Exception
35
- Log.error "Callback thread exception"
35
+ Log.warn "Callback thread exception"
36
36
  parent.raise $!
37
37
  ensure
38
38
  @callback_queue.sread.close unless @callback_queue.sread.closed?
@@ -58,9 +58,9 @@ class RbbtProcessQueue
58
58
  rescue Aborted
59
59
  @processes.each{|p| p.abort }
60
60
  @processes.each{|p| p.join }
61
- Log.error "Process monitor aborted"
61
+ Log.warn "Process monitor aborted"
62
62
  rescue Exception
63
- Log.error "Process monitor exception: #{$!.message}"
63
+ Log.warn "Process monitor exception: #{$!.message}"
64
64
  @processes.each{|p| p.abort }
65
65
  @callback_thread.raise $! if @callback_thread
66
66
  parent.raise $!
@@ -72,7 +72,7 @@ class RbbtProcessQueue
72
72
  begin
73
73
  @callback_queue.push ClosedStream.new if @callback_thread.alive?
74
74
  rescue
75
- Log.error "Error closing callback: #{$!.message}"
75
+ Log.warn "Error closing callback: #{$!.message}"
76
76
  end
77
77
  @callback_thread.join if @callback_thread.alive?
78
78
  end
@@ -89,28 +89,27 @@ class RbbtProcessQueue
89
89
  Log.exception $!
90
90
  raise $!
91
91
  ensure
92
- @queue.swrite.close
92
+ @queue.swrite.close unless @queue.swrite.closed?
93
93
  end
94
94
 
95
95
  @join.call if @join
96
96
  end
97
97
 
98
98
  def clean
99
- if @process_monitor.alive?
100
- @process_monitor.raise Aborted.new
101
- aborted = true
102
- end
103
-
104
- if @callback_thread and @callback_thread.alive?
105
- @callback_thread.raise Aborted.new
106
- aborted = true
99
+ if @process_monitor.alive? or @callback_thread.alive?
100
+ self.abort
101
+ else
102
+ self.join
107
103
  end
108
- raise Aborted.new if aborted
109
104
  end
110
105
 
111
106
  def abort
112
- @process_monitor.raise(Aborted.new); @process_monitor.join if @process_monitor and @process_monitor.alive?
113
- @callback_thread.raise(Aborted.new); @callback_thread.join if @callback_thread and @callback_thread.alive?
107
+ begin
108
+ @process_monitor.raise(Aborted.new); @process_monitor.join if @process_monitor and @process_monitor.alive?
109
+ @callback_thread.raise(Aborted.new); @callback_thread.join if @callback_thread and @callback_thread.alive?
110
+ ensure
111
+ join
112
+ end
114
113
  end
115
114
 
116
115
  def process(*e)
@@ -17,7 +17,9 @@ class RbbtProcessQueue
17
17
  Misc.purge_pipes
18
18
  end
19
19
 
20
- Signal.trap(:INT){ raise Aborted; }
20
+ Signal.trap(:INT){
21
+ Kernel.exit! -1
22
+ }
21
23
 
22
24
  loop do
23
25
  p = @queue.pop
@@ -29,8 +31,8 @@ class RbbtProcessQueue
29
31
  end
30
32
  Kernel.exit! 0
31
33
  rescue ClosedStream
32
- rescue Aborted
33
- Log.error "Worker #{Process.pid} aborted"
34
+ rescue Aborted, Interrupt
35
+ Log.warn "Worker #{Process.pid} aborted"
34
36
  Kernel.exit! -1
35
37
  rescue Exception
36
38
  Log.exception $!
@@ -110,8 +110,9 @@ module Log
110
110
 
111
111
  LOG_MUTEX.synchronize do
112
112
  STDERR.puts str
113
- logfile.puts str unless logfile.nil?
114
113
  Log::LAST.replace "log"
114
+ logfile.puts str unless logfile.nil?
115
+ nil
115
116
  end
116
117
  end
117
118
 
@@ -2,7 +2,7 @@ require 'rbbt/util/log'
2
2
  module Log
3
3
  class ProgressBar
4
4
 
5
- attr_accessor :depth, :num_reports, :desc, :io, :severity, :history
5
+ attr_accessor :depth, :num_reports, :desc, :io, :severity, :history, :max
6
6
 
7
7
  # Creates a new instance. Max is the total number of iterations of the
8
8
  # loop. The depth represents how many other loops are above this one,
@@ -46,7 +46,6 @@ module Log
46
46
  nil
47
47
  end
48
48
 
49
-
50
49
  def progress
51
50
  @current.to_f/ @max
52
51
  end
@@ -104,13 +103,17 @@ module Log
104
103
  end
105
104
 
106
105
  def thr
107
- @history ||= []
108
106
  @last_report = Time.now if @last_report == -1
109
107
  time = Time.now - @last_report
108
+ time = 0.000001 if time == 0
110
109
  thr = (@current / time).to_i
111
110
 
112
- @history << thr
113
- @history.shift if @history.length > 10
111
+ if @history.nil?
112
+ @history ||= []
113
+ else
114
+ @history << thr
115
+ @history.shift if @history.length > 10
116
+ end
114
117
 
115
118
  thr
116
119
  end
@@ -118,7 +121,7 @@ module Log
118
121
  def mean
119
122
  @mean_max ||= 0
120
123
  if @history.length > 3
121
- mean = Misc.mean(@history[1..-1])
124
+ mean = Misc.mean(@history)
122
125
  @mean_max = mean if mean > @mean_max
123
126
  end
124
127
  mean
@@ -132,7 +135,7 @@ module Log
132
135
  indicator = Log.color(:magenta, @desc)
133
136
  indicator << " #{ Log.color :blue, thr } per second"
134
137
 
135
- indicator << " -- #{ Log.color :yellow, mean.to_i } avg. #{ Log.color :yellow, @mean_max.to_i} max." if mean
138
+ indicator << " #{ Log.color :yellow, mean.to_i } avg. #{ Log.color :yellow, @mean_max.to_i} max." if mean
136
139
 
137
140
  indicator
138
141
  end
@@ -150,7 +153,9 @@ module Log
150
153
  # original line. Everything is printed to stderr.
151
154
  def report(io = STDERR)
152
155
  if Log::LAST != "progress"
153
- BARS.length.times{print(io, "\n")}
156
+ Log::ProgressBar.cleanup_bars
157
+ print(io, Log.color(:yellow, "== Progress"))
158
+ (BARS.length-1).times{print(io, "\n")}
154
159
  end
155
160
  print(io, up_lines(@depth) << report_msg << down_lines(@depth)) if severity >= Log.severity
156
161
  @last_report = Time.now if @last_report == -1
@@ -158,15 +163,24 @@ module Log
158
163
 
159
164
  def throughput(io = STDERR)
160
165
  if Log::LAST != "progress"
161
- BARS.length.times{print(io, "\n")}
166
+ Log::ProgressBar.cleanup_bars
167
+ print(io, Log.color(:yellow, "== Progress"))
168
+ (BARS.length-1).times{print(io, "\n")}
162
169
  end
163
170
  print(io, up_lines(@depth) << throughput_msg << down_lines(@depth)) if severity >= Log.severity
164
171
  @last_report = Time.now
165
172
  @current = 0
166
173
  end
174
+
175
+ def done
176
+ print(io, up_lines(@depth) << Log.color(:magenta, @desc) << Log.color(:green, " DONE") << down_lines(@depth)) if severity >= Log.severity
177
+ end
178
+
167
179
  BAR_MUTEX = Mutex.new
168
180
  BARS = []
181
+ REMOVE = []
169
182
  def self.new_bar(max, options = {})
183
+ cleanup_bars
170
184
  BAR_MUTEX.synchronize do
171
185
  options = Misc.add_defaults options, :depth => BARS.length
172
186
  BARS << (bar = ProgressBar.new(max, options))
@@ -174,18 +188,27 @@ module Log
174
188
  end
175
189
  end
176
190
 
177
- def self.remove_bar(bar)
191
+ def self.cleanup_bars
178
192
  BAR_MUTEX.synchronize do
179
- index = BARS.index bar
180
- if index
181
- (index+1..BARS.length-1).each do |pos|
182
- bar = BARS[pos]
183
- bar.depth = pos - 1
184
- BARS[pos-1] = bar
185
- end
186
- BARS.pop
193
+ REMOVE.each do |bar|
194
+ index = BARS.index bar
195
+ 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
202
+ end
187
203
  end
188
- Log::LAST.replace "removeprogress"
204
+ REMOVE.clear
205
+ end
206
+ end
207
+
208
+ def self.remove_bar(bar)
209
+ BAR_MUTEX.synchronize do
210
+ bar.done unless bar.max
211
+ REMOVE << bar
189
212
  end
190
213
  end
191
214
 
@@ -193,8 +216,11 @@ module Log
193
216
  bar = new_bar(max, options)
194
217
  begin
195
218
  yield bar
219
+ keep = false
220
+ rescue KeepBar
221
+ keep = true
196
222
  ensure
197
- remove_bar(bar)
223
+ remove_bar(bar) unless bar
198
224
  end
199
225
  end
200
226
  end
@@ -1,6 +1,10 @@
1
1
  class ParameterException < Exception; end
2
2
  class FieldNotFoundError < Exception;end
3
- class Aborted < Exception; end
3
+ class Aborted < Exception
4
+ def initialize(*args)
5
+ super(*args)
6
+ end
7
+ end
4
8
  class TryAgain < Exception; end
5
9
  class ClosedStream < Exception; end
6
10
  class ProcessFailed < Exception; end
@@ -10,3 +14,9 @@ class KeepLocked < Exception
10
14
  @payload = payload
11
15
  end
12
16
  end
17
+ class KeepBar < Exception
18
+ attr_accessor :payload
19
+ def initialize(payload)
20
+ @payload = payload
21
+ end
22
+ end
@@ -42,7 +42,7 @@ module Misc
42
42
  when (defined? TSV and TSV::Parser)
43
43
  "<TSVStream:" + (obj.filename || "NOFILENAME") + "--" << Misc.fingerprint(obj.options) << ">"
44
44
  when IO
45
- "<IO:" + (obj.respond_to?(:filename) ? obj.filename || obj.inspect : obj.inspect) + ">"
45
+ (obj.respond_to?(:filename) and obj.filename ) ? "<IO:" + (obj.filename || obj.inspect) + ">" : obj.inspect
46
46
  when File
47
47
  "<File:" + obj.path + ">"
48
48
  when Array
@@ -22,7 +22,7 @@ module Misc
22
22
  raise "No info" unless info
23
23
 
24
24
  if hostname == info["host"] and not Misc.pid_exists?(info["pid"])
25
- Log.info("Removing lockfile: #{lock_path}. This pid #{Process.pid}. Content: #{info.inspect}")
25
+ Log.high("Removing lockfile: #{lock_path}. This pid #{Process.pid}. Content: #{info.inspect}")
26
26
  FileUtils.rm lock_path
27
27
  end
28
28
  end
@@ -124,22 +124,22 @@ module Misc
124
124
  begin
125
125
  stream_in1.write block;
126
126
  rescue IOError
127
- Log.error("Tee stream 1 #{stream} IOError: #{$!.message}");
127
+ Log.warn("Tee stream 1 #{Misc.fingerprint stream} IOError: #{$!.message}");
128
128
  skip1 = true
129
129
  end unless skip1
130
130
 
131
131
  begin
132
132
  stream_in2.write block
133
133
  rescue IOError
134
- Log.error("Tee stream 2 #{stream} IOError: #{$!.message}");
134
+ Log.warn("Tee stream 2 #{Misc.fingerprint stream} IOError: #{$!.message}");
135
135
  skip2 = true
136
136
  end unless skip2
137
137
  end
138
138
  stream_in1.close unless stream_in1.closed?
139
139
  stream_in2.close unless stream_in2.closed?
140
140
  stream.join if stream.respond_to? :join
141
- rescue Aborted
142
- Log.error("Tee stream #{stream} Aborted");
141
+ rescue Aborted, Interrupt
142
+ Log.warn("Tee stream #{Misc.fingerprint stream} Aborted");
143
143
  stream.abort if stream.respond_to? :abort
144
144
  rescue Exception
145
145
  Log.exception $!
@@ -177,6 +177,8 @@ module Misc
177
177
  io.join if io.respond_to? :join
178
178
  return
179
179
  end
180
+
181
+ Log.medium "Consuming stream #{Misc.fingerprint io}"
180
182
  if in_thread
181
183
  Thread.new do
182
184
  consume_stream(io, false)
@@ -188,9 +190,9 @@ module Misc
188
190
  Thread.pass
189
191
  end
190
192
  io.join if io.respond_to? :join
193
+ rescue IOError
191
194
  rescue
192
- Log.error "Exception consuming stream: #{io.inspect}"
193
- Log.exception $!
195
+ Log.warn "Exception consuming stream: #{io.inspect}"
194
196
  io.abort if io.respond_to? :abort
195
197
  end
196
198
  end
@@ -240,9 +242,13 @@ module Misc
240
242
 
241
243
  Open.mv tmp_path, path
242
244
  rescue Aborted
243
- Log.error "Aborted sensiblewrite -- #{ Log.color :blue, path }"
245
+ Log.warn "Aborted sensiblewrite -- #{ Log.reset << Log.color(:blue, path) }"
246
+ content.abort if content.respond_to? :abort
247
+ content.join if content.respond_to? :join
244
248
  rescue Exception
245
- Log.error "Exception in sensiblewrite: #{$!.message} -- #{ Log.color :blue, path }"
249
+ Log.warn "Exception in sensiblewrite: #{$!.message} -- #{ Log.color :blue, path }"
250
+ content.abort if content.respond_to? :abort
251
+ content.join if content.respond_to? :join
246
252
  Open.rm_f path if File.exists? path
247
253
  raise $!
248
254
  ensure
@@ -264,29 +270,40 @@ module Misc
264
270
 
265
271
  def self.sort_stream(stream, header_hash = "#")
266
272
  Misc.open_pipe do |sin|
267
- line = stream.gets
268
- while line =~ /^#{header_hash}/ do
269
- sin.puts line
273
+ begin
274
+ if defined? Step and Step === stream
275
+ step = stream
276
+ stream = stream.get_stream || stream.path.open
277
+ end
278
+
270
279
  line = stream.gets
271
- end
280
+ while line =~ /^#{header_hash}/ do
281
+ sin.puts line
282
+ line = stream.gets
283
+ end
272
284
 
273
- line_stream = Misc.open_pipe do |line_stream_in|
274
- begin
275
- while line
276
- line_stream_in.puts line
277
- line = stream.gets
285
+ line_stream = Misc.open_pipe do |line_stream_in|
286
+ begin
287
+ while line
288
+ line_stream_in.puts line
289
+ line = stream.gets
290
+ end
291
+ stream.join if stream.respond_to? :join
292
+ rescue
293
+ stream.abort if stream.respond_to? :abort
294
+ raise $!
278
295
  end
279
- stream.join if stream.respond_to? :join
280
- rescue
281
- stream.abort if stream.respond_to? :abort
282
- raise $!
283
296
  end
284
- end
285
297
 
286
- sorted = CMD.cmd("sort", :in => line_stream, :pipe => true)
298
+ sorted = CMD.cmd("sort", :in => line_stream, :pipe => true)
287
299
 
288
- while block = sorted.read(2048)
289
- sin.write block
300
+ while block = sorted.read(2048)
301
+ sin.write block
302
+ end
303
+ rescue
304
+ if defined? step and step
305
+ step.abort
306
+ end
290
307
  end
291
308
  end
292
309
  end
@@ -330,6 +347,14 @@ module Misc
330
347
  num_streams = streams.length
331
348
  Misc.open_pipe do |sin|
332
349
  sin.puts header if header
350
+ streams = streams.collect do |stream|
351
+ if defined? Step and Step === stream
352
+ stream.get_stream || stream.join.path.open
353
+ else
354
+ stream
355
+ end
356
+ end
357
+
333
358
  begin
334
359
  done_streams = []
335
360
  lines ||= streams.collect{|s| s.gets }
@@ -369,6 +394,7 @@ module Misc
369
394
  stream.join if stream.respond_to? :join
370
395
  end
371
396
  rescue
397
+ Log.exception $!
372
398
  streams.each do |stream|
373
399
  stream.abort if stream.respond_to? :abort
374
400
  end
@@ -388,4 +414,19 @@ module Misc
388
414
  tee2
389
415
  end
390
416
 
417
+ def self.save_stream(file, stream)
418
+ out, save = Misc.tee_stream stream
419
+
420
+ Thread.new(Thread.current) do |parent|
421
+ begin
422
+ Misc.sensiblewrite(file, save)
423
+ rescue
424
+ save.abort if save.respond_to? :abort
425
+ parent.raise $!
426
+ end
427
+ end
428
+
429
+ out
430
+ end
431
+
391
432
  end