fibered_mysql2 0.2.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: 9e44e8e3a3b531c9fe568f4d0fcbd19dea85b92e0fc391ca9e50c898b0119359
4
- data.tar.gz: e41214cb8676608ed5ec6a22dbabea0dfa6d02d41e5ec3a78be4ce0057e76817
3
+ metadata.gz: 75d1eaf3701caa8823cdfbec61e7d9734d1e5f463e7936010c5636715591c2c9
4
+ data.tar.gz: 715db9f2e07df69a6cf51a2389404f030cd9c257524544cb77c16f53de36b944
5
5
  SHA512:
6
- metadata.gz: 3d55a57ce410ccbbbe0c31c08e8dce4f3115ad175ac71cd9747d2072a9771c068c43bfbc05c374631e1f80484619a3adfcee98cfe00eb57fe6458204c538d285
7
- data.tar.gz: 3301cac13fa5c7c2140660e3282f50c06ad3d3bac53a1afe02be328eb5d9e7580e4441e413993fe060a8c1db49d3884c8beafd0295d0dbdc95b9e0113ba1b680
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_0.gemfile
15
- - gemfiles/rails_6_1.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.0")
7
+ appraise 'rails-6' do
8
+ gem 'rails', '~> 6.0.0'
9
+ end
data/CHANGELOG.md CHANGED
@@ -4,10 +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.2.1] - 2024-08-19
8
- ### Fixed
9
- - Fixed bugs in Rails 6.1.
10
-
11
7
  ## [0.2.0] - 2023-01-12
12
8
  ### Added
13
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,83 +1,82 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fibered_mysql2 (0.2.1)
5
- em-synchrony (~> 1.0)
4
+ fibered_mysql2 (1.0.0.colin.1)
5
+ async
6
6
  rails (>= 5.2, < 7)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- actioncable (6.1.7.8)
12
- actionpack (= 6.1.7.8)
13
- activesupport (= 6.1.7.8)
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 (6.1.7.8)
17
- actionpack (= 6.1.7.8)
18
- activejob (= 6.1.7.8)
19
- activerecord (= 6.1.7.8)
20
- activestorage (= 6.1.7.8)
21
- activesupport (= 6.1.7.8)
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
- actionmailer (6.1.7.8)
24
- actionpack (= 6.1.7.8)
25
- actionview (= 6.1.7.8)
26
- activejob (= 6.1.7.8)
27
- activesupport (= 6.1.7.8)
22
+ actionmailer (6.0.3.4)
23
+ actionpack (= 6.0.3.4)
24
+ actionview (= 6.0.3.4)
25
+ activejob (= 6.0.3.4)
28
26
  mail (~> 2.5, >= 2.5.4)
29
27
  rails-dom-testing (~> 2.0)
30
- actionpack (6.1.7.8)
31
- actionview (= 6.1.7.8)
32
- activesupport (= 6.1.7.8)
33
- rack (~> 2.0, >= 2.0.9)
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)
34
32
  rack-test (>= 0.6.3)
35
33
  rails-dom-testing (~> 2.0)
36
34
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
37
- actiontext (6.1.7.8)
38
- actionpack (= 6.1.7.8)
39
- activerecord (= 6.1.7.8)
40
- activestorage (= 6.1.7.8)
41
- activesupport (= 6.1.7.8)
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)
42
40
  nokogiri (>= 1.8.5)
43
- actionview (6.1.7.8)
44
- activesupport (= 6.1.7.8)
41
+ actionview (6.0.3.4)
42
+ activesupport (= 6.0.3.4)
45
43
  builder (~> 3.1)
46
44
  erubi (~> 1.4)
47
45
  rails-dom-testing (~> 2.0)
48
46
  rails-html-sanitizer (~> 1.1, >= 1.2.0)
49
- activejob (6.1.7.8)
50
- activesupport (= 6.1.7.8)
47
+ activejob (6.0.3.4)
48
+ activesupport (= 6.0.3.4)
51
49
  globalid (>= 0.3.6)
