fibered_mysql2 0.3.1 → 1.0.0.colin.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8cf06a5be94da99bc7d1e0de4b5268ff04a72fd7671e6c4d522186d1ea67dd0b
4
- data.tar.gz: 931890052763e7fcf2f1ffb7925848004dc54c4c583f89d24c258cbe1537a67a
3
+ metadata.gz: 75d1eaf3701caa8823cdfbec61e7d9734d1e5f463e7936010c5636715591c2c9
4
+ data.tar.gz: 715db9f2e07df69a6cf51a2389404f030cd9c257524544cb77c16f53de36b944
5
5
  SHA512:
6
- metadata.gz: 42cab06e4e9bccd07df1436db08c8fb0e8038027690bc03cc58a34eab99ecfd6cccedbdde27f63f9607ce391bea3de8d941cc720775deb7c0c7d65134f405bae
7
- data.tar.gz: be4a1bd1357e9d51e2e76e48f93ede62f8b7c3cb9cf515a042cf9d10f4d2afe63721349f5afe65a67d2cc9246741aab39a80c7aa903bafde77d95d75c026cd05
6
+ metadata.gz: 9a21b639b0b0ab6afcb558978a7e1060510e7fc7ca5e9a833b27d2b8c9eb49d023ac5beb5e0c500c3a3ff711d7f6ee0e49ae61f4e72f941c7a07420f60b9c866
7
+ data.tar.gz: 99adce5422229bdea37a08ed76a4dad71c6f4108ce3588d42dadc3b6c6fbb2895f65532842739dbe83cd7d6c748ea4b0cf7d57d05ca8fc26cbd0c6e65ab17e41
@@ -0,0 +1 @@
1
+ * @Invoca/octothorpe
@@ -8,11 +8,11 @@ jobs:
8
8
  strategy:
9
9
  fail-fast: false
10
10
  matrix:
11
- ruby: [3.1, 3.2, 3.3]
11
+ ruby: [2.5, 2.6, 2.7, '3.0', 3.1]
12
12
  gemfile:
13
13
  - Gemfile
14
- - gemfiles/rails_6_1.gemfile
15
- - gemfiles/rails_7_0.gemfile
14
+ - gemfiles/rails_5.gemfile
15
+ - gemfiles/rails_6.gemfile
16
16
  env:
17
17
  BUNDLE_GEMFILE: ${{ matrix.gemfile }}
18
18
  steps:
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.1.6
1
+ 3.2.1
data/Appraisals CHANGED
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "appraisal/matrix"
3
+ appraise 'rails-5' do
4
+ gem 'rails', '~> 5.2'
5
+ end
4
6
 
5
- appraisal_matrix(rails: [">= 6.1", "< 7.1"])
7
+ appraise 'rails-6' do
8
+ gem 'rails', '~> 6.0.0'
9
+ end
data/CHANGELOG.md CHANGED
@@ -4,25 +4,6 @@ Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
4
4
 
5
5
  Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## [0.3.1] - 2024-10-30
8
- ### Fixed
9
- - Fixed bug in FiberedMysqlAdapter.new_client that was causing `uninitialized constant` errors.
10
-
11
- ## [0.3.0] - 2024-10-23
12
- ### Added
13
- - Support for Rails 7.0.
14
-
15
- ### Removed
16
- - Removed support for Rails 6.0 and Rails 5.
17
-
18
- ### Changed
19
- - Clean up FiberedMysql2ConnectionFactory#fibered_mysql2_connection to better match Mysql2Adapter behavior.
20
- - Change FiberedMysql2::FiberedDatabaseConnectionPool#initialize to match ActiveRecord::ConnectionAdapters::ConnectionPool#initialize arguments.
21
-
22
- ## [0.2.1] - 2024-08-19
23
- ### Fixed
24
- - Fixed bugs in Rails 6.1
25
-
26
7
  ## [0.2.0] - 2023-01-12
27
8
  ### Added
28
9
  - Added support for Rails 6+ by adding knowledge of lazy transactions to the adapter.
data/Gemfile CHANGED
@@ -6,11 +6,11 @@ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
6
6
  gemspec
7
7
 
8
8
  gem 'appraisal'
