rbbt-util 5.10.2 → 5.11.1

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: cba82109ac8a97d8964ffd2b7eaa3e47444e6bea
4
- data.tar.gz: ba62c2032f5225afb66da4d21cf2b92419993e5a
3
+ metadata.gz: ee7693bddd82af53509c8ed2e5414f1a86ac51ce
4
+ data.tar.gz: 5122a7d8c8404d7a045e571310cfb34c3e808bbe
5
5
  SHA512:
6
- metadata.gz: 70cbfbc5301a70c101102221baca363898d075e55b12bb8fd06beb3a559bad40d541b95991a627a7f896635ac580aeb9f5e639bf4c49bdbc6e6328b0b75c1068
7
- data.tar.gz: 87d924aa5560c5698adb671b9607c928ecee243aff6a5ec6a002b5b9c600117b138ac2ae289fab9a7889a1e350b0b3105b5e843704cd7e32b0a2f9110e279349
6
+ metadata.gz: e75a716cf8fd069b161d3f167217b0a329eac88d1458e6133fdbc0b3e51cfcd647e6c53cf2e4cbe9a28ab5499e2822138797688eb75239fffe458975195b6ad3
7
+ data.tar.gz: ae968a716ff89c35ba2a07300ac56cba42452692a75e2b811051d360fd64ce51c4f95aba36a9d974234450cdfdab846ddd31a367383a41ac80b1b49f177ac303
data/lib/rbbt/persist.rb CHANGED
@@ -155,11 +155,7 @@ module Persist
155
155
  Misc.sensiblewrite(path, content * "\n" + "\n")
156
156
  end
157
157
  when IO
158
- Misc.sensiblewrite(path) do |file|
159
- while block = content.read(2048)
160
- file.write block
161
- end
162
- end
158
+ Misc.sensiblewrite(path, content)
163
159
  else
164
160
  Misc.sensiblewrite(path, content.to_s)
165
161
  end
@@ -181,14 +177,20 @@ module Persist
181
177
 
182
178
  saver_pid = Process.fork do
183
179
  out.close
184
- Misc.purge_pipes(stream)
180
+ stream.close
181
+ Misc.purge_pipes
185
182
  begin
186
183
  Misc.lock(path) do
187
184
  save_file(path, type, file)
188
185
  end
186
+ rescue Aborted
187
+ stream.abort if stream.respond_to? :abort
188
+ raise $!
189
189
  rescue Exception
190
190
  Log.exception $!
191
+ Kernel.exit! -1
191
192
  end
193
+ Kernel.exit! 0
192
194
  end
193
195
  file.close
194
196
  ConcurrentStream.setup(out, :pids => [saver_pid], :filename => path)
@@ -203,7 +205,11 @@ module Persist
203
205
  Misc.lock(path) do
204
206
  save_file(path, type, file)
205
207
  end
208
+ rescue Aborted
209
+ Log.error "Tee stream thread aborted"
210
+ stream.abort if stream.respond_to? :abort
206
211
  rescue Exception
212
+ stream.abort if stream.respond_to? :abort
207
213
  Log.exception $!
208
214
  parent.raise $!
209
215
  end
@@ -318,36 +324,70 @@ module Persist
318
324
  end
319
325
 
320
326
  begin
327
+
321
328
  lock_filename = Persist.persistence_path(path + '.persist', {:dir => Persist.lock_dir})
322
- Misc.lock lock_filename do
329
+ Misc.lock lock_filename do |lockfile|
323
330
  if is_persisted?(path, persist_options)
324
331
  Log.low "Persist up-to-date (suddenly): #{ path } - #{Misc.fingerprint persist_options}"
325
332
  return path if persist_options[:no_load]
326
333
  return load_file(path, type)
327
334
  end
328
335
 
329
- Log.medium "Persist create: #{ path } - #{persist_options.inspect[0..100]}"
336
+ Log.medium "Persist create: #{ path } - #{Misc.fingerprint persist_options}"
337
+
330
338
  res = yield
