Skip to content

Commit 3eb56ab

Browse files
authored
Merge pull request #40 from Sage/mutex
Use a mutex when checking out and checking in connections
2 parents 34c0f3a + c7983fe commit 3eb56ab

File tree

3 files changed

+36
-17
lines changed

3 files changed

+36
-17
lines changed

lib/mysql_framework/connector.rb

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module MysqlFramework
44
class Connector
55
def initialize(options = {})
66
@options = default_options.merge(options)
7+
@mutex = Mutex.new
78

89
Mysql2::Client.default_query_options.merge!(symbolize_keys: true, cast_booleans: true)
910
end
@@ -25,7 +26,7 @@ def dispose
2526

2627
until @connection_pool.empty?
2728
conn = @connection_pool.pop(true)
28-
conn.close
29+
conn&.close
2930
end
3031

3132
@connection_pool = nil
@@ -38,31 +39,37 @@ def connections
3839

3940
# This method is called to fetch a client from the connection pool.
4041
def check_out
41-
return new_client unless connection_pool_enabled?
42+
@mutex.synchronize do
43+
begin
44+
return new_client unless connection_pool_enabled?
4245

43-
client = @connection_pool.pop(true)
46+
client = @connection_pool.pop(true)
4447

45-
client.ping if @options[:reconnect]
48+
client.ping if @options[:reconnect]
4649

47-
client
48-
rescue ThreadError
49-
if @created_connections < max_pool_size
50-
client = new_client
51-
@created_connections += 1
52-
return client
53-
end
50+
client
51+
rescue ThreadError
52+
if @created_connections < max_pool_size
53+
client = new_client
54+
@created_connections += 1
55+
return client
56+
end
5457

55-
MysqlFramework.logger.error { "[#{self.class}] - Database connection pool depleted." }
58+
MysqlFramework.logger.error { "[#{self.class}] - Database connection pool depleted." }
5659

57-
raise 'Database connection pool depleted.'
60+
raise 'Database connection pool depleted.'
61+
end
62+
end
5863
end
5964

6065
# This method is called to check a client back in to the connection when no longer needed.
6166
def check_in(client)
62-
return client&.close unless connection_pool_enabled?
67+
@mutex.synchronize do
68+
return client&.close unless connection_pool_enabled?
6369

64-
client = new_client if client.nil? || client.closed?
65-
@connection_pool.push(client)
70+
client = new_client if client&.closed?
71+
@connection_pool.push(client)
72+
end
6673
end
6774

6875
# This method is called to use a client from the connection pool.

lib/mysql_framework/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module MysqlFramework
4-
VERSION = '2.1.3'
4+
VERSION = '2.1.4'
55
end

spec/lib/mysql_framework/connector_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@
118118
end
119119

120120
describe '#check_out' do
121+
it 'calls synchronize on the mutex' do
122+
expect(subject.instance_variable_get(:@mutex)).to receive(:synchronize)
123+
124+
subject.check_out
125+
end
126+
121127
context 'when connection pooling is enabled' do
122128
context 'when there are available connections' do
123129
before do
@@ -203,6 +209,12 @@
203209
end
204210

205211
describe '#check_in' do
212+
it 'calls synchronize on the mutex' do
213+
expect(subject.instance_variable_get(:@mutex)).to receive(:synchronize)
214+
215+
subject.check_out
216+
end
217+
206218
context 'when connection pooling is enabled' do
207219
it 'returns the provided client to the connection pool' do
208220
expect(subject.connections).to receive(:push).with(client)

0 commit comments

Comments
 (0)