logstash-output-scalyr 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (21) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +27 -2
  3. data/lib/scalyr/common/client.rb +3 -1
  4. data/logstash-output-scalyr.gemspec +2 -2
  5. data/vendor/bundle/jruby/2.5.0/bin/jruby_executable_hooks +25 -0
  6. data/vendor/bundle/jruby/2.5.0/cache/connection_pool-2.2.3.gem +0 -0
  7. data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/Changes.md +130 -0
  8. data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/Gemfile +5 -0
  9. data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/LICENSE +20 -0
  10. data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/README.md +121 -0
  11. data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/Rakefile +7 -0
  12. data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/connection_pool.gemspec +20 -0
  13. data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/lib/connection_pool.rb +110 -0
  14. data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/lib/connection_pool/timed_stack.rb +170 -0
  15. data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/lib/connection_pool/version.rb +3 -0
  16. data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/lib/connection_pool/wrapper.rb +43 -0
  17. data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/test/helper.rb +8 -0
  18. data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/test/test_connection_pool.rb +553 -0
  19. data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/test/test_connection_pool_timed_stack.rb +140 -0
  20. data/vendor/bundle/jruby/2.5.0/specifications/connection_pool-2.2.3.gemspec +34 -0
  21. metadata +21 -6
@@ -0,0 +1,170 @@
1
+ ##
2
+ # The TimedStack manages a pool of homogeneous connections (or any resource
3
+ # you wish to manage). Connections are created lazily up to a given maximum
4
+ # number.
5
+
6
+ # Examples:
7
+ #
8
+ # ts = TimedStack.new(1) { MyConnection.new }
9
+ #
10
+ # # fetch a connection
11
+ # conn = ts.pop
12
+ #
13
+ # # return a connection
14
+ # ts.push conn
15
+ #
16
+ # conn = ts.pop
17
+ # ts.pop timeout: 5
18
+ # #=> raises Timeout::Error after 5 seconds
19
+
20
+ class ConnectionPool::TimedStack
21
+ attr_reader :max
22
+
23
+ ##
24
+ # Creates a new pool with +size+ connections that are created from the given
25
+ # +block+.
26
+
27
+ def initialize(size = 0, &block)
28
+ @create_block = block
29
+ @created = 0
30
+ @que = []
31
+ @max = size
32
+ @mutex = Mutex.new
33
+ @resource = ConditionVariable.new
34
+ @shutdown_block = nil
35
+ end
36
+
37
+ ##
38
+ # Returns +obj+ to the stack. +options+ is ignored in TimedStack but may be
39
+ # used by subclasses that extend TimedStack.
40
+
41
+ def push(obj, options = {})
42
+ @mutex.synchronize do
43
+ if @shutdown_block
44
+ @shutdown_block.call(obj)
45
+ else
46
+ store_connection obj, options
47
+ end
48
+
49
+ @resource.broadcast
50
+ end
51
+ end
52
+ alias << push
53
+
54
+ ##
55
+ # Retrieves a connection from the stack. If a connection is available it is
56
+ # immediately returned. If no connection is available within the given
57
+ # timeout a Timeout::Error is raised.
58
+ #
59
+ # +:timeout+ is the only checked entry in +options+ and is preferred over
60
+ # the +timeout+ argument (which will be removed in a future release). Other
61
+ # options may be used by subclasses that extend TimedStack.
62
+
63
+ def pop(timeout = 0.5, options = {})
64
+ options, timeout = timeout, 0.5 if Hash === timeout
65
+ timeout = options.fetch :timeout, timeout
66
+
67
+ deadline = current_time + timeout
68
+ @mutex.synchronize do
69
+ loop do
70
+ raise ConnectionPool::PoolShuttingDownError if @shutdown_block
71
+ return fetch_connection(options) if connection_stored?(options)
72
+
73
+ connection = try_create(options)
74
+ return connection if connection
75
+
76
+ to_wait = deadline - current_time
77
+ raise ConnectionPool::TimeoutError, "Waited #{timeout} sec" if to_wait <= 0
78
+ @resource.wait(@mutex, to_wait)
79
+ end
80
+ end
81
+ end
82
+
83
+ ##
84
+ # Shuts down the TimedStack which prevents connections from being checked
85
+ # out. The +block+ is called once for each connection on the stack.
86
+
87
+ def shutdown(&block)
88
+ raise ArgumentError, "shutdown must receive a block" unless block_given?
89
+
90
+ @mutex.synchronize do
91
+ @shutdown_block = block
92
+ @resource.broadcast
93
+
94
+ shutdown_connections
95
+ end
96
+ end
97
+
98
+ ##
99
+ # Returns +true+ if there are no available connections.
100
+
101
+ def empty?
102
+ (@created - @que.length) >= @max
103
+ end
104
+
105
+ ##
106
+ # The number of connections available on the stack.
107
+
108
+ def length
109
+ @max - @created + @que.length
110
+ end
111
+
112
+ private
113
+
114
+ def current_time
115
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
116
+ end
117
+
118
+ ##
119
+ # This is an extension point for TimedStack and is called with a mutex.
120
+ #
121
+ # This method must returns true if a connection is available on the stack.
122
+
123
+ def connection_stored?(options = nil)
124
+ !@que.empty?
125
+ end
126
+
127
+ ##
128
+ # This is an extension point for TimedStack and is called with a mutex.
129
+ #
130
+ # This method must return a connection from the stack.
131
+
132
+ def fetch_connection(options = nil)
133
+ @que.pop
134
+ end
135
+
136
+ ##
137
+ # This is an extension point for TimedStack and is called with a mutex.
138
+ #
139
+ # This method must shut down all connections on the stack.
140
+
141
+ def shutdown_connections(options = nil)
142
+ while connection_stored?(options)
143
+ conn = fetch_connection(options)
144
+ @shutdown_block.call(conn)
145
+ end
146
+ end
147
+
148
+ ##
149
+ # This is an extension point for TimedStack and is called with a mutex.
150
+ #
151
+ # This method must return +obj+ to the stack.
152
+
153
+ def store_connection(obj, options = nil)
154
+ @que.push obj
155
+ end
156
+
157
+ ##
158
+ # This is an extension point for TimedStack and is called with a mutex.
159
+ #
160
+ # This method must create a connection if and only if the total number of
161
+ # connections allowed has not been met.
162
+
163
+ def try_create(options = nil)
164
+ unless @created == @max
165
+ object = @create_block.call
166
+ @created += 1
167
+ object
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,3 @@
1
+ class ConnectionPool
2
+ VERSION = "2.2.3"
3
+ end
@@ -0,0 +1,43 @@
1
+ class ConnectionPool
2
+ class Wrapper < ::BasicObject
3
+ METHODS = [:with, :pool_shutdown, :wrapped_pool]
4
+
5
+ def initialize(options = {}, &block)
6
+ @pool = options.fetch(:pool) { ::ConnectionPool.new(options, &block) }
7
+ end
8
+
9
+ def wrapped_pool
10
+ @pool
11
+ end
12
+
13
+ def with(&block)
14
+ @pool.with(&block)
15
+ end
16
+
17
+ def pool_shutdown(&block)
18
+ @pool.shutdown(&block)
19
+ end
20
+
21
+ def pool_size
22
+ @pool.size
23
+ end
24
+
25
+ def pool_available
26
+ @pool.available
27
+ end
28
+
29
+ def respond_to?(id, *args)
30
+ METHODS.include?(id) || with { |c| c.respond_to?(id, *args) }
31
+ end
32
+
33
+ # rubocop:disable Style/MethodMissingSuper
34
+ # rubocop:disable Style/MissingRespondToMissing
35
+ def method_missing(name, *args, &block)
36
+ with do |connection|
37
+ connection.send(name, *args, &block)
38
+ end
39
+ end
40
+ # rubocop:enable Style/MethodMissingSuper
41
+ # rubocop:enable Style/MissingRespondToMissing
42
+ end
43
+ end
@@ -0,0 +1,8 @@
1
+ gem "minitest"
2
+
3
+ require "minitest/pride"
4
+ require "minitest/autorun"
5
+
6
+ $VERBOSE = 1
7
+
8
+ require_relative "../lib/connection_pool"
@@ -0,0 +1,553 @@
1
+ require_relative "helper"
2
+
3
+ class TestConnectionPool < Minitest::Test
4
+ class NetworkConnection
5
+ SLEEP_TIME = 0.1
6
+
7
+ def initialize
8
+ @x = 0
9
+ end
10
+
11
+ def do_something
12
+ @x += 1
13
+ sleep SLEEP_TIME
14
+ @x
15
+ end
16
+
17
+ def fast
18
+ @x += 1
19
+ end
20
+
21
+ def do_something_with_block
22
+ @x += yield
23
+ sleep SLEEP_TIME
24
+ @x
25
+ end
26
+
27
+ def respond_to?(method_id, *args)
28
+ method_id == :do_magic || super(method_id, *args)
29
+ end
30
+ end
31
+
32
+ class Recorder
33
+ def initialize
34
+ @calls = []
35
+ end
36
+
37
+ attr_reader :calls
38
+
39
+ def do_work(label)
40
+ @calls << label
41
+ end
42
+ end
43
+
44
+ def use_pool(pool, size)
45
+ Array.new(size) {
46
+ Thread.new do
47
+ pool.with { sleep }
48
+ end
49
+ }.each do |thread|
50
+ Thread.pass until thread.status == "sleep"
51
+ end
52
+ end
53
+
54
+ def kill_threads(threads)
55
+ threads.each do |thread|
56
+ thread.kill
57
+ thread.join
58
+ end
59
+ end
60
+
61
+ def test_basic_multithreaded_usage
62
+ pool_size = 5
63
+ pool = ConnectionPool.new(size: pool_size) { NetworkConnection.new }
64
+
65
+ start = Time.new
66
+
67
+ generations = 3
68
+
69
+ result = Array.new(pool_size * generations) {
70
+ Thread.new do
71
+ pool.with do |net|
72
+ net.do_something
73
+ end
74
+ end
75
+ }.map(&:value)
76
+
77
+ finish = Time.new
78
+
79
+ assert_equal((1..generations).cycle(pool_size).sort, result.sort)
80
+
81
+ assert_operator(finish - start, :>, generations * NetworkConnection::SLEEP_TIME)
82
+ end
83
+
84
+ def test_timeout
85
+ pool = ConnectionPool.new(timeout: 0, size: 1) { NetworkConnection.new }
86
+ thread = Thread.new {
87
+ pool.with do |net|
88
+ net.do_something
89
+ sleep 0.01
90
+ end
91
+ }
92
+
93
+ Thread.pass while thread.status == "run"
94
+
95
+ assert_raises Timeout::Error do
96
+ pool.with { |net| net.do_something }
97
+ end
98
+
99
+ thread.join
100
+
101
+ pool.with do |conn|
102
+ refute_nil conn
103
+ end
104
+ end
105
+
106
+ def test_with
107
+ pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
108
+
109
+ pool.with do
110
+ Thread.new {
111
+ assert_raises Timeout::Error do
112
+ pool.checkout
113
+ end
114
+ }.join
115
+ end
116
+
117
+ assert Thread.new { pool.checkout }.join
118
+ end
119
+
120
+ def test_with_timeout
121
+ pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
122
+
123
+ assert_raises Timeout::Error do
124
+ Timeout.timeout(0.01) do
125
+ pool.with do |obj|
126
+ assert_equal 0, pool.available
127
+ sleep 0.015
128
+ end
129
+ end
130
+ end
131
+ assert_equal 1, pool.available
132
+ end
133
+
134
+ def test_invalid_size
135
+ assert_raises ArgumentError, TypeError do
136
+ ConnectionPool.new(timeout: 0, size: nil) { Object.new }
137
+ end
138
+ assert_raises ArgumentError, TypeError do
139
+ ConnectionPool.new(timeout: 0, size: "") { Object.new }
140
+ end
141
+ end
142
+
143
+ def test_handle_interrupt_ensures_checkin
144
+ pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
145
+ def pool.checkout(options)
146
+ sleep 0.015
147
+ super
148
+ end
149
+
150
+ did_something = false
151
+
152
+ action = lambda do
153
+ Timeout.timeout(0.01) do
154
+ pool.with do |obj|
155
+ did_something = true
156
+ # Timeout::Error will be triggered by any non-trivial Ruby code
157
+ # executed here since it couldn't be raised during checkout.
158
+ # It looks like setting the local variable above does not trigger
159
+ # the Timeout check in MRI 2.2.1.
160
+ obj.tap { obj.hash }
161
+ end
162
+ end
163
+ end
164
+
165
+ if RUBY_ENGINE == "ruby"
166
+ # These asserts rely on the Ruby implementation reaching `did_something =
167
+ # true` before the interrupt is detected by the thread. Interrupt
168
+ # detection timing is implementation-specific in practice, with JRuby,
169
+ # Rubinius, and TruffleRuby all having different interrupt timings to MRI.
170
+ # In fact they generally detect interrupts more quickly than MRI, so they
171
+ # may not reach `did_something = true` before detecting the interrupt.
172
+
173
+ assert_raises Timeout::Error, &action
174
+
175
+ assert did_something
176
+ else
177
+ action.call
178
+ end
179
+
180
+ assert_equal 1, pool.available
181
+ end
182
+
183
+ def test_explicit_return
184
+ pool = ConnectionPool.new(timeout: 0, size: 1) {
185
+ mock = Minitest::Mock.new
186
+ def mock.disconnect!
187
+ raise "should not disconnect upon explicit return"
188
+ end
189
+ mock
190
+ }
191
+
192
+ pool.with do |conn|
193
+ return true
194
+ end
195
+ end
196
+
197
+ def test_with_timeout_override
198
+ pool = ConnectionPool.new(timeout: 0, size: 1) { NetworkConnection.new }
199
+
200
+ t = Thread.new {
201
+ pool.with do |net|
202
+ net.do_something
203
+ sleep 0.01
204
+ end
205
+ }
206
+
207
+ Thread.pass while t.status == "run"
208
+
209
+ assert_raises Timeout::Error do
210
+ pool.with { |net| net.do_something }
211
+ end
212
+
213
+ pool.with(timeout: 2 * NetworkConnection::SLEEP_TIME) do |conn|
214
+ refute_nil conn
215
+ end
216
+ end
217
+
218
+ def test_checkin
219
+ pool = ConnectionPool.new(timeout: 0, size: 1) { NetworkConnection.new }
220
+ conn = pool.checkout
221
+
222
+ Thread.new {
223
+ assert_raises Timeout::Error do
224
+ pool.checkout
225
+ end
226
+ }.join
227
+
228
+ pool.checkin
229
+
230
+ assert_same conn, Thread.new { pool.checkout }.value
231
+ end
232
+
233
+ def test_returns_value
234
+ pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
235
+ assert_equal 1, pool.with { |o| 1 }
236
+ end
237
+
238
+ def test_checkin_never_checkout
239
+ pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
240
+
241
+ e = assert_raises(ConnectionPool::Error) { pool.checkin }
242
+ assert_equal "no connections are checked out", e.message
243
+ end
244
+
245
+ def test_checkin_no_current_checkout
246
+ pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
247
+
248
+ pool.checkout
249
+ pool.checkin
250
+
251
+ assert_raises ConnectionPool::Error do
252
+ pool.checkin
253
+ end
254
+ end
255
+
256
+ def test_checkin_twice
257
+ pool = ConnectionPool.new(timeout: 0, size: 1) { Object.new }
258
+
259
+ pool.checkout
260
+ pool.checkout
261
+
262
+ pool.checkin
263
+
264
+ Thread.new {
265
+ assert_raises Timeout::Error do
266
+ pool.checkout
267
+ end
268
+ }.join
269
+
270
+ pool.checkin
271
+
272
+ assert Thread.new { pool.checkout }.join
273
+ end
274
+
275
+ def test_checkout
276
+ pool = ConnectionPool.new(size: 1) { NetworkConnection.new }
277
+
278
+ conn = pool.checkout
279
+
280
+ assert_kind_of NetworkConnection, conn
281
+
282
+ assert_same conn, pool.checkout
283
+ end
284
+
285
+ def test_checkout_multithread
286
+ pool = ConnectionPool.new(size: 2) { NetworkConnection.new }
287
+ conn = pool.checkout
288
+
289
+ t = Thread.new {
290
+ pool.checkout
291
+ }
292
+
293
+ refute_same conn, t.value
294
+ end
295
+
296
+ def test_checkout_timeout
297
+ pool = ConnectionPool.new(timeout: 0, size: 0) { Object.new }
298
+
299
+ assert_raises Timeout::Error do
300
+ pool.checkout
301
+ end
302
+ end
303
+
304
+ def test_checkout_timeout_override
305
+ pool = ConnectionPool.new(timeout: 0, size: 1) { NetworkConnection.new }
306
+
307
+ thread = Thread.new {
308
+ pool.with do |net|
309
+ net.do_something
310
+ sleep 0.01
311
+ end
312
+ }
313
+
314
+ Thread.pass while thread.status == "run"
315
+
316
+ assert_raises Timeout::Error do
317
+ pool.checkout
318
+ end
319
+
320
+ assert pool.checkout timeout: 2 * NetworkConnection::SLEEP_TIME
321
+ end
322
+
323
+ def test_passthru
324
+ pool = ConnectionPool.wrap(timeout: 2 * NetworkConnection::SLEEP_TIME, size: 1) { NetworkConnection.new }
325
+ assert_equal 1, pool.do_something
326
+ assert_equal 2, pool.do_something
327
+ assert_equal 5, pool.do_something_with_block { 3 }
328
+ assert_equal 6, pool.with { |net| net.fast }
329
+ end
330
+
331
+ def test_passthru_respond_to
332
+ pool = ConnectionPool.wrap(timeout: 2 * NetworkConnection::SLEEP_TIME, size: 1) { NetworkConnection.new }
333
+ assert pool.respond_to?(:with)
334
+ assert pool.respond_to?(:do_something)
335
+ assert pool.respond_to?(:do_magic)
336
+ refute pool.respond_to?(:do_lots_of_magic)
337
+ end
338
+
339
+ def test_return_value
340
+ pool = ConnectionPool.new(timeout: 2 * NetworkConnection::SLEEP_TIME, size: 1) { NetworkConnection.new }
341
+ result = pool.with { |net|
342
+ net.fast
343
+ }
344
+ assert_equal 1, result
345
+ end
346
+
347
+ def test_heavy_threading
348
+ pool = ConnectionPool.new(timeout: 0.5, size: 3) { NetworkConnection.new }
349
+
350
+ threads = Array.new(20) {
351
+ Thread.new do
352
+ pool.with do |net|
353
+ sleep 0.01
354
+ end
355
+ end
356
+ }
357
+
358
+ threads.map { |thread| thread.join }
359
+ end
360
+
361
+ def test_reuses_objects_when_pool_not_saturated
362
+ pool = ConnectionPool.new(size: 5) { NetworkConnection.new }
363
+
364
+ ids = 10.times.map {
365
+ pool.with { |c| c.object_id }
366
+ }
367
+
368
+ assert_equal 1, ids.uniq.size
369
+ end
370
+
371
+ def test_nested_checkout
372
+ recorder = Recorder.new
373
+ pool = ConnectionPool.new(size: 1) { recorder }
374
+ pool.with do |r_outer|
375
+ @other = Thread.new { |t|
376
+ pool.with do |r_other|
377
+ r_other.do_work("other")
378
+ end
379
+ }
380
+
381
+ pool.with do |r_inner|
382
+ r_inner.do_work("inner")
383
+ end
384
+
385
+ Thread.pass
386
+
387
+ r_outer.do_work("outer")
388
+ end
389
+
390
+ @other.join
391
+
392
+ assert_equal ["inner", "outer", "other"], recorder.calls
393
+ end
394
+
395
+ def test_shutdown_is_executed_for_all_connections
396
+ recorders = []
397
+
398
+ pool = ConnectionPool.new(size: 3) {
399
+ Recorder.new.tap { |r| recorders << r }
400
+ }
401
+
402
+ threads = use_pool pool, 3
403
+
404
+ pool.shutdown do |recorder|
405
+ recorder.do_work("shutdown")
406
+ end
407
+
408
+ kill_threads(threads)
409
+
410
+ assert_equal [["shutdown"]] * 3, recorders.map { |r| r.calls }
411
+ end
412
+
413
+ def test_raises_error_after_shutting_down
414
+ pool = ConnectionPool.new(size: 1) { true }
415
+
416
+ pool.shutdown {}
417
+
418
+ assert_raises ConnectionPool::PoolShuttingDownError do
419
+ pool.checkout
420
+ end
421
+ end
422
+
423
+ def test_runs_shutdown_block_asynchronously_if_connection_was_in_use
424
+ recorders = []
425
+
426
+ pool = ConnectionPool.new(size: 3) {
427
+ Recorder.new.tap { |r| recorders << r }
428
+ }
429
+
430
+ threads = use_pool pool, 2
431
+
432
+ pool.checkout
433
+
434
+ pool.shutdown do |recorder|
435
+ recorder.do_work("shutdown")
436
+ end
437
+
438
+ kill_threads(threads)
439
+
440
+ assert_equal [["shutdown"], ["shutdown"], []], recorders.map { |r| r.calls }
441
+
442
+ pool.checkin
443
+
444
+ assert_equal [["shutdown"], ["shutdown"], ["shutdown"]], recorders.map { |r| r.calls }
445
+ end
446
+
447
+ def test_raises_an_error_if_shutdown_is_called_without_a_block
448
+ pool = ConnectionPool.new(size: 1) {}
449
+
450
+ assert_raises ArgumentError do
451
+ pool.shutdown
452
+ end
453
+ end
454
+
455
+ def test_shutdown_is_executed_for_all_connections_in_wrapped_pool
456
+ recorders = []
457
+
458
+ wrapper = ConnectionPool::Wrapper.new(size: 3) {
459
+ Recorder.new.tap { |r| recorders << r }
460
+ }
461
+
462
+ threads = use_pool wrapper, 3
463
+
464
+ wrapper.pool_shutdown do |recorder|
465
+ recorder.do_work("shutdown")
466
+ end
467
+
468
+ kill_threads(threads)
469
+
470
+ assert_equal [["shutdown"]] * 3, recorders.map { |r| r.calls }
471
+ end
472
+
473
+ def test_wrapper_wrapped_pool
474
+ wrapper = ConnectionPool::Wrapper.new { NetworkConnection.new }
475
+ assert_equal ConnectionPool, wrapper.wrapped_pool.class
476
+ end
477
+
478
+ def test_wrapper_method_missing
479
+ wrapper = ConnectionPool::Wrapper.new { NetworkConnection.new }
480
+
481
+ assert_equal 1, wrapper.fast
482
+ end
483
+
484
+ def test_wrapper_respond_to_eh
485
+ wrapper = ConnectionPool::Wrapper.new { NetworkConnection.new }
486
+
487
+ assert_respond_to wrapper, :with
488
+
489
+ assert_respond_to wrapper, :fast
490
+ refute_respond_to wrapper, :"nonexistent method"
491
+ end
492
+
493
+ def test_wrapper_with
494
+ wrapper = ConnectionPool::Wrapper.new(timeout: 0, size: 1) { Object.new }
495
+
496
+ wrapper.with do
497
+ Thread.new {
498
+ assert_raises Timeout::Error do
499
+ wrapper.with { flunk "connection checked out :(" }
500
+ end
501
+ }.join
502
+ end
503
+
504
+ assert Thread.new { wrapper.with {} }.join
505
+ end
506
+
507
+ class ConnWithEval
508
+ def eval(arg)
509
+ "eval'ed #{arg}"
510
+ end
511
+ end
512
+
513
+ def test_wrapper_kernel_methods
514
+ wrapper = ConnectionPool::Wrapper.new(timeout: 0, size: 1) { ConnWithEval.new }
515
+
516
+ assert_equal "eval'ed 1", wrapper.eval(1)
517
+ end
518
+
519
+ def test_wrapper_with_connection_pool
520
+ recorder = Recorder.new
521
+ pool = ConnectionPool.new(size: 1) { recorder }
522
+ wrapper = ConnectionPool::Wrapper.new(pool: pool)
523
+
524
+ pool.with { |r| r.do_work("with") }
525
+ wrapper.do_work("wrapped")
526
+
527
+ assert_equal ["with", "wrapped"], recorder.calls
528
+ end
529
+
530
+ def test_stats_without_active_connection
531
+ pool = ConnectionPool.new(size: 2) { NetworkConnection.new }
532
+
533
+ assert_equal(2, pool.size)
534
+ assert_equal(2, pool.available)
535
+ end
536
+
537
+ def test_stats_with_active_connection
538
+ pool = ConnectionPool.new(size: 2) { NetworkConnection.new }
539
+
540
+ pool.with do
541
+ assert_equal(1, pool.available)
542
+ end
543
+ end
544
+
545
+ def test_stats_with_string_size
546
+ pool = ConnectionPool.new(size: "2") { NetworkConnection.new }
547
+
548
+ pool.with do
549
+ assert_equal(2, pool.size)
550
+ assert_equal(1, pool.available)
551
+ end
552
+ end
553
+ end