Skip to content

Commit d72b5f5

Browse files
committed
refactor kwarg handling, update documentation, no functional changes
1 parent 6f3912f commit d72b5f5

3 files changed

Lines changed: 52 additions & 61 deletions

File tree

README.md

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -102,24 +102,15 @@ Like `shutdown`, this will block until all connections are checked in and closed
102102

103103
## Reap
104104

105-
You can reap idle connections in the ConnectionPool instance to close connections that were created but have not been used for a certain amount of time. This can be useful to run periodically in a separate thread especially if keeping the connection open is resource intensive.
105+
You can call `reap` periodically on the ConnectionPool instance to close connections that were created but have not been used for a certain amount of time. This can be useful in environments where connections are expensive.
106106

107-
You can specify how many seconds the connections have to be idle for them to be reaped.
108-
Defaults to 60 seconds.
107+
You can specify how many seconds the connections have to be idle for them to be reaped, defaulting to 60 seconds.
109108

110109
```ruby
111110
cp = ConnectionPool.new { Redis.new }
112-
cp.reap(idle_seconds: 300) { |conn| conn.close } # Reaps connections that have been idle for 300 seconds (5 minutes).
113-
```
114-
115-
### Reaper Thread
116-
117-
You can start your own reaper thread to reap idle connections in the ConnectionPool instance on a regular interval.
118111

119-
```ruby
120-
cp = ConnectionPool.new { Redis.new }
121-
122-
# Start a reaper thread to reap connections that have been idle for 300 seconds (5 minutes).
112+
# Start a reaper thread to reap connections that have been
113+
# idle more than 300 seconds (5 minutes)
123114
Thread.new do
124115
loop do
125116
cp.reap(idle_seconds: 300) { |conn| conn.close }
@@ -139,14 +130,14 @@ It can only be done inside the block passed to `with` or `with_timeout`.
139130
Takes an optional block that will be executed with the connection.
140131

141132
```ruby
142-
pool.with do |conn|
143-
begin
144-
conn.execute("SELECT 1")
145-
rescue SomeConnectionError
146-
pool.discard_current_connection # remove the connection from the pool
147-
raise
148-
end
149-
end
133+
pool.with do |conn|
134+
begin
135+
conn.execute("SELECT 1")
136+
rescue SomeConnectionError
137+
pool.discard_current_connection # remove the connection from the pool
138+
raise
139+
end
140+
end
150141
```
151142

152143
## Current State
@@ -168,12 +159,11 @@ end
168159
cp.idle # => 1
169160
```
170161

171-
Upgrading from ConnectionPool 2
172-
---------------------------------
162+
## Upgrading from ConnectionPool 2
173163

174-
* Support for Rubies <3.2 has been removed.
164+
* Support for Ruby <3.2 has been removed.
175165
* ConnectionPool's APIs now consistently use keyword arguments everywhere.
176-
Any positional arguments must be converted to keywords:
166+
Positional arguments must be converted to keywords:
177167
```ruby
178168
pool = ConnectionPool.new(size: 5, timeout: 5)
179169
pool.checkout(1) # 2.x
@@ -182,20 +172,15 @@ pool.checkout(timeout: 1) # 3.x
182172
pool.reap(idle_seconds: 30) # 3.x
183173
```
184174

185-
Notes
186-
-----
175+
## Notes
187176

188177
- Connections are lazily created as needed.
189-
- There is no provision for repairing or checking the health of a connection;
190-
connections should be self-repairing. This is true of the Dalli and Redis
191-
clients.
192-
- **WARNING**: Don't ever use `Timeout.timeout` in your Ruby code or you will see
178+
- **WARNING**: Avoid `Timeout.timeout` in your Ruby code or you can see
193179
occasional silent corruption and mysterious errors. The Timeout API is unsafe
194-
and cannot be used correctly, ever. Use proper socket timeout options as
195-
exposed by Net::HTTP, Redis, Dalli, etc.
180+
and dangerous to use. Use proper socket timeout options as exposed by
181+
Net::HTTP, Redis, Dalli, etc.
196182

197183

198-
Author
199-
------
184+
## Author
200185

