with_advisory_lock 7.0.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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f594bf1ed9b20028febee227bd33eddf70f2c3deb42ae7e8a4d83d794125281d
|
4
|
+
data.tar.gz: 6882cea1e84d517bdf847b8f66b7dd6bb7b6c93de09c156b459019aab324ace0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a89eff2b9fccadd2f64ac7467c9daf19156fbac5196358b9ce7089c2d743c353e4fbb8b993d2c0440b0f253c78a56620a603cd9d41dd0e3f027e02b5f901f72c
|
7
|
+
data.tar.gz: 02b5903b081175e8f7ce07450738fd88d8f0f92dfc52fbb6901e9738aa90312313c3313c70ccfcdab998aa799399a173215edf913145b72d56958042681fb4e6
|
@@ -1 +1 @@
|
|
1
|
-
{".":"7.0.
|
1
|
+
{".":"7.0.1"}
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
## Changelog
|
2
2
|
|
3
|
+
## [7.0.1](https://github.com/ClosureTree/with_advisory_lock/compare/with_advisory_lock/v7.0.0...with_advisory_lock/v7.0.1) (2025-07-21)
|
4
|
+
|
5
|
+
|
6
|
+
### Bug Fixes
|
7
|
+
|
8
|
+
* handle ActiveRecord's release_advisory_lock signature for Rails 7.2+ ([#127](https://github.com/ClosureTree/with_advisory_lock/issues/127)) ([94253ca](https://github.com/ClosureTree/with_advisory_lock/commit/94253ca2af7f684a3c99645765853546c3da8e02)), closes [#126](https://github.com/ClosureTree/with_advisory_lock/issues/126)
|
9
|
+
|
3
10
|
## [7.0.0](https://github.com/ClosureTree/with_advisory_lock/compare/with_advisory_lock/v6.0.0...with_advisory_lock/v7.0.0) (2025-07-05)
|
4
11
|
|
5
12
|
|
@@ -25,8 +25,17 @@ module WithAdvisoryLock
|
|
25
25
|
execute_successful?("GET_LOCK(#{quote(lock_keys.first)}, #{mysql_timeout})")
|
26
26
|
end
|
27
27
|
|
28
|
-
def release_advisory_lock(
|
29
|
-
|
28
|
+
def release_advisory_lock(*args, **kwargs)
|
29
|
+
# Handle both signatures - ActiveRecord's built-in and ours
|
30
|
+
if args.length == 1 && kwargs.empty?
|
31
|
+
# ActiveRecord's signature: release_advisory_lock(lock_id)
|
32
|
+
# Called by Rails migrations with a single positional argument
|
33
|
+
super
|
34
|
+
else
|
35
|
+
# Our signature: release_advisory_lock(lock_keys, lock_name:, **)
|
36
|
+
lock_keys = args.first
|
37
|
+
execute_successful?("RELEASE_LOCK(#{quote(lock_keys.first)})")
|
38
|
+
end
|
30
39
|
rescue ActiveRecord::StatementInvalid => e
|
31
40
|
# If the connection is broken, the lock is automatically released by MySQL
|
32
41
|
# No need to fail the release operation
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class MySQLReleaseLockTest < GemTestCase
|
6
|
+
self.use_transactional_tests = false
|
7
|
+
|
8
|
+
def model_class
|
9
|
+
MysqlTag
|
10
|
+
end
|
11
|
+
|
12
|
+
def setup
|
13
|
+
super
|
14
|
+
begin
|
15
|
+
skip unless model_class.connection.adapter_name =~ /mysql/i
|
16
|
+
MysqlTag.delete_all
|
17
|
+
rescue ActiveRecord::NoDatabaseError
|
18
|
+
skip "MySQL database not available. Please create the database first."
|
19
|
+
rescue StandardError => e
|
20
|
+
skip "MySQL connection failed: #{e.message}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
test 'release_advisory_lock handles gem signature with lock_keys' do
|
25
|
+
lock_name = 'test_gem_signature'
|
26
|
+
lock_keys = model_class.connection.lock_keys_for(lock_name)
|
27
|
+
|
28
|
+
# Acquire the lock
|
29
|
+
result = model_class.connection.try_advisory_lock(
|
30
|
+
lock_keys,
|
31
|
+
lock_name: lock_name,
|
32
|
+
shared: false,
|
33
|
+
transaction: false
|
34
|
+
)
|
35
|
+
assert result, 'Failed to acquire lock'
|
36
|
+
|
37
|
+
# Release using gem signature
|
38
|
+
released = model_class.connection.release_advisory_lock(
|
39
|
+
lock_keys,
|
40
|
+
lock_name: lock_name,
|
41
|
+
shared: false,
|
42
|
+
transaction: false
|
43
|
+
)
|
44
|
+
assert released, 'Failed to release lock using gem signature'
|
45
|
+
|
46
|
+
# Verify lock is released by trying to acquire it again
|
47
|
+
result = model_class.connection.try_advisory_lock(
|
48
|
+
lock_keys,
|
49
|
+
lock_name: lock_name,
|
50
|
+
shared: false,
|
51
|
+
transaction: false
|
52
|
+
)
|
53
|
+
assert result, 'Lock was not properly released'
|
54
|
+
|
55
|
+
# Clean up
|
56
|
+
model_class.connection.release_advisory_lock(
|
57
|
+
lock_keys,
|
58
|
+
lock_name: lock_name,
|
59
|
+
shared: false,
|
60
|
+
transaction: false
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
test 'release_advisory_lock handles ActiveRecord signature' do
|
65
|
+
# Rails calls release_advisory_lock with a positional argument (lock_id)
|
66
|
+
# This test ensures our override doesn't break Rails' migration locking
|
67
|
+
|
68
|
+
lock_name = 'test_rails_signature'
|
69
|
+
|
70
|
+
# Acquire lock using SQL (ActiveRecord doesn't provide get_advisory_lock method)
|
71
|
+
lock_keys = model_class.connection.lock_keys_for(lock_name)
|
72
|
+
result = model_class.connection.select_value("SELECT GET_LOCK(#{model_class.connection.quote(lock_keys.first)}, 0)")
|
73
|
+
assert_equal 1, result, 'Failed to acquire lock using SQL'
|
74
|
+
|
75
|
+
# Release using ActiveRecord signature (positional argument, as Rails does)
|
76
|
+
released = model_class.connection.release_advisory_lock(lock_keys.first)
|
77
|
+
assert released, 'Failed to release lock using ActiveRecord signature'
|
78
|
+
|
79
|
+
# Verify lock is released
|
80
|
+
lock_keys = model_class.connection.lock_keys_for(lock_name)
|
81
|
+
result = model_class.connection.select_value("SELECT GET_LOCK(#{model_class.connection.quote(lock_keys.first)}, 0)")
|
82
|
+
assert_equal 1, result, 'Lock was not properly released'
|
83
|
+
|
84
|
+
# Clean up
|
85
|
+
model_class.connection.select_value("SELECT RELEASE_LOCK(#{model_class.connection.quote(lock_keys.first)})")
|
86
|
+
end
|
87
|
+
|
88
|
+
test 'release_advisory_lock handles connection errors gracefully' do
|
89
|
+
lock_name = 'test_connection_error'
|
90
|
+
lock_keys = model_class.connection.lock_keys_for(lock_name)
|
91
|
+
|
92
|
+
# Acquire the lock
|
93
|
+
result = model_class.connection.try_advisory_lock(
|
94
|
+
lock_keys,
|
95
|
+
lock_name: lock_name,
|
96
|
+
shared: false,
|
97
|
+
transaction: false
|
98
|
+
)
|
99
|
+
assert result, 'Failed to acquire lock'
|
100
|
+
|
101
|
+
# Simulate connection error handling
|
102
|
+
# The method should handle various connection error types without raising
|
103
|
+
begin
|
104
|
+
# Try to release - even if we can't simulate a real connection error,
|
105
|
+
# the code path exists and should work
|
106
|
+
model_class.connection.release_advisory_lock(
|
107
|
+
lock_keys,
|
108
|
+
lock_name: lock_name,
|
109
|
+
shared: false,
|
110
|
+
transaction: false
|
111
|
+
)
|
112
|
+
rescue StandardError => e
|
113
|
+
# Should not raise connection-related errors
|
114
|
+
refute_match(/Lost connection|MySQL server has gone away|Connection refused/i, e.message)
|
115
|
+
raise
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
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: 7.0.
|
4
|
+
version: 7.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew McEachen
|
@@ -157,6 +157,7 @@ files:
|
|
157
157
|
- test/with_advisory_lock/concern_test.rb
|
158
158
|
- test/with_advisory_lock/lock_test.rb
|
159
159
|
- test/with_advisory_lock/multi_adapter_test.rb
|
160
|
+
- test/with_advisory_lock/mysql_release_lock_test.rb
|
160
161
|
- test/with_advisory_lock/parallelism_test.rb
|
161
162
|
- test/with_advisory_lock/postgresql_race_condition_test.rb
|
162
163
|
- test/with_advisory_lock/shared_test.rb
|