52
- activemodel (6.1.7.8)
53
- activesupport (= 6.1.7.8)
54
- activerecord (6.1.7.8)
55
- activemodel (= 6.1.7.8)
56
- activesupport (= 6.1.7.8)
57
- activestorage (6.1.7.8)
58
- actionpack (= 6.1.7.8)
59
- activejob (= 6.1.7.8)
60
- activerecord (= 6.1.7.8)
61
- activesupport (= 6.1.7.8)
62
- marcel (~> 1.0)
63
- mini_mime (>= 1.1.0)
64
- activesupport (6.1.7.8)
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)
65
61
  concurrent-ruby (~> 1.0, >= 1.0.2)
66
- i18n (>= 1.6, < 2)
67
- minitest (>= 5.1)
68
- tzinfo (~> 2.0)
69
- zeitwerk (~> 2.3)
70
- 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)
71
67
  bundler
72
68
  rake
73
69
  thor (>= 0.14.0)
74
- appraisal-matrix (0.3.0)
75
- appraisal (~> 2.2)
76
- bigdecimal (3.1.8)
77
- 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)
78
75
  byebug (11.1.3)
79
76
  coderay (1.1.3)
80
- concurrent-ruby (1.3.4)
77
+ concurrent-ruby (1.1.8)
78
+ console (1.16.2)
79
+ fiber-local
81
80
  coveralls (0.8.23)
82
81
  json (>= 1.8, < 3)
83
82
  simplecov (~> 0.16.1)
@@ -85,138 +84,126 @@ GEM
85
84
  thor (>= 0.19.4, < 2.0)
86
85
  tins (~> 1.6)
87
86
  crass (1.0.6)
88
- date (3.3.4)
89
- diff-lcs (1.5.1)
90
- docile (1.4.1)
91
- em-synchrony (1.0.6)
92
- eventmachine (>= 1.0.0.beta.1)
93
- erubi (1.13.0)
94
- eventmachine (1.2.7)
95
- globalid (1.2.1)
96
- activesupport (>= 6.1)
97
- i18n (1.14.5)
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)
98
94
  concurrent-ruby (~> 1.0)
99
- json (2.7.2)
100
- loofah (2.22.0)
95
+ io-event (1.2.2)
96
+ json (2.3.1)
97
+ loofah (2.8.0)
101
98
  crass (~> 1.0.2)
102
- nokogiri (>= 1.12.0)
103
- mail (2.8.1)
99
+ nokogiri (>= 1.5.9)
100
+ mail (2.7.1)
104
101
  mini_mime (>= 0.1.1)
105
- net-imap
106
- net-pop
107
- net-smtp
108
- marcel (1.0.4)
109
- method_source (1.1.0)
110
- mini_mime (1.1.5)
111
- mini_portile2 (2.8.7)
112
- minitest (5.25.1)
113
- mysql2 (0.5.6)
114
- net-imap (0.4.14)
115
- date
116
- net-protocol
117
- net-pop (0.1.2)
118
- net-protocol
119
- net-protocol (0.2.2)
120
- timeout
121
- net-smtp (0.5.0)
122
- net-protocol
123
- nio4r (2.7.3)
124
- nokogiri (1.16.7)
125
- 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)
126
115
  racc (~> 1.4)
127
- pry (0.14.2)
116
+ pry (0.13.1)
128
117
  coderay (~> 1.1)
129
118
  method_source (~> 1.0)
130
- pry-byebug (3.10.1)
119
+ pry-byebug (3.9.0)
131
120
  byebug (~> 11.0)
