rbbt-util 5.13.31 → 5.13.32

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,7 +3,9 @@ require 'tokyocabinet'
3
3
  module Persist
4
4
 
5
5
  module TCAdapter
6
- attr_accessor :persistence_path, :tokyocabinet_class, :closed, :writable, :mutex
6
+ include Persist::TSVAdapter
7
+
8
+ attr_accessor :tokyocabinet_class
7
9
 
8
10
  def self.open(path, write, serializer, tokyocabinet_class = TokyoCabinet::HDB)
9
11
  tokyocabinet_class = TokyoCabinet::HDB if tokyocabinet_class == "HDB" or tokyocabinet_class.nil?
@@ -27,21 +29,6 @@ module Persist
27
29
  database
28
30
  end
29
31
 
30
- MAX_CHAR = 255.chr
31
-
32
- def prefix(key)
33
- range(key, 1, key + MAX_CHAR, 1)
34
- end
35
-
36
- def get_prefix(key)
37
- keys = prefix(key)
38
- select(:key => keys)
39
- end
40
-
41
- def closed?
42
- @closed
43
- end
44
-
45
32
  def close
46
33
  @closed = true
47
34
  super
@@ -73,83 +60,129 @@ module Persist
73
60
  self
74
61
  end
75
62
 
76
- def write?
77
- @writable
78
- end
79
-
80
- def read?
81
- ! write?
82
- end
83
-
84
- def collect
85
- res = []
86
- each do |key, value|
87
- res << if block_given?
88
- yield key, value
89
- else
90
- [key, value]
91
- end
92
- end
93
- res
94
- end
95
-
96
- def delete(key)
97
- out(key)
98
- end
99
-
100
- def write_and_read
101
- lock_filename = Persist.persistence_path(persistence_path + '.write', {:dir => TSV.lock_dir})
102
- Misc.lock(lock_filename) do
103
- @mutex.synchronize do
104
- write if @closed or not write?
105
- res = begin
106
- yield
107
- ensure
108
- read
109
- end
110
- res
111
- end
112
- end
113
- end
114
-
115
- def write_and_close
116
- lock_filename = Persist.persistence_path(persistence_path + '.write', {:dir => TSV.lock_dir})
117
- Misc.lock(lock_filename) do
118
- @mutex.synchronize do
119
- write if @closed or not write?
120
- res = begin
121
- yield
122
- ensure
123
- close
124
- end
125
- res
126
- end
127
- end
128
- end
129
-
130
- def read_and_close
131
- @mutex.synchronize do
132
- read if @closed or not read?
133
- res = begin
134
- yield
135
- ensure
136
- close
137
- end
138
- res
139
- end
140
- end
141
-
142
-
143
- def merge!(hash)
144
- hash.each do |key,values|
145
- self[key] = values
146
- end
147
- end
148
-
149
-
150
- def range(*args)
151
- super(*args) #- TSV::ENTRY_KEYS.to_a
152
- end
63
+ #MAX_CHAR = 255.chr
64
+
65
+ #def prefix(key)
66
+ # range(key, 1, key + MAX_CHAR, 1)
67
+ #end
68
+
69
+ #def get_prefix(key)
70
+ # keys = prefix(key)
71
+ # select(:key => keys)
72
+ #end
73
+
74
+ #def closed?
75
+ # @closed
76
+ #end
77
+
78
+ #def close
79
+ # @closed = true
80
+ # super
81
+ #end
82
+
83
+ #def read(force = false)
84
+ # return if not write? and not closed and not force
85
+ # self.close
86
+ # if !self.open(@persistence_path, tokyocabinet_class::OREADER)
87
+ # ecode = self.ecode
88
+ # raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
89
+ # end
90
+ # @writable = false
91
+ # @closed = false
92
+ # self
93
+ #end
94
+
95
+ #def write(force = true)
96
+ # return if write? and not closed and not force
97
+ # self.close
98
+
99
+ # if !self.open(@persistence_path, tokyocabinet_class::OWRITER)
100
+ # ecode = self.ecode
101
+ # raise "Open error: #{self.errmsg(ecode)}. Trying to open file #{@persistence_path}"
102
+ # end
103
+
104
+ # @writable = true
105
+ # @closed = false
106
+ # self
107
+ #end
108
+
109
+ #def write?
110
+ # @writable
111
+ #end
112
+
113
+ #def read?
114
+ # ! write?
115
+ #end
116
+
117
+ #def collect
118
+ # res = []
119
+ # each do |key, value|
120
+ # res << if block_given?
121
+ # yield key, value
122
+ # else
123
+ # [key, value]
124
+ # end
125
+ # end
126
+ # res
127
+ #end
128
+
129
+ #def delete(key)
130
+ # out(key)
131
+ #end
132
+
133
+ #def write_and_read
134
+ # lock_filename = Persist.persistence_path(persistence_path + '.write', {:dir => TSV.lock_dir})
135
+ # Misc.lock(lock_filename) do
136
+ # @mutex.synchronize do
137
+ # write if @closed or not write?
138
+ # res = begin
139
+ # yield
140
+ # ensure
141
+ # read
142
+ # end
143
+ # res
144
+ # end
145
+ # end
146
+ #end
147
+
148
+ #def write_and_close
149
+ # lock_filename = Persist.persistence_path(persistence_path + '.write', {:dir => TSV.lock_dir})
150
+ # Misc.lock(lock_filename) do
151
+ # @mutex.synchronize do
152
+ # write if @closed or not write?
153
+ # res = begin
154
+ # yield
155
+ # ensure
156
+ # close
157
+ # end
158
+ # res
159
+ # end
160
+ # end
161
+ #end
162
+
163
+ #def read_and_close
164
+ # @mutex.synchronize do
165
+ # read if @closed or not read?
166
+ # res = begin
167
+ # yield
168
+ # ensure
169
+ # close
170
+ # end
171
+ # res
172
+ # end
173
+ #end
174
+
175
+
176
+ #def merge!(hash)
177
+ # hash.each do |key,values|
178
+ # self[key] = values
179
+ # end
180
+ #end
181
+
182
+
183
+ #def range(*args)
184
+ # super(*args) #- TSV::ENTRY_KEYS.to_a
185
+ #end
153
186
  end
