fibered_mysql2 0.4.0.pre.tstarck.3 → 1.0.0.colin.1
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/.github/CODEOWNERS +1 -0
- data/.github/workflows/build.yml +4 -3
- data/.ruby-version +1 -1
- data/Appraisals +5 -7
- data/CHANGELOG.md +0 -36
- data/Gemfile +7 -6
- data/Gemfile.lock +166 -204
- data/fibered_mysql2.gemspec +2 -2
- data/gemfiles/rails_5.gemfile +15 -0
- data/gemfiles/rails_6.gemfile +15 -0
- data/lib/active_record/connection_adapters/fibered_mysql2_adapter.rb +32 -132
- data/lib/fibered_mysql2/async_task.rb +18 -0
- data/lib/fibered_mysql2/fibered_database_connection_pool.rb +44 -217
- data/lib/fibered_mysql2/fibered_mysql2_connection_factory.rb +14 -8
- data/lib/fibered_mysql2/version.rb +1 -1
- data/lib/fibered_mysql2.rb +1 -1
- metadata +18 -18
- data/gemfiles/.bundle/config +0 -2
- data/gemfiles/rails_7_0.gemfile +0 -18
- data/gemfiles/rails_7_1.gemfile +0 -15
- data/lib/fibered_mysql2/hash_config_override.rb +0 -16
@@ -1,176 +1,76 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'em-synchrony'
|
4
3
|
require 'active_model'
|
5
4
|
require 'active_record/errors'
|
6
|
-
|
7
5
|
require 'active_record/connection_adapters/mysql2_adapter'
|
8
|
-
|
6
|
+
require_relative '../../fibered_mysql2/async_task'
|
9
7
|
|
10
8
|
module FiberedMysql2
|
11
|
-
module
|
9
|
+
module FiberedMysql2Adapter_6
|
12
10
|
def lease
|
13
|
-
if
|
14
|
-
msg = "Cannot lease connection
|
15
|
-
if
|
16
|
-
msg << "it is already leased by the current
|
11
|
+
if (ot = owner_task)
|
12
|
+
msg = +"Cannot lease connection; "
|
13
|
+
if ot == (current_task = AsyncTask.current_or_none)
|
14
|
+
msg << "it is already leased by the current Async::Task."
|
17
15
|
else
|
18
|
-
msg << "it is already in use by a different
|
19
|
-
"Current
|
16
|
+
msg << "it is already in use by a different Async::Task: #{ot}. " \
|
17
|
+
"Current Async::Task: #{current_task}."
|
20
18
|
end
|
21
19
|
raise ::ActiveRecord::ActiveRecordError, msg
|
22
20
|
end
|
23
21
|
|
24
|
-
@owner =
|
22
|
+
@owner = AsyncTask.current_or_none
|
25
23
|
end
|
26
24
|
|
27
25
|
def expire
|
28
|
-
if
|
29
|
-
# Because we are actively releasing connections from dead
|
30
|
-
# to enforce that we're expiring the current
|
26
|
+
if (ot = owner_task)
|
27
|
+
# Because we are actively releasing connections from dead tasks, we only want
|
28
|
+
# to enforce that we're expiring the current task's connection, iff the owner
|
31
29
|
# of the connection is still alive.
|
32
|
-
if
|
33
|
-
raise ::ActiveRecord::ActiveRecordError, "Cannot expire connection
|
34
|
-
"it is owned by a different
|
35
|
-
"Current
|
30
|
+
if ot.alive? && ot != (current_task = AsyncTask.current_or_none)
|
31
|
+
raise ::ActiveRecord::ActiveRecordError, "Cannot expire connection; " \
|
32
|
+
"it is owned by a different Async::Task: #{ot}. " \
|
33
|
+
"Current Async::Task: #{current_task}."
|
36
34
|
end
|
37
35
|
|
38
36
|
@idle_since = ::Concurrent.monotonic_time
|
39
37
|
@owner = nil
|
40
38
|
else
|
41
|
-
raise ::ActiveRecord::ActiveRecordError, "Cannot expire connection
|
39
|
+
raise ::ActiveRecord::ActiveRecordError, "Cannot expire connection; it is not currently leased."
|
42
40
|
end
|
43
41
|
end
|
44
42
|
|
45
43
|
def steal!
|
46
|
-
if
|
47
|
-
if
|
48
|
-
pool.send :remove_connection_from_thread_cache, self,
|
44
|
+
if (ot = owner_task)
|
45
|
+
if ot != (current_task = AsyncTask.current_or_none)
|
46
|
+
pool.send :remove_connection_from_thread_cache, self, ot
|
49
47
|
|
50
|
-
@owner =
|
48
|
+
@owner = current_task
|
51
49
|
end
|
52
50
|
else
|
53
|
-
raise ::ActiveRecord::ActiveRecordError, "Cannot steal connection
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def reset_transaction #:nodoc:
|
58
|
-
@transaction_manager = ::FiberedMysql2::FiberedMysql2Adapter_7_0::TransactionManager.new(self)
|
59
|
-
end
|
60
|
-
|
61
|
-
class TransactionManager < ::ActiveRecord::ConnectionAdapters::TransactionManager
|
62
|
-
def initialize(...)
|
63
|
-
super
|
64
|
-
@stack = Hash.new { |h, k| h[k] = [] }
|
65
|
-
end
|
66
|
-
|
67
|
-
def current_transaction #:nodoc:
|
68
|
-
_current_stack.last || ::ActiveRecord::ConnectionAdapters::TransactionManager::NULL_TRANSACTION
|
69
|
-
end
|
70
|
-
|
71
|
-
def open_transactions
|
72
|
-
_current_stack.size
|
73
|
-
end
|
74
|
-
|
75
|
-
def begin_transaction(isolation: nil, joinable: true, _lazy: true)
|
76
|
-
@connection.lock.synchronize do
|
77
|
-
run_commit_callbacks = !current_transaction.joinable?
|
78
|
-
transaction =
|
79
|
-
if _current_stack.empty?
|
80
|
-
::ActiveRecord::ConnectionAdapters::RealTransaction.new(@connection, isolation:, joinable:, run_commit_callbacks: run_commit_callbacks)
|
81
|
-
else
|
82
|
-
::ActiveRecord::ConnectionAdapters::SavepointTransaction.new(@connection, "active_record_#{Fiber.current.object_id}_#{open_transactions}", _current_stack.last, isolation:, joinable:, run_commit_callbacks: run_commit_callbacks)
|
83
|
-
end
|
84
|
-
|
85
|
-
if @connection.supports_lazy_transactions? && lazy_transactions_enabled? && _lazy
|
86
|
-
@has_unmaterialized_transactions = true
|
87
|
-
else
|
88
|
-
transaction.materialize!
|
89
|
-
end
|
90
|
-
_current_stack.push(transaction)
|
91
|
-
transaction
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
# Overriding the ActiveRecord::TransactionManager#materialize_transactions method to use
|
96
|
-
# fiber safe the _current_stack instead of the @stack instance variable. when marterializing
|
97
|
-
# transactions.
|
98
|
-
def materialize_transactions
|
99
|
-
return if @materializing_transactions
|
100
|
-
return unless @has_unmaterialized_transactions
|
101
|
-
|
102
|
-
@connection.lock.synchronize do
|
103
|
-
begin
|
104
|
-
@materializing_transactions = true
|
105
|
-
_current_stack.each { |t| t.materialize! unless t.materialized? }
|
106
|
-
ensure
|
107
|
-
@materializing_transactions = false
|
108
|
-
end
|
109
|
-
@has_unmaterialized_transactions = false
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
# Overriding the ActiveRecord::TransactionManager#commit_transaction method to use
|
114
|
-
# fiber safe the _current_stack instead of the @stack instance variable. when marterializing
|
115
|
-
# transactions.
|
116
|
-
def commit_transaction
|
117
|
-
@connection.lock.synchronize do
|
118
|
-
transaction = _current_stack.last
|
119
|
-
|
120
|
-
begin
|
121
|
-
transaction.before_commit_records
|
122
|
-
ensure
|
123
|
-
_current_stack.pop
|
124
|
-
end
|
125
|
-
|
126
|
-
transaction.commit
|
127
|
-
transaction.commit_records
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
# Overriding the ActiveRecord::TransactionManager#rollback_transaction method to use
|
132
|
-
# fiber safe the _current_stack instead of the @stack instance variable. when marterializing
|
133
|
-
# transactions.
|
134
|
-
def rollback_transaction(transaction = nil)
|
135
|
-
@connection.lock.synchronize do
|
136
|
-
transaction ||= _current_stack.pop
|
137
|
-
transaction.rollback
|
138
|
-
transaction.rollback_records
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
private
|
143
|
-
|
144
|
-
def _current_stack
|
145
|
-
@stack[Fiber.current.object_id]
|
51
|
+
raise ::ActiveRecord::ActiveRecordError, "Cannot steal connection; it is not currently leased."
|
146
52
|
end
|
147
53
|
end
|
148
54
|
|
149
55
|
private
|
150
56
|
|
151
|
-
def
|
152
|
-
@owner.nil? || @owner.is_a?(
|
153
|
-
raise "@owner must be
|
57
|
+
def owner_task
|
58
|
+
@owner.nil? || @owner == AsyncTask::NoTaskPlaceholder || @owner.is_a?(Async::Task) or
|
59
|
+
raise "@owner must be an Async::Task or FiberedMysql2::AsyncTask::NoTaskPlaceholder! Found #{@owner.inspect}"
|
154
60
|
@owner
|
155
61
|
end
|
156
62
|
end
|
157
63
|
|
158
64
|
class FiberedMysql2Adapter < ::ActiveRecord::ConnectionAdapters::Mysql2Adapter
|
159
|
-
|
160
|
-
|
65
|
+
case ::Rails::VERSION::MAJOR
|
66
|
+
when 6
|
67
|
+
include FiberedMysql2Adapter_6
|
68
|
+
else
|
69
|
+
raise ArgumentError, "unexpected Rails version #{Rails::VERSION::MAJOR}"
|
161
70
|
end
|
162
71
|
|
163
|
-
|
164
|
-
|
165
|
-
def new_client(config)
|
166
|
-
Mysql2::EM::Client.new(config)
|
167
|
-
rescue Mysql2::Error => error
|
168
|
-
if error.error_number == 1049
|
169
|
-
raise ActiveRecord::NoDatabaseError.new, error.message
|
170
|
-
else
|
171
|
-
raise ActiveRecord::ConnectionNotEstablished, error.message
|
172
|
-
end
|
173
|
-
end
|
72
|
+
def initialize(*args)
|
73
|
+
super
|
174
74
|
end
|
175
75
|
end
|
176
76
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FiberedMysql2
|
4
|
+
module AsyncTask
|
5
|
+
class NoTaskPlaceholder
|
6
|
+
class << self
|
7
|
+
def alive? = true
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class << self
|
12
|
+
# Adapted from https://github.com/socketry/async/blob/main/lib/async/task.rb#L236-L238
|
13
|
+
def current_or_none
|
14
|
+
Thread.current[:async_task] || NoTaskPlaceholder
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,246 +1,52 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# This class behaves the same as ActiveRecord's ConnectionPool, but synchronizes with fibers rather than threads.
|
3
|
+
# This class behaves the same as ActiveRecord's ConnectionPool, but synchronizes with Async::Task fibers rather than threads.
|
4
4
|
|
5
5
|
# Note - trace statements have been commented out. This is useful trace but we do not want it on by default.
|
6
6
|
# When we have configurable logging we can put this back and have it off by default.
|
7
7
|
|
8
|
-
require 'em-synchrony'
|
9
|
-
require 'em-synchrony/thread'
|
10
|
-
require 'fibered_mysql2/fibered_mutex_with_waiter_priority'
|
11
|
-
|
12
|
-
EventMachine::Synchrony::Thread::Mutex.prepend(FiberedMysql2::FiberedMutexWithWaiterPriority)
|
13
|
-
|
14
8
|
module FiberedMysql2
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
# FIXME: This isn't documented in Nutshell.
|
21
|
-
#
|
22
|
-
# Since MonitorMixin.new_cond returns a ConditionVariable, and the example
|
23
|
-
# above calls while_wait and signal, this class should be documented.
|
24
|
-
#
|
25
|
-
class Timeout < Exception; end
|
26
|
-
|
27
|
-
#
|
28
|
-
# Releases the lock held in the associated monitor and waits; reacquires the lock on wakeup.
|
29
|
-
#
|
30
|
-
# If +timeout+ is given, this method returns after +timeout+ seconds passed,
|
31
|
-
# even if no other thread doesn't signal.
|
32
|
-
#
|
33
|
-
def wait(timeout = nil)
|
34
|
-
Thread.handle_interrupt(EXCEPTION_NEVER) do
|
35
|
-
@monitor.__send__(:mon_check_owner)
|
36
|
-
count = @monitor.__send__(:mon_exit_for_cond)
|
37
|
-
begin
|
38
|
-
Thread.handle_interrupt(EXCEPTION_IMMEDIATE) do
|
39
|
-
@cond.wait(@monitor.instance_variable_get(:@mon_mutex), timeout)
|
40
|
-
end
|
41
|
-
return true
|
42
|
-
ensure
|
43
|
-
@monitor.__send__(:mon_enter_for_cond, count)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
#
|
49
|
-
# Calls wait repeatedly while the given block yields a truthy value.
|
50
|
-
#
|
51
|
-
def wait_while
|
52
|
-
while yield
|
53
|
-
wait
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
#
|
58
|
-
# Calls wait repeatedly until the given block yields a truthy value.
|
59
|
-
#
|
60
|
-
def wait_until
|
61
|
-
until yield
|
62
|
-
wait
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
#
|
67
|
-
# Wakes up the first thread in line waiting for this lock.
|
68
|
-
#
|
69
|
-
def signal
|
70
|
-
@monitor.__send__(:mon_check_owner)
|
71
|
-
@cond.signal
|
72
|
-
end
|
73
|
-
|
74
|
-
#
|
75
|
-
# Wakes up all threads waiting for this lock.
|
76
|
-
#
|
77
|
-
def broadcast
|
78
|
-
@monitor.__send__(:mon_check_owner)
|
79
|
-
@cond.broadcast
|
80
|
-
end
|
81
|
-
|
82
|
-
def initialize(monitor)
|
83
|
-
@monitor = monitor
|
84
|
-
@cond = EM::Synchrony::Thread::ConditionVariable.new
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
# From Ruby's MonitorMixin, with all occurrences of Thread changed to Fiber
|
89
|
-
module FiberedMonitorMixin
|
90
|
-
def self.extend_object(obj)
|
91
|
-
super
|
92
|
-
obj.__send__(:mon_initialize)
|
93
|
-
end
|
94
|
-
|
95
|
-
#
|
96
|
-
# Attempts to enter exclusive section. Returns +false+ if lock fails.
|
97
|
-
#
|
98
|
-
def mon_try_enter
|
99
|
-
if @mon_owner != Fiber.current
|
100
|
-
@mon_mutex.try_lock or return false
|
101
|
-
@mon_owner = Fiber.current
|
102
|
-
@mon_count = 0
|
103
|
-
end
|
104
|
-
@mon_count += 1
|
105
|
-
true
|
9
|
+
module FiberedDatabaseConnectionPool
|
10
|
+
case ::Rails::VERSION::MAJOR
|
11
|
+
when 6
|
12
|
+
else
|
13
|
+
raise ArgumentError, "unexpected Rails version #{Rails::VERSION::MAJOR}"
|
106
14
|
end
|
107
15
|
|
108
|
-
|
109
|
-
|
110
|
-
#
|
111
|
-
def mon_enter
|
112
|
-
if @mon_owner != Fiber.current
|
113
|
-
@mon_mutex.lock
|
114
|
-
@mon_owner = Fiber.current
|
115
|
-
@mon_count = 0
|
116
|
-
end
|
117
|
-
@mon_count += 1
|
16
|
+
def cached_connections
|
17
|
+
@thread_cached_conns
|
118
18
|
end
|
119
19
|
|
120
|
-
|
121
|
-
|
122
|
-
#
|
123
|
-
def mon_exit
|
124
|
-
mon_check_owner
|
125
|
-
@mon_count -= 1
|
126
|
-
if @mon_count == 0
|
127
|
-
@mon_owner = nil
|
128
|
-
@mon_mutex.unlock
|
129
|
-
end
|
20
|
+
def current_connection_id
|
21
|
+
connection_cache_key(current_thread)
|
130
22
|
end
|
131
23
|
|
132
|
-
|
133
|
-
# Enters exclusive section and executes the block. Leaves the exclusive
|
134
|
-
# section automatically when the block exits. See example under
|
135
|
-
# +MonitorMixin+.
|
136
|
-
#
|
137
|
-
def mon_synchronize
|
138
|
-
mon_enter
|
24
|
+
def checkout(checkout_timeout = @checkout_timeout)
|
139
25
|
begin
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
mon_exit
|
144
|
-
rescue => ex
|
145
|
-
ActiveRecord::Base.logger.error("Exception occurred while executing mon_exit: #{ex}")
|
146
|
-
end
|
26
|
+
reap_connections
|
27
|
+
rescue => ex
|
28
|
+
ActiveRecord::Base.logger.error("Exception occurred while executing reap_connections: #{ex.class}: #{ex.message}")
|
147
29
|
end
|
30
|
+
super
|
148
31
|
end
|
149
|
-
alias synchronize mon_synchronize
|
150
|
-
|
151
|
-
#
|
152
|
-
# Creates a new FiberedConditionVariable associated with the
|
153
|
-
# receiver.
|
154
|
-
#
|
155
|
-
def new_cond
|
156
|
-
FiberedConditionVariable.new(self)
|
157
|
-
end
|
158
|
-
|
159
|
-
# Initializes the FiberedMonitorMixin after being included in a class
|
160
|
-
def mon_initialize
|
161
|
-
@mon_owner = nil
|
162
|
-
@mon_count = 0
|
163
|
-
@mon_mutex = EM::Synchrony::Thread::Mutex.new
|
164
|
-
end
|
165
|
-
|
166
|
-
def mon_check_owner
|
167
|
-
@mon_owner == Fiber.current or raise FiberError, "current fiber not owner"
|
168
|
-
end
|
169
|
-
|
170
|
-
private
|
171
|
-
|
172
|
-
def mon_enter_for_cond(count)
|
173
|
-
@mon_owner = Fiber.current
|
174
|
-
@mon_count = count
|
175
|
-
end
|
176
|
-
|
177
|
-
# returns the old mon_count
|
178
|
-
def mon_exit_for_cond
|
179
|
-
count = @mon_count
|
180
|
-
@mon_owner = nil
|
181
|
-
@mon_count = 0
|
182
|
-
count
|
183
|
-
end
|
184
|
-
end
|
185
32
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
if (conn = @thread_cached_conns.delete(connection_cache_key(owner_thread)))
|
190
|
-
checkin(conn)
|
191
|
-
end
|
33
|
+
def release_connection(owner_task = AsyncTask.current_or_none)
|
34
|
+
if (conn = @thread_cached_conns.delete(connection_cache_key(owner_task)))
|
35
|
+
checkin(conn)
|
192
36
|
end
|
193
|
-
|
194
|
-
def with_connection
|
195
|
-
unless (conn = cached_connections[current_connection_id]) # Invoca Patch to use Fiber
|
196
|
-
conn = connection
|
197
|
-
fresh_connection = true
|
198
|
-
end
|
199
|
-
yield conn
|
200
|
-
ensure
|
201
|
-
release_connection if fresh_connection
|
202
|
-
end
|
203
|
-
|
204
|
-
def current_thread
|
205
|
-
Fiber.current
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
if ::ActiveRecord.gem_version < "7.1"
|
210
|
-
include Adapter_7_0
|
211
37
|
end
|
212
|
-
include FiberedMonitorMixin # This is switches the connection pool's mutex and condition variables to event machine / Fiber compatible ones.
|
213
38
|
|
214
|
-
def initialize(
|
215
|
-
|
216
|
-
|
217
|
-
end
|
39
|
+
def initialize(connection_spec, *args, **keyword_args)
|
40
|
+
connection_spec.config[:reaping_frequency] and raise "reaping_frequency is not supported (the ActiveRecord Reaper is thread-based)"
|
41
|
+
connection_spec.config[:reaping_frequency] = nil # starting in Rails 5, this defaults to 60 if not explicitly set
|
218
42
|
|
219
|
-
super(
|
43
|
+
super(connection_spec, *args, **keyword_args)
|
220
44
|
|
221
45
|
@reaper = nil # no need to keep a reference to this since it does nothing in this sub-class
|
222
|
-
end
|
223
|
-
|
224
|
-
def current_connection_id
|
225
|
-
connection_cache_key(current_thread)
|
226
|
-
end
|
227
|
-
|
228
|
-
def cached_connections
|
229
|
-
@thread_cached_conns
|
230
|
-
end
|
231
46
|
|
232
|
-
|
233
|
-
# instead of waiting for all connections to be used in the pool before they are reaped.
|
234
|
-
def checkout(checkout_timeout = @checkout_timeout)
|
235
|
-
begin
|
236
|
-
reap
|
237
|
-
rescue => ex
|
238
|
-
ActiveRecord::Base.logger.error("Exception occurred while executing reap_connections: #{ex}")
|
239
|
-
end
|
240
|
-
super
|
47
|
+
# note that @reserved_connections is a ThreadSafe::Cache which is overkill in a fibered world, but harmless
|
241
48
|
end
|
242
49
|
|
243
|
-
# Invoca patch to ensure that we are using the current fiber's connection.
|
244
50
|
def connection
|
245
51
|
# this is correctly done double-checked locking
|
246
52
|
# (ThreadSafe::Cache's lookups have volatile semantics)
|
@@ -256,6 +62,27 @@ module FiberedMysql2
|
|
256
62
|
end
|
257
63
|
end
|
258
64
|
end
|
65
|
+
|
66
|
+
def reap_connections
|
67
|
+
cached_connections.values.each do |connection|
|
68
|
+
unless connection.owner.alive?
|
69
|
+
checkin(connection)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
#--
|
77
|
+
# This hook-in method allows for easier monkey-patching fixes needed by
|
78
|
+
# JRuby users that use Fibers.
|
79
|
+
def connection_cache_key(fiber)
|
80
|
+
fiber
|
81
|
+
end
|
82
|
+
|
83
|
+
def current_thread
|
84
|
+
AsyncTask.current_or_none
|
85
|
+
end
|
259
86
|
end
|
260
87
|
end
|
261
88
|
|
@@ -6,17 +6,23 @@ module FiberedMysql2
|
|
6
6
|
module FiberedMysql2ConnectionFactory
|
7
7
|
def fibered_mysql2_connection(raw_config)
|
8
8
|
config = raw_config.symbolize_keys
|
9
|
-
config[:flags] ||= 0
|
10
9
|
|
11
|
-
if config[:flags].kind_of? Array
|
12
|
-
config[:flags].push "FOUND_ROWS"
|
13
|
-
else
|
14
|
-
config[:flags] |= Mysql2::Client::FOUND_ROWS
|
15
|
-
end
|
16
10
|
config[:username] = 'root' if config[:username].nil?
|
11
|
+
config[:flags] = Mysql2::Client::FOUND_ROWS if Mysql2::Client.const_defined?(:FOUND_ROWS)
|
17
12
|
|
18
|
-
client =
|
19
|
-
|
13
|
+
client =
|
14
|
+
begin
|
15
|
+
Mysql2::Client.new(config)
|
16
|
+
rescue Mysql2::Error => error
|
17
|
+
if error.message.include?("Unknown database")
|
18
|
+
raise ActiveRecord::NoDatabaseError.new(error.message)
|
19
|
+
else
|
20
|
+
raise
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
options = [config[:host], config[:username], config[:password], config[:database], config[:port], config[:socket], 0]
|
25
|
+
FiberedMysql2Adapter.new(client, logger, options, config)
|
20
26
|
end
|
21
27
|
end
|
22
28
|
end
|
data/lib/fibered_mysql2.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'async'
|
3
4
|
require 'fibered_mysql2/version'
|
4
5
|
require_relative '../lib/active_record/connection_adapters/fibered_mysql2_adapter'
|
5
6
|
require 'fibered_mysql2/fibered_database_connection_pool'
|
6
7
|
require 'fibered_mysql2/fibered_mutex_with_waiter_priority'
|
7
8
|
require 'fibered_mysql2/fibered_mysql2_connection_factory'
|
8
|
-
require_relative 'fibered_mysql2/hash_config_override'
|
9
9
|
|
10
10
|
module FiberedMysql2
|
11
11
|
class Error < StandardError; end
|
metadata
CHANGED
@@ -1,49 +1,49 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fibered_mysql2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.colin.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Invoca Development
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: async
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rails
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '5.2'
|
34
34
|
- - "<"
|
35
35
|
- !ruby/object:Gem::Version
|
36
|
-
version: '7
|
36
|
+
version: '7'
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
40
40
|
requirements:
|
41
41
|
- - ">="
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: '
|
43
|
+
version: '5.2'
|
44
44
|
- - "<"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '7
|
46
|
+
version: '7'
|
47
47
|
description:
|
48
48
|
email:
|
49
49
|
- development@invoca.com
|
@@ -51,6 +51,7 @@ executables: []
|
|
51
51
|
extensions: []
|
52
52
|
extra_rdoc_files: []
|
53
53
|
files:
|
54
|
+
- ".github/CODEOWNERS"
|
54
55
|
- ".github/workflows/build.yml"
|
55
56
|
- ".github/workflows/release.yml"
|
56
57
|
- ".gitignore"
|
@@ -65,15 +66,14 @@ files:
|
|
65
66
|
- bin/console
|
66
67
|
- bin/setup
|
67
68
|
- fibered_mysql2.gemspec
|
68
|
-
- gemfiles
|
69
|
-
- gemfiles/
|
70
|
-
- gemfiles/rails_7_1.gemfile
|
69
|
+
- gemfiles/rails_5.gemfile
|
70
|
+
- gemfiles/rails_6.gemfile
|
71
71
|
- lib/active_record/connection_adapters/fibered_mysql2_adapter.rb
|
72
72
|
- lib/fibered_mysql2.rb
|
73
|
+
- lib/fibered_mysql2/async_task.rb
|
73
74
|
- lib/fibered_mysql2/fibered_database_connection_pool.rb
|
74
75
|
- lib/fibered_mysql2/fibered_mutex_with_waiter_priority.rb
|
75
76
|
- lib/fibered_mysql2/fibered_mysql2_connection_factory.rb
|
76
|
-
- lib/fibered_mysql2/hash_config_override.rb
|
77
77
|
- lib/fibered_mysql2/version.rb
|
78
78
|
homepage: https://github.com/Invoca/fibered_mysql2
|
79
79
|
licenses: []
|
@@ -91,11 +91,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
91
91
|
version: '0'
|
92
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - ">"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
96
|
+
version: 1.3.1
|
97
97
|
requirements: []
|
98
|
-
rubygems_version: 3.
|
98
|
+
rubygems_version: 3.4.6
|
99
99
|
signing_key:
|
100
100
|
specification_version: 4
|
101
101
|
summary: An adapter for fibered mysql2
|
data/gemfiles/.bundle/config
DELETED