331
339
 
340
+ if persist_options[:no_load] == :stream
341
+ case res
342
+ when IO
343
+ res = tee_stream(res, path, type, res.respond_to?(:callback)? res.callback : nil)
344
+ ConcurrentStream.setup res do
345
+ lockfile.unlock
346
+ end
347
+ raise KeepLocked.new res
348
+ when TSV::Dumper
349
+ res = tee_stream(res.stream, path, type, res.respond_to?(:callback)? res.callback : nil)
350
+ ConcurrentStream.setup res do
351
+ lockfile.unlock
352
+ end
353
+ raise KeepLocked.new res
354
+ end
355
+ end
356
+
332
357
  case res
333
- when nil
334
- res = load_file(path) unless persist_options[:no_load]
335
- when IO, StringIO
336
- res = tee_stream(res, path, type, res.respond_to?(:callback)? res.callback : nil)
337
- return res if persist_options[:no_load] == :stream
358
+ when IO
359
+ begin
360
+ res = case
361
+ when :array
362
+ res.read.split "\n"
363
+ when :tsv
364
+ TSV.open(res)
365
+ else
366
+ res.read
367
+ end
368
+ rescue
369
+ res.abort if res.respond_to? :abort
370
+ ensure
371
+ res.join if res.respond_to? :join
372
+ end
338
373
  when TSV::Dumper
339
- res = tee_stream(res.stream, path, type, res.respond_to?(:callback)? res.callback : nil)
340
- return res if persist_options[:no_load] == :stream
341
- else
342
- Misc.lock(path) do
343
- save_file(path, type, res)
374
+ begin
375
+ io = res.stream
376
+ res = TSV.open(io)
377
+ rescue
378
+ io.abort if io.respond_to? :abort
379
+ ensure
380
+ io.join if io.respond_to? :join
344
381
  end
345
382
  end
346
383
 
347
- return path if persist_options[:no_load]
384
+ Misc.lock(path) do
385
+ save_file(path, type, res)
386
+ end
348
387
 
349
- res
388
+ persist_options[:no_load] ? path : res
350
389
  end
390
+
351
391
  rescue
352
392
  Log.high "Error in persist: #{path}#{Open.exists?(path) ? Log.color(:red, " Erasing") : ""}"
353
393
  FileUtils.rm path if Open.exists? path
@@ -7,8 +7,8 @@ module TSV
7
7
  begin
8
8
  yield dumper
9
9
  dumper.close
10
+ rescue Aborted
10
11
  rescue Exception
11
- Log.exception $!
12
12
  parent.raise $!
13
13
  end
14
14
  end
@@ -10,6 +10,19 @@ module TSV
10
10
  end
11
11
  end
12
12
 
13
+ def self.stream_name(obj)
14
+ filename_obj = obj.respond_to?(:filename) ? obj.filename : nil
15
+ filename_obj ||= obj.respond_to?(:path) ? obj.path : nil
16
+ stream_obj = obj_stream(obj)
17
+ filename_obj.nil? ? stream_obj.inspect : filename_obj + "(#{stream_obj.inspect})"
18
+ end
19
+
20
+ def self.report(msg, obj, into)
21
+ into = into[:into] if Hash === into and into.include? :into
22
+
23
+ Log.error "#{ msg } #{stream_name(obj)} -> #{stream_name(into)}"
24
+ end
25
+
13
26
  def self.traverse_tsv(tsv, options = {}, &block)
14
27
  callback = Misc.process_options options, :callback
15
28
 
@@ -103,15 +116,21 @@ module TSV
103
116
  obj.traverse(options, &block)
104
117
  end
105
118
  when IO, File, StringIO