154
187
 
155
188
 
@@ -1,3 +1,5 @@
1
+ require 'rbbt/persist/tsv/adapter'
2
+
1
3
  begin
2
4
  require 'rbbt/persist/tsv/tokyocabinet'
3
5
  rescue Exception
data/lib/rbbt/persist.rb CHANGED
@@ -111,16 +111,8 @@ module Persist
111
111
  res
112
112
  when :marshal
113
113
  Open.open(path) do |stream|
114
- case stream
115
- when StringIO
116
- begin
117
- Marshal.load(stream)
118
- rescue
119
- raise $!
120
- end
121
- else
122
- Marshal.load(stream)
123
- end
114
+ content = stream.read.unpack("m").first
115
+ Marshal.load(content)
124
116
  end
125
117
  when :yaml
126
118
  Open.open(path) do |stream|
@@ -180,7 +172,8 @@ module Persist
180
172
  when :marshal_tsv
181
173
  Misc.sensiblewrite(path, Marshal.dump(content.dup))
182
174
  when :marshal
183
- Misc.sensiblewrite(path, Marshal.dump(content))
175
+ dump = Marshal.dump(content)
176
+ Misc.sensiblewrite(path, [dump].pack("m"))
184
177
  when :yaml
185
178
  Misc.sensiblewrite(path, YAML.dump(content))
186
179
  when :float, :integer, :tsv
@@ -288,36 +281,25 @@ module Persist
288
281
  if stream
289
282
  if persist_options[:no_load] == :stream
290
283
  res = tee_stream(stream, path, type, stream.respond_to?(:callback)? stream.callback : nil, stream.respond_to?(:abort_callback)? stream.abort_callback : nil)
284
+ res.lockfile = lockfile
291
285
 
292
- ConcurrentStream.setup res do
293
- begin
294
- lockfile.unlock #if File.exists? lockfile.path and lockfile.locked?
295
- rescue Exception
296
- Log.medium "Lockfile exception: " << $!.message
297
- end
298
- end
299
- res.abort_callback = Proc.new do
300
- begin
301
- lockfile.unlock #if File.exists? lockfile.path and lockfile.locked?
302
- rescue Exception
303
- Log.medium "Lockfile exception: " << $!.message
304
- end
305
- end
306
286
  raise KeepLocked.new res
307
287
  else
288
+ stream = res.get_stream if res.respond_to? :get_stream
308
289
  begin
