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.
- checksums.yaml +4 -4
- data/README.md +27 -2
- data/lib/scalyr/common/client.rb +3 -1
- data/logstash-output-scalyr.gemspec +2 -2
- data/vendor/bundle/jruby/2.5.0/bin/jruby_executable_hooks +25 -0
- data/vendor/bundle/jruby/2.5.0/cache/connection_pool-2.2.3.gem +0 -0
- data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/Changes.md +130 -0
- data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/Gemfile +5 -0
- data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/LICENSE +20 -0
- data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/README.md +121 -0
- data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/Rakefile +7 -0
- data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/connection_pool.gemspec +20 -0
- data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/lib/connection_pool.rb +110 -0
- data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/lib/connection_pool/timed_stack.rb +170 -0
- data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/lib/connection_pool/version.rb +3 -0
- data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/lib/connection_pool/wrapper.rb +43 -0
- data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/test/helper.rb +8 -0
- data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/test/test_connection_pool.rb +553 -0
- data/vendor/bundle/jruby/2.5.0/gems/connection_pool-2.2.3/test/test_connection_pool_timed_stack.rb +140 -0
- data/vendor/bundle/jruby/2.5.0/specifications/connection_pool-2.2.3.gemspec +34 -0
- metadata +21 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f07d1addbee89789c0819a0566262a22754990d87a70f479b33534f1d793410d
|
4
|
+
data.tar.gz: 72a1ebd3076e811232cfca2851b923e5fa0a2ef444cf3710d3268de41935532b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1e01a579378b28d69c184e6513d9c33f86963a4ce4bc6078cbbd78c9a380367605e369013417792041eb7b40efa3380c4e2b39b6b3b2bb2ec6761421329b92b
|
7
|
+
data.tar.gz: b5554805e01d55a70b20bfc51c70b1e1bf96164d24c43fe5e56dd1444c3891434a5202aa181341d318787605aacc92a6f21c2ff0601872636ff621de929dc292
|
data/README.md
CHANGED
@@ -5,12 +5,12 @@
|
|
5
5
|
|
6
6
|
This plugin implements a Logstash output plugin that uploads data to [Scalyr](http://www.scalyr.com).
|
7
7
|
|
8
|
-
You can view documentation for this plugin [on the Scalyr website](https://
|
8
|
+
You can view documentation for this plugin [on the Scalyr website](https://app.scalyr.com/solutions/logstash).
|
9
9
|
|
10
10
|
# Quick start
|
11
11
|
|
12
12
|
1. Build the gem, run `gem build logstash-output-scalyr.gemspec`
|
13
|
-
2. Install the gem into a Logstash installation, run `/usr/share/logstash/bin/logstash-plugin install logstash-output-scalyr-0.1.
|
13
|
+
2. Install the gem into a Logstash installation, run `/usr/share/logstash/bin/logstash-plugin install logstash-output-scalyr-0.1.3.gem` or follow the latest official instructions on working with plugins from Logstash.
|
14
14
|
3. Configure the output plugin (e.g. add it to a pipeline .conf)
|
15
15
|
4. Restart Logstash
|
16
16
|
|
@@ -305,3 +305,28 @@ bundle exec rspec
|
|
305
305
|
```
|
306
306
|
|
307
307
|
in the root of the repo.
|
308
|
+
|
309
|
+
# Releasing
|
310
|
+
|
311
|
+
## Updating version
|
312
|
+
|
313
|
+
Currently references to the version need to be manually updated, files to look in for this are `logstash-putput-scalyr.gemspec`,
|
314
|
+
`client.rb`, twice in the CircleCI `Dockerfile`, and under "Quick Start" in this `README.md`.
|
315
|
+
|
316
|
+
The changelog should also be updated with the latest version and changes of note.
|
317
|
+
|
318
|
+
## Releasing to RubyGems.org
|
319
|
+
|
320
|
+
To deploy the current code on your machine run these commands:
|
321
|
+
|
322
|
+
```
|
323
|
+
bundle check --path vendor/bundle || bundle install --deployment
|
324
|
+
curl -u RUBY_USER:RUBY_PASSWORD https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials
|
325
|
+
chmod 0600 ~/.gem/credentials
|
326
|
+
bundle exec rake vendor
|
327
|
+
bundle exec rspec
|
328
|
+
bundle exec rake publish_gem
|
329
|
+
```
|
330
|
+
|
331
|
+
`RUBY_USER` and `RUBY_PASSWORD` should be replaced with the username and password to the RubyGems.org account you wish to release to,
|
332
|
+
these credentials should be found in Keeper.
|
data/lib/scalyr/common/client.rb
CHANGED
@@ -82,6 +82,8 @@ class ClientSession
|
|
82
82
|
@http.ca_file = @ssl_ca_bundle_path
|
83
83
|
@http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
84
84
|
@http.verify_depth = @ssl_verify_depth
|
85
|
+
else
|
86
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
85
87
|
end
|
86
88
|
end # def initialize
|
87
89
|
|
@@ -161,7 +163,7 @@ class ClientSession
|
|
161
163
|
|
162
164
|
post = Net::HTTP::Post.new uri_path
|
163
165
|
post.add_field('Content-Type', 'application/json')
|
164
|
-
version = 'output-logstash-scalyr 0.1.
|
166
|
+
version = 'output-logstash-scalyr 0.1.3'
|
165
167
|
post.add_field('User-Agent', version + ';' + RUBY_VERSION + ';' + RUBY_PLATFORM)
|
166
168
|
|
167
169
|
if not encoding.nil?
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'logstash-output-scalyr'
|
3
|
-
s.version = '0.1.
|
3
|
+
s.version = '0.1.3'
|
4
4
|
s.licenses = ['Apache-2.0']
|
5
5
|
s.summary = "Scalyr output plugin for Logstash"
|
6
6
|
s.description = "Sends log data collected by Logstash to Scalyr (https://www.scalyr.com)"
|
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
|
|
22
22
|
s.add_runtime_dependency 'net-http-persistent'
|
23
23
|
s.add_runtime_dependency 'logstash-core-plugin-api', '>= 1.60', '<= 2.99'
|
24
24
|
s.add_runtime_dependency 'logstash-codec-plain'
|
25
|
-
s.add_runtime_dependency 'ffi', '>= 1.9.
|
25
|
+
s.add_runtime_dependency 'ffi', '>= 1.9.18'
|
26
26
|
s.add_runtime_dependency 'rbzip2', '0.3.0'
|
27
27
|
s.add_development_dependency 'logstash-devutils'
|
28
28
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
title = "ruby #{ARGV*" "}"
|
4
|
+
$0 = ARGV.shift
|
5
|
+
Process.setproctitle(title) if Process.methods.include?(:setproctitle)
|
6
|
+
|
7
|
+
require 'rubygems'
|
8
|
+
begin
|
9
|
+
require 'executable-hooks/hooks'
|
10
|
+
Gem::ExecutableHooks.run($0)
|
11
|
+
rescue LoadError
|
12
|
+
warn "unable to load executable-hooks/hooks" if ENV.key?('ExecutableHooks_DEBUG')
|
13
|
+
end unless $0.end_with?('/executable-hooks-uninstaller')
|
14
|
+
|
15
|
+
content = File.read($0)
|
16
|
+
|
17
|
+
if
|
18
|
+
(index = content.index("\n#!ruby\n")) && index > 0
|
19
|
+
then
|
20
|
+
skipped_content = content.slice!(0..index)
|
21
|
+
start_line = skipped_content.count("\n") + 1
|
22
|
+
eval content, binding, $0, start_line
|
23
|
+
else
|
24
|
+
eval content, binding, $0
|
25
|
+
end
|
Binary file
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# connection_pool Changelog
|
2
|
+
|
3
|
+
2.2.3
|
4
|
+
------
|
5
|
+
|
6
|
+
- Pool now throws `ConnectionPool::TimeoutError` on timeout. [#130]
|
7
|
+
- Use monotonic clock present in all modern Rubies [Tero Tasanen, #109]
|
8
|
+
- Remove code hacks necessary for JRuby 1.7
|
9
|
+
- Expose wrapped pool from ConnectionPool::Wrapper [Thomas Lecavelier, #113]
|
10
|
+
|
11
|
+
2.2.2
|
12
|
+
------
|
13
|
+
|
14
|
+
- Add pool `size` and `available` accessors for metrics and monitoring
|
15
|
+
purposes [#97, robholland]
|
16
|
+
|
17
|
+
2.2.1
|
18
|
+
------
|
19
|
+
|
20
|
+
- Allow CP::Wrapper to use an existing pool [#87, etiennebarrie]
|
21
|
+
- Use monotonic time for more accurate timeouts [#84, jdantonio]
|
22
|
+
|
23
|
+
2.2.0
|
24
|
+
------
|
25
|
+
|
26
|
+
- Rollback `Timeout` handling introduced in 2.1.1 and 2.1.2. It seems
|
27
|
+
impossible to safely work around the issue. Please never, ever use
|
28
|
+
`Timeout.timeout` in your code or you will see rare but mysterious bugs. [#75]
|
29
|
+
|
30
|
+
2.1.3
|
31
|
+
------
|
32
|
+
|
33
|
+
- Don't increment created count until connection is successfully
|
34
|
+
created. [mylesmegyesi, #73]
|
35
|
+
|
36
|
+
2.1.2
|
37
|
+
------
|
38
|
+
|
39
|
+
- The connection\_pool will now close any connections which respond to
|
40
|
+
`close` (Dalli) or `disconnect!` (Redis). This ensures discarded connections
|
41
|
+
from the fix in 2.1.1 are torn down ASAP and don't linger open.
|
42
|
+
|
43
|
+
|
44
|
+
2.1.1
|
45
|
+
------
|
46
|
+
|
47
|
+
- Work around a subtle race condition with code which uses `Timeout.timeout` and
|
48
|
+
checks out a connection within the timeout block. This might cause
|
49
|
+
connections to get into a bad state and raise very odd errors. [tamird, #67]
|
50
|
+
|
51
|
+
|
52
|
+
2.1.0
|
53
|
+
------
|
54
|
+
|
55
|
+
- Refactoring to better support connection pool subclasses [drbrain,
|
56
|
+
#55]
|
57
|
+
- `with` should return value of the last expression [#59]
|
58
|
+
|
59
|
+
|
60
|
+
2.0.0
|
61
|
+
-----
|
62
|
+
|
63
|
+
- The connection pool is now lazy. Connections are created as needed
|
64
|
+
and retained until the pool is shut down. [drbrain, #52]
|
65
|
+
|
66
|
+
1.2.0
|
67
|
+
-----
|
68
|
+
|
69
|
+
- Add `with(options)` and `checkout(options)`. [mattcamuto]
|
70
|
+
Allows the caller to override the pool timeout.
|
71
|
+
```ruby
|
72
|
+
@pool.with(:timeout => 2) do |conn|
|
73
|
+
end
|
74
|
+
```
|
75
|
+
|
76
|
+
1.1.0
|
77
|
+
-----
|
78
|
+
|
79
|
+
- New `#shutdown` method (simao)
|
80
|
+
|
81
|
+
This method accepts a block and calls the block for each
|
82
|
+
connection in the pool. After calling this method, trying to get a
|
83
|
+
connection from the pool raises `PoolShuttingDownError`.
|
84
|
+
|
85
|
+
1.0.0
|
86
|
+
-----
|
87
|
+
|
88
|
+
- `#with_connection` is now gone in favor of `#with`.
|
89
|
+
|
90
|
+
- We no longer pollute the top level namespace with our internal
|
91
|
+
`TimedStack` class.
|
92
|
+
|
93
|
+
0.9.3
|
94
|
+
--------
|
95
|
+
|
96
|
+
- `#with_connection` is now deprecated in favor of `#with`.
|
97
|
+
|
98
|
+
A warning will be issued in the 0.9 series and the method will be
|
99
|
+
removed in 1.0.
|
100
|
+
|
101
|
+
- We now reuse objects when possible.
|
102
|
+
|
103
|
+
This means that under no contention, the same object will be checked
|
104
|
+
out from the pool after subsequent calls to `ConnectionPool#with`.
|
105
|
+
|
106
|
+
This change should have no impact on end user performance. If
|
107
|
+
anything, it should be an improvement, depending on what objects you
|
108
|
+
are pooling.
|
109
|
+
|
110
|
+
0.9.2
|
111
|
+
--------
|
112
|
+
|
113
|
+
- Fix reentrant checkout leading to early checkin.
|
114
|
+
|
115
|
+
0.9.1
|
116
|
+
--------
|
117
|
+
|
118
|
+
- Fix invalid superclass in version.rb
|
119
|
+
|
120
|
+
0.9.0
|
121
|
+
--------
|
122
|
+
|
123
|
+
- Move method\_missing magic into ConnectionPool::Wrapper (djanowski)
|
124
|
+
- Remove BasicObject superclass (djanowski)
|
125
|
+
|
126
|
+
0.1.0
|
127
|
+
--------
|
128
|
+
|
129
|
+
- More precise timeouts and better error message
|
130
|
+
- ConnectionPool now subclasses BasicObject so `method_missing` is more effective.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Mike Perham
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,121 @@
|
|
1
|
+
connection\_pool
|
2
|
+
=================
|
3
|
+
[![Build Status](https://travis-ci.org/mperham/connection_pool.svg)](https://travis-ci.org/mperham/connection_pool)
|
4
|
+
|
5
|
+
Generic connection pooling for Ruby.
|
6
|
+
|
7
|
+
MongoDB has its own connection pool. ActiveRecord has its own connection pool.
|
8
|
+
This is a generic connection pool that can be used with anything, e.g. Redis,
|
9
|
+
Dalli and other Ruby network clients.
|
10
|
+
|
11
|
+
|
12
|
+
Usage
|
13
|
+
-----
|
14
|
+
|
15
|
+
Create a pool of objects to share amongst the fibers or threads in your Ruby
|
16
|
+
application:
|
17
|
+
|
18
|
+
``` ruby
|
19
|
+
$memcached = ConnectionPool.new(size: 5, timeout: 5) { Dalli::Client.new }
|
20
|
+
```
|
21
|
+
|
22
|
+
Then use the pool in your application:
|
23
|
+
|
24
|
+
``` ruby
|
25
|
+
$memcached.with do |conn|
|
26
|
+
conn.get('some-count')
|
27
|
+
end
|
28
|
+
```
|
29
|
+
|
30
|
+
If all the objects in the connection pool are in use, `with` will block
|
31
|
+
until one becomes available. If no object is available within `:timeout` seconds,
|
32
|
+
`with` will raise a `Timeout::Error`.
|
33
|
+
|
34
|
+
Optionally, you can specify a timeout override using the with-block semantics:
|
35
|
+
|
36
|
+
``` ruby
|
37
|
+
$memcached.with(timeout: 2.0) do |conn|
|
38
|
+
conn.get('some-count')
|
39
|
+
end
|
40
|
+
```
|
41
|
+
|
42
|
+
This will only modify the resource-get timeout for this particular
|
43
|
+
invocation. This is useful if you want to fail-fast on certain non critical
|
44
|
+
sections when a resource is not available, or conversely if you are comfortable
|
45
|
+
blocking longer on a particular resource. This is not implemented in the below
|
46
|
+
`ConnectionPool::Wrapper` class.
|
47
|
+
|
48
|
+
## Migrating to a Connection Pool
|
49
|
+
|
50
|
+
You can use `ConnectionPool::Wrapper` to wrap a single global connection,
|
51
|
+
making it easier to migrate existing connection code over time:
|
52
|
+
|
53
|
+
``` ruby
|
54
|
+
$redis = ConnectionPool::Wrapper.new(size: 5, timeout: 3) { Redis.new }
|
55
|
+
$redis.sadd('foo', 1)
|
56
|
+
$redis.smembers('foo')
|
57
|
+
```
|
58
|
+
|
59
|
+
The wrapper uses `method_missing` to checkout a connection, run the requested
|
60
|
+
method and then immediately check the connection back into the pool. It's
|
61
|
+
**not** high-performance so you'll want to port your performance sensitive code
|
62
|
+
to use `with` as soon as possible.
|
63
|
+
|
64
|
+
``` ruby
|
65
|
+
$redis.with do |conn|
|
66
|
+
conn.sadd('foo', 1)
|
67
|
+
conn.smembers('foo')
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
Once you've ported your entire system to use `with`, you can simply remove
|
72
|
+
`Wrapper` and use the simpler and faster `ConnectionPool`.
|
73
|
+
|
74
|
+
|
75
|
+
## Shutdown
|
76
|
+
|
77
|
+
You can shut down a ConnectionPool instance once it should no longer be used.
|
78
|
+
Further checkout attempts will immediately raise an error but existing checkouts
|
79
|
+
will work.
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
cp = ConnectionPool.new { Redis.new }
|
83
|
+
cp.shutdown { |conn| conn.quit }
|
84
|
+
```
|
85
|
+
|
86
|
+
Shutting down a connection pool will block until all connections are checked in and closed.
|
87
|
+
**Note that shutting down is completely optional**; Ruby's garbage collector will reclaim
|
88
|
+
unreferenced pools under normal circumstances.
|
89
|
+
|
90
|
+
## Current State
|
91
|
+
|
92
|
+
There are several methods that return information about a pool.
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
cp = ConnectionPool.new(size: 10) { Redis.new }
|
96
|
+
cp.size # => 10
|
97
|
+
cp.available # => 10
|
98
|
+
|
99
|
+
cp.with do |conn|
|
100
|
+
cp.size # => 10
|
101
|
+
cp.available # => 9
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
Notes
|
106
|
+
-----
|
107
|
+
|
108
|
+
- Connections are lazily created as needed.
|
109
|
+
- There is no provision for repairing or checking the health of a connection;
|
110
|
+
connections should be self-repairing. This is true of the Dalli and Redis
|
111
|
+
clients.
|
112
|
+
- **WARNING**: Don't ever use `Timeout.timeout` in your Ruby code or you will see
|
113
|
+
occasional silent corruption and mysterious errors. The Timeout API is unsafe
|
114
|
+
and cannot be used correctly, ever. Use proper socket timeout options as
|
115
|
+
exposed by Net::HTTP, Redis, Dalli, etc.
|
116
|
+
|
117
|
+
|
118
|
+
Author
|
119
|
+
------
|
120
|
+
|
121
|
+
Mike Perham, [@mperham](https://twitter.com/mperham), <http://mikeperham.com>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "./lib/connection_pool/version"
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "connection_pool"
|
5
|
+
s.version = ConnectionPool::VERSION
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
s.authors = ["Mike Perham", "Damian Janowski"]
|
8
|
+
s.email = ["mperham@gmail.com", "damian@educabilia.com"]
|
9
|
+
s.homepage = "https://github.com/mperham/connection_pool"
|
10
|
+
s.description = s.summary = "Generic connection pool for Ruby"
|
11
|
+
|
12
|
+
s.files = `git ls-files`.split("\n")
|
13
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
15
|
+
s.require_paths = ["lib"]
|
16
|
+
s.license = "MIT"
|
17
|
+
s.add_development_dependency "bundler"
|
18
|
+
s.add_development_dependency "minitest", ">= 5.0.0"
|
19
|
+
s.add_development_dependency "rake"
|
20
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require "timeout"
|
2
|
+
require "connection_pool/version"
|
3
|
+
|
4
|
+
class ConnectionPool
|
5
|
+
class Error < ::RuntimeError; end
|
6
|
+
class PoolShuttingDownError < ::ConnectionPool::Error; end
|
7
|
+
class TimeoutError < ::Timeout::Error; end
|
8
|
+
end
|
9
|
+
|
10
|
+
# Generic connection pool class for sharing a limited number of objects or network connections
|
11
|
+
# among many threads. Note: pool elements are lazily created.
|
12
|
+
#
|
13
|
+
# Example usage with block (faster):
|
14
|
+
#
|
15
|
+
# @pool = ConnectionPool.new { Redis.new }
|
16
|
+
# @pool.with do |redis|
|
17
|
+
# redis.lpop('my-list') if redis.llen('my-list') > 0
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# Using optional timeout override (for that single invocation)
|
21
|
+
#
|
22
|
+
# @pool.with(timeout: 2.0) do |redis|
|
23
|
+
# redis.lpop('my-list') if redis.llen('my-list') > 0
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# Example usage replacing an existing connection (slower):
|
27
|
+
#
|
28
|
+
# $redis = ConnectionPool.wrap { Redis.new }
|
29
|
+
#
|
30
|
+
# def do_work
|
31
|
+
# $redis.lpop('my-list') if $redis.llen('my-list') > 0
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# Accepts the following options:
|
35
|
+
# - :size - number of connections to pool, defaults to 5
|
36
|
+
# - :timeout - amount of time to wait for a connection if none currently available, defaults to 5 seconds
|
37
|
+
#
|
38
|
+
class ConnectionPool
|
39
|
+
DEFAULTS = {size: 5, timeout: 5}
|
40
|
+
|
41
|
+
def self.wrap(options, &block)
|
42
|
+
Wrapper.new(options, &block)
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize(options = {}, &block)
|
46
|
+
raise ArgumentError, "Connection pool requires a block" unless block
|
47
|
+
|
48
|
+
options = DEFAULTS.merge(options)
|
49
|
+
|
50
|
+
@size = Integer(options.fetch(:size))
|
51
|
+
@timeout = options.fetch(:timeout)
|
52
|
+
|
53
|
+
@available = TimedStack.new(@size, &block)
|
54
|
+
@key = :"pool-#{@available.object_id}"
|
55
|
+
@key_count = :"pool-#{@available.object_id}-count"
|
56
|
+
end
|
57
|
+
|
58
|
+
def with(options = {})
|
59
|
+
Thread.handle_interrupt(Exception => :never) do
|
60
|
+
conn = checkout(options)
|
61
|
+
begin
|
62
|
+
Thread.handle_interrupt(Exception => :immediate) do
|
63
|
+
yield conn
|
64
|
+
end
|
65
|
+
ensure
|
66
|
+
checkin
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def checkout(options = {})
|
72
|
+
if ::Thread.current[@key]
|
73
|
+
::Thread.current[@key_count] += 1
|
74
|
+
::Thread.current[@key]
|
75
|
+
else
|
76
|
+
::Thread.current[@key_count] = 1
|
77
|
+
::Thread.current[@key] = @available.pop(options[:timeout] || @timeout)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def checkin
|
82
|
+
if ::Thread.current[@key]
|
83
|
+
if ::Thread.current[@key_count] == 1
|
84
|
+
@available.push(::Thread.current[@key])
|
85
|
+
::Thread.current[@key] = nil
|
86
|
+
else
|
87
|
+
::Thread.current[@key_count] -= 1
|
88
|
+
end
|
89
|
+
else
|
90
|
+
raise ConnectionPool::Error, "no connections are checked out"
|
91
|
+
end
|
92
|
+
|
93
|
+
nil
|
94
|
+
end
|
95
|
+
|
96
|
+
def shutdown(&block)
|
97
|
+
@available.shutdown(&block)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Size of this connection pool
|
101
|
+
attr_reader :size
|
102
|
+
|
103
|
+
# Number of pool entries available for checkout at this instant.
|
104
|
+
def available
|
105
|
+
@available.length
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
require "connection_pool/timed_stack"
|
110
|
+
require "connection_pool/wrapper"
|