9
- gem 'appraisal-matrix'
10
9
  gem 'coveralls', require: false
11
10
  gem 'mysql2', '~> 0.5'
12
- gem 'nokogiri'
13
- gem 'pry'
14
- gem 'pry-byebug'
15
- gem 'rake'
16
- gem 'rspec'
11
+ gem 'nokogiri', '< 1.13'
12
+ gem 'pry', '~> 0.13'
13
+ gem 'pry-byebug', '~> 3.9'
14
+ gem 'rails', '< 6.1'
15
+ gem 'rake', '~> 13.0'
16
+ gem 'rspec', '~> 3.0'
data/Gemfile.lock CHANGED
@@ -1,89 +1,82 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fibered_mysql2 (0.3.1)
5
- em-synchrony (~> 1.0)
6
- rails (>= 6.1, < 7.1)
4
+ fibered_mysql2 (1.0.0.colin.1)
5
+ async
6
+ rails (>= 5.2, < 7)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- actioncable (7.0.8.6)
12
- actionpack (= 7.0.8.6)
13
- activesupport (= 7.0.8.6)
11
+ actioncable (6.0.3.4)
12
+ actionpack (= 6.0.3.4)
14
13
  nio4r (~> 2.0)
15
14
  websocket-driver (>= 0.6.1)
16
- actionmailbox (7.0.8.6)
17
- actionpack (= 7.0.8.6)
18
- activejob (= 7.0.8.6)
19
- activerecord (= 7.0.8.6)
20
- activestorage (= 7.0.8.6)
21
- activesupport (= 7.0.8.6)
15
+ actionmailbox (6.0.3.4)
16
+ actionpack (= 6.0.3.4)
17
+ activejob (= 6.0.3.4)
18
+ activerecord (= 6.0.3.4)
19
+ activestorage (= 6.0.3.4)
20
+ activesupport (= 6.0.3.4)
22
21
  mail (>= 2.7.1)
23
- net-imap
24
- net-pop
25
- net-smtp
26
- actionmailer (7.0.8.6)
27
- actionpack (= 7.0.8.6)
28
- actionview (= 7.0.8.6)
29
- activejob (= 7.0.8.6)
30
- activesupport (= 7.0.8.6)
22
+ actionmailer (6.0.3.4)
23
+ actionpack (= 6.0.3.4)
24
+ actionview (= 6.0.3.4)
25
+ activejob (= 6.0.3.4)
31
26
  mail (~> 2.5, >= 2.5.4)
32
- net-imap
33
- net-pop
34
- net-smtp
35
27
  rails-dom-testing (~> 2.0)
36
- actionpack (7.0.8.6)
37
- actionview (= 7.0.8.6)
38
- activesupport (= 7.0.8.6)
39
- rack (~> 2.0, >= 2.2.4)
28
+ actionpack (6.0.3.4)
29
+ actionview (= 6.0.3.4)
30
+ activesupport (= 6.0.3.4)
31
+ rack (~> 2.0, >= 2.0.8)
40
32
  rack-test (>= 0.6.3)
41
33
  rails-dom-testing (~> 2.0)
42
34
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
43
- actiontext (7.0.8.6)
44
- actionpack (= 7.0.8.6)
45
- activerecord (= 7.0.8.6)
46
- activestorage (= 7.0.8.6)
47
- activesupport (= 7.0.8.6)
48
- globalid (>= 0.6.0)
35
+ actiontext (6.0.3.4)
36
+ actionpack (= 6.0.3.4)
37
+ activerecord (= 6.0.3.4)
38
+ activestorage (= 6.0.3.4)
39
+ activesupport (= 6.0.3.4)
49
40
  nokogiri (>= 1.8.5)
50
- actionview (7.0.8.6)
51
- activesupport (= 7.0.8.6)
41
+ actionview (6.0.3.4)
42
+ activesupport (= 6.0.3.4)
52
43
  builder (~> 3.1)
53
44
  erubi (~> 1.4)
54
45
  rails-dom-testing (~> 2.0)
55
46
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
56
- activejob (7.0.8.6)
57
- activesupport (= 7.0.8.6)
47
+ activejob (6.0.3.4)
48
+ activesupport (= 6.0.3.4)
58
49
  globalid (>= 0.3.6)