309
- res = case type
310
- when :array
311
- res.read.split "\n"
312
- when :tsv
313
- TSV.open(res)
314
- else
315
- res.read
316
- end
317
- res.join if res.respond_to? :join
318
- res
290
+ Open.write(path, stream)
291
+ Open.open(path) do |stream|
292
+ case type
293
+ when :array
294
+ stream.read.split "\n"
295
+ when :tsv
296
+ TSV.open(stream)
297
+ else
298
+ stream.read
299
+ end
300
+ end
319
301
  rescue
320
- res.abort if res.respond_to? :abort
302
+ stream.abort if stream.respond_to? :abort
321
303
  raise $!
322
304
  end
323
305
  end
@@ -326,61 +308,7 @@ module Persist
326
308
  end
327
309
  end
328
310
 
329
- def self._get_result(path, type, persist_options, lockfile, &block)
330
- res = yield
331
-
332
- if persist_options[:no_load] == :stream
333
- stream = IO === res ? res : res.stream
334
- res = tee_stream(stream, path, type, stream.respond_to?(:callback)? stream.callback : nil, stream.respond_to?(:abort_callback)? stream.abort_callback : nil)
335
-
336
- ConcurrentStream.setup res do
337
- begin
338
- lockfile.unlock #if File.exists? lockfile.path and lockfile.locked?
339
- rescue Exception
340
- Log.medium "Lockfile exception: " << $!.message
341
- end
342
- end
343
- res.abort_callback = Proc.new do
344
- begin
345
- lockfile.unlock #if File.exists? lockfile.path and lockfile.locked?
346
- rescue Exception
347
- Log.medium "Lockfile exception: " << $!.message
348
- end
349
- end
350
- raise KeepLocked.new res
351
- end
352
-
353
- case res
354
- when IO
355
- begin
356
- res = case
357
- when :array
358
- res.read.split "\n"
359
- when :tsv
360
- TSV.open(res)
361
- else
362
- res.read
363
- end
364
- res.join if res.respond_to? :join
365
- rescue
366
- res.abort if res.respond_to? :abort
367
- raise $!
368
- end
369
- when (defined? TSV and TSV::Dumper)
370
- begin
371
- io = res.stream
372
- res = TSV.open(io)
373
- io.join if io.respond_to? :join
374
- rescue
375
- io.abort if io.respond_to? :abort
376
- raise $!
377
- end
378
- end
379
- res
380
- end
381
-
382
311
  def self.persist_file(path, type, persist_options, &block)
383
-
384
312
  begin
385
313
  if is_persisted?(path, persist_options)
386
314
  Log.low "Persist up-to-date: #{ path } - #{Misc.fingerprint persist_options}"
@@ -414,7 +342,9 @@ module Persist
414
342
  save_file(path, type, res)
415
343
  end
416
344
 
417
- persist_options[:no_load] ? path : res
345
+ return path if persist_options[:no_load]
346
+
347
+ res
418
348
  end
419
349
 
420
350
  rescue Lockfile::StolenLockError
@@ -281,11 +281,13 @@ module TSV
281
281
  rescue Exception
282
282
  Log.medium{"Exception traversing #{stream_name(obj)}"}
283
283
  Log.exception $!
284
- stream = obj_stream(obj)
285
- stream.abort if stream and stream.respond_to? :abort
286
- stream = obj_stream(options[:into])
287
- stream.abort if stream.respond_to? :abort
288
- raise $!
284
+ begin
285
+ stream = obj_stream(obj)
286
+ stream.abort if stream and stream.respond_to? :abort
287
+ stream = obj_stream(options[:into])
288
+ stream.abort if stream.respond_to? :abort
289
+ raise $!
290
+ end
289
291
  end
290
292
  end
291
293
 
@@ -425,6 +427,8 @@ module TSV
425
427
  end
426
428
 
427
429
  def self.traverse_run(obj, threads, cpus, options = {}, &block)
430
+ threads = nil if threads == 1
431
+ cpus = nil if cpus == 1
428
432
  if ENV["RBBT_NO_MAP_REDUCE"] == "true" or (threads.nil? and cpus.nil?)
429
433
  traverse_obj obj, options, &block
430
434
  else
data/lib/rbbt/util/cmd.rb CHANGED
@@ -202,7 +202,7 @@ module CMD
202
202
  Log.log line, stderr if Integer === stderr and log
203
203
  end
204
204
  serr.close
205
- Thread.exit
205
+ Thread.exit!
206
206
  end
207
207
 
208
208
  #SmartIO.tie sout, pid, cmd, post, in_content, sin, serr
