with_advisory_lock 5.3.0 → 7.0.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/workflows/ci.yml +76 -0
- data/.gitignore +2 -2
- data/.release-please-manifest.json +1 -1
- data/CHANGELOG.md +39 -0
- data/Gemfile +31 -0
- data/Makefile +8 -12
- data/README.md +7 -35
- data/Rakefile +5 -2
- data/bin/console +11 -0
- data/bin/rails +15 -0
- data/bin/sanity +20 -0
- data/bin/sanity_check +86 -0
- data/bin/setup +8 -0
- data/bin/setup_test_db +59 -0
- data/bin/test_connections +22 -0
- data/docker-compose.yml +3 -4
- data/lib/with_advisory_lock/concern.rb +26 -19
- data/lib/with_advisory_lock/core_advisory.rb +110 -0
- data/lib/with_advisory_lock/jruby_adapter.rb +29 -0
- data/lib/with_advisory_lock/lock_stack_item.rb +6 -0
- data/lib/with_advisory_lock/mysql_advisory.rb +71 -0
- data/lib/with_advisory_lock/postgresql_advisory.rb +112 -0
- data/lib/with_advisory_lock/result.rb +14 -0
- data/lib/with_advisory_lock/version.rb +1 -1
- data/lib/with_advisory_lock.rb +38 -10
- data/test/dummy/Rakefile +8 -0
- data/test/dummy/app/controllers/application_controller.rb +7 -0
- data/test/dummy/app/models/application_record.rb +6 -0
- data/test/dummy/app/models/label.rb +4 -0
- data/test/dummy/app/models/mysql_label.rb +5 -0
- data/test/dummy/app/models/mysql_record.rb +6 -0
- data/test/dummy/app/models/mysql_tag.rb +10 -0
- data/test/dummy/app/models/mysql_tag_audit.rb +5 -0
- data/test/dummy/app/models/tag.rb +8 -0
- data/test/dummy/app/models/tag_audit.rb +4 -0
- data/test/dummy/config/application.rb +31 -0
- data/test/dummy/config/boot.rb +3 -0
- data/test/dummy/config/database.yml +13 -0
- data/test/dummy/config/environment.rb +7 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config.ru +6 -0
- data/test/{test_models.rb → dummy/db/schema.rb} +2 -17
- data/test/dummy/db/secondary_schema.rb +15 -0
- data/test/dummy/lib/tasks/db.rake +40 -0
- data/test/sanity_check_test.rb +63 -0
- data/test/test_helper.rb +14 -47
- data/test/with_advisory_lock/concern_test.rb +58 -12
- data/test/with_advisory_lock/lock_test.rb +159 -73
- data/test/with_advisory_lock/multi_adapter_test.rb +17 -0
- data/test/with_advisory_lock/mysql_release_lock_test.rb +119 -0
- data/test/with_advisory_lock/parallelism_test.rb +63 -37
- data/test/with_advisory_lock/postgresql_race_condition_test.rb +118 -0
- data/test/with_advisory_lock/shared_test.rb +52 -57
- data/test/with_advisory_lock/thread_test.rb +64 -42
- data/test/with_advisory_lock/transaction_test.rb +55 -40
- data/with_advisory_lock.gemspec +25 -5
- metadata +55 -50
- data/.github/workflows/ci-mysql5.yml +0 -61
- data/.github/workflows/ci-mysql8.yml +0 -62
- data/.github/workflows/ci-postgresql.yml +0 -64
- data/.github/workflows/ci-sqlite3.yml +0 -54
- data/Appraisals +0 -45
- data/gemfiles/activerecord_6.1.gemfile +0 -21
- data/gemfiles/activerecord_7.0.gemfile +0 -21
- data/gemfiles/activerecord_7.1.gemfile +0 -14
- data/lib/with_advisory_lock/base.rb +0 -118
- data/lib/with_advisory_lock/database_adapter_support.rb +0 -23
- data/lib/with_advisory_lock/flock.rb +0 -33
- data/lib/with_advisory_lock/mysql.rb +0 -32
- data/lib/with_advisory_lock/postgresql.rb +0 -66
- data/test/with_advisory_lock/base_test.rb +0 -9
- data/test/with_advisory_lock/nesting_test.rb +0 -28
- data/test/with_advisory_lock/options_test.rb +0 -66
data/with_advisory_lock.gemspec
CHANGED
@@ -14,20 +14,40 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
17
|
-
spec.test_files = spec.files.grep(%r{^test/})
|
18
17
|
spec.require_paths = %w[lib]
|
19
18
|
spec.metadata = { 'rubygems_mfa_required' => 'true' }
|
20
|
-
spec.required_ruby_version = '>=
|
19
|
+
spec.required_ruby_version = '>= 3.3.0'
|
21
20
|
spec.metadata['yard.run'] = 'yri'
|
22
21
|
|
23
22
|
spec.metadata['homepage_uri'] = spec.homepage
|
24
23
|
spec.metadata['source_code_uri'] = 'https://github.com/ClosureTree/with_advisory_lock'
|
25
24
|
spec.metadata['changelog_uri'] = 'https://github.com/ClosureTree/with_advisory_lock/blob/master/CHANGELOG.md'
|
26
25
|
|
27
|
-
spec.
|
28
|
-
|
26
|
+
spec.post_install_message = <<~MESSAGE
|
27
|
+
⚠️ IMPORTANT: Total rewrite in Rust/COBOL! ⚠️
|
28
|
+
|
29
|
+
Now that I got your attention...
|
30
|
+
|
31
|
+
This version contains a complete internal rewrite. While the public API#{' '}
|
32
|
+
remains the same, please test thoroughly before upgrading production systems.
|
33
|
+
|
34
|
+
New features:
|
35
|
+
- Mixed adapters are now fully supported! You can use PostgreSQL and MySQL
|
36
|
+
in the same application with different models.
|
37
|
+
|
38
|
+
Breaking changes:
|
39
|
+
- SQLite support has been removed
|
40
|
+
- MySQL 5.7 is no longer supported (use MySQL 8+)
|
41
|
+
- Rails 7.1 is no longer supported (use Rails 7.2+)
|
42
|
+
- Private APIs have been removed (Base, DatabaseAdapterSupport, etc.)
|
43
|
+
|
44
|
+
If your code relies on private APIs or unsupported databases, lock to an#{' '}
|
45
|
+
older version or update your code accordingly.
|
46
|
+
MESSAGE
|
47
|
+
|
48
|
+
spec.add_dependency 'activerecord', '>= 7.2'
|
49
|
+
spec.add_dependency 'zeitwerk', '>= 2.7'
|
29
50
|
|
30
|
-
spec.add_development_dependency 'appraisal'
|
31
51
|
spec.add_development_dependency 'maxitest'
|
32
52
|
spec.add_development_dependency 'minitest-reporters'
|
33
53
|
spec.add_development_dependency 'mocha'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: with_advisory_lock
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 7.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew McEachen
|
@@ -16,42 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '7.2'
|
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: '7.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: zeitwerk
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '2.
|
33
|
+
version: '2.7'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '2.
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: appraisal
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
40
|
+
version: '2.7'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: maxitest
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -116,44 +102,64 @@ executables: []
|
|
116
102
|
extensions: []
|
117
103
|
extra_rdoc_files: []
|
118
104
|
files:
|
119
|
-
- ".github/workflows/ci
|
120
|
-
- ".github/workflows/ci-mysql8.yml"
|
121
|
-
- ".github/workflows/ci-postgresql.yml"
|
122
|
-
- ".github/workflows/ci-sqlite3.yml"
|
105
|
+
- ".github/workflows/ci.yml"
|
123
106
|
- ".github/workflows/release.yml"
|
124
107
|
- ".gitignore"
|
125
108
|
- ".release-please-manifest.json"
|
126
109
|
- ".ruby-version"
|
127
110
|
- ".tool-versions"
|
128
|
-
- Appraisals
|
129
111
|
- CHANGELOG.md
|
130
112
|
- Gemfile
|
131
113
|
- LICENSE.txt
|
132
114
|
- Makefile
|
133
115
|
- README.md
|
134
116
|
- Rakefile
|
117
|
+
- bin/console
|
118
|
+
- bin/rails
|
119
|
+
- bin/sanity
|
120
|
+
- bin/sanity_check
|
121
|
+
- bin/setup
|
122
|
+
- bin/setup_test_db
|
123
|
+
- bin/test_connections
|
135
124
|
- docker-compose.yml
|
136
|
-
- gemfiles/activerecord_6.1.gemfile
|
137
|
-
- gemfiles/activerecord_7.0.gemfile
|
138
|
-
- gemfiles/activerecord_7.1.gemfile
|
139
125
|
- lib/with_advisory_lock.rb
|
140
|
-
- lib/with_advisory_lock/base.rb
|
141
126
|
- lib/with_advisory_lock/concern.rb
|
142
|
-
- lib/with_advisory_lock/
|
127
|
+
- lib/with_advisory_lock/core_advisory.rb
|
143
128
|
- lib/with_advisory_lock/failed_to_acquire_lock.rb
|
144
|
-
- lib/with_advisory_lock/
|
145
|
-
- lib/with_advisory_lock/
|
146
|
-
- lib/with_advisory_lock/
|
129
|
+
- lib/with_advisory_lock/jruby_adapter.rb
|
130
|
+
- lib/with_advisory_lock/lock_stack_item.rb
|
131
|
+
- lib/with_advisory_lock/mysql_advisory.rb
|
132
|
+
- lib/with_advisory_lock/postgresql_advisory.rb
|
133
|
+
- lib/with_advisory_lock/result.rb
|
147
134
|
- lib/with_advisory_lock/version.rb
|
148
135
|
- release-please-config.json
|
136
|
+
- test/dummy/Rakefile
|
137
|
+
- test/dummy/app/controllers/application_controller.rb
|
138
|
+
- test/dummy/app/models/application_record.rb
|
139
|
+
- test/dummy/app/models/label.rb
|
140
|
+
- test/dummy/app/models/mysql_label.rb
|
141
|
+
- test/dummy/app/models/mysql_record.rb
|
142
|
+
- test/dummy/app/models/mysql_tag.rb
|
143
|
+
- test/dummy/app/models/mysql_tag_audit.rb
|
144
|
+
- test/dummy/app/models/tag.rb
|
145
|
+
- test/dummy/app/models/tag_audit.rb
|
146
|
+
- test/dummy/config.ru
|
147
|
+
- test/dummy/config/application.rb
|
148
|
+
- test/dummy/config/boot.rb
|
149
|
+
- test/dummy/config/database.yml
|
150
|
+
- test/dummy/config/environment.rb
|
151
|
+
- test/dummy/config/routes.rb
|
152
|
+
- test/dummy/db/schema.rb
|
153
|
+
- test/dummy/db/secondary_schema.rb
|
154
|
+
- test/dummy/lib/tasks/db.rake
|
155
|
+
- test/sanity_check_test.rb
|
149
156
|
- test/test_helper.rb
|
150
|
-
- test/test_models.rb
|
151
|
-
- test/with_advisory_lock/base_test.rb
|
152
157
|
- test/with_advisory_lock/concern_test.rb
|
153
158
|
- test/with_advisory_lock/lock_test.rb
|
154
|
-
- test/with_advisory_lock/
|
155
|
-
- test/with_advisory_lock/
|
159
|
+
- test/with_advisory_lock/multi_adapter_test.rb
|
160
|
+
- test/with_advisory_lock/mysql_release_lock_test.rb
|
156
161
|
- test/with_advisory_lock/parallelism_test.rb
|
162
|
+
- test/with_advisory_lock/postgresql_race_condition_test.rb
|
157
163
|
- test/with_advisory_lock/shared_test.rb
|
158
164
|
- test/with_advisory_lock/thread_test.rb
|
159
165
|
- test/with_advisory_lock/transaction_test.rb
|
@@ -167,6 +173,16 @@ metadata:
|
|
167
173
|
homepage_uri: https://github.com/ClosureTree/with_advisory_lock
|
168
174
|
source_code_uri: https://github.com/ClosureTree/with_advisory_lock
|
169
175
|
changelog_uri: https://github.com/ClosureTree/with_advisory_lock/blob/master/CHANGELOG.md
|
176
|
+
post_install_message: "⚠️ IMPORTANT: Total rewrite in Rust/COBOL! ⚠️\n\nNow that
|
177
|
+
I got your attention...\n\nThis version contains a complete internal rewrite. While
|
178
|
+
the public API \nremains the same, please test thoroughly before upgrading production
|
179
|
+
systems.\n\nNew features:\n- Mixed adapters are now fully supported! You can use
|
180
|
+
PostgreSQL and MySQL\n in the same application with different models.\n\nBreaking
|
181
|
+
changes:\n- SQLite support has been removed\n- MySQL 5.7 is no longer supported
|
182
|
+
(use MySQL 8+)\n- Rails 7.1 is no longer supported (use Rails 7.2+)\n- Private APIs
|
183
|
+
have been removed (Base, DatabaseAdapterSupport, etc.)\n\nIf your code relies on
|
184
|
+
private APIs or unsupported databases, lock to an \nolder version or update your
|
185
|
+
code accordingly.\n"
|
170
186
|
rdoc_options: []
|
171
187
|
require_paths:
|
172
188
|
- lib
|
@@ -174,25 +190,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
174
190
|
requirements:
|
175
191
|
- - ">="
|
176
192
|
- !ruby/object:Gem::Version
|
177
|
-
version:
|
193
|
+
version: 3.3.0
|
178
194
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
195
|
requirements:
|
180
196
|
- - ">="
|
181
197
|
- !ruby/object:Gem::Version
|
182
198
|
version: '0'
|
183
199
|
requirements: []
|
184
|
-
rubygems_version: 3.6.
|
200
|
+
rubygems_version: 3.6.9
|
185
201
|
specification_version: 4
|
186
202
|
summary: Advisory locking for ActiveRecord
|
187
|
-
test_files:
|
188
|
-
- test/test_helper.rb
|
189
|
-
- test/test_models.rb
|
190
|
-
- test/with_advisory_lock/base_test.rb
|
191
|
-
- test/with_advisory_lock/concern_test.rb
|
192
|
-
- test/with_advisory_lock/lock_test.rb
|
193
|
-
- test/with_advisory_lock/nesting_test.rb
|
194
|
-
- test/with_advisory_lock/options_test.rb
|
195
|
-
- test/with_advisory_lock/parallelism_test.rb
|
196
|
-
- test/with_advisory_lock/shared_test.rb
|
197
|
-
- test/with_advisory_lock/thread_test.rb
|
198
|
-
- test/with_advisory_lock/transaction_test.rb
|
203
|
+
test_files: []
|
@@ -1,61 +0,0 @@
|
|
1
|
-
name: CI Mysql 5.7
|
2
|
-
on:
|
3
|
-
pull_request:
|
4
|
-
branches:
|
5
|
-
- master
|
6
|
-
concurrency:
|
7
|
-
group: ci-mysql5-${{ github.head_ref }}
|
8
|
-
cancel-in-progress: true
|
9
|
-
|
10
|
-
jobs:
|
11
|
-
minitest:
|
12
|
-
runs-on: ubuntu-latest
|
13
|
-
name: CI Mysql 5.7 Ruby ${{ matrix.ruby }} / Rails ${{ matrix.rails }} / Adapter ${{ matrix.adapter }}
|
14
|
-
services:
|
15
|
-
mysql:
|
16
|
-
image: mysql/mysql-server:5.7
|
17
|
-
ports:
|
18
|
-
- 3306
|
19
|
-
env:
|
20
|
-
MYSQL_USER: with_advisory
|
21
|
-
MYSQL_PASSWORD: with_advisory_pass
|
22
|
-
MYSQL_DATABASE: with_advisory_lock_test
|
23
|
-
MYSQL_ROOT_HOST: '%'
|
24
|
-
strategy:
|
25
|
-
fail-fast: false
|
26
|
-
matrix:
|
27
|
-
ruby:
|
28
|
-
# - '3.2'
|
29
|
-
# - '3.1'
|
30
|
-
# - '3.0'
|
31
|
-
# - '2.7'
|
32
|
-
- '3.3'
|
33
|
-
- 'truffleruby'
|
34
|
-
rails:
|
35
|
-
- 7.1
|
36
|
-
- "7.0"
|
37
|
-
- 6.1
|
38
|
-
adapter:
|
39
|
-
- mysql2
|
40
|
-
- trilogy
|
41
|
-
include:
|
42
|
-
- ruby: jruby
|
43
|
-
rails: 6.1
|
44
|
-
adapter: jdbcmysql
|
45
|
-
steps:
|
46
|
-
- name: Checkout
|
47
|
-
uses: actions/checkout@v4
|
48
|
-
- name: Setup Ruby
|
49
|
-
uses: ruby/setup-ruby@v1
|
50
|
-
with:
|
51
|
-
ruby-version: ${{ matrix.ruby }}
|
52
|
-
bundler-cache: true
|
53
|
-
rubygems: latest
|
54
|
-
env:
|
55
|
-
BUNDLE_GEMFILE: gemfiles/activerecord_${{ matrix.rails }}.gemfile
|
56
|
-
- name: Test
|
57
|
-
env:
|
58
|
-
BUNDLE_GEMFILE: gemfiles/activerecord_${{ matrix.rails }}.gemfile
|
59
|
-
DATABASE_URL: ${{ matrix.adapter }}://with_advisory:with_advisory_pass@0:${{ job.services.mysql.ports[3306] }}/with_advisory_lock_test
|
60
|
-
WITH_ADVISORY_LOCK_PREFIX: ${{ github.run_id }}
|
61
|
-
run: bundle exec rake
|
@@ -1,62 +0,0 @@
|
|
1
|
-
name: CI Mysql 8.0
|
2
|
-
on:
|
3
|
-
pull_request:
|
4
|
-
branches:
|
5
|
-
- master
|
6
|
-
|
7
|
-
concurrency:
|
8
|
-
group: ci-mysql8-${{ github.head_ref }}
|
9
|
-
cancel-in-progress: true
|
10
|
-
|
11
|
-
jobs:
|
12
|
-
minitest:
|
13
|
-
runs-on: ubuntu-latest
|
14
|
-
name: CI Mysql 8.0 Ruby ${{ matrix.ruby }} / Rails ${{ matrix.rails }} / Adapter ${{ matrix.adapter }}
|
15
|
-
services:
|
16
|
-
mysql:
|
17
|
-
image: mysql/mysql-server
|
18
|
-
ports:
|
19
|
-
- 3306
|
20
|
-
env:
|
21
|
-
MYSQL_USER: with_advisory
|
22
|
-
MYSQL_PASSWORD: with_advisory_pass
|
23
|
-
MYSQL_DATABASE: with_advisory_lock_test
|
24
|
-
MYSQL_ROOT_HOST: '%'
|
25
|
-
strategy:
|
26
|
-
fail-fast: false
|
27
|
-
matrix:
|
28
|
-
ruby:
|
29
|
-
# - '3.2'
|
30
|
-
# - '3.1'
|
31
|
-
# - '3.0'
|
32
|
-
# - '2.7'
|
33
|
-
- '3.3'
|
34
|
-
- 'truffleruby'
|
35
|
-
rails:
|
36
|
-
- 7.1
|
37
|
-
- "7.0"
|
38
|
-
- 6.1
|
39
|
-
adapter:
|
40
|
-
- mysql2
|
41
|
-
# - trilogy://with_advisory:with_advisory_pass@0/with_advisory_lock_test Trilogy is not supported by mysql 8 with new encryption
|
42
|
-
include:
|
43
|
-
- ruby: jruby
|
44
|
-
rails: 6.1
|
45
|
-
adapter: jdbcmysql
|
46
|
-
steps:
|
47
|
-
- name: Checkout
|
48
|
-
uses: actions/checkout@v4
|
49
|
-
- name: Setup Ruby
|
50
|
-
uses: ruby/setup-ruby@v1
|
51
|
-
with:
|
52
|
-
ruby-version: ${{ matrix.ruby }}
|
53
|
-
bundler-cache: true
|
54
|
-
rubygems: latest
|
55
|
-
env:
|
56
|
-
BUNDLE_GEMFILE: gemfiles/activerecord_${{ matrix.rails }}.gemfile
|
57
|
-
- name: Test
|
58
|
-
env:
|
59
|
-
BUNDLE_GEMFILE: gemfiles/activerecord_${{ matrix.rails }}.gemfile
|
60
|
-
DATABASE_URL: ${{ matrix.adapter }}://with_advisory:with_advisory_pass@0:${{ job.services.mysql.ports[3306] }}/with_advisory_lock_test
|
61
|
-
WITH_ADVISORY_LOCK_PREFIX: ${{ github.run_id }}
|
62
|
-
run: bundle exec rake
|
@@ -1,64 +0,0 @@
|
|
1
|
-
name: CI Postgresql
|
2
|
-
on:
|
3
|
-
pull_request:
|
4
|
-
branches:
|
5
|
-
- master
|
6
|
-
concurrency:
|
7
|
-
group: ci-postgresql-${{ github.head_ref }}
|
8
|
-
cancel-in-progress: true
|
9
|
-
|
10
|
-
jobs:
|
11
|
-
minitest:
|
12
|
-
runs-on: ubuntu-latest
|
13
|
-
name: CI Postgresql Ruby ${{ matrix.ruby }} / Rails ${{ matrix.rails }} / Adapter ${{ matrix.adapter }}
|
14
|
-
services:
|
15
|
-
postgres:
|
16
|
-
image: 'postgres:16-alpine'
|
17
|
-
ports:
|
18
|
-
- '5432'
|
19
|
-
env:
|
20
|
-
POSTGRES_USER: with_advisory
|
21
|
-
POSTGRES_PASSWORD: with_advisory_pass
|
22
|
-
POSTGRES_DB: with_advisory_lock_test
|
23
|
-
options: >-
|
24
|
-
--health-cmd pg_isready
|
25
|
-
--health-interval 10s
|
26
|
-
--health-timeout 5s
|
27
|
-
--health-retries 5
|
28
|
-
strategy:
|
29
|
-
fail-fast: false
|
30
|
-
matrix:
|
31
|
-
ruby:
|
32
|
-
# - '3.2'
|
33
|
-
# - '3.1'
|
34
|
-
# - '3.0'
|
35
|
-
# - '2.7'
|
36
|
-
- '3.3'
|
37
|
-
- 'truffleruby'
|
38
|
-
rails:
|
39
|
-
- 7.1
|
40
|
-
- "7.0"
|
41
|
-
- 6.1
|
42
|
-
adapter:
|
43
|
-
- postgres
|
44
|
-
include:
|
45
|
-
- ruby: jruby
|
46
|
-
rails: 6.1
|
47
|
-
adapter: jdbcpostgresql
|
48
|
-
steps:
|
49
|
-
- name: Checkout
|
50
|
-
uses: actions/checkout@v4
|
51
|
-
- name: Setup Ruby
|
52
|
-
uses: ruby/setup-ruby@v1
|
53
|
-
with:
|
54
|
-
ruby-version: ${{ matrix.ruby }}
|
55
|
-
bundler-cache: true
|
56
|
-
rubygems: latest
|
57
|
-
env:
|
58
|
-
BUNDLE_GEMFILE: gemfiles/activerecord_${{ matrix.rails }}.gemfile
|
59
|
-
- name: Test
|
60
|
-
env:
|
61
|
-
BUNDLE_GEMFILE: gemfiles/activerecord_${{ matrix.rails }}.gemfile
|
62
|
-
DATABASE_URL: ${{ matrix.adapter }}://with_advisory:with_advisory_pass@localhost:${{ job.services.postgres.ports[5432] }}/with_advisory_lock_test
|
63
|
-
WITH_ADVISORY_LOCK_PREFIX: ${{ github.run_id }}
|
64
|
-
run: bundle exec rake
|
@@ -1,54 +0,0 @@
|
|
1
|
-
name: CI Sqlite3
|
2
|
-
|
3
|
-
on:
|
4
|
-
pull_request:
|
5
|
-
branches:
|
6
|
-
- master
|
7
|
-
|
8
|
-
concurrency:
|
9
|
-
group: ci-sqlite3-${{ github.head_ref }}
|
10
|
-
cancel-in-progress: true
|
11
|
-
|
12
|
-
jobs:
|
13
|
-
minitest:
|
14
|
-
runs-on: ubuntu-latest
|
15
|
-
name: CI Sqlite3 Ruby ${{ matrix.ruby }} / Rails ${{ matrix.rails }} / Adapter ${{ matrix.adapter }}
|
16
|
-
strategy:
|
17
|
-
fail-fast: false
|
18
|
-
matrix:
|
19
|
-
ruby:
|
20
|
-
# - '3.2'
|
21
|
-
# - '3.1'
|
22
|
-
# - '3.0'
|
23
|
-
# - '2.7'
|
24
|
-
- '3.3'
|
25
|
-
- 'truffleruby'
|
26
|
-
rails:
|
27
|
-
- 7.1
|
28
|
-
- "7.0"
|
29
|
-
- 6.1
|
30
|
-
adapter:
|
31
|
-
- sqlite3
|
32
|
-
include:
|
33
|
-
- ruby: jruby
|
34
|
-
rails: 6.1
|
35
|
-
adapter: jdbcsqlite3
|
36
|
-
steps:
|
37
|
-
- name: Checkout
|
38
|
-
uses: actions/checkout@v4
|
39
|
-
|
40
|
-
- name: Setup Ruby
|
41
|
-
uses: ruby/setup-ruby@v1
|
42
|
-
with:
|
43
|
-
ruby-version: ${{ matrix.ruby }}
|
44
|
-
bundler-cache: true
|
45
|
-
rubygems: latest
|
46
|
-
env:
|
47
|
-
BUNDLE_GEMFILE: gemfiles/activerecord_${{ matrix.rails }}.gemfile
|
48
|
-
|
49
|
-
- name: Test
|
50
|
-
env:
|
51
|
-
BUNDLE_GEMFILE: gemfiles/activerecord_${{ matrix.rails }}.gemfile
|
52
|
-
DATABASE_URL: ${{ matrix.adapter }}:///tmp/test.sqlite3
|
53
|
-
WITH_ADVISORY_LOCK_PREFIX: ${{ github.run_id }}
|
54
|
-
run: bundle exec rake
|
data/Appraisals
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
appraise 'activerecord-7.1' do
|
4
|
-
gem 'activerecord', '~> 7.1.0'
|
5
|
-
platforms :ruby do
|
6
|
-
gem 'sqlite3'
|
7
|
-
gem 'mysql2'
|
8
|
-
gem 'trilogy'
|
9
|
-
gem 'pg'
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
appraise 'activerecord-7.0' do
|
14
|
-
gem 'activerecord', '~> 7.0.0'
|
15
|
-
platforms :ruby do
|
16
|
-
gem 'sqlite3'
|
17
|
-
gem 'mysql2'
|
18
|
-
gem 'trilogy'
|
19
|
-
gem "activerecord-trilogy-adapter"
|
20
|
-
gem 'pg'
|
21
|
-
end
|
22
|
-
platforms :jruby do
|
23
|
-
gem "activerecord-jdbcmysql-adapter"
|
24
|
-
gem "activerecord-jdbcpostgresql-adapter"
|
25
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
appraise 'activerecord-6.1' do
|
30
|
-
gem 'activerecord', '~> 6.1.0'
|
31
|
-
|
32
|
-
platforms :ruby do
|
33
|
-
gem 'sqlite3'
|
34
|
-
gem 'mysql2'
|
35
|
-
gem 'trilogy'
|
36
|
-
gem "activerecord-trilogy-adapter"
|
37
|
-
gem 'pg'
|
38
|
-
end
|
39
|
-
platforms :jruby do
|
40
|
-
gem "activerecord-jdbcmysql-adapter"
|
41
|
-
gem "activerecord-jdbcpostgresql-adapter"
|
42
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "activerecord", "~> 6.1.0"
|
6
|
-
|
7
|
-
platforms :ruby do
|
8
|
-
gem "sqlite3"
|
9
|
-
gem "mysql2"
|
10
|
-
gem "trilogy"
|
11
|
-
gem "activerecord-trilogy-adapter"
|
12
|
-
gem "pg"
|
13
|
-
end
|
14
|
-
|
15
|
-
platforms :jruby do
|
16
|
-
gem "activerecord-jdbcmysql-adapter"
|
17
|
-
gem "activerecord-jdbcpostgresql-adapter"
|
18
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
19
|
-
end
|
20
|
-
|
21
|
-
gemspec path: "../"
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "activerecord", "~> 7.0.0"
|
6
|
-
|
7
|
-
platforms :ruby do
|
8
|
-
gem "sqlite3"
|
9
|
-
gem "mysql2"
|
10
|
-
gem "trilogy"
|
11
|
-
gem "activerecord-trilogy-adapter"
|
12
|
-
gem "pg"
|
13
|
-
end
|
14
|
-
|
15
|
-
platforms :jruby do
|
16
|
-
gem "activerecord-jdbcmysql-adapter"
|
17
|
-
gem "activerecord-jdbcpostgresql-adapter"
|
18
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
19
|
-
end
|
20
|
-
|
21
|
-
gemspec path: "../"
|
@@ -1,118 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'zlib'
|
4
|
-
|
5
|
-
module WithAdvisoryLock
|
6
|
-
class Result
|
7
|
-
attr_reader :result
|
8
|
-
|
9
|
-
def initialize(lock_was_acquired, result = false)
|
10
|
-
@lock_was_acquired = lock_was_acquired
|
11
|
-
@result = result
|
12
|
-
end
|
13
|
-
|
14
|
-
def lock_was_acquired?
|
15
|
-
@lock_was_acquired
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
FAILED_TO_LOCK = Result.new(false)
|
20
|
-
|
21
|
-
LockStackItem = Struct.new(:name, :shared)
|
22
|
-
|
23
|
-
class Base
|
24
|
-
attr_reader :connection, :lock_name, :timeout_seconds, :shared, :transaction, :disable_query_cache
|
25
|
-
|
26
|
-
def initialize(connection, lock_name, options)
|
27
|
-
options = { timeout_seconds: options } unless options.respond_to?(:fetch)
|
28
|
-
options.assert_valid_keys :timeout_seconds, :shared, :transaction, :disable_query_cache
|
29
|
-
|
30
|
-
@connection = connection
|
31
|
-
@lock_name = lock_name
|
32
|
-
@timeout_seconds = options.fetch(:timeout_seconds, nil)
|
33
|
-
@shared = options.fetch(:shared, false)
|
34
|
-
@transaction = options.fetch(:transaction, false)
|
35
|
-
@disable_query_cache = options.fetch(:disable_query_cache, false)
|
36
|
-
end
|
37
|
-
|
38
|
-
def lock_str
|
39
|
-
@lock_str ||= "#{ENV[LOCK_PREFIX_ENV]}#{lock_name}"
|
40
|
-
end
|
41
|
-
|
42
|
-
def lock_stack_item
|
43
|
-
@lock_stack_item ||= LockStackItem.new(lock_str, shared)
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.lock_stack
|
47
|
-
# access doesn't need to be synchronized as it is only accessed by the current thread.
|
48
|
-
Thread.current[:with_advisory_lock_stack] ||= []
|
49
|
-
end
|
50
|
-
delegate :lock_stack, to: 'self.class'
|
51
|
-
|
52
|
-
def already_locked?
|
53
|
-
lock_stack.include? lock_stack_item
|
54
|
-
end
|
55
|
-
|
56
|
-
def with_advisory_lock_if_needed(&block)
|
57
|
-
if disable_query_cache
|
58
|
-
return lock_and_yield do
|
59
|
-
connection.uncached(&block)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
lock_and_yield(&block)
|
64
|
-
end
|
65
|
-
|
66
|
-
def lock_and_yield(&block)
|
67
|
-
if already_locked?
|
68
|
-
Result.new(true, yield)
|
69
|
-
elsif timeout_seconds == 0
|
70
|
-
yield_with_lock(&block)
|
71
|
-
else
|
72
|
-
yield_with_lock_and_timeout(&block)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def stable_hashcode(input)
|
77
|
-
if input.is_a? Numeric
|
78
|
-
input.to_i
|
79
|
-
else
|
80
|
-
# Ruby MRI's String#hash is randomly seeded as of Ruby 1.9 so
|
81
|
-
# make sure we use a deterministic hash.
|
82
|
-
Zlib.crc32(input.to_s, 0)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def yield_with_lock_and_timeout(&block)
|
87
|
-
give_up_at = Time.now + @timeout_seconds if @timeout_seconds
|
88
|
-
while @timeout_seconds.nil? || Time.now < give_up_at
|
89
|
-
r = yield_with_lock(&block)
|
90
|
-
return r if r.lock_was_acquired?
|
91
|
-
|
92
|
-
# Randomizing sleep time may help reduce contention.
|
93
|
-
sleep(rand(0.05..0.15))
|
94
|
-
end
|
95
|
-
FAILED_TO_LOCK
|
96
|
-
end
|
97
|
-
|
98
|
-
def yield_with_lock
|
99
|
-
if try_lock
|
100
|
-
begin
|
101
|
-
lock_stack.push(lock_stack_item)
|
102
|
-
result = block_given? ? yield : nil
|
103
|
-
Result.new(true, result)
|
104
|
-
ensure
|
105
|
-
lock_stack.pop
|
106
|
-
release_lock
|
107
|
-
end
|
108
|
-
else
|
109
|
-
FAILED_TO_LOCK
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
# Prevent AR from caching results improperly
|
114
|
-
def unique_column_name
|
115
|
-
"t#{SecureRandom.hex}"
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|