59
- activemodel (7.0.8.6)
60
- activesupport (= 7.0.8.6)
61
- activerecord (7.0.8.6)
62
- activemodel (= 7.0.8.6)
63
- activesupport (= 7.0.8.6)
64
- activestorage (7.0.8.6)
65
- actionpack (= 7.0.8.6)
66
- activejob (= 7.0.8.6)
67
- activerecord (= 7.0.8.6)
68
- activesupport (= 7.0.8.6)
69
- marcel (~> 1.0)
70
- mini_mime (>= 1.1.0)
71
- activesupport (7.0.8.6)
50
+ activemodel (6.0.3.4)
51
+ activesupport (= 6.0.3.4)
52
+ activerecord (6.0.3.4)
53
+ activemodel (= 6.0.3.4)
54
+ activesupport (= 6.0.3.4)
55
+ activestorage (6.0.3.4)
56
+ actionpack (= 6.0.3.4)
57
+ activejob (= 6.0.3.4)
58
+ activerecord (= 6.0.3.4)
59
+ marcel (~> 0.3.1)
60
+ activesupport (6.0.3.4)
72
61
  concurrent-ruby (~> 1.0, >= 1.0.2)
73
- i18n (>= 1.6, < 2)
74
- minitest (>= 5.1)
75
- tzinfo (~> 2.0)
76
- appraisal (2.5.0)
62
+ i18n (>= 0.7, < 2)
63
+ minitest (~> 5.1)
64
+ tzinfo (~> 1.1)
65
+ zeitwerk (~> 2.2, >= 2.2.2)
66
+ appraisal (2.4.0)
77
67
  bundler
78
68
  rake
79
69
  thor (>= 0.14.0)
80
- appraisal-matrix (0.3.0)
81
- appraisal (~> 2.2)
82
- bigdecimal (3.1.8)
83
- builder (3.3.0)
70
+ async (2.5.1)
71
+ console (~> 1.10)
72
+ io-event (~> 1.1)
73
+ timers (~> 4.1)
74
+ builder (3.2.4)
84
75
  byebug (11.1.3)
85
76
  coderay (1.1.3)
86
- concurrent-ruby (1.3.4)
77
+ concurrent-ruby (1.1.8)
78
+ console (1.16.2)
79
+ fiber-local
87
80
  coveralls (0.8.23)
88
81
  json (>= 1.8, < 3)
89
82
  simplecov (~> 0.16.1)
@@ -91,131 +84,126 @@ GEM
91
84
  thor (>= 0.19.4, < 2.0)
92
85
  tins (~> 1.6)
93
86
  crass (1.0.6)
94
- date (3.3.4)
95
- diff-lcs (1.5.1)
96
- docile (1.4.1)
97
- em-synchrony (1.0.6)
98
- eventmachine (>= 1.0.0.beta.1)
99
- erubi (1.13.0)
100
- eventmachine (1.2.7)
101
- globalid (1.2.1)
102
- activesupport (>= 6.1)
103
- i18n (1.14.6)
87
+ diff-lcs (1.4.4)
88
+ docile (1.3.2)
89
+ erubi (1.10.0)
90
+ fiber-local (1.0.0)
91
+ globalid (0.4.2)
92
+ activesupport (>= 4.2.0)
93
+ i18n (1.8.7)
104
94
  concurrent-ruby (~> 1.0)
105
- json (2.7.2)
106
- loofah (2.23.1)
95
+ io-event (1.2.2)
96
+ json (2.3.1)
97
+ loofah (2.8.0)
107
98
  crass (~> 1.0.2)
108
- nokogiri (>= 1.12.0)
109
- mail (2.8.1)
99
+ nokogiri (>= 1.5.9)
100
+ mail (2.7.1)
110
101
  mini_mime (>= 0.1.1)
