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.
@@ -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
- require 'em-synchrony/mysql2'
6
+ require_relative '../../fibered_mysql2/async_task'
9
7
 
10
8
  module FiberedMysql2
11
- module FiberedMysql2Adapter_7_0
9
+ module FiberedMysql2Adapter_6
12
10
  def lease
13
- if in_use?
14
- msg = "Cannot lease connection, ".dup
15
- if owner_fiber == Fiber.current
16
- msg << "it is already leased by the current fiber."
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 fiber: #{owner_fiber}. " \
19
- "Current fiber: #{Fiber.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 = Fiber.current
22
+ @owner = AsyncTask.current_or_none
25
23
  end
26
24
 
27
25
  def expire
28
- if in_use?
29
- # Because we are actively releasing connections from dead fibers, we only want
30
- # to enforce that we're expiring the current fibers connection, iff the owner
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 owner_fiber.alive? && owner_fiber != Fiber.current
33
- raise ::ActiveRecord::ActiveRecordError, "Cannot expire connection, " \
34
- "it is owned by a different fiber: #{owner_fiber}. " \
35
- "Current fiber: #{Fiber.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, it is not currently leased."
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 in_use?
47
- if owner_fiber != Fiber.current
48
- pool.send :remove_connection_from_thread_cache, self, owner_fiber
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 = Fiber.current
48
+ @owner = current_task
51
49
  end
52
50
  else
53
- raise ::ActiveRecord::ActiveRecordError, "Cannot steal connection, it is not currently leased."
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 owner_fiber
152
- @owner.nil? || @owner.is_a?(Fiber) or
153
- raise "@owner must be a Fiber! Found #{@owner.inspect}"
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
- if ::ActiveRecord.gem_version < "7.1"
160
- include FiberedMysql2Adapter_7_0
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
- class << self
164
- # Copied from Mysql2Adapter, except with the EM Mysql2 client
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
- class FiberedConditionVariable
16
- EXCEPTION_NEVER = {Exception => :never}.freeze
17
- EXCEPTION_IMMEDIATE = {Exception => :immediate}.freeze
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
- # Enters exclusive section.
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
- # Leaves exclusive section.
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
- yield
141
- ensure
142
- begin
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
- module FiberedDatabaseConnectionPool
187
- module Adapter_7_0
188
- def release_connection(owner_thread = Fiber.current)
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(pool_config)
215
- if pool_config.db_config.reaping_frequency
216
- pool_config.db_config.reaping_frequency > 0 and raise "reaping_frequency is not supported (the ActiveRecord Reaper is thread-based)"
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(pool_config)
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
- # Invoca patch that reaps orphaned connections on checkout. This lets us immediately use a connection left open by dead fibers
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 = FiberedMysql2Adapter.new_client(config)
19
- FiberedMysql2Adapter.new(client, logger, nil, config)
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FiberedMysql2
4
- VERSION = "0.4.0.pre.tstarck.3"
4
+ VERSION = "1.0.0.colin.1"
5
5
  end
@@ -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.0.pre.tstarck.3
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: 2025-08-06 00:00:00.000000000 Z
11
+ date: 2023-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: em-synchrony
14
+ name: async
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
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: '1.0'
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: '7.0'
33
+ version: '5.2'
34
34
  - - "<"
35
35
  - !ruby/object:Gem::Version
36
- version: '7.2'
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: '7.0'
43
+ version: '5.2'
44
44
  - - "<"
45
45
  - !ruby/object:Gem::Version
46
- version: '7.2'
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/.bundle/config
69
- - gemfiles/rails_7_0.gemfile
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: '0'
96
+ version: 1.3.1
97
97
  requirements: []
98
- rubygems_version: 3.5.22
98
+ rubygems_version: 3.4.6
99
99
  signing_key:
100
100
  specification_version: 4
101
101
  summary: An adapter for fibered mysql2
@@ -1,2 +0,0 @@
1
- ---
2
- BUNDLE_RETRY: "1"