132
- pry (>= 0.13, < 0.15)
133
- racc (1.8.1)
134
- rack (2.2.9)
135
- rack-test (2.1.0)
136
- rack (>= 1.3)
137
- rails (6.1.7.8)
138
- actioncable (= 6.1.7.8)
139
- actionmailbox (= 6.1.7.8)
140
- actionmailer (= 6.1.7.8)
141
- actionpack (= 6.1.7.8)
142
- actiontext (= 6.1.7.8)
143
- actionview (= 6.1.7.8)
144
- activejob (= 6.1.7.8)
145
- activemodel (= 6.1.7.8)
146
- activerecord (= 6.1.7.8)
147
- activestorage (= 6.1.7.8)
148
- activesupport (= 6.1.7.8)
149
- bundler (>= 1.15.0)
150
- railties (= 6.1.7.8)
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)
151
140
  sprockets-rails (>= 2.0.0)
152
- rails-dom-testing (2.2.0)
153
- activesupport (>= 5.0.0)
154
- minitest
141
+ rails-dom-testing (2.0.3)
142
+ activesupport (>= 4.2.0)
155
143
  nokogiri (>= 1.6)
156
- rails-html-sanitizer (1.6.0)
157
- loofah (~> 2.21)
158
- nokogiri (~> 1.14)
159
- railties (6.1.7.8)
160
- actionpack (= 6.1.7.8)
161
- activesupport (= 6.1.7.8)
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)
162
149
  method_source
163
- rake (>= 12.2)
164
- thor (~> 1.0)
165
- rake (13.2.1)
166
- rspec (3.13.0)
167
- rspec-core (~> 3.13.0)
168
- rspec-expectations (~> 3.13.0)
169
- rspec-mocks (~> 3.13.0)
170
- rspec-core (3.13.0)
171
- rspec-support (~> 3.13.0)
172
- 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)
173
160
  diff-lcs (>= 1.2.0, < 2.0)
174
- rspec-support (~> 3.13.0)
175
- rspec-mocks (3.13.1)
161
+ rspec-support (~> 3.9.0)
162
+ rspec-mocks (3.9.1)
176
163
  diff-lcs (>= 1.2.0, < 2.0)
177
- rspec-support (~> 3.13.0)
178
- rspec-support (3.13.1)
164
+ rspec-support (~> 3.9.0)
165
+ rspec-support (3.9.3)
179
166
  simplecov (0.16.1)
180
167
  docile (~> 1.1)
181
168
  json (>= 1.8, < 3)
182
169
  simplecov-html (~> 0.10.0)
183
170
  simplecov-html (0.10.2)
184
- sprockets (4.2.1)
171
+ sprockets (4.0.2)
185
172
  concurrent-ruby (~> 1.0)
186
- rack (>= 2.2.4, < 4)
187
- sprockets-rails (3.5.2)
188
- actionpack (>= 6.1)
189
- activesupport (>= 6.1)
173
+ rack (> 1, < 3)
174
+ sprockets-rails (3.2.2)
175
+ actionpack (>= 4.0)
176
+ activesupport (>= 4.0)
190
177
  sprockets (>= 3.0.0)
191
178
  sync (0.5.0)
192
- term-ansicolor (1.11.2)
179
+ term-ansicolor (1.7.1)
193
180
  tins (~> 1.0)
194
- thor (1.3.1)
195
- timeout (0.4.1)
196
- tins (1.33.0)
197
- bigdecimal
181
+ thor (1.0.1)
182
+ thread_safe (0.3.6)
183
+ timers (4.3.5)
184
+ tins (1.25.0)
198
185
  sync
199
- tzinfo (2.0.6)
200
- concurrent-ruby (~> 1.0)
201
- websocket-driver (0.7.6)
186
+ tzinfo (1.2.9)
187
+ thread_safe (~> 0.1)
188
+ websocket-driver (0.7.3)
202
189
  websocket-extensions (>= 0.1.0)
203
190
  websocket-extensions (0.1.5)
204
- zeitwerk (2.6.17)
191
+ zeitwerk (2.4.1)
205
192
 
206
193
  PLATFORMS
207
194
  ruby
208
195
 
209
196
  DEPENDENCIES
210
197
  appraisal
211
- appraisal-matrix
212
198
  coveralls
213
199
  fibered_mysql2!
214
200
  mysql2 (~> 0.5)
