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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +76 -0
  3. data/.gitignore +2 -2
  4. data/.release-please-manifest.json +1 -1
  5. data/CHANGELOG.md +32 -0
  6. data/Gemfile +31 -0
  7. data/Makefile +8 -12
  8. data/README.md +7 -35
  9. data/Rakefile +5 -2
  10. data/bin/console +11 -0
  11. data/bin/rails +15 -0
  12. data/bin/sanity +20 -0
  13. data/bin/sanity_check +86 -0
  14. data/bin/setup +8 -0
  15. data/bin/setup_test_db +59 -0
  16. data/bin/test_connections +22 -0
  17. data/docker-compose.yml +3 -4
  18. data/lib/with_advisory_lock/concern.rb +26 -19
  19. data/lib/with_advisory_lock/core_advisory.rb +110 -0
  20. data/lib/with_advisory_lock/jruby_adapter.rb +29 -0
  21. data/lib/with_advisory_lock/lock_stack_item.rb +6 -0
  22. data/lib/with_advisory_lock/mysql_advisory.rb +62 -0
  23. data/lib/with_advisory_lock/postgresql_advisory.rb +112 -0
  24. data/lib/with_advisory_lock/result.rb +14 -0
  25. data/lib/with_advisory_lock/version.rb +1 -1
  26. data/lib/with_advisory_lock.rb +38 -10
  27. data/test/dummy/Rakefile +8 -0
  28. data/test/dummy/app/controllers/application_controller.rb +7 -0
  29. data/test/dummy/app/models/application_record.rb +6 -0
  30. data/test/dummy/app/models/label.rb +4 -0
  31. data/test/dummy/app/models/mysql_label.rb +5 -0
  32. data/test/dummy/app/models/mysql_record.rb +6 -0
  33. data/test/dummy/app/models/mysql_tag.rb +10 -0
  34. data/test/dummy/app/models/mysql_tag_audit.rb +5 -0
  35. data/test/dummy/app/models/tag.rb +8 -0
  36. data/test/dummy/app/models/tag_audit.rb +4 -0
  37. data/test/dummy/config/application.rb +31 -0
  38. data/test/dummy/config/boot.rb +3 -0
  39. data/test/dummy/config/database.yml +13 -0
  40. data/test/dummy/config/environment.rb +7 -0
  41. data/test/dummy/config/routes.rb +4 -0
  42. data/test/dummy/config.ru +6 -0
  43. data/test/{test_models.rb → dummy/db/schema.rb} +2 -17
  44. data/test/dummy/db/secondary_schema.rb +15 -0
  45. data/test/dummy/lib/tasks/db.rake +40 -0
  46. data/test/sanity_check_test.rb +63 -0
  47. data/test/test_helper.rb +14 -47
  48. data/test/with_advisory_lock/concern_test.rb +58 -12
  49. data/test/with_advisory_lock/lock_test.rb +159 -73
  50. data/test/with_advisory_lock/multi_adapter_test.rb +17 -0
  51. data/test/with_advisory_lock/parallelism_test.rb +63 -37
  52. data/test/with_advisory_lock/postgresql_race_condition_test.rb +118 -0
  53. data/test/with_advisory_lock/shared_test.rb +52 -57
  54. data/test/with_advisory_lock/thread_test.rb +64 -42
  55. data/test/with_advisory_lock/transaction_test.rb +55 -40
  56. data/with_advisory_lock.gemspec +25 -5
  57. metadata +54 -50
  58. data/.github/workflows/ci-mysql5.yml +0 -61
  59. data/.github/workflows/ci-mysql8.yml +0 -62
  60. data/.github/workflows/ci-postgresql.yml +0 -64
  61. data/.github/workflows/ci-sqlite3.yml +0 -54
  62. data/Appraisals +0 -45
  63. data/gemfiles/activerecord_6.1.gemfile +0 -21
  64. data/gemfiles/activerecord_7.0.gemfile +0 -21
  65. data/gemfiles/activerecord_7.1.gemfile +0 -14
  66. data/lib/with_advisory_lock/base.rb +0 -118
  67. data/lib/with_advisory_lock/database_adapter_support.rb +0 -23
  68. data/lib/with_advisory_lock/flock.rb +0 -33
  69. data/lib/with_advisory_lock/mysql.rb +0 -32
  70. data/lib/with_advisory_lock/postgresql.rb +0 -66
  71. data/test/with_advisory_lock/base_test.rb +0 -9
  72. data/test/with_advisory_lock/nesting_test.rb +0 -28
  73. 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: 5.3.0
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: '6.1'
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: '6.1'
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.6'
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.6'
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-mysql5.yml"
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/database_adapter_support.rb
127
+ - lib/with_advisory_lock/core_advisory.rb
143
128
  - lib/with_advisory_lock/failed_to_acquire_lock.rb
144
- - lib/with_advisory_lock/flock.rb
145
- - lib/with_advisory_lock/mysql.rb
146
- - lib/with_advisory_lock/postgresql.rb
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/nesting_test.rb
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: 2.7.0
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.7
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,14 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "~> 7.1.0"
6
-
7
- platforms :ruby do
8
- gem "sqlite3"
9
- gem "mysql2"
10
- gem "trilogy"
11
- gem "pg"
12
- end
13
-
14
- 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