with_advisory_lock 4.0.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +80 -0
  3. data/.gitignore +3 -0
  4. data/.tool-versions +1 -0
  5. data/Appraisals +37 -11
  6. data/CHANGELOG.md +131 -0
  7. data/Gemfile +0 -12
  8. data/README.md +85 -171
  9. data/gemfiles/{activerecord_5.1.gemfile → activerecord_6.1.gemfile} +4 -2
  10. data/gemfiles/{activerecord_5.2.gemfile → activerecord_7.0.gemfile} +4 -2
  11. data/gemfiles/activerecord_7.1.gemfile +14 -0
  12. data/lib/with_advisory_lock/base.rb +16 -2
  13. data/lib/with_advisory_lock/concern.rb +13 -2
  14. data/lib/with_advisory_lock/database_adapter_support.rb +10 -3
  15. data/lib/with_advisory_lock/failed_to_acquire_lock.rb +7 -0
  16. data/lib/with_advisory_lock/flock.rb +4 -3
  17. data/lib/with_advisory_lock/mysql.rb +6 -16
  18. data/lib/with_advisory_lock/postgresql.rb +9 -7
  19. data/lib/with_advisory_lock/version.rb +3 -1
  20. data/lib/with_advisory_lock.rb +1 -1
  21. data/test/concern_test.rb +23 -10
  22. data/test/lock_test.rb +61 -28
  23. data/test/nesting_test.rb +14 -46
  24. data/test/options_test.rb +35 -33
  25. data/test/parallelism_test.rb +35 -37
  26. data/test/shared_test.rb +93 -90
  27. data/test/test_helper.rb +52 -0
  28. data/test/test_models.rb +9 -7
  29. data/test/thread_test.rb +23 -22
  30. data/test/transaction_test.rb +34 -36
  31. data/with_advisory_lock.gemspec +24 -23
  32. metadata +27 -41
  33. data/.travis.install-mysql-5.7.sh +0 -11
  34. data/.travis.yml +0 -32
  35. data/gemfiles/activerecord_4.2.gemfile +0 -19
  36. data/gemfiles/activerecord_5.0.gemfile +0 -19
  37. data/lib/with_advisory_lock/nested_advisory_lock_error.rb +0 -14
  38. data/test/database.yml +0 -17
  39. data/test/minitest_helper.rb +0 -40
  40. data/tests.sh +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 82b0119f2158391cace745c0fa71a65497198de1
4
- data.tar.gz: eb7f626ed7db658000ad0db260a2692035ee4dc1
2
+ SHA256:
3
+ metadata.gz: 784812e261b5a57a5d3da8c878e536949245b29372b40b2baf15a52d7c65b854
4
+ data.tar.gz: ba2f6fc8bf78c89d56635c4f56500117f79a443404d3574d8b54b2a45d1811de
5
5
  SHA512:
6
- metadata.gz: efe96bf02dc09cf167ed2058c164405c4f6d6ae9e31442b46d9e9f5ceebc7add1850861d0b6bd311087a056cab5928ad27afa680a4b11884d1474bee4ae25269
7
- data.tar.gz: f9f753d910d24f6cb98fc91a47aed8dcccb82bf99f55ea193aceb8ffedf3c2732eef1c7945c64d1a5ac72aa27d89a0205307ddab72cce7113ca6c37c22496ac9
6
+ metadata.gz: bb7dc11c1f206639943daa363a4d917bfe93792e7db764c7860ef68151e99defaa03f58640fae0480b566e3d4a0697695f5b60ae8af09838bb176979c328d8ae
7
+ data.tar.gz: 10132a0c47ed8070a0661a7b6ae0409be76ef14693be65c12a8e8cdd9c5a506ba25c60bda264f7c60bd92952e4cd4c5513a5e566a3e0d757f0ab6fc4311ffcd5
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: CI
3
+
4
+ on:
5
+ pull_request:
6
+ branches:
7
+ - master
8
+
9
+ jobs:
10
+ minitest:
11
+ runs-on: ubuntu-latest
12
+ services:
13
+ mysql:
14
+ image: mysql/mysql-server:5.7
15
+ ports:
16
+ - "3306:3306"
17
+ env:
18
+ MYSQL_ROOT_PASSWORD: root
19
+ MYSQL_DATABASE: with_advisory_lock_test
20
+ MYSQL_ROOT_HOST: '%'
21
+ postgres:
22
+ image: 'postgres:14-alpine'
23
+ ports: ['5432:5432']
24
+ env:
25
+ POSTGRES_USER: closure_tree
26
+ POSTGRES_PASSWORD: closure_tree
27
+ POSTGRES_DB: with_advisory_lock_test
28
+ options: >-
29
+ --health-cmd pg_isready
30
+ --health-interval 10s
31
+ --health-timeout 5s
32
+ --health-retries 5
33
+
34
+ strategy:
35
+ fail-fast: false
36
+ matrix:
37
+ ruby:
38
+ - '3.2'
39
+ - '3.1'
40
+ - '3.0'
41
+ - '2.7'
42
+ - 'truffleruby'
43
+ rails:
44
+ - activerecord_7.1
45
+ - activerecord_7.0
46
+ - activerecord_6.1
47
+ adapter:
48
+ - sqlite3:///tmp/test.sqlite3
49
+ - mysql2://root:root@0/with_advisory_lock_test
50
+ - trilogy://root:root@0/with_advisory_lock_test
51
+ - postgres://closure_tree:closure_tree@0/with_advisory_lock_test
52
+ include:
53
+ - ruby: jruby
54
+ rails: activerecord_6.1
55
+ adapter: jdbcmysql://root:root@0/with_advisory_lock_test
56
+ - ruby: jruby
57
+ rails: activerecord_6.1
58
+ adapter: jdbcsqlite3:///tmp/test.sqlite3
59
+ - ruby: jruby
60
+ rails: activerecord_6.1
61
+ adapter: jdbcpostgresql://closure_tree:closure_tree@0/with_advisory_lock_test
62
+ steps:
63
+ - name: Checkout
64
+ uses: actions/checkout@v4
65
+
66
+ - name: Setup Ruby
67
+ uses: ruby/setup-ruby@v1
68
+ with:
69
+ ruby-version: ${{ matrix.ruby }}
70
+ bundler-cache: true
71
+ rubygems: latest
72
+ env:
73
+ BUNDLE_GEMFILE: gemfiles/${{ matrix.rails }}.gemfile
74
+
75
+ - name: Test
76
+ env:
77
+ BUNDLE_GEMFILE: gemfiles/${{ matrix.rails }}.gemfile
78
+ DATABASE_URL: ${{ matrix.adapter }}
79
+ WITH_ADVISORY_LOCK_PREFIX: ${{ github.run_id }}
80
+ run: bundle exec rake
data/.gitignore CHANGED
@@ -17,3 +17,6 @@ spec/reports
17
17
  test/tmp
18
18
  test/version_tmp
19
19
  tmp
20
+ *.iml
21
+ test/sqlite.db
22
+ .env
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 3.0.5
data/Appraisals CHANGED
@@ -1,19 +1,45 @@
1
- appraise "activerecord-4.2" do
2
- gem "activerecord", "~> 4.2.0"
1
+ # frozen_string_literal: true
2
+
3
+ appraise 'activerecord-7.1' do
4
+ gem 'activerecord', '~> 7.1.0'
3
5
  platforms :ruby do
4
- gem "pg", "~> 0.21"
5
- gem "mysql2", "< 0.5"
6
+ gem 'sqlite3'
7
+ gem 'mysql2'
8
+ gem 'trilogy'
9
+ gem 'pg'
6
10
  end
7
11
  end
8
12
 
9
- appraise "activerecord-5.0" do
10
- gem "activerecord", "~> 5.0.0"
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
11
27
  end
12
28
 
13
- appraise "activerecord-5.1" do
14
- gem "activerecord", "~> 5.1.0"
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
15
44
  end
16
45
 