215
- nokogiri
216
- pry
217
- pry-byebug
218
- rake
219
- 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)
220
207
 
221
208
  BUNDLED WITH
222
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'
32
+ spec.add_dependency 'async'
33
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"
8
+ gem "nokogiri", "< 1.13"
9
+ gem "pry", "~> 0.13"
10
+ gem "pry-byebug", "~> 3.9"
14
11
  gem "rails", "~> 6.0.0"
12
+ gem "rake", "~> 13.0"
13
+ gem "rspec", "~> 3.0"
15
14
 
16
15
  gemspec path: "../"
@@ -1,82 +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
- require 'active_record/connection_adapters/em_mysql2_adapter'
5
+ require 'active_record/connection_adapters/mysql2_adapter'
6
+ require_relative '../../fibered_mysql2/async_task'
7
7
 
8
8
  module FiberedMysql2
9
- module FiberedMysql2Adapter_4_2
9
+ module FiberedMysql2Adapter_6
10
10
  def lease
11
- synchronize do
12
- unless in_use?
13
- @owner = Fiber.current
14
- end
15
- end
16
- end
17
- end
18
-
19
- module FiberedMysql2Adapter_5_2
20
- def lease
21
- if in_use?
22
- msg = "Cannot lease connection, ".dup
23
- if owner_fiber == Fiber.current
24
- 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."
25
15
  else
26
- msg << "it is already in use by a different fiber: #{owner_fiber}. " \
27
- "Current fiber: #{Fiber.current}."
16
+ msg << "it is already in use by a different Async::Task: #{ot}. " \
17
+ "Current Async::Task: #{current_task}."
28
18
  end
29
19
  raise ::ActiveRecord::ActiveRecordError, msg
30
20
  end
31
21
 
32
- @owner = Fiber.current
22
+ @owner = AsyncTask.current_or_none
33
23
  end
34
24
 
35
25
  def expire
36
- if in_use?
37
- # Because we are actively releasing connections from dead fibers, we only want
38
- # 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
39
29
  # of the connection is still alive.
40
- if owner_fiber.alive? && owner_fiber != Fiber.current
41
- raise ::ActiveRecord::ActiveRecordError, "Cannot expire connection, " \
42
- "it is owned by a different fiber: #{owner_fiber}. " \
43
- "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}."
44
34
  end
45
35
 
46
36
  @idle_since = ::Concurrent.monotonic_time
47
37
  @owner = nil
48
38
  else
49
- raise ::ActiveRecord::ActiveRecordError, "Cannot expire connection, it is not currently leased."
39
+ raise ::ActiveRecord::ActiveRecordError, "Cannot expire connection; it is not currently leased."
50
40
  end
51
41
  end
52
42
 
53
43
  def steal!
54
- if in_use?
55
- if owner_fiber != Fiber.current
56
- 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
57
47
 
58
- @owner = Fiber.current
48
+ @owner = current_task
59
49
  end
60
50
  else
61
- raise ::ActiveRecord::ActiveRecordError, "Cannot steal connection, it is not currently leased."
51
+ raise ::ActiveRecord::ActiveRecordError, "Cannot steal connection; it is not currently leased."
62
52
  end
63
53
  end
64
54
 
65
55
  private
66
56
 
67
- def owner_fiber
68
- @owner.nil? || @owner.is_a?(Fiber) or
69
- 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}"
70
60
  @owner
71
61
  end
72
62
  end
73
63
 
74
- class FiberedMysql2Adapter < ::ActiveRecord::ConnectionAdapters::EMMysql2Adapter
64
+ class FiberedMysql2Adapter < ::ActiveRecord::ConnectionAdapters::Mysql2Adapter
75
65
  case ::Rails::VERSION::MAJOR
76
- when 4
77
- include FiberedMysql2Adapter_4_2
78
- when 5, 6
79
- include FiberedMysql2Adapter_5_2
66
+ when 6
67
+ include FiberedMysql2Adapter_6
68
+ else
69
+ raise ArgumentError, "unexpected Rails version #{Rails::VERSION::MAJOR}"
80
70
  end
