hot_tub 0.4.0 → 0.5.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/HISTORY.md +6 -1
- data/README.md +110 -64
- data/benchmarks/block_passing.rb +96 -0
- data/benchmarks/hot_tub.rb +76 -41
- data/hot_tub.gemspec +2 -4
- data/lib/hot_tub/known_clients.rb +40 -23
- data/lib/hot_tub/pool.rb +96 -83
- data/lib/hot_tub/reaper.rb +14 -2
- data/lib/hot_tub/sessions.rb +111 -78
- data/lib/hot_tub/version.rb +1 -1
- data/lib/hot_tub.rb +48 -10
- data/spec/hot_tub/integration/excon_spec.rb +15 -21
- data/spec/hot_tub/integration/net_http_spec.rb +14 -14
- data/spec/hot_tub/integration/sessions_spec.rb +26 -15
- data/spec/hot_tub/pool_spec.rb +15 -34
- data/spec/hot_tub/sessions_spec.rb +50 -69
- data/spec/hot_tub_spec.rb +12 -7
- data/spec/spec_helper.rb +2 -0
- metadata +5 -19
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 78df9f4441ecfb13b4eb6de670d8384c140c3b4d
|
|
4
|
+
data.tar.gz: 345d9409cd6e30bbfff90bea8cc9bef734dbe062
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 56004ba7b29c84e4633cdf22dd88701bd2ecfa02980e146cf2358bb4cf0f6fc6fd044d7df998359f4f3fcb3988f9583ef7b78121726b58fa31bf25a2ab9177ed
|
|
7
|
+
data.tar.gz: c18c797037130388cdd8e3faa094b592702811364d726bac1ef5f0b57d4ef38576e0c504da8371b66864b6ca27cff80b3b7a16e0e8d749dc770be6deaed935b0
|
data/.travis.yml
CHANGED
data/HISTORY.md
CHANGED
|
@@ -3,6 +3,12 @@ HotTub Changelog
|
|
|
3
3
|
|
|
4
4
|
Head
|
|
5
5
|
=======
|
|
6
|
+
- Drop Thread::Safe dependency
|
|
7
|
+
- Make Sessions useful, complete re-write and provide global sessions support
|
|
8
|
+
- Refactor and clean up Pool
|
|
9
|
+
- Improve logging and add HotTub.trace for more detailed logs
|
|
10
|
+
- Name your pools and sessions for better logging
|
|
11
|
+
- Remove :on_reaper in favor of setting :reaper to false
|
|
6
12
|
|
|
7
13
|
0.4.0
|
|
8
14
|
=======
|
|
@@ -15,7 +21,6 @@ Head
|
|
|
15
21
|
|
|
16
22
|
0.3.0
|
|
17
23
|
=======
|
|
18
|
-
|
|
19
24
|
- Drop EM support, will move to separate gem
|
|
20
25
|
- Simplify API with HotTub.new
|
|
21
26
|
- Use ThreadSafe::Cache for sessions
|
data/README.md
CHANGED
|
@@ -1,25 +1,34 @@
|
|
|
1
1
|
# HotTub [](https://travis-ci.org/JoshMcKin/hot_tub) [](https://coveralls.io/r/JoshMcKin/hot_tub)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Flexible, thread-safe, connection pooling for Ruby. Configurable for any client you desire. Built in reaper th built in support for Net::HTTP and [Excon](https://github.com/excon/excon).
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
### HotTub::Pool
|
|
8
|
-
A thread safe, lazy pool.
|
|
9
8
|
|
|
10
9
|
* Thread safe
|
|
11
10
|
* Lazy, pool starts off at 0 and grows as necessary.
|
|
12
|
-
* Non-Blocking, can be configured to always return a
|
|
13
|
-
* Can be used with any client library instance.
|
|
11
|
+
* Non-Blocking, can be configured to always return a connection if your pool runs out under load. Overflow connections are returned to the pool for reuse. Once load dies, the pool is reaped down to size.
|
|
14
12
|
* Support for cleaning dirty resources, no one likes a dirty `HotTub`
|
|
15
13
|
* Support for closing resources on shutdown
|
|
14
|
+
* Support for process forking
|
|
15
|
+
|
|
16
16
|
|
|
17
17
|
### HotTub::Sessions
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
A synchronized hash where keys are mapped to a HotTub::Pools that are managed by a single HotTub::Reaper.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### HotTub::Reaper
|
|
23
|
+
|
|
24
|
+
A separate thread thats manages your pool(s). All HotTub::Pools managed by HotTub::Sessions share a single reaper. One-off HotTub::Pools have their own reaper. The reaper periodically checks pool(s) based on the `:reap_timeout` set for the pool or session. Over-flow connections or connections deemed reap-able ready are pulled from the pool and closed.
|
|
25
|
+
|
|
19
26
|
|
|
20
27
|
### Requirements
|
|
28
|
+
|
|
21
29
|
HotTub is tested on MRI, JRUBY and Rubinius
|
|
22
|
-
* Ruby >=
|
|
30
|
+
* Ruby >= 2.0 # Although older versions may work
|
|
31
|
+
|
|
23
32
|
|
|
24
33
|
## Installation
|
|
25
34
|
|
|
@@ -27,6 +36,7 @@ HotTub is available through [Rubygems](https://rubygems.org/gems/hot_tub) and ca
|
|
|
27
36
|
|
|
28
37
|
$ gem install hot_tub
|
|
29
38
|
|
|
39
|
+
|
|
30
40
|
### Rails setup
|
|
31
41
|
|
|
32
42
|
Add hot_tub to your gemfile:
|
|
@@ -41,95 +51,131 @@ Configure Logger by creating `config\initializers\hot_tub.rb` and adding the fol
|
|
|
41
51
|
|
|
42
52
|
HotTub.logger = Rails.logger
|
|
43
53
|
|
|
44
|
-
# Usage
|
|
45
|
-
|
|
46
|
-
For convenience you can initialize a new HotTub::Pool by calling HotTub.new or HotTub::Pool.new directly.
|
|
47
|
-
Returns an instance of HotTub::Pool.
|
|
48
54
|
|
|
49
|
-
|
|
50
|
-
# We don't want too many connections so we set our :max_size. Under load our pool
|
|
51
|
-
# can grow to 30 connections. Once load dies down our pool can be reaped back down to 5
|
|
52
|
-
pool = HotTub::Pool.new(:size => 5, :max_size => 30, :reap_timeout => 60) { Redis.new }
|
|
53
|
-
pool.set('hot', 'stuff')
|
|
54
|
-
pool.get('hot')
|
|
55
|
-
# => 'stuff'
|
|
55
|
+
# Usage
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
## Pools Managed by HotTub
|
|
58
58
|
|
|
59
|
+
HotTub::Sessions are used to manage multiple pools with a single object and using a single reaper.
|
|
60
|
+
A global Sessions object is available from the HotTub module and has several helper methods.
|
|
61
|
+
|
|
59
62
|
require 'hot_tub'
|
|
60
63
|
require 'net/http'
|
|
64
|
+
require 'excon'
|
|
65
|
+
require 'redis'
|
|
61
66
|
|
|
62
|
-
|
|
63
|
-
|
|
67
|
+
# Add a HotTub::Pool of Net::HTTP connections to our sessions with a size of 12.
|
|
68
|
+
# We are using the url as the key but could use anything.
|
|
69
|
+
# we are not setting :max_size so our connections will grow to match our currency.
|
|
70
|
+
# Once load dies down our pool will be reaped back down to 12 connections
|
|
71
|
+
|
|
72
|
+
url = "https://google.com"
|
|
73
|
+
HotTub.add(url, { :size => 12 }) do
|
|
74
|
+
uri = URI.parse(url)
|
|
64
75
|
http = Net::HTTP.new(uri.host, uri.port)
|
|
65
76
|
http.use_ssl = false
|
|
66
77
|
http.start
|
|
67
|
-
http
|
|
68
|
-
|
|
69
|
-
pool.run {|clnt| puts clnt.head('/').code }
|
|
78
|
+
http
|
|
79
|
+
end
|
|
70
80
|
|
|
71
|
-
|
|
81
|
+
# A separate HotTub::Pool of Excon connections.
|
|
72
82
|
|
|
73
|
-
|
|
74
|
-
|
|
83
|
+
url2 = "http://someOtherServices.com"
|
|
84
|
+
HotTub.add(url2, { :size => 5 }) { Excon.new }
|
|
75
85
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
pool.run {|clnt| puts clnt.head('/').status }
|
|
86
|
+
# Lets add Redis too.
|
|
87
|
+
# We don't want too many connections so we set our :max_size. Under load our pool
|
|
88
|
+
# can grow to 30 connections. Once load dies down our pool can be reaped back down to 5
|
|
80
89
|
|
|
81
|
-
|
|
82
|
-
|
|
90
|
+
HotTub.add("redis", :size => 5, :max_size => 30) { Redis.new }
|
|
91
|
+
|
|
92
|
+
# Now we can call any of our pools using the key we set any where in our code.
|
|
83
93
|
|
|
84
|
-
|
|
94
|
+
HotTub.run(url) do |clnt|
|
|
95
|
+
puts clnt.head('/').code
|
|
96
|
+
end
|
|
85
97
|
|
|
86
|
-
|
|
98
|
+
HotTub.run(url2) do |clnt|
|
|
99
|
+
puts clnt.get(:path => "/some_stuff", :query => {:foo => 'bar'}).body
|
|
100
|
+
end
|
|
87
101
|
|
|
88
|
-
|
|
102
|
+
HotTub.run('redis') do |clnt|
|
|
103
|
+
clnt.set('hot', 'stuff')
|
|
104
|
+
end
|
|
89
105
|
|
|
90
|
-
**close**: Default is nil. Can be a symbol representing an method to call on a client to close the client or a lambda that accepts the client as a parameter that will close a client. The close option is performed on clients on reaping and shutdown after the client has been removed from the pool. When nil, as is the default, no action is performed.
|
|
91
106
|
|
|
92
|
-
|
|
107
|
+
## Single Pool
|
|
108
|
+
|
|
109
|
+
pool = HotTub::Pool.new(:size => 5, :max_size => 30, :reap_timeout => 60) { Redis.new }
|
|
93
110
|
|
|
94
|
-
|
|
111
|
+
pool.run |clnt|
|
|
112
|
+
clnt.set('hot', 'stuff')
|
|
113
|
+
end
|
|
95
114
|
|
|
96
|
-
|
|
115
|
+
pool.run |clnt|
|
|
116
|
+
pool.get('hot')
|
|
117
|
+
end
|
|
97
118
|
|
|
98
|
-
**sessions**: Default is false. Returns an instance of `HotTub::Sessions.new` that wraps clients in `HotTub::Pool.new`
|
|
99
119
|
|
|
100
|
-
|
|
101
|
-
Available via `HotTub.new(:sessions => true)` or `HotTub::Sessions.new`
|
|
120
|
+
## Connection Life Cycles
|
|
102
121
|
|
|
103
|
-
|
|
104
|
-
|
|
122
|
+
HotTub has built in support for closing NetHTTP and Excon. If you need more control or have
|
|
123
|
+
a different library you would like to use, HotTub can be configured to support your needs
|
|
124
|
+
using `:close`, `:clean`, and `:reap?` options in a pools settings.
|
|
105
125
|
|
|
106
|
-
|
|
107
|
-
|
|
126
|
+
`:close` is used to define how a connections should be closed at shutdown and upon reaping.
|
|
127
|
+
reaped.
|
|
108
128
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
129
|
+
`:clean` is called on each existing connection as its pulled from the pool.
|
|
130
|
+
|
|
131
|
+
`:reap?` is used to determine if a connection in the pool is ready for reaping.
|
|
132
|
+
|
|
133
|
+
EX:
|
|
134
|
+
pool_options = {
|
|
135
|
+
:size => 5
|
|
136
|
+
:max_size => 10
|
|
137
|
+
:close => lambda { |clnt| clnt.close_it }, # could also use :close_id symbol instead of a lambda
|
|
138
|
+
:clean => lambda { |clnt| clnt.reconnect if clnt.dirty? },
|
|
139
|
+
:reap? => lambda { |clnt| clnt.stail? }
|
|
115
140
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
141
|
+
|
|
142
|
+
HotTub.add('offBrand', pool_options) { MyCoolClient.new }
|
|
143
|
+
# or
|
|
144
|
+
HotTub::Pool.new(pool_options){ MyCoolClient.new }
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
## Forking
|
|
148
|
+
|
|
149
|
+
HotTub's `#reset!` methods close all idle connections, prevents connections in use from returning
|
|
150
|
+
to the pool and attempts to close orphaned connections as they attempt to return.
|
|
151
|
+
|
|
152
|
+
# Puma
|
|
153
|
+
on_worker_boot do
|
|
154
|
+
|
|
155
|
+
# If you let HotTub manage all your connections
|
|
156
|
+
HotTub.reset!
|
|
157
|
+
|
|
158
|
+
# If you have your own HotTub::Sessions
|
|
159
|
+
MY_SESSIONS.reset!
|
|
160
|
+
|
|
161
|
+
# If you have any one-off pools
|
|
162
|
+
MY_POOL.reset!
|
|
163
|
+
|
|
121
164
|
end
|
|
122
165
|
|
|
123
|
-
|
|
124
|
-
|
|
166
|
+
# Unicorn
|
|
167
|
+
before_fork do |server, worker|
|
|
168
|
+
|
|
169
|
+
# If you let HotTub manage all your connections
|
|
170
|
+
HotTub.reset!
|
|
125
171
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
hot_tub.run { |clnt| clnt.get(url,query).body }
|
|
172
|
+
# If you have your own HotTub::Sessions
|
|
173
|
+
MY_SESSIONS.reset!
|
|
129
174
|
|
|
130
|
-
|
|
175
|
+
# If you have any one-off pools
|
|
176
|
+
MY_POOL.reset!
|
|
177
|
+
end
|
|
131
178
|
|
|
132
|
-
* [ThreadSafe](https://github.com/headius/thread_safe)
|
|
133
179
|
|
|
134
180
|
## Contributing to HotTub
|
|
135
181
|
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
2
|
+
require 'benchmark'
|
|
3
|
+
|
|
4
|
+
puts `ruby -v`
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# HotTub uses persisted blocks in several places.
|
|
8
|
+
|
|
9
|
+
# Tests performance of passing a known block to block call or yield.
|
|
10
|
+
|
|
11
|
+
class BlockTest
|
|
12
|
+
class << self
|
|
13
|
+
def block_to_yield &block
|
|
14
|
+
block_yield &block
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def block_to_call &block
|
|
18
|
+
block_call &block
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def block_yield
|
|
22
|
+
yield
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def block_call &block
|
|
26
|
+
block.call
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
n = 1_000_000
|
|
33
|
+
Benchmark.bmbm do |x|
|
|
34
|
+
x.report("block yield") do
|
|
35
|
+
n.times do
|
|
36
|
+
BlockTest.block_yield { "foo" }
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
x.report("block call") do
|
|
40
|
+
n.times do
|
|
41
|
+
BlockTest.block_call { "foo" }
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
x.report("block to yield") do
|
|
45
|
+
n.times do
|
|
46
|
+
BlockTest.block_yield { "foo" }
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
x.report("block to call") do
|
|
50
|
+
n.times do
|
|
51
|
+
BlockTest.block_call { "foo" }
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-darwin14]
|
|
57
|
+
# Rehearsal --------------------------------------------------
|
|
58
|
+
# block yield 0.160000 0.000000 0.160000 ( 0.166351)
|
|
59
|
+
# block call 0.690000 0.000000 0.690000 ( 0.684485)
|
|
60
|
+
# block to yield 0.160000 0.000000 0.160000 ( 0.166744)
|
|
61
|
+
# block to call 0.680000 0.000000 0.680000 ( 0.677085)
|
|
62
|
+
# ----------------------------------------- total: 1.690000sec
|
|
63
|
+
|
|
64
|
+
# user system total real
|
|
65
|
+
# block yield 0.160000 0.000000 0.160000 ( 0.165289)
|
|
66
|
+
# block call 0.690000 0.010000 0.700000 ( 0.699424)
|
|
67
|
+
# block to yield 0.180000 0.000000 0.180000 ( 0.172781)
|
|
68
|
+
# block to call 0.700000 0.010000 0.710000 ( 0.702157)
|
|
69
|
+
|
|
70
|
+
# rubinius 2.5.8 (2.1.0 bef51ae3 2015-07-14 3.5.1 JI) [x86_64-darwin14.4.0]
|
|
71
|
+
# Rehearsal --------------------------------------------------
|
|
72
|
+
# block yield 0.164459 0.009985 0.174444 ( 0.136798)
|
|
73
|
+
# block call 0.396599 0.001442 0.398041 ( 0.374256)
|
|
74
|
+
# block to yield 0.095014 0.000532 0.095546 ( 0.068005)
|
|
75
|
+
# block to call 0.386417 0.001135 0.387552 ( 0.370419)
|
|
76
|
+
# ----------------------------------------- total: 1.055583sec
|
|
77
|
+
|
|
78
|
+
# user system total real
|
|
79
|
+
# block yield 0.050738 0.000172 0.050910 ( 0.050869)
|
|
80
|
+
# block call 0.359893 0.000935 0.360828 ( 0.360429)
|
|
81
|
+
# block to yield 0.050676 0.000181 0.050857 ( 0.050787)
|
|
82
|
+
# block to call 0.360640 0.001018 0.361658 ( 0.361311)
|
|
83
|
+
|
|
84
|
+
# jruby 9.0.3.0 (2.2.2) 2015-10-21 633c9aa Java HotSpot(TM) 64-Bit Server VM 23.5-b02 on 1.7.0_09-b05 +jit [darwin-x86_64]
|
|
85
|
+
# Rehearsal --------------------------------------------------
|
|
86
|
+
# block yield 0.410000 0.010000 0.420000 ( 0.260548)
|
|
87
|
+
# block call 0.420000 0.000000 0.420000 ( 0.356582)
|
|
88
|
+
# block to yield 0.220000 0.000000 0.220000 ( 0.189081)
|
|
89
|
+
# block to call 0.360000 0.010000 0.370000 ( 0.266201)
|
|
90
|
+
# ----------------------------------------- total: 1.430000sec
|
|
91
|
+
|
|
92
|
+
# user system total real
|
|
93
|
+
# block yield 0.170000 0.000000 0.170000 ( 0.173698)
|
|
94
|
+
# block call 0.220000 0.000000 0.220000 ( 0.222841)
|
|
95
|
+
# block to yield 0.180000 0.000000 0.180000 ( 0.172968)
|
|
96
|
+
# block to call 0.220000 0.000000 0.220000 ( 0.224151)
|
data/benchmarks/hot_tub.rb
CHANGED
|
@@ -12,10 +12,11 @@ class MocClient
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
puts `ruby -v`
|
|
15
|
+
|
|
15
16
|
Benchmark.bmbm do |b|
|
|
16
17
|
|
|
17
18
|
b.report("single thread") do
|
|
18
|
-
hot_tub = HotTub
|
|
19
|
+
hot_tub = HotTub.new(:size => 1, :max_size => 1) { MocClient.new }
|
|
19
20
|
1000.times.each do
|
|
20
21
|
hot_tub.run do |conn|
|
|
21
22
|
conn.get
|
|
@@ -24,12 +25,14 @@ Benchmark.bmbm do |b|
|
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
b.report("threaded size 5") do
|
|
27
|
-
hot_tub = HotTub
|
|
28
|
+
hot_tub = HotTub.new(:size => 5, :max_size => 5) { MocClient.new }
|
|
28
29
|
threads = []
|
|
29
|
-
|
|
30
|
+
50.times.each do
|
|
30
31
|
threads << Thread.new do
|
|
31
|
-
|
|
32
|
-
conn
|
|
32
|
+
20.times do
|
|
33
|
+
hot_tub.run do |conn|
|
|
34
|
+
conn.get
|
|
35
|
+
end
|
|
33
36
|
end
|
|
34
37
|
end
|
|
35
38
|
end
|
|
@@ -39,12 +42,14 @@ Benchmark.bmbm do |b|
|
|
|
39
42
|
end
|
|
40
43
|
|
|
41
44
|
b.report("threaded size 5, max 10") do
|
|
42
|
-
hot_tub = HotTub
|
|
45
|
+
hot_tub = HotTub.new(:size => 5, :max_size => 10) { MocClient.new }
|
|
43
46
|
threads = []
|
|
44
|
-
|
|
47
|
+
50.times.each do
|
|
45
48
|
threads << Thread.new do
|
|
46
|
-
|
|
47
|
-
conn
|
|
49
|
+
20.times do
|
|
50
|
+
hot_tub.run do |conn|
|
|
51
|
+
conn.get
|
|
52
|
+
end
|
|
48
53
|
end
|
|
49
54
|
end
|
|
50
55
|
end
|
|
@@ -54,12 +59,37 @@ Benchmark.bmbm do |b|
|
|
|
54
59
|
end
|
|
55
60
|
|
|
56
61
|
b.report("threaded, size 5, no max") do
|
|
57
|
-
hot_tub = HotTub
|
|
62
|
+
hot_tub = HotTub.new(:size => 5) { MocClient.new }
|
|
63
|
+
threads = []
|
|
64
|
+
50.times.each do
|
|
65
|
+
threads << Thread.new do
|
|
66
|
+
20.times do
|
|
67
|
+
hot_tub.run do |conn|
|
|
68
|
+
conn.get
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
threads.each do |t|
|
|
74
|
+
t.join
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
b.report("threaded, HotTub.run ") do
|
|
80
|
+
urls = ['http://foo.com','http://bar.com','http://zap.com']
|
|
81
|
+
urls.each do |url|
|
|
82
|
+
HotTub.add(url) { MocClient.new }
|
|
83
|
+
end
|
|
58
84
|
threads = []
|
|
59
|
-
|
|
85
|
+
50.times.each do
|
|
60
86
|
threads << Thread.new do
|
|
61
|
-
|
|
62
|
-
|
|
87
|
+
20.times do
|
|
88
|
+
urls.each do |url|
|
|
89
|
+
HotTub.run(url) do |conn|
|
|
90
|
+
conn.get
|
|
91
|
+
end
|
|
92
|
+
end
|
|
63
93
|
end
|
|
64
94
|
end
|
|
65
95
|
end
|
|
@@ -72,45 +102,50 @@ end
|
|
|
72
102
|
|
|
73
103
|
# ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-darwin14]
|
|
74
104
|
# Rehearsal ------------------------------------------------------------
|
|
75
|
-
# single thread 0.
|
|
76
|
-
# threaded size 5 0.
|
|
77
|
-
# threaded size 5, max 10 0.
|
|
78
|
-
# threaded, size 5, no max 0.
|
|
79
|
-
#
|
|
105
|
+
# single thread 0.070000 0.040000 0.110000 ( 10.859963)
|
|
106
|
+
# threaded size 5 0.080000 0.090000 0.170000 ( 2.288797)
|
|
107
|
+
# threaded size 5, max 10 0.060000 0.060000 0.120000 ( 1.197574)
|
|
108
|
+
# threaded, size 5, no max 0.030000 0.030000 0.060000 ( 0.222523)
|
|
109
|
+
# threaded, HotTub.run 0.090000 0.090000 0.180000 ( 0.659862)
|
|
110
|
+
# --------------------------------------------------- total: 0.640000sec
|
|
80
111
|
|
|
81
112
|
# user system total real
|
|
82
|
-
# single thread 0.
|
|
83
|
-
# threaded size 5 0.
|
|
84
|
-
# threaded size 5, max 10 0.
|
|
85
|
-
# threaded, size 5, no max 0.
|
|
113
|
+
# single thread 0.080000 0.030000 0.110000 ( 10.871813)
|
|
114
|
+
# threaded size 5 0.080000 0.090000 0.170000 ( 2.228075)
|
|
115
|
+
# threaded size 5, max 10 0.060000 0.070000 0.130000 ( 1.204607)
|
|
116
|
+
# threaded, size 5, no max 0.030000 0.020000 0.050000 ( 0.220836)
|
|
117
|
+
# threaded, HotTub.run 0.090000 0.080000 0.170000 ( 0.670364)
|
|
86
118
|
|
|
87
119
|
|
|
88
120
|
# rubinius 2.5.8 (2.1.0 bef51ae3 2015-07-14 3.5.1 JI) [x86_64-darwin14.4.0]
|
|
89
121
|
# Rehearsal ------------------------------------------------------------
|
|
90
|
-
# single thread 0.
|
|
91
|
-
# threaded size 5 0.
|
|
92
|
-
# threaded size 5, max 10 0.
|
|
93
|
-
# threaded, size 5, no max 0.
|
|
94
|
-
#
|
|
122
|
+
# single thread 0.152422 0.059901 0.212323 ( 11.104594)
|
|
123
|
+
# threaded size 5 0.204700 0.192881 0.397581 ( 2.273955)
|
|
124
|
+
# threaded size 5, max 10 0.166915 0.155789 0.322704 ( 1.161038)
|
|
125
|
+
# threaded, size 5, no max 0.143544 0.055138 0.198682 ( 0.233619)
|
|
126
|
+
# threaded, HotTub.run 0.184800 0.143068 0.327868 ( 0.699002)
|
|
127
|
+
# --------------------------------------------------- total: 1.459158sec
|
|
95
128
|
|
|
96
129
|
# user system total real
|
|
97
|
-
# single thread 0.
|
|
98
|
-
# threaded size 5 0.
|
|
99
|
-
# threaded size 5, max 10 0.
|
|
100
|
-
# threaded, size 5, no max 0.
|
|
130
|
+
# single thread 0.146872 0.053339 0.200211 ( 11.129070)
|
|
131
|
+
# threaded size 5 0.206160 0.199475 0.405635 ( 2.270780)
|
|
132
|
+
# threaded size 5, max 10 0.201255 0.163359 0.364614 ( 1.205708)
|
|
133
|
+
# threaded, size 5, no max 0.066599 0.067142 0.133741 ( 0.237895)
|
|
134
|
+
# threaded, HotTub.run 0.533596 0.093450 0.627046 ( 0.670178)
|
|
101
135
|
|
|
102
136
|
|
|
103
137
|
# jruby 9.0.3.0 (2.2.2) 2015-10-21 633c9aa Java HotSpot(TM) 64-Bit Server VM 23.5-b02 on 1.7.0_09-b05 +jit [darwin-x86_64]
|
|
104
138
|
# Rehearsal ------------------------------------------------------------
|
|
105
|
-
# single thread
|
|
106
|
-
# threaded size 5
|
|
107
|
-
# threaded size 5, max 10 0.
|
|
108
|
-
# threaded, size 5, no max 0.
|
|
109
|
-
#
|
|
139
|
+
# single thread 0.760000 0.050000 0.810000 ( 11.191212)
|
|
140
|
+
# threaded size 5 0.790000 0.120000 0.910000 ( 2.262856)
|
|
141
|
+
# threaded size 5, max 10 0.600000 0.080000 0.680000 ( 1.160630)
|
|
142
|
+
# threaded, size 5, no max 0.360000 0.040000 0.400000 ( 0.228086)
|
|
143
|
+
# threaded, HotTub.run 0.860000 0.100000 0.960000 ( 0.673639)
|
|
144
|
+
# --------------------------------------------------- total: 3.760000sec
|
|
110
145
|
|
|
111
146
|
# user system total real
|
|
112
|
-
# single thread 0.
|
|
113
|
-
# threaded size 5 0.
|
|
114
|
-
# threaded size 5, max 10 0.
|
|
115
|
-
# threaded, size 5, no max 0.300000 0.
|
|
116
|
-
|
|
147
|
+
# single thread 0.520000 0.060000 0.580000 ( 11.079422)
|
|
148
|
+
# threaded size 5 0.390000 0.100000 0.490000 ( 2.235107)
|
|
149
|
+
# threaded size 5, max 10 0.290000 0.080000 0.370000 ( 1.171805)
|
|
150
|
+
# threaded, size 5, no max 0.300000 0.030000 0.330000 ( 0.265258)
|
|
151
|
+
# threaded, HotTub.run 0.580000 0.090000 0.670000 ( 0.672435)
|
data/hot_tub.gemspec
CHANGED
|
@@ -9,12 +9,10 @@ Gem::Specification.new do |s|
|
|
|
9
9
|
s.email = ["joshmckin@gmail.com"]
|
|
10
10
|
s.homepage = "https://github.com/JoshMcKin/hot_tub"
|
|
11
11
|
s.license = "MIT"
|
|
12
|
-
s.summary = %q{
|
|
13
|
-
s.description = %q{
|
|
12
|
+
s.summary = %q{Flexible connection pooling for Ruby.}
|
|
13
|
+
s.description = %q{Flexible connection pooling for Ruby.}
|
|
14
14
|
|
|
15
15
|
s.rubyforge_project = "hot_tub"
|
|
16
|
-
|
|
17
|
-
s.add_runtime_dependency "thread_safe"
|
|
18
16
|
|
|
19
17
|
s.add_development_dependency "rspec"
|
|
20
18
|
s.add_development_dependency "rspec-autotest"
|
|
@@ -14,14 +14,20 @@ module HotTub
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
+
|
|
17
18
|
# Attempts to clean the provided client, checking the options first for a clean block
|
|
18
19
|
# then checking the known clients
|
|
19
20
|
def clean_client(clnt)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
if @clean_client
|
|
22
|
+
begin
|
|
23
|
+
if @clean_client.is_a?(Proc)
|
|
24
|
+
preform_client_block(clnt,&@clean_client)
|
|
25
|
+
else
|
|
26
|
+
preform_client_method(clnt,@clean_client)
|
|
27
|
+
end
|
|
28
|
+
rescue => e
|
|
29
|
+
HotTub.logger.error "[HotTub] There was an error cleaning one of your #{self.class.name} clients: #{e}" if HotTub.logger
|
|
30
|
+
end
|
|
25
31
|
end
|
|
26
32
|
clnt
|
|
27
33
|
end
|
|
@@ -29,24 +35,36 @@ module HotTub
|
|
|
29
35
|
# Attempts to close the provided client, checking the options first for a close block
|
|
30
36
|
# then checking the known clients
|
|
31
37
|
def close_client(clnt)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
@close_action = (@close_client || known_client_action(clnt,:close) || false) if @close_action.nil?
|
|
39
|
+
if @close_action
|
|
40
|
+
begin
|
|
41
|
+
if @close_action.is_a?(Proc)
|
|
42
|
+
preform_client_block(clnt,&@close_action)
|
|
43
|
+
else
|
|
44
|
+
preform_client_method(clnt,@close_action)
|
|
45
|
+
end
|
|
46
|
+
rescue => e
|
|
47
|
+
HotTub.logger.error "[HotTub] There was an error closing one of your #{self.class.name} clients: #{e}" if HotTub.logger
|
|
48
|
+
end
|
|
37
49
|
end
|
|
38
50
|
nil
|
|
39
51
|
end
|
|
40
52
|
|
|
41
53
|
# Attempts to determine if a client should be reaped, block should return a boolean
|
|
42
54
|
def reap_client?(clnt)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
55
|
+
rc = false
|
|
56
|
+
if @reap_client
|
|
57
|
+
begin
|
|
58
|
+
if @reap_client.is_a?(Proc)
|
|
59
|
+
rc = preform_client_block(clnt,&@reap_client)
|
|
60
|
+
else
|
|
61
|
+
rc = preform_client_method(clnt,@reap_client)
|
|
62
|
+
end
|
|
63
|
+
rescue => e
|
|
64
|
+
HotTub.logger.error "[HotTub] There was an error reaping one of your #{self.class.name} clients: #{e}" if HotTub.logger
|
|
65
|
+
end
|
|
48
66
|
end
|
|
49
|
-
|
|
67
|
+
rc
|
|
50
68
|
end
|
|
51
69
|
|
|
52
70
|
private
|
|
@@ -55,13 +73,12 @@ module HotTub
|
|
|
55
73
|
(KNOWN_CLIENTS[clnt.class.name] && KNOWN_CLIENTS[clnt.class.name][key])
|
|
56
74
|
end
|
|
57
75
|
|
|
58
|
-
def
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
false
|
|
76
|
+
def preform_client_block(clnt,action=nil)
|
|
77
|
+
yield clnt
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def preform_client_method(clnt,action=nil)
|
|
81
|
+
clnt.send(action)
|
|
65
82
|
end
|
|
66
83
|
end
|
|
67
84
|
end
|