data/lib/rbbt/util/log.rb CHANGED
@@ -17,15 +17,16 @@ module Log
17
17
  end
18
18
 
19
19
  def self.ignore_stderr
20
- backup_stderr = STDERR.dup
21
20
  LOG_MUTEX.synchronize do
22
- begin
23
- File.open('/dev/null', 'w') do |f|
24
- STDERR.reopen(f)
21
+ backup_stderr = STDERR.dup
22
+ File.open('/dev/null', 'w') do |f|
23
+ STDERR.reopen(f)
24
+ begin
25
25
  yield
26
+ ensure
27
+ STDERR.reopen backup_stderr
28
+ backup_stderr.close
26
29
  end
27
- ensure
28
- STDERR.reopen backup_stderr
29
30
  end
30
31
  end
31
32
  end
@@ -1,5 +1,5 @@
1
1
  module ConcurrentStream
2
- attr_accessor :threads, :pids, :callback, :abort_callback, :filename, :joined, :aborted, :autojoin
2
+ attr_accessor :threads, :pids, :callback, :abort_callback, :filename, :joined, :aborted, :autojoin, :lockfile
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
@@ -87,6 +87,7 @@ module ConcurrentStream
87
87
 
88
88
  @joined = true
89
89
  close unless closed?
90
+ lockfile.unlock if lockfile and lockfile.locked?
90
91
  end
91
92
 
92
93
  def abort_threads
@@ -220,4 +220,27 @@ module Misc
220
220
  ary.values_at *p
221
221
  end
222
222
  end
223
+
224
+ def self.object_delta(*args)
225
+ res, delta = nil, nil
226
+ Thread.exclusive do
227
+ pre = Set.new
228
+ delta = Set.new
229
+
230
+ GC.start
231
+ ObjectSpace.each_object(*args) do |o|
232
+ pre.add o
233
+ end
234
+
235
+ res = yield
236
+
237
+ GC.start
238
+ ObjectSpace.each_object(*args) do |o|
239
+ delta.add o unless pre.include? o
240
+ end
241
+
242
+ end
243
+ Log.info "Delta: #{delta.inspect}"
244
+ res
245
+ end
223
246
  end
@@ -1,17 +1,22 @@
1
- if ENV["RBBT_NO_LOCKFILE_REFRESH"] == "true"
2
- Lockfile.refresh = false
3
- Lockfile.max_age = 60 * 60 * 5
4
- Lockfile.max_age = 15
5
- Lockfile.suspend = 10
6
- else
7
- Lockfile.dont_use_lock_id = true
8
- Lockfile.refresh = 5
9
- Lockfile.max_age = 60
10
- Lockfile.suspend = 15
11
- end
12
-
13
-
14
1
  module Misc
2
+ def self.use_lock_id=(use = true)
3
+ if use
4
+ Log.medium "Activating lockfile ids"
5
+ Lockfile.dont_use_lock_id = false
6
+ Lockfile.refresh = 20
7
+ Lockfile.max_age = 60 * 10
8
+ Lockfile.suspend = 10
9
+ else
10
+ Log.medium "De-activating lockfile ids"
11
+ Lockfile.dont_use_lock_id = false
12
+ Lockfile.dont_use_lock_id = true
13
+ Lockfile.refresh = 2
14
+ Lockfile.max_age = 5
15
+ Lockfile.suspend = 1
16
+ end
17
+ end
18
+
19
+ self.use_lock_id = ENV["RBBT_NO_LOCKFILE_ID"] != "true"
15
20
 
16
21
  LOCK_MUTEX = Mutex.new
17
22
  def self.lock(file, unlock = true, options = {})
@@ -83,7 +83,6 @@ module Misc
83
83
 
84
84
  splitter_thread = Thread.new(Thread.current) do |parent|
85
85
  begin
86
- filename = stream.respond_to?(:filename)? stream.filename : nil
87
86
  skip1 = skip2 = false
88
87
  while block = stream.read(2048)
89
88
  begin
@@ -148,7 +147,7 @@ module Misc
148
147
  str
149
148
  end
150
149
 
151
- def self.consume_stream(io, in_thread = false)
150
+ def self.consume_stream(io, in_thread = false, into = nil)
152
151
  return if Path === io
153
152
  return unless io.respond_to? :read
154
153
  if io.respond_to? :closed? and io.closed?
@@ -163,16 +162,19 @@ module Misc
163
162
  else
164
163
  Log.medium "Consuming stream #{Misc.fingerprint io}"