81
71
 
82
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,249 +1,44 @@
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
147
- end
148
- 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_4_2
190
- def cached_connections
191
- @reserved_connections
192
- end
193
-
194
- def current_connection_id
195
- ActiveRecord::Base.connection_id ||= Fiber.current.object_id
196
- end
197
-
198
- def checkout
199
- begin
200
- reap_connections
201
- rescue => ex
202
- ActiveRecord::Base.logger.error("Exception occurred while executing reap_connections: #{ex}")
203
- end
204
- super
26
+ reap_connections
27
+ rescue => ex
28
+ ActiveRecord::Base.logger.error("Exception occurred while executing reap_connections: #{ex.class}: #{ex.message}")
205
29
  end
30
+ super
206
31
  end
207
32
 
208
- module Adapter_5_2
209
- def cached_connections
210
- @thread_cached_conns
211
- end
212
-
213
- def current_connection_id
214
- connection_cache_key(current_thread)
215
- end
216
-
217
- def checkout(checkout_timeout = @checkout_timeout)
218
- begin
219
- reap_connections
220
- rescue => ex
221
- ActiveRecord::Base.logger.error("Exception occurred while executing reap_connections: #{ex}")
222
- end
223
- super
224
- end
225
-
226
- def release_connection(owner_thread = Fiber.current)
227
- if (conn = @thread_cached_conns.delete(connection_cache_key(owner_thread)))
228
- checkin(conn)
229
- 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)
230
36
  end
231
37
  end
232
38
 
233
- case Rails::VERSION::MAJOR
234
- when 4
235
- include Adapter_4_2
236
- when 5, 6
237
- include Adapter_5_2
238
- end
239
-
240
39
  def initialize(connection_spec, *args, **keyword_args)
241
- if ActiveRecord.gem_version < "6.1"
242
- connection_spec.config[:reaping_frequency] and raise "reaping_frequency is not supported (the ActiveRecord Reaper is thread-based)"
243
- connection_spec.config[:reaping_frequency] = nil # starting in Rails 5, this defaults to 60 if not explicitly set
244
- elsif connection_spec.db_config.reaping_frequency
245
- connection_spec.db_config.reaping_frequency > 0 and raise "reaping_frequency is not supported (the ActiveRecord Reaper is thread-based)"
246
- end
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
247
42
 
248
43
  super(connection_spec, *args, **keyword_args)
249
44
 
@@ -286,7 +81,7 @@ module FiberedMysql2
286
81
  end
287
82
 
288
83
  def current_thread
289
- Fiber.current
84
+ AsyncTask.current_or_none
290
85
  end
291
86
  end
292
87
  end