106
- if options[:type] == :array
107
- traverse_io_array(obj, options, &block)
108
- else
109
- traverse_io(obj, options, &block)
119
+ begin
120
+ if options[:type] == :array
121
+ traverse_io_array(obj, options, &block)
122
+ else
123
+ traverse_io(obj, options, &block)
124
+ end
125
+ rescue Exception
126
+ raise Aborted
127
+ ensure
128
+ begin
129
+ obj.close if obj.respond_to? :close and not obj.closed?
130
+ ensure
131
+ obj.join if obj.respond_to? :join
132
+ end
110
133
  end
111
-
112
- io = obj
113
- obj.join if io.respond_to? :join
114
- io.close if io.respond_to? :close and not io.closed?
115
134
  when Path
116
135
  obj.open do |stream|
117
136
  traverse_obj(stream, options, &block)
@@ -120,12 +139,13 @@ module TSV
120
139
  traverse_obj(obj.stream, options, &block)
121
140
  when (defined? Step and Step)
122
141
 
123
- case obj.result
124
- when IO, TSV::Dumper, TSV
125
- traverse_obj(obj.result, options, &block)
142
+ stream = obj.get_stream
143
+
144
+ if stream
145
+ traverse_obj(stream, options, &block)
126
146
  else
127
147
  obj.join
128
- traverse_obj(obj.path.open, options, &block)
148
+ traverse_obj(obj.path, options, &block)
129
149
  end
130
150
  when Array
131
151
  traverse_array(obj, options, &block)
@@ -163,45 +183,55 @@ module TSV
163
183
  end
164
184
 
165
185
  def self.traverse_cpus(num, obj, options, &block)
166
- filename = obj.respond_to?(:filename)? obj.filename : "none"
167
- callback, cleanup = Misc.process_options options, :callback, :cleanup
168
- q = RbbtProcessQueue.new num, cleanup
186
+ begin
187
+ filename = obj.respond_to?(:filename)? obj.filename : "none"
188
+ callback, cleanup = Misc.process_options options, :callback, :cleanup
189
+ q = RbbtProcessQueue.new num, cleanup
169
190
 
170
- q.callback &callback
171
- q.init &block
191
+ q.callback &callback
192
+ q.init &block
172
193
 
173
- traverse_obj(obj, options) do |*p|
174
- q.process *p
175
- end
194
+ traverse_obj(obj, options) do |*p|
195
+ q.process *p
196
+ end
176
197
 
177
- into = options[:into]
198
+ into = options[:into]
199
+ rescue Exception
200
+ q.abort
201
+ raise $!
202
+ ensure
203
+ q.join
204
+ end
178
205
 
179
- q.join
180
206
  end
181
207
 
182
208
  def self.store_into(store, value)
183
- case store
184
- when Hash
185
- return if value.nil?
186
- if Hash === value
187
- if TSV === store and store.type == :double
188
- store.merge_zip value
209
+ begin
210
+ case store
211
+ when Hash
212
+ return if value.nil?
213
+ if Hash === value
214
+ if TSV === store and store.type == :double
215
+ store.merge_zip value
216
+ else
217
+ store.merge! value
218
+ end
189
219
  else
190
- store.merge! value
220
+ k,v = value
221
+ store[k] = v
191
222
  end
223
+ when TSV::Dumper
224
+ return if value.nil?
225
+ store.add *value
226
+ when IO
227
+ return if value.nil?
228
+ store.puts value.strip
192
229
  else
193
- k,v = value
194
- store[k] = v
195
- end
196
- when TSV::Dumper
197
- return if value.nil?
198
- store.add *value
199
- when IO
200
- return if value.nil?
201
- store.puts value.strip
202
- else
203
- store << value
204
- end
230
+ store << value
231
+ end
232
+ rescue
233
+ raise "Error storing into #{store.inspect}: #{$!.message}"
234
+ end
205
235
  end
206
236
 
207
237
  def self.get_streams_to_close(obj)
@@ -268,30 +298,6 @@ module TSV
268
298
  ConcurrentStream.setup(obj_stream(into), :threads => thread)
269
299
  end
270
300
 