165
164
  begin
166
- while block = io.read(2048)
165
+ while not io.closed? and block = io.read(2048)
166
+ into << block if into
167
167
  end
168
168
  io.join if io.respond_to? :join
169
+ io.close unless io.closed?
169
170
  rescue Aborted
170
171
  Log.medium "Consume stream aborted #{Misc.fingerprint io}"
171
172
  io.abort if io.respond_to? :abort
173
+ io.close unless io.closed?
172
174
  rescue Exception
173
175
  Log.medium "Exception consuming stream: #{Misc.fingerprint io}: #{$!.message}"
174
176
  io.abort if io.respond_to? :abort
175
- io.join
177
+ io.close unless io.closed?
176
178
  raise $!
177
179
  end
178
180
  end
@@ -207,20 +209,30 @@ module Misc
207
209
  begin
208
210
  case
209
211
  when block_given?
210
- File.open(tmp_path, 'w', &block)
212
+ File.open(tmp_path, 'wb', &block)
211
213
  when String === content
212
- File.open(tmp_path, 'w') do |f| f.write content end
214
+ File.open(tmp_path, 'wb') do |f| f.write content end
213
215
  when (IO === content or StringIO === content or File === content)
214
- File.open(tmp_path, 'w') do |f|
215
- while block = content.read(2048);
216
- f.write block
217
- end
216
+
217
+ out = nil
218
+ PIPE_MUTEX.synchronize do
219
+ out = File.open(tmp_path, 'wb')
220
+ out.sync = true
221
+ OPEN_PIPE_IN << out
218
222
  end
223
+
224
+ while block = content.read(2048);
225
+ out.write block
226
+ end
227
+
228
+ content.close
229
+ out.close
219
230
  else
220
- File.open(tmp_path, 'w') do |f| end
231
+ File.open(tmp_path, 'wb') do |f| end
221
232
  end
222
233
 
223
234
  Open.mv tmp_path, path
235
+ content.join if content.respond_to? :join
224
236
  rescue Aborted
225
237
  Log.medium "Aborted sensiblewrite -- #{ Log.reset << Log.color(:blue, path) }"
226
238
  content.abort if content.respond_to? :abort
@@ -146,8 +146,8 @@ module Open
146
146
  def self.get_stream_from_repo(dir, sub_path)
147
147
  repo = get_repo_from_dir(dir)
148
148
  repo.read_and_close do
149
- text = repo[sub_path]
150
- text.nil? ? nil : StringIO.new(text)
149
+ content = repo[sub_path]
150
+ content.nil? ? nil : StringIO.new(content)
151
151
  end
152
152
  end
153
153
 
@@ -367,9 +367,9 @@ module Open
367
367
  file_open(in_cache(url, wget_options), options[:grep], mode, options[:invert_grep])
368
368
  else
369
369
  io = wget(url, wget_options)
370
- add_cache(url, io, wget_options)
371
- io.close
372
- file_open(in_cache(url, wget_options), options[:grep], mode, options[:invert_grep])
370
+ new, save = Misc.tee_stream io
371
+ add_cache(url, save, wget_options)
372
+ new
373
373
  end
374
374
  io = unzip(io) if ((String === url and zip?(url)) and not options[:noz]) or options[:zip]
375
375
  io = gunzip(io) if ((String === url and gzip?(url)) and not options[:noz]) or options[:gzip]
@@ -106,7 +106,7 @@ module SOPT
106
106
 
107
107
  if description and not description.empty?
108
108
  doc << Log.color(:magenta, "## DESCRIPTION") << "\n\n"
109
- doc << Misc.format_paragraph(description)
109
+ doc << Misc.format_paragraph(description) << "\n\n"
110
110
  end
111
111
 
112
112
  doc << Log.color(:magenta, "## OPTIONS") << "\n\n"
@@ -400,7 +400,8 @@ class Step
400
400
  stream = get_stream if @result
401
401
  if stream
402
402
  begin
403
- Misc.consume_stream stream
403
+ @stream_data = StringIO.new
404
+ Misc.consume_stream stream, false, @stream_data
404
405
  rescue Exception
405
406
  self._abort
406
407
  raise $!
@@ -409,7 +410,7 @@ class Step
409
410
  end
410
411
 
411
412
  def grace
412
- until done? or result or error? or aborted? or streaming?
413
+ until done? or result or error? or aborted? or streaming?
413
414
  sleep 1
414
415
  end
415
416
  self