111
- net-imap
112
- net-pop
113
- net-smtp
114
- marcel (1.0.4)
115
- method_source (1.1.0)
116
- mini_mime (1.1.5)
117
- mini_portile2 (2.8.7)
118
- minitest (5.25.1)
119
- mysql2 (0.5.6)
120
- net-imap (0.5.0)
121
- date
122
- net-protocol
123
- net-pop (0.1.2)
124
- net-protocol
125
- net-protocol (0.2.2)
126
- timeout
127
- net-smtp (0.5.0)
128
- net-protocol
129
- nio4r (2.7.4)
130
- nokogiri (1.16.7)
131
- mini_portile2 (~> 2.8.2)
102
+ marcel (0.3.3)
103
+ mimemagic (~> 0.3.2)
104
+ method_source (1.0.0)
105
+ mimemagic (0.3.10)
106
+ nokogiri (~> 1)
107
+ rake
108
+ mini_mime (1.0.2)
109
+ mini_portile2 (2.6.1)
110
+ minitest (5.14.3)
111
+ mysql2 (0.5.5)
112
+ nio4r (2.5.4)
113
+ nokogiri (1.12.5)
114
+ mini_portile2 (~> 2.6.1)
132
115
  racc (~> 1.4)
133
- pry (0.14.2)
116
+ pry (0.13.1)
134
117
  coderay (~> 1.1)
135
118
  method_source (~> 1.0)
136
- pry-byebug (3.10.1)
119
+ pry-byebug (3.9.0)
137
120
  byebug (~> 11.0)
138
- pry (>= 0.13, < 0.15)
139
- racc (1.8.1)
140
- rack (2.2.10)
141
- rack-test (2.1.0)
142
- rack (>= 1.3)
143
- rails (7.0.8.6)
144
- actioncable (= 7.0.8.6)
145
- actionmailbox (= 7.0.8.6)
146
- actionmailer (= 7.0.8.6)
147
- actionpack (= 7.0.8.6)
148
- actiontext (= 7.0.8.6)
149
- actionview (= 7.0.8.6)
150
- activejob (= 7.0.8.6)
151
- activemodel (= 7.0.8.6)
152
- activerecord (= 7.0.8.6)
153
- activestorage (= 7.0.8.6)
154
- activesupport (= 7.0.8.6)
155
- bundler (>= 1.15.0)
156
- railties (= 7.0.8.6)
157
- rails-dom-testing (2.2.0)
158
- activesupport (>= 5.0.0)
159
- minitest
121
+ pry (~> 0.13.0)
122
+ racc (1.6.0)
123
+ rack (2.2.3)
124
+ rack-test (1.1.0)
125
+ rack (>= 1.0, < 3)
126
+ rails (6.0.3.4)
127
+ actioncable (= 6.0.3.4)
128
+ actionmailbox (= 6.0.3.4)
129
+ actionmailer (= 6.0.3.4)
130
+ actionpack (= 6.0.3.4)
131
+ actiontext (= 6.0.3.4)
132
+ actionview (= 6.0.3.4)
133
+ activejob (= 6.0.3.4)
134
+ activemodel (= 6.0.3.4)
135
+ activerecord (= 6.0.3.4)
136
+ activestorage (= 6.0.3.4)
137
+ activesupport (= 6.0.3.4)
138
+ bundler (>= 1.3.0)
139
+ railties (= 6.0.3.4)
140
+ sprockets-rails (>= 2.0.0)
141
+ rails-dom-testing (2.0.3)
142
+ activesupport (>= 4.2.0)
160
143
  nokogiri (>= 1.6)
161
- rails-html-sanitizer (1.6.0)
162
- loofah (~> 2.21)
163
- nokogiri (~> 1.14)
164
- railties (7.0.8.6)
165
- actionpack (= 7.0.8.6)
166
- activesupport (= 7.0.8.6)
144
+ rails-html-sanitizer (1.3.0)
145
+ loofah (~> 2.3)
146
+ railties (6.0.3.4)
147
+ actionpack (= 6.0.3.4)
148
+ activesupport (= 6.0.3.4)
167
149
  method_source