17
- appraise "activerecord-5.2" do
18
- gem "activerecord", "~> 5.1.0"
19
- end
data/CHANGELOG.md ADDED
@@ -0,0 +1,131 @@
1
+ ## Changelog
2
+
3
+ ### 5.0.0
4
+ - Drop support for EOL rubies and activerecord (ruby below 2.7 and activerecord below 6.1).
5
+ - Allow lock name to be integer
6
+ - Jruby support
7
+ - Truffleruby support
8
+ - Add `with_advisory_lock!`, which raises an error if the lock acquisition fails
9
+ - Add `disable_query_cache` option to `with_advisory_lock`
10
+ - Drop support for mysql < 5.7.5
11
+
12
+ ### 4.6.0
13
+
14
+ - Support for ActiveRecord 6
15
+ - Add Support for nested locks in MySQL
16
+
17
+ ### 4.0.0
18
+
19
+ - Drop support for unsupported versions of activerecord
20
+ - Drop support for unsupported versions of ruby
21
+
22
+ ### 3.2.0
23
+
24
+ - [Joshua Flanagan](https://github.com/joshuaflanagan) [added a SQL comment to the lock query for PostgreSQL](https://github.com/ClosureTree/with_advisory_lock/pull/28). Thanks!
25
+ - [Fernando Luizão](https://github.com/fernandoluizao) found a spurious requirement for `thread_safe`. Thanks for the [fix](https://github.com/ClosureTree/with_advisory_lock/pull/27)!
26
+
27
+ ### 3.1.1
28
+
29
+ - [Joel Turkel](https://github.com/jturkel) added `require 'active_support'` (it was required, but relied on downstream gems to pull in active_support before pulling in with_advisory_lock). Thanks!
30
+
31
+ ### 3.1.0
32
+
33
+ - [Jason Weathered](https://github.com/jasoncodes) Added new shared and transaction-level lock options ([Pull request 21](https://github.com/ClosureTree/with_advisory_lock/pull/21)). Thanks!
34
+ - Added ActiveRecord 5.0 to build matrix. Dropped 3.2, 4.0, and 4.1 (which no longer get security updates: http://rubyonrails.org/security/)
35
+ - Replaced ruby 1.9 and 2.0 (both EOL) with ruby 2.2 and 2.3 (see https://www.ruby-lang.org/en/downloads/)
36
+
37
+ ### 3.0.0
38
+
39
+ - Added jruby/PostgreSQL support for Rails 4.x
40
+ - Reworked threaded tests to allow jruby tests to pass
41
+
42
+ #### API changes
43
+
44
+ - `yield_with_lock_and_timeout` and `yield_with_lock` now return instances of
45
+ `WithAdvisoryLock::Result`, so blocks that return `false` are not misinterpreted
46
+ as a failure to lock. As this changes the interface (albeit internal methods), the major version
47
+ number was incremented.
48
+ - `with_advisory_lock_result` was introduced, which clarifies whether the lock was acquired
49
+ versus the yielded block returned false.
50
+
51
+ ### 2.0.0
52
+
53
+ - Lock timeouts of 0 now attempt the lock once, as per suggested by
54
+ [Jon Leighton](https://github.com/jonleighton) and implemented by
55
+ [Abdelkader Boudih](https://github.com/seuros). Thanks to both of you!
56
+ - [Pull request 11](https://github.com/ClosureTree/with_advisory_lock/pull/11)
57
+ fixed a downstream issue with jruby support! Thanks, [Aaron Todd](https://github.com/ozzyaaron)!
58
+ - Added Travis tests for jruby
59
+ - Dropped support for Rails 3.0, 3.1, and Ruby 1.8.7, as they are no longer
60
+ receiving security patches. See http://rubyonrails.org/security/ for more information.
61
+ This required the major version bump.
62
+ - Refactored `advisory_lock_exists?` to use existing functionality
63
+ - Fixed sqlite's implementation so parallel tests could be run against it
64
+
65
+ ### 1.0.0
66
+
67
+ - Releasing 1.0.0. The interface will be stable.
68
+ - Added `advisory_lock_exists?`. Thanks, [Sean Devine](https://github.com/barelyknown), for the
69
+ great pull request!
70
+ - Added Travis test for Rails 4.1
71
+
72
+ ### 0.0.10
73
+
74
+ - Explicitly added MIT licensing to the gemspec.
75
+
76
+ ### 0.0.9
77
+
78
+ - Merged in Postgis Adapter Support to address [issue 7](https://github.com/ClosureTree/with_advisory_lock/issues/7)
79
+ Thanks for the pull request, [Abdelkader Boudih](https://github.com/seuros)!
80
+ - The database switching code had to be duplicated by [Closure Tree](https://github.com/ClosureTree/closure_tree),
81
+ so I extracted a new `WithAdvisoryLock::DatabaseAdapterSupport` one-trick pony.
82
+ - Builds were failing on Travis, so I introduced a global lock prefix that can be set with the
83
+ `WITH_ADVISORY_LOCK_PREFIX` environment variable. I'm not going to advertise this feature yet.
84
+ It's a secret. Only you and I know, now. _shhh_
85
+
86
+ ### 0.0.8
87
+
88
+ - Addressed [issue 5](https://github.com/ClosureTree/with_advisory_lock/issues/5) by
89
+ using a deterministic hash for Postgresql + MRI >= 1.9.
90
+ Thanks for the pull request, [Joel Turkel](https://github.com/jturkel)!
91
+ - Addressed [issue 2](https://github.com/ClosureTree/with_advisory_lock/issues/2) by
92
+ using a cache-busting query for MySQL and Postgres to deal with AR value caching bug.
93
+ Thanks for the pull request, [Jaime Giraldo](https://github.com/sposmen)!
94
+ - Addressed [issue 4](https://github.com/ClosureTree/with_advisory_lock/issues/4) by
95
+ adding support for `em-postgresql-adapter`.
96
+ Thanks, [lestercsp](https://github.com/lestercsp)!
97
+
98
+ (Hey, github—your notifications are WAY too easy to ignore!)
99
+
100
+ ### 0.0.7
101
+
102
+ - Added Travis tests for Rails 3.0, 3.1, 3.2, and 4.0
103
+ - Fixed MySQL bug with select_value returning a string instead of an integer when using AR 3.0.x
104
+
105
+ ### 0.0.6
106
+
107
+ - Only require ActiveRecord >= 3.0.x
108
+ - Fixed MySQL error reporting
109
+
110
+ ### 0.0.5
111
+
112
+ - Asking for the currently acquired advisory lock doesn't re-ask for the lock now.
113
+ - Introduced NestedAdvisoryLockError when asking for different, nested advisory locksMySQL
114
+
115
+ ### 0.0.4
116
+
117
+ - Moved require into on_load, which should speed loading when AR doesn't have to spin up
118
+
119
+ ### 0.0.3
120
+
121
+ - Fought with ActiveRecord 3.0.x and 3.1.x. You don't want them if you use threads—they fail
122
+ predictably.
123
+
124
+ ### 0.0.2
125
+
126
+ - Added warning log message for nested MySQL lock calls
127
+ - Randomized lock wait time, which can help ameliorate lock contention
128
+
129
+ ### 0.0.1
130
+
131
+ - First whack
data/Gemfile CHANGED
@@ -1,15 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
-
5
- platforms :ruby do
6
- gem 'mysql2'
7
- gem 'pg'
8
- gem 'sqlite3'
9
- end
10
-
11
- platforms :jruby do
12
- gem 'activerecord-jdbcmysql-adapter'
13
- gem 'activerecord-jdbcpostgresql-adapter'
14
- gem 'activerecord-jdbcsqlite3-adapter'
15
- end
data/README.md CHANGED
@@ -1,22 +1,26 @@
1
1
  # with_advisory_lock
2
2
 
3
- Adds advisory locking (mutexes) to ActiveRecord 4.2 and 5.0, with ruby 2.4, 2.3 or 2.2, when used with
4
- [MySQL](http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_get-lock)
5
- or [PostgreSQL](http://www.postgresql.org/docs/9.3/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS).
3
+ Adds advisory locking (mutexes) to ActiveRecord 6.0+, with ruby 2.7+, jruby or truffleruby, when used with
4
+ [MySQL](https://dev.mysql.com/doc/refman/8.0/en/miscellaneous-functions.html#function_get-lock)
5
+ or
6
+ [PostgreSQL](https://www.postgresql.org/docs/current/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS).
6
7
  SQLite resorts to file locking.
7
8
 
8
- [![Build Status](https://api.travis-ci.org/ClosureTree/with_advisory_lock.svg?branch=master)](http://travis-ci.org/ClosureTree/with_advisory_lock)
9
9
  [![Gem Version](https://badge.fury.io/rb/with_advisory_lock.svg)](https://badge.fury.io/rb/with_advisory_lock)
10
+ [![CI](https://github.com/ClosureTree/with_advisory_lock/actions/workflows/ci.yml/badge.svg)](https://github.com/ClosureTree/with_advisory_lock/actions/workflows/ci.yml)
10
11
 
11
12
  ## What's an "Advisory Lock"?
12
13
 
13
- An advisory lock is a [mutex](http://en.wikipedia.org/wiki/Mutual_exclusion) used to ensure no two
14
- processes run some process at the same time. When the advisory lock is powered by your database
15
- server, as long as it isn't SQLite, your mutex spans hosts.
14
+ An advisory lock is a [mutex](https://en.wikipedia.org/wiki/Mutual_exclusion)
15
+ used to ensure no two processes run some process at the same time. When the
16
+ advisory lock is powered by your database server, as long as it isn't SQLite,
17
+ your mutex spans hosts.
16
18
 
17
19
  ## Usage
18
20
 
19
- Where ```User``` is an ActiveRecord model, and ```lock_name``` is some string:
21
+ This gem automatically includes the `WithAdvisoryLock` module in all of your
22
+ ActiveRecord models. Here's an example of how to use it where `User` is an
23
+ ActiveRecord model, and `lock_name` is some string:
20
24
 
21
25
  ```ruby
22
26
  User.with_advisory_lock(lock_name) do
@@ -32,58 +36,77 @@ end
32
36
 
33
37
  ### Lock wait timeouts
34
38
 
35
- ```with_advisory_lock``` takes an options hash as the second parameter.
36
- The ```timeout_seconds``` option defaults to ```nil```, which means wait indefinitely for the lock.
39
+ `with_advisory_lock` takes an options hash as the second parameter. The
40
+ `timeout_seconds` option defaults to `nil`, which means wait indefinitely for
41
+ the lock.
37
42
 
38
43
  A value of zero will try the lock only once. If the lock is acquired, the block
39
- will be yielded to. If the lock is currently being held, the block will not be called.
44
+ will be yielded to. If the lock is currently being held, the block will not be
45
+ called.
40
46
 
41
- Note that if a non-nil value is provided for `timeout_seconds`, the block will not be invoked if
42
- the lock cannot be acquired within that time-frame.
47
+ > **Note**
48
+ >
49
+ > If a non-nil value is provided for `timeout_seconds`, the block will
50
+ *not* be invoked if the lock cannot be acquired within that time-frame. In this case, `with_advisory_lock` will return `false`, while `with_advisory_lock!` will raise a `WithAdvisoryLock::FailedToAcquireLock` error.
43
51
 
44
- For backwards compatability, the timeout value can be specified directly as the second parameter.
52
+ For backwards compatability, the timeout value can be specified directly as the
53
+ second parameter.
45
54
 
46
55
  ### Shared locks
47
56
 
48
- The ```shared``` option defaults to ```false``` which means an exclusive lock will be obtained.
49
- Setting ```shared``` to ```true``` will allow locks to be obtained by multiple actors
50
- as long as they are all shared locks.
57
+ The `shared` option defaults to `false` which means an exclusive lock will be
58
+ obtained. Setting `shared` to `true` will allow locks to be obtained by multiple
59
+ actors as long as they are all shared locks.
51
60
 
52
61
  Note: MySQL does not support shared locks.
53
62
 
54
63
  ### Transaction-level locks
55
64
 
56
- PostgreSQL supports transaction-level locks which remain held until the transaction completes.
57
- You can enable this by setting the ```transaction``` option to ```true```.
65
+ PostgreSQL supports transaction-level locks which remain held until the
66
+ transaction completes. You can enable this by setting the `transaction` option
67
+ to `true`.
58
68
 
59
- Note: transaction-level locks will not be reflected by `.current_advisory_lock` when the block has returned.
69
+ Note: transaction-level locks will not be reflected by `.current_advisory_lock`
70
+ when the block has returned.
60
71
 
61
72
  ### Return values
62
73
 
63
- The return value of `with_advisory_lock_result` is a `WithAdvisoryLock::Result` instance,
64
- which has a `lock_was_acquired?` method and a `result` accessor method, which is
65
- the returned value of the given block. If your block may validly return false, you should use
66
- this method.
67
-
68
- The return value of ```with_advisory_lock``` will be the result of the yielded block,
69
- if the lock was able to be acquired and the block yielded, or ```false```, if you provided
70
- a timeout_seconds value and the lock was not able to be acquired in time.
74
+ The return value of `with_advisory_lock_result` is a `WithAdvisoryLock::Result`
75
+ instance, which has a `lock_was_acquired?` method and a `result` accessor
76
+ method, which is the returned value of the given block. If your block may
77
+ validly return false, you should use this method.
78
+
79
+ The return value of `with_advisory_lock` will be the result of the yielded
80
+ block, if the lock was able to be acquired and the block yielded, or `false`, if
81
+ you provided a timeout_seconds value and the lock was not able to be acquired in
82
+ time.
83
+
84
+ `with_advisory_lock!` is similar to `with_advisory_lock`, but raises a `WithAdvisoryLock::FailedToAcquireLock` error if the lock was not able to be acquired in time.
71
85
 
72
86
  ### Testing for the current lock status
73
87
 
74
- If you needed to check if the advisory lock is currently being held, you can call
75
- ```Tag.advisory_lock_exists?("foo")```, but realize the lock can be acquired between the time you
76
- test for the lock, and the time you try to acquire the lock.
88
+ If you needed to check if the advisory lock is currently being held, you can
89
+ call `Tag.advisory_lock_exists?("foo")`, but realize the lock can be acquired
90
+ between the time you test for the lock, and the time you try to acquire the
91
+ lock.
92
+
93
+ If you want to see if the current Thread is holding a lock, you can call
94
+ `Tag.current_advisory_lock` which will return the name of the current lock. If
95
+ no lock is currently held, `.current_advisory_lock` returns `nil`.
77
96
 
78
- If you want to see if the current Thread is holding a lock, you can call ```Tag.current_advisory_lock```
79
- which will return the name of the current lock. If no lock is currently held,
80
- ```.current_advisory_lock``` returns ```nil```.
97
+ ### ActiveRecord Query Cache
98
+
99
+ You can optionally pass `disable_query_cache: true` to the options hash of
100
+ `with_advisory_lock` in order to disable ActiveRecord's query cache. This can
101
+ prevent problems when you query the database from within the lock and it returns
102
+ stale results. More info on why this can be a problem can be
103
+ [found here](https://github.com/ClosureTree/with_advisory_lock/issues/52)
81
104
 
82
105
  ## Installation
83
106
 
84
107
  Add this line to your application's Gemfile:
85
108
 
86
- ``` ruby
109
+ ```ruby
87
110
  gem 'with_advisory_lock'
88
111
  ```
89
112
 
@@ -93,27 +116,31 @@ And then execute:
93
116
 
94
117
  ## Lock Types
95
118
 
96
- First off, know that there are **lots** of different kinds of locks available to you. **Pick the
97
- finest-grain lock that ensures correctness.** If you choose a lock that is too coarse, you are
98
- unnecessarily blocking other processes.
119
+ First off, know that there are **lots** of different kinds of locks available to
120
+ you. **Pick the finest-grain lock that ensures correctness.** If you choose a
121
+ lock that is too coarse, you are unnecessarily blocking other processes.
99
122
 
100
123
  ### Advisory locks
101
- These are named mutexes that are inherently "application level"—it is up to the application
102
- to acquire, run a critical code section, and release the advisory lock.
124
+
125
+ These are named mutexes that are inherently "application level"—it is up to the
126
+ application to acquire, run a critical code section, and release the advisory
127
+ lock.
103
128
 
104
129
  ### Row-level locks
130
+
105
131
  Whether [optimistic](http://api.rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html)
106
132
  or [pessimistic](http://api.rubyonrails.org/classes/ActiveRecord/Locking/Pessimistic.html),
107
133
  row-level locks prevent concurrent modification to a given model.
108
134
 
109
135
  **If you're building a
110
- [CRUD](http://en.wikipedia.org/wiki/Create,_read,_update_and_delete) application, this will be your
111
- most commonly used lock.**
136
+ [CRUD](http://en.wikipedia.org/wiki/Create,_read,_update_and_delete)
137
+ application, this will be 2.4, 2.5 and your most commonly used lock.**
112
138
 
113
139
  ### Table-level locks
114
140
 
115
- Provided through something like the [monogamy](https://github.com/ClosureTree/monogamy)
116
- gem, these prevent concurrent access to **any instance of a model**. Their coarseness means they
141
+ Provided through something like the
142
+ [monogamy](https://github.com/ClosureTree/monogamy) gem, these prevent
143
+ concurrent access to **any instance of a model**. Their coarseness means they
117
144
  aren't going to be commonly applicable, and they can be a source of
118
145
  [deadlocks](http://en.wikipedia.org/wiki/Deadlock).
119
146
 
@@ -125,26 +152,31 @@ Advisory locks with MySQL and PostgreSQL ignore database transaction boundaries.
125
152
 
126
153
  You will want to wrap your block within a transaction to ensure consistency.
127
154
 
128
- ### MySQL doesn't support nesting
155
+ ### MySQL < 5.7.5 doesn't support nesting
156
+
157
+ With MySQL < 5.7.5, if you ask for a _different_ advisory lock within
158
+ a `with_advisory_lock` block, you will be releasing the parent lock (!!!). A
159
+ `NestedAdvisoryLockError`will be raised in this case. If you ask for the same
160
+ lock name, `with_advisory_lock` won't ask for the lock again, and the block
161
+ given will be yielded to.
129
162
 
130
- With MySQL (at least <= v5.5), if you ask for a *different* advisory lock within a ```with_advisory_lock``` block,
131
- you will be releasing the parent lock (!!!). A ```NestedAdvisoryLockError```will be raised
132
- in this case. If you ask for the same lock name, ```with_advisory_lock``` won't ask for the
133
- lock again, and the block given will be yielded to.
163
+ This is not an issue in MySQL >= 5.7.5, and no error will be raised for nested
164
+ lock usage. You can override this by passing `force_nested_lock_support: true`
165
+ or `force_nested_lock_support: false` to the `with_advisory_lock` options.
134
166
 
135
167
  ### Is clustered MySQL supported?
136
168
 
137
169
  [No.](https://github.com/ClosureTree/with_advisory_lock/issues/16)
138
170
 
139
- ### There are many ```lock-*``` files in my project directory after test runs
171
+ ### There are many `lock-*` files in my project directory after test runs
140
172
 
141
173
  This is expected if you aren't using MySQL or Postgresql for your tests.
142
174
  See [issue 3](https://github.com/ClosureTree/with_advisory_lock/issues/3).
143
175
 
144
- SQLite doesn't have advisory locks, so we resort to file locking, which will only work
145
- if the ```FLOCK_DIR``` is set consistently for all ruby processes.
176
+ SQLite doesn't have advisory locks, so we resort to file locking, which will
177
+ only work if the `FLOCK_DIR` is set consistently for all ruby processes.
146
178
 
147
- In your ```spec_helper.rb``` or ```minitest_helper.rb```, add a ```before``` and ```after``` block:
179
+ In your `spec_helper.rb` or `minitest_helper.rb`, add a `before` and `after` block:
148
180
 
149
181
  ```ruby
150
182
  before do
@@ -155,121 +187,3 @@ after do
155
187
  FileUtils.remove_entry_secure ENV['FLOCK_DIR']
156
188
  end
157
189
  ```
158
-
159
- ## Changelog
160
-
161
- ### 4.0.0
162
-
163
- * Drop support for unsupported versions of activerecord
164
- * Drop support for unsupported versions of ruby
165
-
166
- ### 3.2.0
167
-
168
- * [Joshua Flanagan](https://github.com/joshuaflanagan) [added a SQL comment to the lock query for PostgreSQL](https://github.com/ClosureTree/with_advisory_lock/pull/28). Thanks!
169
- * [Fernando Luizão](https://github.com/fernandoluizao) found a spurious requirement for `thread_safe`. Thanks for the [fix](https://github.com/ClosureTree/with_advisory_lock/pull/27)!
170
-
171
- ### 3.1.1
172
-
173
- * [Joel Turkel](https://github.com/jturkel) added `require 'active_support'` (it was required, but relied on downstream gems to pull in active_support before pulling in with_advisory_lock). Thanks!
174
-
175
- ### 3.1.0
176
-
177
- * [Jason Weathered](https://github.com/jasoncodes) Added new shared and transaction-level lock options ([Pull request 21](https://github.com/ClosureTree/with_advisory_lock/pull/21)). Thanks!
178
- * Added ActiveRecord 5.0 to build matrix. Dropped 3.2, 4.0, and 4.1 (which no longer get security updates: http://rubyonrails.org/security/)
179
- * Replaced ruby 1.9 and 2.0 (both EOL) with ruby 2.2 and 2.3 (see https://www.ruby-lang.org/en/downloads/)
180
-
181
- ### 3.0.0
182
-
183
- * Added jruby/PostgreSQL support for Rails 4.x
184
- * Reworked threaded tests to allow jruby tests to pass
185
-
186
- #### API changes
187
-
188
- * `yield_with_lock_and_timeout` and `yield_with_lock` now return instances of
189
- `WithAdvisoryLock::Result`, so blocks that return `false` are not misinterpreted
190
- as a failure to lock. As this changes the interface (albeit internal methods), the major version
191
- number was incremented.
192
- * `with_advisory_lock_result` was introduced, which clarifies whether the lock was acquired
193
- versus the yielded block returned false.
194
-
195
- ### 2.0.0
196
-
197
- * Lock timeouts of 0 now attempt the lock once, as per suggested by
198
- [Jon Leighton](https://github.com/jonleighton) and implemented by
199
- [Abdelkader Boudih](https://github.com/seuros). Thanks to both of you!
200
- * [Pull request 11](https://github.com/ClosureTree/with_advisory_lock/pull/11)
201
- fixed a downstream issue with jruby support! Thanks, [Aaron Todd](https://github.com/ozzyaaron)!
202
- * Added Travis tests for jruby
203
- * Dropped support for Rails 3.0, 3.1, and Ruby 1.8.7, as they are no longer
204
- receiving security patches. See http://rubyonrails.org/security/ for more information.
205
- This required the major version bump.
206
- * Refactored `advisory_lock_exists?` to use existing functionality
207
- * Fixed sqlite's implementation so parallel tests could be run against it
208
-
209
- ### 1.0.0
210
-
211
- * Releasing 1.0.0. The interface will be stable.
212
- * Added ```advisory_lock_exists?```. Thanks, [Sean Devine](https://github.com/barelyknown), for the
213
- great pull request!
214
- * Added Travis test for Rails 4.1
215
-
216
- ### 0.0.10
217
-
218
- * Explicitly added MIT licensing to the gemspec.
219
-
220
- ### 0.0.9
221
-
222
- * Merged in Postgis Adapter Support to address [issue 7](https://github.com/ClosureTree/with_advisory_lock/issues/7)
223
- Thanks for the pull request, [Abdelkader Boudih](https://github.com/seuros)!
224
- * The database switching code had to be duplicated by [Closure Tree](https://github.com/ClosureTree/closure_tree),
225
- so I extracted a new ```WithAdvisoryLock::DatabaseAdapterSupport``` one-trick pony.
226
- * Builds were failing on Travis, so I introduced a global lock prefix that can be set with the
227
- ```WITH_ADVISORY_LOCK_PREFIX``` environment variable. I'm not going to advertise this feature yet.
228
- It's a secret. Only you and I know, now. *shhh*
229
-
230
- ### 0.0.8
231
-
232
- * Addressed [issue 5](https://github.com/ClosureTree/with_advisory_lock/issues/5) by
233
- using a deterministic hash for Postgresql + MRI >= 1.9.
234
- Thanks for the pull request, [Joel Turkel](https://github.com/jturkel)!
235
- * Addressed [issue 2](https://github.com/ClosureTree/with_advisory_lock/issues/2) by
236
- using a cache-busting query for MySQL and Postgres to deal with AR value caching bug.
237
- Thanks for the pull request, [Jaime Giraldo](https://github.com/sposmen)!
238
- * Addressed [issue 4](https://github.com/ClosureTree/with_advisory_lock/issues/4) by
239
- adding support for ```em-postgresql-adapter```.
240
- Thanks, [lestercsp](https://github.com/lestercsp)!
241
-
242
- (Hey, github—your notifications are WAY too easy to ignore!)
243
-
244
- ### 0.0.7
245
-
246
- * Added Travis tests for Rails 3.0, 3.1, 3.2, and 4.0
247
- * Fixed MySQL bug with select_value returning a string instead of an integer when using AR 3.0.x
248
-
249
- ### 0.0.6
250
-
251
- * Only require ActiveRecord >= 3.0.x
252
- * Fixed MySQL error reporting
253
-
254
- ### 0.0.5
255
-
256
- * Asking for the currently acquired advisory lock doesn't re-ask for the lock now.
257
- * Introduced NestedAdvisoryLockError when asking for different, nested advisory locksMySQL
258
-
259
- ### 0.0.4
260
-
261
- * Moved require into on_load, which should speed loading when AR doesn't have to spin up
262
-
263
- ### 0.0.3
264
-
265
- * Fought with ActiveRecord 3.0.x and 3.1.x. You don't want them if you use threads—they fail
266
- predictably.
267
-
268
- ### 0.0.2
269
-
270
- * Added warning log message for nested MySQL lock calls
271
- * Randomized lock wait time, which can help ameliorate lock contention
272
-
273
- ### 0.0.1
274
-
275
- * First whack
@@ -2,12 +2,14 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", "~> 5.1.0"
5
+ gem "activerecord", "~> 6.1.0"
6
6
 
7
7
  platforms :ruby do
8
+ gem "sqlite3"
8
9
  gem "mysql2"
10
+ gem "trilogy"
11
+ gem "activerecord-trilogy-adapter"
9
12
  gem "pg"
10
- gem "sqlite3"
11
13
  end
12
14
 
13
15
  platforms :jruby do