201-
Mike Perham, [@getajobmike](https://twitter.com/getajobmike), <https://www.mikeperham.com>
186+
Mike Perham, [@getajobmike](https://ruby.social/@getajobmike), <https://www.mikeperham.com>

connection_pool.gemspec

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,18 @@ Gem::Specification.new do |s|
1515
s.executables = []
1616
s.require_paths = ["lib"]
1717
s.license = "MIT"
18+
19+
s.required_ruby_version = ">= 3.2.0"
1820
s.add_development_dependency "bundler"
1921
s.add_development_dependency "maxitest"
2022
s.add_development_dependency "rake"
21-
s.required_ruby_version = ">= 2.5.0"
2223

23-
s.metadata = {"changelog_uri" => "https://github.com/mperham/connection_pool/blob/main/Changes.md", "rubygems_mfa_required" => "true"}
24+
s.metadata = {
25+
"bug_tracker_uri" => "https://github.com/mperham/connection_pool/issues",
26+
"documentation_uri" => "https://github.com/mperham/connection_pool/wiki",
27+
"changelog_uri" => "https://github.com/mperham/connection_pool/blob/main/Changes.md",
28+
"source_code_uri" => "https://github.com/mperham/connection_pool",
29+
"homepage_uri" => "https://github.com/mperham/connection_pool",
30+
"rubygems_mfa_required" => "true"
31+
}
2432
end

lib/connection_pool/timed_stack.rb

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ def initialize(size: 0, &block)
3333
end
3434

3535
##
36-
# Returns +obj+ to the stack. +kwargs+ is ignored in TimedStack but may be
36+
# Returns +obj+ to the stack. Additional kwargs are ignored in TimedStack but may be
3737
# used by subclasses that extend TimedStack.
38-
def push(obj, **options)
38+
def push(obj, **)
3939
@mutex.synchronize do
4040
if @shutdown_block
4141
@created -= 1 unless @created == 0
4242
@shutdown_block.call(obj)
4343
else
44-
store_connection obj, **options
44+
store_connection obj, **
4545
end
4646

4747
@resource.broadcast
@@ -60,16 +60,16 @@ def push(obj, **options)
6060
#
6161
# The +timeout+ argument will be removed in 3.0.
6262
# Other options may be used by subclasses that extend TimedStack.
63-
def pop(timeout: 0.5, exception: ConnectionPool::TimeoutError, **options)
63+
def pop(timeout: 0.5, exception: ConnectionPool::TimeoutError, **)
6464
deadline = current_time + timeout
6565
@mutex.synchronize do
6666
loop do
6767
raise ConnectionPool::PoolShuttingDownError if @shutdown_block
68-
if (conn = try_fetch_connection(**options))
68+
if (conn = try_fetch_connection(**))
6969
return conn
7070
end
7171

72-
connection = try_create(**options)
72+
connection = try_create(**)
7373
return connection if connection
7474

7575
to_wait = deadline - current_time
@@ -104,21 +104,19 @@ def shutdown(reload: false, &block)
104104

105105
##
106106
# Reaps connections that were checked in more than +idle_seconds+ ago.
107-
def reap(idle_seconds:, &block)
108-
raise ArgumentError, "reap must receive a block" unless block
107+
def reap(idle_seconds:, &)
108+
raise ArgumentError, "reap must receive a block" unless block_given?
109109
raise ArgumentError, "idle_seconds must be a number" unless idle_seconds.is_a?(Numeric)
110110
raise ConnectionPool::PoolShuttingDownError if @shutdown_block
111111

112112
idle.times do
113-
conn =
114-
@mutex.synchronize do
115-
raise ConnectionPool::PoolShuttingDownError if @shutdown_block
116-
117-
reserve_idle_connection(idle_seconds)
118-
end
113+
conn = @mutex.synchronize do
114+
raise ConnectionPool::PoolShuttingDownError if @shutdown_block
115+
reserve_idle_connection(idle_seconds)
116+
end
119117
break unless conn
120118

121-
block.call(conn)
119+
yield conn
122120
end
123121
end
124122

@@ -158,32 +156,32 @@ def current_time
158156
# This method must returns a connection from the stack if one exists. Allows
159157
# subclasses with expensive match/search algorithms to avoid double-handling
160158
# their stack.
161-
def try_fetch_connection(**options)
162-
connection_stored?(**options) && fetch_connection(**options)
159+
def try_fetch_connection(**)
160+
connection_stored?(**) && fetch_connection(**)
163161
end
164162

165163
##
166164
# This is an extension point for TimedStack and is called with a mutex.
167165
#
168166
# This method must returns true if a connection is available on the stack.
169-
def connection_stored?(**options)
167+
def connection_stored?(**)
170168
!@que.empty?
171169
end
172170

173171
##
174172
# This is an extension point for TimedStack and is called with a mutex.
175173
#
176174
# This method must return a connection from the stack.
177-
def fetch_connection(**options)
175+
def fetch_connection(**)
178176
@que.pop&.first
179177
end
180178

181179
##
182180
# This is an extension point for TimedStack and is called with a mutex.
183181
#
184182
# This method must shut down all connections on the stack.
185-
def shutdown_connections(**options)
186-
while (conn = try_fetch_connection(**options))
183+
def shutdown_connections(**)
184+
while (conn = try_fetch_connection(**))
187185
@created -= 1 unless @created == 0
188186
@shutdown_block.call(conn)
189187
end
@@ -214,7 +212,7 @@ def idle_connections?(idle_seconds)
214212
# This is an extension point for TimedStack and is called with a mutex.
215213
#
216214
# This method must return +obj+ to the stack.
217-
def store_connection(obj, **options)
215+
def store_connection(obj, **)
218216
@que.push [obj, current_time]
219217
end
220218

@@ -223,7 +221,7 @@ def store_connection(obj, **options)
223221
#
224222
# This method must create a connection if and only if the total number of
225223
# connections allowed has not been met.
226-
def try_create(**options)
224+
def try_create(**)
227225
unless @created == @max
228226
object = @create_block.call
229227
@created += 1

0 commit comments

Comments
 (0)