168
- rake (>= 12.2)
169
- thor (~> 1.0)
170
- zeitwerk (~> 2.5)
171
- rake (13.2.1)
172
- rspec (3.13.0)
173
- rspec-core (~> 3.13.0)
174
- rspec-expectations (~> 3.13.0)
175
- rspec-mocks (~> 3.13.0)
176
- rspec-core (3.13.0)
177
- rspec-support (~> 3.13.0)
178
- rspec-expectations (3.13.1)
150
+ rake (>= 0.8.7)
151
+ thor (>= 0.20.3, < 2.0)
152
+ rake (13.0.6)
153
+ rspec (3.9.0)
154
+ rspec-core (~> 3.9.0)
155
+ rspec-expectations (~> 3.9.0)
156
+ rspec-mocks (~> 3.9.0)
157
+ rspec-core (3.9.3)
158
+ rspec-support (~> 3.9.3)
159
+ rspec-expectations (3.9.2)
179
160
  diff-lcs (>= 1.2.0, < 2.0)
180
- rspec-support (~> 3.13.0)
181
- rspec-mocks (3.13.1)
161
+ rspec-support (~> 3.9.0)
162
+ rspec-mocks (3.9.1)
182
163
  diff-lcs (>= 1.2.0, < 2.0)
183
- rspec-support (~> 3.13.0)
184
- rspec-support (3.13.1)
164
+ rspec-support (~> 3.9.0)
165
+ rspec-support (3.9.3)
185
166
  simplecov (0.16.1)
186
167
  docile (~> 1.1)
187
168
  json (>= 1.8, < 3)
188
169
  simplecov-html (~> 0.10.0)
189
170
  simplecov-html (0.10.2)
171
+ sprockets (4.0.2)
172
+ concurrent-ruby (~> 1.0)
173
+ rack (> 1, < 3)
174
+ sprockets-rails (3.2.2)
175
+ actionpack (>= 4.0)
176
+ activesupport (>= 4.0)
177
+ sprockets (>= 3.0.0)
190
178
  sync (0.5.0)
191
- term-ansicolor (1.11.2)
179
+ term-ansicolor (1.7.1)
192
180
  tins (~> 1.0)
193
- thor (1.3.2)
194
- timeout (0.4.1)
195
- tins (1.33.0)
196
- bigdecimal
181
+ thor (1.0.1)
182
+ thread_safe (0.3.6)
183
+ timers (4.3.5)
184
+ tins (1.25.0)
197
185
  sync
198
- tzinfo (2.0.6)
199
- concurrent-ruby (~> 1.0)
200
- websocket-driver (0.7.6)
186
+ tzinfo (1.2.9)
187
+ thread_safe (~> 0.1)
188
+ websocket-driver (0.7.3)
201
189
  websocket-extensions (>= 0.1.0)
202
190
  websocket-extensions (0.1.5)
203
- zeitwerk (2.6.18)
191
+ zeitwerk (2.4.1)
204
192
 
205
193
  PLATFORMS
206
194
  ruby
207
195
 
208
196
  DEPENDENCIES
209
197
  appraisal
210
- appraisal-matrix
211
198
  coveralls
212
199
  fibered_mysql2!
213
200
  mysql2 (~> 0.5)
214
- nokogiri
215
- pry
216
- pry-byebug
217
- rake
218
- rspec
201
+ nokogiri (< 1.13)
202
+ pry (~> 0.13)
203
+ pry-byebug (~> 3.9)
204
+ rails (< 6.1)
205
+ rake (~> 13.0)
206
+ rspec (~> 3.0)
219
207
 
220
208
  BUNDLED WITH
221
209
  2.2.29
@@ -29,6 +29,6 @@ Gem::Specification.new do |spec|
29
29
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
30
  spec.require_paths = ["lib"]
31
31
 
32
- spec.add_dependency 'em-synchrony', '~> 1.0'
33
- spec.add_dependency 'rails', '>= 6.1', '< 7.1'
32
+ spec.add_dependency 'async'
33
+ spec.add_dependency 'rails', '>= 5.2', '< 7'
34
34
  end
@@ -3,14 +3,13 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal"
6
- gem "appraisal-matrix"
7
6
  gem "coveralls", require: false
8
7
  gem "mysql2", "~> 0.5"
9
- gem "nokogiri"
10
- gem "pry"
11
- gem "pry-byebug"
12
- gem "rake"
13
- gem "rspec"
14
- gem "rails", "~> 6.1.0"
8
+ gem "nokogiri", "< 1.13"
9
+ gem "pry", "~> 0.13"
10
+ gem "pry-byebug", "~> 3.9"
11
+ gem "rails", "~> 5.2"
12
+ gem "rake", "~> 13.0"
13
+ gem "rspec", "~> 3.0"
15
14
 
