extlib 0.9.8 → 0.9.9
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of extlib might be problematic. Click here for more details.
- data/History.txt +22 -0
- data/LICENSE +1 -1
- data/README +0 -0
- data/Rakefile +17 -12
- data/lib/extlib.rb +1 -1
- data/lib/extlib/blank.rb +51 -21
- data/lib/extlib/boolean.rb +1 -1
- data/lib/extlib/class.rb +12 -12
- data/lib/extlib/datetime.rb +20 -2
- data/lib/extlib/dictionary.rb +2 -2
- data/lib/extlib/hash.rb +57 -34
- data/lib/extlib/inflection.rb +0 -1
- data/lib/extlib/lazy_array.rb +327 -36
- data/lib/extlib/logger.rb +8 -8
- data/lib/extlib/mash.rb +45 -45
- data/lib/extlib/module.rb +1 -1
- data/lib/extlib/nil.rb +1 -1
- data/lib/extlib/numeric.rb +1 -1
- data/lib/extlib/object.rb +8 -21
- data/lib/extlib/object_space.rb +3 -3
- data/lib/extlib/pathname.rb +10 -0
- data/lib/extlib/pooling.rb +9 -17
- data/lib/extlib/rubygems.rb +7 -7
- data/lib/extlib/simple_set.rb +35 -8
- data/lib/extlib/string.rb +85 -42
- data/lib/extlib/struct.rb +10 -1
- data/lib/extlib/symbol.rb +11 -7
- data/lib/extlib/time.rb +31 -9
- data/lib/extlib/version.rb +1 -1
- data/lib/extlib/virtual_file.rb +1 -1
- data/spec/blank_spec.rb +85 -0
- data/spec/class_spec.rb +141 -0
- data/spec/datetime_spec.rb +22 -0
- data/spec/hash_spec.rb +537 -0
- data/spec/hook_spec.rb +1198 -0
- data/spec/inflection/plural_spec.rb +564 -0
- data/spec/inflection/singular_spec.rb +497 -0
- data/spec/inflection_extras_spec.rb +93 -0
- data/spec/lazy_array_spec.rb +1869 -0
- data/spec/mash_spec.rb +286 -0
- data/spec/module_spec.rb +58 -0
- data/spec/object_space_spec.rb +9 -0
- data/spec/object_spec.rb +114 -0
- data/spec/pooling_spec.rb +499 -0
- data/spec/simple_set_spec.rb +57 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/string_spec.rb +220 -0
- data/spec/struct_spec.rb +12 -0
- data/spec/symbol_spec.rb +8 -0
- data/spec/time_spec.rb +22 -0
- data/spec/try_dup_spec.rb +45 -0
- data/spec/virtual_file_spec.rb +21 -0
- metadata +51 -26
- data/README.txt +0 -3
@@ -0,0 +1,499 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
2
|
+
require 'timeout'
|
3
|
+
|
4
|
+
module Extlib::Pooling
|
5
|
+
def self.scavenger_interval
|
6
|
+
1
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "Extlib::Pooling" do
|
11
|
+
before do
|
12
|
+
|
13
|
+
Object.send(:remove_const, :Person) if defined?(Person)
|
14
|
+
class Person
|
15
|
+
include Extlib::Pooling
|
16
|
+
|
17
|
+
attr_accessor :name
|
18
|
+
|
19
|
+
def initialize(name)
|
20
|
+
@name = name
|
21
|
+
end
|
22
|
+
|
23
|
+
def dispose
|
24
|
+
@name = nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
Object.send(:remove_const, :Overwriter) if defined?(Overwriter)
|
29
|
+
class Overwriter
|
30
|
+
|
31
|
+
def self.new(*args)
|
32
|
+
instance = allocate
|
33
|
+
instance.send(:initialize, *args)
|
34
|
+
instance.overwritten = true
|
35
|
+
instance
|
36
|
+
end
|
37
|
+
|
38
|
+
include Extlib::Pooling
|
39
|
+
|
40
|
+
attr_accessor :name
|
41
|
+
|
42
|
+
def initialize(name)
|
43
|
+
@name = name
|
44
|
+
@overwritten = false
|
45
|
+
end
|
46
|
+
|
47
|
+
def overwritten?
|
48
|
+
@overwritten
|
49
|
+
end
|
50
|
+
|
51
|
+
def overwritten=(value)
|
52
|
+
@overwritten = value
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.pool_size
|
56
|
+
pool_size = if RUBY_PLATFORM =~ /java/
|
57
|
+
20
|
58
|
+
else
|
59
|
+
2
|
60
|
+
end
|
61
|
+
pool_size
|
62
|
+
end
|
63
|
+
|
64
|
+
def dispose
|
65
|
+
@name = nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
after :each do
|
71
|
+
Extlib::Pooling.lock.synchronize do
|
72
|
+
Extlib::Pooling.pools.each do |pool|
|
73
|
+
pool.lock.synchronize do
|
74
|
+
pool.dispose
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should track the initialized pools" do
|
81
|
+
bob = Person.new('Bob') # Ensure the pool is "primed"
|
82
|
+
bob.name.should == 'Bob'
|
83
|
+
bob.instance_variable_get(:@__pool).should_not be_nil
|
84
|
+
Person.__pools.size.should == 1
|
85
|
+
bob.release
|
86
|
+
Person.__pools.size.should == 1
|
87
|
+
|
88
|
+
Extlib::Pooling::pools.should_not be_empty
|
89
|
+
|
90
|
+
sleep(1.2)
|
91
|
+
|
92
|
+
Extlib::Pooling::pools.should be_empty
|
93
|
+
bob.name.should be_nil
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should maintain a size of 1" do
|
97
|
+
bob = Person.new('Bob')
|
98
|
+
fred = Person.new('Fred')
|
99
|
+
ted = Person.new('Ted')
|
100
|
+
|
101
|
+
Person.__pools.each do |args, pool|
|
102
|
+
pool.size.should == 1
|
103
|
+
end
|
104
|
+
|
105
|
+
bob.release
|
106
|
+
fred.release
|
107
|
+
ted.release
|
108
|
+
|
109
|
+
Person.__pools.each do |args, pool|
|
110
|
+
pool.size.should == 1
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should allow you to overwrite Class#new" do
|
115
|
+
bob = Overwriter.new('Bob')
|
116
|
+
bob.should be_overwritten
|
117
|
+
bob.release
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should allow multiple threads to access the pool" do
|
121
|
+
t1 = Thread.new do
|
122
|
+
bob = Person.new('Bob')
|
123
|
+
sleep(1)
|
124
|
+
bob.release
|
125
|
+
end
|
126
|
+
|
127
|
+
lambda do
|
128
|
+
bob = Person.new('Bob')
|
129
|
+
t1.join
|
130
|
+
bob.release
|
131
|
+
end.should_not raise_error
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should allow you to flush a pool" do
|
135
|
+
bob = Overwriter.new('Bob')
|
136
|
+
Overwriter.new('Bob').release
|
137
|
+
bob.release
|
138
|
+
|
139
|
+
bob.name.should == 'Bob'
|
140
|
+
|
141
|
+
Overwriter.__pools[['Bob']].size.should == 2
|
142
|
+
Overwriter.__pools[['Bob']].flush!
|
143
|
+
Overwriter.__pools[['Bob']].size.should == 0
|
144
|
+
|
145
|
+
bob.name.should be_nil
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should wake up the scavenger thread when exiting" do
|
149
|
+
pending 'Fix for Ruby 1.9.1 and JRuby' if RUBY_VERSION >= '1.9.1' || RUBY_PLATFORM =~ /java/
|
150
|
+
bob = Person.new('Bob')
|
151
|
+
bob.release
|
152
|
+
Extlib.exiting = true
|
153
|
+
sleep(0.1)
|
154
|
+
Extlib::Pooling.scavenger?.should be_false
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
# describe Extlib::Pooling::ResourcePool do
|
160
|
+
# before :each do
|
161
|
+
# @pool = Extlib::Pooling::ResourcePool.new(7, DisposableResource, :expiration_period => 50)
|
162
|
+
# end
|
163
|
+
#
|
164
|
+
# it "responds to flush!" do
|
165
|
+
# @pool.should respond_to(:flush!)
|
166
|
+
# end
|
167
|
+
#
|
168
|
+
# it "responds to acquire" do
|
169
|
+
# @pool.should respond_to(:acquire)
|
170
|
+
# end
|
171
|
+
#
|
172
|
+
# it "responds to release" do
|
173
|
+
# @pool.should respond_to(:release)
|
174
|
+
# end
|
175
|
+
#
|
176
|
+
# it "responds to :available?" do
|
177
|
+
# @pool.should respond_to(:available?)
|
178
|
+
# end
|
179
|
+
#
|
180
|
+
# it "has a size limit" do
|
181
|
+
# @pool.size_limit.should == 7
|
182
|
+
# end
|
183
|
+
#
|
184
|
+
# it "has initial size of zero" do
|
185
|
+
# @pool.size.should == 0
|
186
|
+
# end
|
187
|
+
#
|
188
|
+
# it "has a set of reserved resources" do
|
189
|
+
# @pool.instance_variable_get("@reserved").should be_empty
|
190
|
+
# end
|
191
|
+
#
|
192
|
+
# it "has a set of available resources" do
|
193
|
+
# @pool.instance_variable_get("@available").should be_empty
|
194
|
+
# end
|
195
|
+
#
|
196
|
+
# it "knows class of resources (objects) it works with" do
|
197
|
+
# @pool.class_of_resources.should == DisposableResource
|
198
|
+
# end
|
199
|
+
#
|
200
|
+
# it "raises exception when given anything but class for resources class" do
|
201
|
+
# lambda {
|
202
|
+
# @pool = Extlib::Pooling::ResourcePool.new(7, "Hooray!", {})
|
203
|
+
# }.should raise_error(ArgumentError, /class/)
|
204
|
+
# end
|
205
|
+
#
|
206
|
+
# it "requires class of resources (objects) it works with to have a dispose instance method" do
|
207
|
+
# lambda {
|
208
|
+
# @pool = Extlib::Pooling::ResourcePool.new(3, UndisposableResource, {})
|
209
|
+
# }.should raise_error(ArgumentError, /dispose/)
|
210
|
+
# end
|
211
|
+
#
|
212
|
+
# it "may take initialization arguments" do
|
213
|
+
# @pool = Extlib::Pooling::ResourcePool.new(7, DisposableResource, { :initialization_args => ["paper"] })
|
214
|
+
# @pool.instance_variable_get("@initialization_args").should == ["paper"]
|
215
|
+
# end
|
216
|
+
#
|
217
|
+
# it "may take expiration period option" do
|
218
|
+
# @pool = Extlib::Pooling::ResourcePool.new(7, DisposableResource, { :expiration_period => 100 })
|
219
|
+
# @pool.expiration_period.should == 100
|
220
|
+
# end
|
221
|
+
#
|
222
|
+
# it "has default expiration period of one minute" do
|
223
|
+
# @pool = Extlib::Pooling::ResourcePool.new(7, DisposableResource, {})
|
224
|
+
# @pool.expiration_period.should == 60
|
225
|
+
# end
|
226
|
+
#
|
227
|
+
# it "spawns a thread to dispose objects haven't been used for a while" do
|
228
|
+
# @pool = Extlib::Pooling::ResourcePool.new(7, DisposableResource, {})
|
229
|
+
# @pool.instance_variable_get("@pool_expiration_thread").should be_an_instance_of(Thread)
|
230
|
+
# end
|
231
|
+
# end
|
232
|
+
#
|
233
|
+
#
|
234
|
+
#
|
235
|
+
# describe "Acquire from constant size pool" do
|
236
|
+
# before :each do
|
237
|
+
# DisposableResource.initialize_pool(2)
|
238
|
+
# end
|
239
|
+
#
|
240
|
+
# after :each do
|
241
|
+
# DisposableResource.instance_variable_set("@__pool", nil)
|
242
|
+
# end
|
243
|
+
#
|
244
|
+
# it "increased size of the pool" do
|
245
|
+
# @time = DisposableResource.pool.acquire
|
246
|
+
# DisposableResource.pool.size.should == 1
|
247
|
+
# end
|
248
|
+
#
|
249
|
+
# it "places initialized instance in the reserved set" do
|
250
|
+
# @time = DisposableResource.pool.acquire
|
251
|
+
# DisposableResource.pool.instance_variable_get("@reserved").size.should == 1
|
252
|
+
# end
|
253
|
+
#
|
254
|
+
# it "raises an exception when pool size limit is hit" do
|
255
|
+
# @t1 = DisposableResource.pool.acquire
|
256
|
+
# @t2 = DisposableResource.pool.acquire
|
257
|
+
#
|
258
|
+
# lambda { DisposableResource.pool.acquire }.should raise_error(RuntimeError)
|
259
|
+
# end
|
260
|
+
#
|
261
|
+
# it "returns last released resource" do
|
262
|
+
# @t1 = DisposableResource.pool.acquire
|
263
|
+
# @t2 = DisposableResource.pool.acquire
|
264
|
+
# DisposableResource.pool.release(@t1)
|
265
|
+
#
|
266
|
+
# DisposableResource.pool.acquire.should == @t1
|
267
|
+
# end
|
268
|
+
#
|
269
|
+
# it "really truly returns last released resource" do
|
270
|
+
# @t1 = DisposableResource.pool.acquire
|
271
|
+
# DisposableResource.pool.release(@t1)
|
272
|
+
#
|
273
|
+
# @t2 = DisposableResource.pool.acquire
|
274
|
+
# DisposableResource.pool.release(@t2)
|
275
|
+
#
|
276
|
+
# @t3 = DisposableResource.pool.acquire
|
277
|
+
# DisposableResource.pool.release(@t3)
|
278
|
+
#
|
279
|
+
# DisposableResource.pool.acquire.should == @t1
|
280
|
+
# @t1.should == @t3
|
281
|
+
# end
|
282
|
+
#
|
283
|
+
# it "sets allocation timestamp on resource instance" do
|
284
|
+
# @t1 = DisposableResource.new
|
285
|
+
# @t1.instance_variable_get("@__pool_acquire_timestamp").should be_close(Time.now, 2)
|
286
|
+
# end
|
287
|
+
# end
|
288
|
+
#
|
289
|
+
#
|
290
|
+
#
|
291
|
+
# describe "Releasing from constant size pool" do
|
292
|
+
# before :each do
|
293
|
+
# DisposableResource.initialize_pool(2)
|
294
|
+
# end
|
295
|
+
#
|
296
|
+
# after :each do
|
297
|
+
# DisposableResource.instance_variable_set("@__pool", nil)
|
298
|
+
# end
|
299
|
+
#
|
300
|
+
# it "decreases size of the pool" do
|
301
|
+
# @t1 = DisposableResource.pool.acquire
|
302
|
+
# @t2 = DisposableResource.pool.acquire
|
303
|
+
# DisposableResource.pool.release(@t1)
|
304
|
+
#
|
305
|
+
# DisposableResource.pool.size.should == 1
|
306
|
+
# end
|
307
|
+
#
|
308
|
+
# it "raises an exception on attempt to releases object not in pool" do
|
309
|
+
# @t1 = DisposableResource.new
|
310
|
+
# @t2 = Set.new
|
311
|
+
#
|
312
|
+
# DisposableResource.pool.release(@t1)
|
313
|
+
# lambda { DisposableResource.pool.release(@t2) }.should raise_error(RuntimeError)
|
314
|
+
# end
|
315
|
+
#
|
316
|
+
# it "removes released object from reserved set" do
|
317
|
+
# @t1 = DisposableResource.pool.acquire
|
318
|
+
#
|
319
|
+
# lambda {
|
320
|
+
# DisposableResource.pool.release(@t1)
|
321
|
+
# }.should change(DisposableResource.pool.instance_variable_get("@reserved"), :size).by(-1)
|
322
|
+
# end
|
323
|
+
#
|
324
|
+
# it "returns released object back to available set" do
|
325
|
+
# @t1 = DisposableResource.pool.acquire
|
326
|
+
#
|
327
|
+
# lambda {
|
328
|
+
# DisposableResource.pool.release(@t1)
|
329
|
+
# }.should change(DisposableResource.pool.instance_variable_get("@available"), :size).by(1)
|
330
|
+
# end
|
331
|
+
#
|
332
|
+
# it "updates acquire timestamp on already allocated resource instance" do
|
333
|
+
# # acquire it once
|
334
|
+
# @t1 = DisposableResource.new
|
335
|
+
# # wait a bit
|
336
|
+
# sleep 3
|
337
|
+
#
|
338
|
+
# # check old timestamp
|
339
|
+
# @t1.instance_variable_get("@__pool_acquire_timestamp").should be_close(Time.now, 4)
|
340
|
+
#
|
341
|
+
# # re-acquire
|
342
|
+
# DisposableResource.pool.release(@t1)
|
343
|
+
# @t1 = DisposableResource.new
|
344
|
+
# # see timestamp is updated
|
345
|
+
# @t1.instance_variable_get("@__pool_acquire_timestamp").should be_close(Time.now, 2)
|
346
|
+
# end
|
347
|
+
# end
|
348
|
+
#
|
349
|
+
#
|
350
|
+
#
|
351
|
+
# describe Extlib::Pooling::ResourcePool, "#available?" do
|
352
|
+
# before :each do
|
353
|
+
# DisposableResource.initialize_pool(2)
|
354
|
+
# DisposableResource.new
|
355
|
+
# end
|
356
|
+
#
|
357
|
+
# after :each do
|
358
|
+
# DisposableResource.instance_variable_set("@__pool", nil)
|
359
|
+
# end
|
360
|
+
#
|
361
|
+
# it "returns true when pool has available instances" do
|
362
|
+
# DisposableResource.pool.should be_available
|
363
|
+
# end
|
364
|
+
#
|
365
|
+
# it "returns false when pool is exhausted" do
|
366
|
+
# # acquires the last available resource
|
367
|
+
# DisposableResource.new
|
368
|
+
# DisposableResource.pool.should_not be_available
|
369
|
+
# end
|
370
|
+
# end
|
371
|
+
#
|
372
|
+
#
|
373
|
+
#
|
374
|
+
# describe "Flushing of constant size pool" do
|
375
|
+
# before :each do
|
376
|
+
# DisposableResource.initialize_pool(2)
|
377
|
+
#
|
378
|
+
# @t1 = DisposableResource.new
|
379
|
+
# @t2 = DisposableResource.new
|
380
|
+
#
|
381
|
+
# # sanity check
|
382
|
+
# DisposableResource.pool.instance_variable_get("@reserved").should_not be_empty
|
383
|
+
# end
|
384
|
+
#
|
385
|
+
# after :each do
|
386
|
+
# DisposableResource.instance_variable_set("@__pool", nil)
|
387
|
+
# end
|
388
|
+
#
|
389
|
+
# it "disposes all pooled objects" do
|
390
|
+
# [@t1, @t2].each { |instance| instance.should_receive(:dispose) }
|
391
|
+
#
|
392
|
+
# DisposableResource.pool.flush!
|
393
|
+
# end
|
394
|
+
#
|
395
|
+
# it "empties reserved set" do
|
396
|
+
# DisposableResource.pool.flush!
|
397
|
+
#
|
398
|
+
# DisposableResource.pool.instance_variable_get("@reserved").should be_empty
|
399
|
+
# end
|
400
|
+
#
|
401
|
+
# it "returns all instances to available set" do
|
402
|
+
# DisposableResource.pool.flush!
|
403
|
+
#
|
404
|
+
# DisposableResource.pool.instance_variable_get("@available").size.should == 2
|
405
|
+
# end
|
406
|
+
# end
|
407
|
+
#
|
408
|
+
#
|
409
|
+
#
|
410
|
+
# describe "Poolable resource class" do
|
411
|
+
# before :each do
|
412
|
+
# DisposableResource.initialize_pool(3, :initialization_args => ["paper"])
|
413
|
+
# end
|
414
|
+
#
|
415
|
+
# after :each do
|
416
|
+
# DisposableResource.instance_variable_set("@__pool", nil)
|
417
|
+
# end
|
418
|
+
#
|
419
|
+
# it "acquires new instances from pool" do
|
420
|
+
# @instance_one = DisposableResource.new
|
421
|
+
#
|
422
|
+
# DisposableResource.pool.acquired?(@instance_one).should be(true)
|
423
|
+
# end
|
424
|
+
#
|
425
|
+
# it "flushed existing pool on re-initialization" do
|
426
|
+
# DisposableResource.pool.should_receive(:flush!)
|
427
|
+
# DisposableResource.initialize_pool(5)
|
428
|
+
# end
|
429
|
+
#
|
430
|
+
# it "replaces pool on re-initialization" do
|
431
|
+
# DisposableResource.initialize_pool(5)
|
432
|
+
# DisposableResource.pool.size_limit.should == 5
|
433
|
+
# end
|
434
|
+
#
|
435
|
+
# it "passes initialization parameters to newly created resource instances" do
|
436
|
+
# DisposableResource.new.name.should == "paper"
|
437
|
+
# end
|
438
|
+
# end
|
439
|
+
#
|
440
|
+
#
|
441
|
+
#
|
442
|
+
# describe "Pooled object", "on initialization" do
|
443
|
+
# after :each do
|
444
|
+
# DisposableResource.instance_variable_set("@__pool", nil)
|
445
|
+
# end
|
446
|
+
#
|
447
|
+
# it "does not flush pool" do
|
448
|
+
# # using pool here initializes the pool first
|
449
|
+
# # so we use instance variable directly
|
450
|
+
# DisposableResource.instance_variable_get("@__pool").should_not_receive(:flush!)
|
451
|
+
# DisposableResource.initialize_pool(23)
|
452
|
+
# end
|
453
|
+
#
|
454
|
+
# it "flushes pool first when re-initialized" do
|
455
|
+
# DisposableResource.initialize_pool(5)
|
456
|
+
# DisposableResource.pool.should_receive(:flush!)
|
457
|
+
# DisposableResource.initialize_pool(23)
|
458
|
+
# end
|
459
|
+
# end
|
460
|
+
#
|
461
|
+
#
|
462
|
+
#
|
463
|
+
# describe Extlib::Pooling::ResourcePool, "#time_to_dispose?" do
|
464
|
+
# before :each do
|
465
|
+
# DisposableResource.initialize_pool(7, :expiration_period => 2)
|
466
|
+
# end
|
467
|
+
#
|
468
|
+
# after :each do
|
469
|
+
# DisposableResource.instance_variable_set("@__pool", nil)
|
470
|
+
# end
|
471
|
+
#
|
472
|
+
# it "returns true when object's last aquisition time is greater than limit" do
|
473
|
+
# @t1 = DisposableResource.new
|
474
|
+
# DisposableResource.pool.time_to_release?(@t1).should be(false)
|
475
|
+
#
|
476
|
+
# sleep 3
|
477
|
+
# DisposableResource.pool.time_to_release?(@t1).should be(true)
|
478
|
+
# end
|
479
|
+
# end
|
480
|
+
#
|
481
|
+
#
|
482
|
+
#
|
483
|
+
# describe Extlib::Pooling::ResourcePool, "#dispose_outdated" do
|
484
|
+
# before :each do
|
485
|
+
# DisposableResource.initialize_pool(7, :expiration_period => 2)
|
486
|
+
# end
|
487
|
+
#
|
488
|
+
# after :each do
|
489
|
+
# DisposableResource.instance_variable_set("@__pool", nil)
|
490
|
+
# end
|
491
|
+
#
|
492
|
+
# it "releases and thus disposes outdated instances" do
|
493
|
+
# @t1 = DisposableResource.new
|
494
|
+
# DisposableResource.pool.should_receive(:time_to_release?).with(@t1).and_return(true)
|
495
|
+
# DisposableResource.pool.should_receive(:release).with(@t1)
|
496
|
+
#
|
497
|
+
# DisposableResource.pool.dispose_outdated
|
498
|
+
# end
|
499
|
+
# end
|