with_advisory_lock 5.3.0 → 7.0.0
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 +32 -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 +62 -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/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 +54 -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
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.0
|
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,63 @@ 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/options_test.rb
|
159
|
+
- test/with_advisory_lock/multi_adapter_test.rb
|
156
160
|
- test/with_advisory_lock/parallelism_test.rb
|
161
|
+
- test/with_advisory_lock/postgresql_race_condition_test.rb
|
157
162
|
- test/with_advisory_lock/shared_test.rb
|
158
163
|
- test/with_advisory_lock/thread_test.rb
|
159
164
|
- test/with_advisory_lock/transaction_test.rb
|
@@ -167,6 +172,16 @@ metadata:
|
|
167
172
|
homepage_uri: https://github.com/ClosureTree/with_advisory_lock
|
168
173
|
source_code_uri: https://github.com/ClosureTree/with_advisory_lock
|
169
174
|
changelog_uri: https://github.com/ClosureTree/with_advisory_lock/blob/master/CHANGELOG.md
|
175
|
+
post_install_message: "⚠️ IMPORTANT: Total rewrite in Rust/COBOL! ⚠️\n\nNow that
|
176
|
+
I got your attention...\n\nThis version contains a complete internal rewrite. While
|
177
|
+
the public API \nremains the same, please test thoroughly before upgrading production
|
178
|
+
systems.\n\nNew features:\n- Mixed adapters are now fully supported! You can use
|
179
|
+
PostgreSQL and MySQL\n in the same application with different models.\n\nBreaking
|
180
|
+
changes:\n- SQLite support has been removed\n- MySQL 5.7 is no longer supported
|
181
|
+
(use MySQL 8+)\n- Rails 7.1 is no longer supported (use Rails 7.2+)\n- Private APIs
|
182
|
+
have been removed (Base, DatabaseAdapterSupport, etc.)\n\nIf your code relies on
|
183
|
+
private APIs or unsupported databases, lock to an \nolder version or update your
|
184
|
+
code accordingly.\n"
|
170
185
|
rdoc_options: []
|
171
186
|
require_paths:
|
172
187
|
- lib
|
@@ -174,25 +189,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
174
189
|
requirements:
|
175
190
|
- - ">="
|
176
191
|
- !ruby/object:Gem::Version
|
177
|
-
version:
|
192
|
+
version: 3.3.0
|
178
193
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
194
|
requirements:
|
180
195
|
- - ">="
|
181
196
|
- !ruby/object:Gem::Version
|
182
197
|
version: '0'
|
183
198
|
requirements: []
|
184
|
-
rubygems_version: 3.6.
|
199
|
+
rubygems_version: 3.6.9
|
185
200
|
specification_version: 4
|
186
201
|
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
|
202
|
+
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
|
@@ -1,23 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module WithAdvisoryLock
|
4
|
-
class DatabaseAdapterSupport
|
5
|
-
attr_reader :adapter_name
|
6
|
-
def initialize(connection)
|
7
|
-
@connection = connection
|
8
|
-
@adapter_name = connection.adapter_name.downcase.to_sym
|
9
|
-
end
|
10
|
-
|
11
|
-
def mysql?
|
12
|
-
%i[mysql2 trilogy].include? adapter_name
|
13
|
-
end
|
14
|
-
|
15
|
-
def postgresql?
|
16
|
-
%i[postgresql empostgresql postgis].include? adapter_name
|
17
|
-
end
|
18
|
-
|
19
|
-
def sqlite?
|
20
|
-
[:sqlite3, :sqlite].include? adapter_name
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|