16
15
  gemspec path: "../"
@@ -3,14 +3,13 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal"
6
- gem "appraisal-matrix"
7
6
  gem "coveralls", require: false
8
7
  gem "mysql2", "~> 0.5"
9
- gem "nokogiri"
10
- gem "pry"
11
- gem "pry-byebug"
12
- gem "rake"
13
- gem "rspec"
14
- gem "rails", "~> 7.0.0"
8
+ gem "nokogiri", "< 1.13"
9
+ gem "pry", "~> 0.13"
10
+ gem "pry-byebug", "~> 3.9"
11
+ gem "rails", "~> 6.0.0"
12
+ gem "rake", "~> 13.0"
13
+ gem "rspec", "~> 3.0"
15
14
 
16
15
  gemspec path: "../"
@@ -1,81 +1,72 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'em-synchrony'
4
3
  require 'active_model'
5
4
  require 'active_record/errors'
6
5
  require 'active_record/connection_adapters/mysql2_adapter'
7
- require 'active_record/connection_adapters/em_mysql2_adapter'
6
+ require_relative '../../fibered_mysql2/async_task'
8
7
 
9
8
  module FiberedMysql2
10
- module FiberedMysql2Adapter_5_2
9
+ module FiberedMysql2Adapter_6
11
10
  def lease
12
- if in_use?
13
- msg = "Cannot lease connection, ".dup
14
- if owner_fiber == Fiber.current
15
- 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."
16
15
  else
17
- msg << "it is already in use by a different fiber: #{owner_fiber}. " \
18
- "Current fiber: #{Fiber.current}."
16
+ msg << "it is already in use by a different Async::Task: #{ot}. " \
17
+ "Current Async::Task: #{current_task}."
19
18
  end
20
19
  raise ::ActiveRecord::ActiveRecordError, msg
21
20
  end
22
21
 
23
- @owner = Fiber.current
22
+ @owner = AsyncTask.current_or_none
24
23
  end
25
24
 
26
25
  def expire
27
- if in_use?
28
- # Because we are actively releasing connections from dead fibers, we only want
29
- # 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
30
29
  # of the connection is still alive.
31
- if owner_fiber.alive? && owner_fiber != Fiber.current
32
- raise ::ActiveRecord::ActiveRecordError, "Cannot expire connection, " \
33
- "it is owned by a different fiber: #{owner_fiber}. " \
34
- "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}."
35
34
  end
36
35
 
37
36
  @idle_since = ::Concurrent.monotonic_time
38
37
  @owner = nil
39
38
  else
40
- raise ::ActiveRecord::ActiveRecordError, "Cannot expire connection, it is not currently leased."
39
+ raise ::ActiveRecord::ActiveRecordError, "Cannot expire connection; it is not currently leased."
41
40
  end
42
41
  end
43
42
 
44
43
  def steal!
45
- if in_use?
46
- if owner_fiber != Fiber.current
47
- 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
48
47
 
49
- @owner = Fiber.current
48
+ @owner = current_task
50
49
  end
51
50
  else
52
- raise ::ActiveRecord::ActiveRecordError, "Cannot steal connection, it is not currently leased."
51
+ raise ::ActiveRecord::ActiveRecordError, "Cannot steal connection; it is not currently leased."
53
52
  end
54
53
  end
55
54
 
56
55
  private
57
56
 
58
- def owner_fiber
59
- @owner.nil? || @owner.is_a?(Fiber) or
60
- 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}"
61
60
  @owner
62
61
  end
63
62
  end
64
63
 