271
- def self.stream_name(obj)
272
- filename_obj = obj.respond_to?(:filename) ? obj.filename : nil
273
- filename_obj ||= obj.respond_to?(:path) ? obj.path : nil
274
- stream_obj = obj_stream(obj)
275
- filename_obj.nil? ? stream_obj.inspect : filename_obj + "(#{stream_obj.inspect})"
276
- end
277
-
278
- def self.report(msg, obj, into)
279
- into = into[:into] if Hash === into and into.include? :into
280
-
281
- #filename_into = into.respond_to?(:filename) ? into.filename : nil
282
- #filename_into ||= into.respond_to?(:path) ? into.path : nil
283
- #stream_into = obj_stream(into)
284
- #str_into = filename_into.nil? ? stream_into.inspect : filename_into + "(#{stream_into.inspect})"
285
-
286
- #filename_obj = obj.respond_to?(:filename) ? obj.filename : nil
287
- #filename_obj ||= obj.respond_to?(:path) ? obj.path : nil
288
- #stream_obj = obj_stream(obj)
289
- #str_obj = filename_obj.nil? ? stream_obj.inspect : filename_obj + "(#{stream_obj.inspect})"
290
-
291
- #Log.error "#{ msg } #{filename_obj} - #{filename_into}"
292
- Log.error "#{ msg } #{stream_name(obj)} -> #{stream_name(into)}"
293
- end
294
-
295
301
  def self.traverse(obj, options = {}, &block)
296
302
  threads = Misc.process_options options, :threads
297
303
  cpus = Misc.process_options options, :cpus
@@ -300,12 +306,24 @@ module TSV
300
306
  threads = nil if threads and threads.to_i <= 1
301
307
  cpus = nil if cpus and cpus.to_i <= 1
302
308
 
309
+ if into == :stream
310
+ sout = Misc.open_pipe false, false do |sin|
311
+ begin
312
+ traverse(obj, options.merge(:into => sin), &block)
313
+ rescue Exception
314
+ sin.abort if sin.respond_to? :abort
315
+ end
316
+ end
317
+ return sout
318
+ end
319
+
303
320
  if into
304
321
  options[:callback] = Proc.new do |e|
305
322
  begin
306
323
  store_into into, e
307
324
  rescue Exception
308
325
  Log.exception $!
326
+ raise $!
309
327
  end
310
328
  end
311
329
 
@@ -16,9 +16,9 @@ module TSV
16
16
 
17
17
  # Get line
18
18
 
19
- Thread.pass while IO.select([stream], nil, nil, 1).nil? if IO === stream
19
+ #Thread.pass while IO.select([stream], nil, nil, 1).nil? if IO === stream
20
20
  line = stream.gets
21
- raise "Empty content" if line.nil?
21
+ raise "Empty content: #{ stream.inspect }" if line.nil?
22
22
  line = Misc.fixutf8 line
23
23
  line.chomp!
24
24
 
@@ -41,7 +41,7 @@ module TSV
41
41
  @key_field = @fields.shift
42
42
  @key_field = @key_field[(0 + header_hash.length)..-1] # Remove initial hash character
43
43
 
44
- Thread.pass while IO.select([stream], nil, nil, 1).nil? if IO === stream
44
+ #Thread.pass while IO.select([stream], nil, nil, 1).nil? if IO === stream
45
45
  line = @header_hash != "" ? Misc.fixutf8(stream.gets) : nil
46
46
  end
47
47
 
@@ -123,14 +123,20 @@ module TSV
123
123
  end
124
124
 
125
125
  def get_values_flat(parts)
126
+ begin
127
+ orig = parts
126
128
  if key_position and key_position != 0 and field_positions.nil?
127
129
  value = parts.shift
128
130
  keys = parts.dup
129
131
  return [keys, [value]]
130
132
  end
131
133
 
132
- return parts.shift.split(@sep2, -1).first, parts.collect{|value| value.split(@sep2, -1)}.flatten if
134
+ return parts.shift.split(@sep2, -1).first, parts.collect{|value| value.split(@sep2, -1)}.flatten if
133
135
  field_positions.nil? and (key_position.nil? or key_position == 0)