@@ -2,111 +2,6 @@
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
- if Rails::VERSION::MAJOR > 5
20
- # Overriding the em-synchrony override to bring it up to rails 6 requirements.
21
- # Changes from the original Rails 6 source are:
22
- # 1. the usage of _current_stack created by em-synchrony instead of the Rails provided @stack instance variable
23
- # 2. the usage of Fiber.current.object_id as a part of the savepoint transaction name
24
- #
25
- # Original EM Synchrony Source:
26
- # https://github.com/igrigorik/em-synchrony/blob/master/lib/em-synchrony/activerecord_4_2.rb#L35-L44
27
- #
28
- # Original Rails Source:
29
- # https://github.com/rails/rails/blob/6-0-stable/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb#L205-L224
30
- def begin_transaction(options = {})
31
- @connection.lock.synchronize do
32
- run_commit_callbacks = !current_transaction.joinable?
33
- transaction =
34
- if _current_stack.empty?
35
- if ::ActiveRecord.gem_version < "6.1"
36
- ::ActiveRecord::ConnectionAdapters::RealTransaction.new(@connection, options, run_commit_callbacks: run_commit_callbacks)
37
- else
38
- ::ActiveRecord::ConnectionAdapters::RealTransaction.new(@connection, **options, run_commit_callbacks: run_commit_callbacks)
39
- end
40
- else
41
- if ::ActiveRecord.gem_version < "6.1"
42
- ::ActiveRecord::ConnectionAdapters::SavepointTransaction.new(@connection, "active_record_#{Fiber.current.object_id}_#{open_transactions}", _current_stack.last, options, run_commit_callbacks: run_commit_callbacks)
43
- else
44
- ::ActiveRecord::ConnectionAdapters::SavepointTransaction.new(@connection, "active_record_#{Fiber.current.object_id}_#{open_transactions}", _current_stack.last, **options, run_commit_callbacks: run_commit_callbacks)
45
- end
46
- end
47
-
48
- if @connection.supports_lazy_transactions? && lazy_transactions_enabled? && options[:_lazy] != false
49
- @has_unmaterialized_transactions = true
50
- else
51
- transaction.materialize!
52
- end
53
- _current_stack.push(transaction)
54
- transaction
55
- end
56
- end
57
-
58
- # Overriding the ActiveRecord::TransactionManager#materialize_transactions method to use
59
- # fiber safe the _current_stack instead of the @stack instance variable. when marterializing
60
- # transactions.
61
- def materialize_transactions
62
- return if @materializing_transactions
63
- return unless @has_unmaterialized_transactions
64
-
65
- @connection.lock.synchronize do
66
- begin
67
- @materializing_transactions = true
68
- _current_stack.each { |t| t.materialize! unless t.materialized? }
69
- ensure
70
- @materializing_transactions = false
71
- end
72
- @has_unmaterialized_transactions = false
73
- end
74
- end
75
-
76
- # Overriding the ActiveRecord::TransactionManager#commit_transaction method to use
77
- # fiber safe the _current_stack instead of the @stack instance variable. when marterializing
78
- # transactions.
79
- def commit_transaction
80
- @connection.lock.synchronize do
81
- transaction = _current_stack.last
82
-
83
- begin
84
- transaction.before_commit_records
85
- ensure
86
- _current_stack.pop
87
- end
88
-
89
- transaction.commit
90
- transaction.commit_records
91
- end
92
- end
93
-
94
- # Overriding the ActiveRecord::TransactionManager#rollback_transaction method to use
95
- # fiber safe the _current_stack instead of the @stack instance variable. when marterializing
96
- # transactions.
97
- def rollback_transaction(transaction = nil)
98
- @connection.lock.synchronize do
99
- transaction ||= _current_stack.pop
100
- transaction.rollback
101
- transaction.rollback_records
102
- end
103
- end
104
- end
105
- end
106
- end
107
- end
108
- end
109
-
110
5
  module FiberedMysql2
111
6
  module FiberedMysql2ConnectionFactory
112
7
  def fibered_mysql2_connection(raw_config)
@@ -117,10 +12,10 @@ module FiberedMysql2
117
12
 
118
13
  client =
119
14
  begin
120
- Mysql2::EM::Client.new(config)
15
+ Mysql2::Client.new(config)
121
16
  rescue Mysql2::Error => error
122
17
  if error.message.include?("Unknown database")
123
- raise ActiveRecord::NoDatabaseError.new(error.message, error)
18
+ raise ActiveRecord::NoDatabaseError.new(error.message)
124
19
  else
125
20
  raise
126
21
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FiberedMysql2
4
- VERSION = "0.2.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,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fibered_mysql2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.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-08-19 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
@@ -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_0.gemfile
70
- - gemfiles/rails_6_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.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,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FiberedMysql2
4
- module HashConfigOverride
5
- # Override the reaping_frequency method to return nil so that the connection pool does not reap connections when in fibered mode.
6
- def reaping_frequency
7
- nil
8
- end
9
- end
10
- end
11
-
12
- if ActiveRecord.gem_version >= "6.1"
13
- ActiveRecord::DatabaseConfigurations::HashConfig.prepend(FiberedMysql2::HashConfigOverride)
14
- end