65
- class FiberedMysql2Adapter < ::ActiveRecord::ConnectionAdapters::EMMysql2Adapter
66
- include FiberedMysql2Adapter_5_2
67
-
68
- class << self
69
- # Copied from Mysql2Adapter, except with the EM Mysql2 client
70
- def new_client(config)
71
- Mysql2::EM::Client.new(config)
72
- rescue Mysql2::Error => error
73
- if error.error_number == 1049
74
- raise ActiveRecord::NoDatabaseError.new, error.message
75
- else
76
- raise ActiveRecord::ConnectionNotEstablished, error.message
77
- end
78
- end
64
+ class FiberedMysql2Adapter < ::ActiveRecord::ConnectionAdapters::Mysql2Adapter
65
+ case ::Rails::VERSION::MAJOR
66
+ when 6
67
+ include FiberedMysql2Adapter_6
68
+ else
69
+ raise ArgumentError, "unexpected Rails version #{Rails::VERSION::MAJOR}"
79
70
  end
80
71
 
81
72
  def initialize(*args)
@@ -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,225 +1,50 @@
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
-
186
- module FiberedDatabaseConnectionPool
187
- include FiberedMonitorMixin
188
-
189
- module Adapter_5_2
190
- def cached_connections
191
- @thread_cached_conns
192
- end
193
-
194
- def current_connection_id
195
- connection_cache_key(current_thread)
196
- end
197
32
 
198
- def checkout(checkout_timeout = @checkout_timeout)
199
- begin
200
- reap_connections
201
- rescue => ex
202
- ActiveRecord::Base.logger.error("Exception occurred while executing reap_connections: #{ex}")
203
- end
204
- super
205
- end
206
-
207
- def release_connection(owner_thread = Fiber.current)
208
- if (conn = @thread_cached_conns.delete(connection_cache_key(owner_thread)))
209
- checkin(conn)
210
- 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)
211
36
  end
212
37
  end
213
- include Adapter_5_2
214
38
 
215
- def initialize(pool_config)
216
- if pool_config.db_config.reaping_frequency
217
- pool_config.db_config.reaping_frequency > 0 and raise "reaping_frequency is not supported (the ActiveRecord Reaper is thread-based)"
218
- 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
219
42
 
220
- super(pool_config)
43
+ super(connection_spec, *args, **keyword_args)
221
44
 
222
45
  @reaper = nil # no need to keep a reference to this since it does nothing in this sub-class
46
+
47
+ # note that @reserved_connections is a ThreadSafe::Cache which is overkill in a fibered world, but harmless
223
48
  end
224
49
 
225
50
  def connection
@@ -256,7 +81,7 @@ module FiberedMysql2
256
81
  end
257
82
 
258
83
  def current_thread
259
- Fiber.current
84
+ AsyncTask.current_or_none
260
85
  end
261
86
  end
262
87
  end
@@ -2,116 +2,27 @@
2
2
 
3
3
  require_relative '../active_record/connection_adapters/fibered_mysql2_adapter'
4
4
 
