logstash-output-scalyr 0.1.2 → 0.1.3

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.
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