136
+ rescue
137
+ eee [:rescue, orig]
138
+ raise $!
139
+ end
134
140
 
135
141
  keys = parts[key_position].split(@sep2, -1)
136
142
 
@@ -486,6 +492,7 @@ module TSV
486
492
  # parser
487
493
  line_num = 1
488
494
  begin
495
+
489
496
  while not line.nil?
490
497
  begin
491
498
  progress_monitor.tick(stream.pos) if progress_monitor
@@ -494,13 +501,14 @@ module TSV
494
501
 
495
502
  line = Misc.fixutf8(line)
496
503
  line = self.process line
504
+ raise SKIP_LINE if line.empty?
497
505
  parts = self.chop_line line
498
506
  key, values = self.get_values parts
499
507
  values = self.cast_values values if self.cast?
500
508
 
501
509
  yield key, values
502
510
 
503
- Thread.pass while IO.select([stream], nil, nil, 1).nil? if IO === stream
511
+ #Thread.pass while IO.select([stream], nil, nil, 1).nil? if IO === stream
504
512
 
505
513
  line = stream.gets
506
514
 
@@ -515,11 +523,18 @@ module TSV
515
523
  end
516
524
  rescue END_PARSING
517
525
  break
518
- rescue IOError
519
- Log.exception $!
520
- break
526
+ #rescue IOError
527
+ # Log.exception $!
528
+ # break
529
+ rescue Exception
530
+ stream.abort if stream.respond_to? :abort
531
+ raise $!
521
532
  end
522
533
  end
534
+
535
+ ensure
536
+ stream.close
537
+ stream.join if stream.respond_to? :join
523
538
  end
524
539
 
525
540
  self
@@ -27,10 +27,11 @@ class RbbtProcessQueue
27
27
  raise p.first if Array === p and Exception === p.first
28
28
  @callback.call p
29
29
  end
30
+ rescue Aborted
31
+ Log.error "Callback thread aborted"
30
32
  rescue ClosedStream
31
33
  rescue Exception
32
34
  Log.exception $!
33
- sleep 1
34
35
  parent.raise $!
35
36
  ensure
36
37
  @callback_queue.sread.close unless @callback_queue.sread.closed?
@@ -53,14 +54,13 @@ class RbbtProcessQueue
53
54
  @processes[0].join
54
55
  @processes.shift
55
56
  end
57
+ rescue Aborted
58
+ @processes.each{|p| p.abort }
59
+ Log.error "Process monitor aborted"
56
60
  rescue Exception
57
- @processes.each do |p|
58
- begin
59
- Process.kill :INT, p
60
- rescue
61
- end
62
- end
63
- Log.exception $!
61
+ Log.error "Process monitor exception: #{$!.message}"
62
+ @processes.each{|p| p.abort }
63
+ @callback_thread.raise Aborted.new if @callback_thread
64
64
  parent.raise $!
65
65
  end
66
66
  end
@@ -87,8 +87,21 @@ class RbbtProcessQueue
87
87
  end
88
88
 
89
89
  def clean
90
- @processes.each{|p| p.abort }
91
- @callback_thread.raise Aborted if @callback_thread and @callback_thread.alive?
90
+ if @process_monitor.alive?
91
+ @process_monitor.raise Aborted.new
92
+ aborted = true
93
+ end
94
+
95
+ if @callback_thread and @callback_thread.alive?
96
+ @callback_thread.raise Aborted.new
97
+ aborted = true
98
+ end
99
+ raise Aborted.new if aborted
100
+ end
101
+
102
+ def abort
103
+ @process_monitor.raise Aborted.new if @process_monitor.alive?
104
+ @callback_thread.raise Aborted.new if @callback_thread and @callback_thread.alive?
92
105
  end
93
106
 
94
107
  def process(*e)