5
- module EM::Synchrony
6
- module ActiveRecord
7
- _ = Adapter_4_2
8
- module Adapter_4_2
9
- def configure_connection
10
- super # undo EM::Synchrony's override here
11
- end
12
-
13
- def transaction(*args)
14
- super # and here
15
- end
16
-
17
- _ = TransactionManager
18
- class TransactionManager < _
19
- # Overriding the em-synchrony override to bring it up to rails 6 requirements.
20
- # Changes from the original Rails 6 source are:
21
- # 1. the usage of _current_stack created by em-synchrony instead of the Rails provided @stack instance variable
22
- # 2. the usage of Fiber.current.object_id as a part of the savepoint transaction name
23
- #
24
- # Original EM Synchrony Source:
25
- # https://github.com/igrigorik/em-synchrony/blob/master/lib/em-synchrony/activerecord_4_2.rb#L35-L44
26
- #
27
- # Original Rails Source:
28
- # https://github.com/rails/rails/blob/6-0-stable/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb#L205-L224
29
- def begin_transaction(isolation: nil, joinable: true, _lazy: true)
30
- @connection.lock.synchronize do
31
- run_commit_callbacks = !current_transaction.joinable?
32
- transaction =
33
- if _current_stack.empty?
34
- ::ActiveRecord::ConnectionAdapters::RealTransaction.new(@connection, isolation:, joinable:, run_commit_callbacks: run_commit_callbacks)
35
- else
36
- ::ActiveRecord::ConnectionAdapters::SavepointTransaction.new(@connection, "active_record_#{Fiber.current.object_id}_#{open_transactions}", _current_stack.last, isolation:, joinable:, run_commit_callbacks: run_commit_callbacks)
37
- end
38
-
39
- if @connection.supports_lazy_transactions? && lazy_transactions_enabled? && _lazy
40
- @has_unmaterialized_transactions = true
41
- else
42
- transaction.materialize!
43
- end
44
- _current_stack.push(transaction)
45
- transaction
46
- end
47
- end
48
-
49
- # Overriding the ActiveRecord::TransactionManager#materialize_transactions method to use
50
- # fiber safe the _current_stack instead of the @stack instance variable. when marterializing
51
- # transactions.
52
- def materialize_transactions
53
- return if @materializing_transactions
54
- return unless @has_unmaterialized_transactions
55
-
56
- @connection.lock.synchronize do
57
- begin
58
- @materializing_transactions = true
59
- _current_stack.each { |t| t.materialize! unless t.materialized? }
60
- ensure
61
- @materializing_transactions = false
62
- end
63
- @has_unmaterialized_transactions = false
64
- end
65
- end
66
-
67
- # Overriding the ActiveRecord::TransactionManager#commit_transaction method to use
68
- # fiber safe the _current_stack instead of the @stack instance variable. when marterializing
69
- # transactions.
70
- def commit_transaction
71
- @connection.lock.synchronize do
72
- transaction = _current_stack.last
73
-
74
- begin
75
- transaction.before_commit_records
76
- ensure
77
- _current_stack.pop
78
- end
79
-
80
- transaction.commit
81
- transaction.commit_records
82
- end
83
- end
84
-
85
- # Overriding the ActiveRecord::TransactionManager#rollback_transaction method to use
86
- # fiber safe the _current_stack instead of the @stack instance variable. when marterializing
87
- # transactions.
88
- def rollback_transaction(transaction = nil)
89
- @connection.lock.synchronize do
90
- transaction ||= _current_stack.pop
91
- transaction.rollback
92
- transaction.rollback_records
93
- end
94
- end
95
- end
96
- end
97
- end
98
- end
99
-
100
5
  module FiberedMysql2
101
6
  module FiberedMysql2ConnectionFactory
102
7
  def fibered_mysql2_connection(raw_config)
103
8
  config = raw_config.symbolize_keys
104
- config[:flags] ||= 0
105
9
 
106
- if config[:flags].kind_of? Array
107
- config[:flags].push "FOUND_ROWS"
108
- else
109
- config[:flags] |= Mysql2::Client::FOUND_ROWS
110
- end
111
10
  config[:username] = 'root' if config[:username].nil?
11
+ config[:flags] = Mysql2::Client::FOUND_ROWS if Mysql2::Client.const_defined?(:FOUND_ROWS)
12
+
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
112
23
 
113
- client = FiberedMysql2Adapter.new_client(config)
114
- FiberedMysql2Adapter.new(client, logger, nil, config)
24
+ options = [config[:host], config[:username], config[:password], config[:database], config[:port], config[:socket], 0]
25
+ FiberedMysql2Adapter.new(client, logger, options, config)
115
26
  end
116
27
  end
117
28
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FiberedMysql2
4
- VERSION = "0.3.1"
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.3.1
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: 2024-10-31 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: '6.1'
33
+ version: '5.2'
34
34
  - - "<"
35
35
  - !ruby/object:Gem::Version
36
- version: '7.1'
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: '6.1'
43
+ version: '5.2'
44
44
  - - "<"
45
45
  - !ruby/object:Gem::Version
46
- version: '7.1'
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_6_1.gemfile
70
- - gemfiles/rails_7_0.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.3.27
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"
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "active_record/database_configurations/hash_config"
4
-
5
- module FiberedMysql2
6
- module HashConfigOverride
7
- # Override the reaping_frequency method to return nil so that the connection pool does not reap connections when in fibered mode.
8
- def reaping_frequency
9
- nil
10
- end
11
- end
12
- end
13
-
14
- if ActiveRecord.gem_version >= "6.1"
15
- ActiveRecord::DatabaseConfigurations::HashConfig.prepend(FiberedMysql2::HashConfigOverride)
16
- end