active_record_mutex 2.2.1 → 2.3.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/README.md +0 -7
- data/VERSION +1 -1
- data/active_record_mutex.gemspec +3 -3
- data/lib/active_record/database_mutex/implementation.rb +50 -11
- data/lib/active_record/database_mutex/version.rb +1 -1
- data/lib/active_record/database_mutex.rb +2 -0
- data/test/database_mutex_test.rb +19 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 82a2b14490ab51a0627c72260226d1742b1c0441
|
4
|
+
data.tar.gz: c487aa29472b77887e5dec81cd7f624676091d4a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52337abd846212ae910f0d66ba99b39e35e02ad55a540e952dcbee8f195ec4c74d5dbc5f507d2f3dfa9e8b1189c6ba4e245805015893f561fdcd8c1eea4ca8fc
|
7
|
+
data.tar.gz: cbaceacb0cb2e06fef1b1d4a89b5940400e2a06213d7ab031f22f5151087357d0f5e8e092b9acdff49de08a8b133a8647ee064f8b9dea0fafbb82b8b85f9e4f8
|
data/README.md
CHANGED
@@ -40,13 +40,6 @@ create Mutex instance like this:
|
|
40
40
|
|
41
41
|
Now you can send all messages directly to the Mutex instance.
|
42
42
|
|
43
|
-
## Changes
|
44
|
-
|
45
|
-
* 2016-08-19 Make locks rails environments independent
|
46
|
-
* 2014-12-12 Release 2.0.0
|
47
|
-
* 2014-12-12 Add license information
|
48
|
-
* 2014-12-09 Adapt to newer Rails versions' API
|
49
|
-
|
50
43
|
## Download
|
51
44
|
|
52
45
|
The homepage of this library is located at
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.3.0
|
data/active_record_mutex.gemspec
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: active_record_mutex 2.
|
2
|
+
# stub: active_record_mutex 2.3.0 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "active_record_mutex"
|
6
|
-
s.version = "2.
|
6
|
+
s.version = "2.3.0"
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
9
9
|
s.require_paths = ["lib"]
|
10
10
|
s.authors = ["Florian Frank"]
|
11
|
-
s.date = "2016-08-
|
11
|
+
s.date = "2016-08-23"
|
12
12
|
s.description = "Mutex that can be used to synchronise ruby processes via an ActiveRecord datababase connection. (Only Mysql is supported at the moment.)"
|
13
13
|
s.email = "flori@ping.de"
|
14
14
|
s.extra_rdoc_files = ["README.md", "lib/active_record/database_mutex.rb", "lib/active_record/database_mutex/implementation.rb", "lib/active_record/database_mutex/version.rb", "lib/active_record/mutex.rb", "lib/active_record_mutex.rb"]
|
@@ -29,7 +29,7 @@ module ActiveRecord
|
|
29
29
|
rescue ActiveRecord::DatabaseMutex::MutexLocked
|
30
30
|
return nil
|
31
31
|
ensure
|
32
|
-
locked
|
32
|
+
locked and unlock
|
33
33
|
end
|
34
34
|
|
35
35
|
# Locks the mutex and returns true if successful. If the mutex is
|
@@ -58,9 +58,18 @@ module ActiveRecord
|
|
58
58
|
# Unlocks the mutex and returns true if successful. Otherwise this method
|
59
59
|
# raises a MutexLocked exception.
|
60
60
|
def unlock(*)
|
61
|
-
|
62
|
-
|
63
|
-
|
61
|
+
if aquired_lock?
|
62
|
+
decrease_counter
|
63
|
+
if counter_zero?
|
64
|
+
case query("SELECT RELEASE_LOCK(#{quote(name)})")
|
65
|
+
when 1
|
66
|
+
true
|
67
|
+
when 0, nil
|
68
|
+
raise MutexUnlockFailed, "unlocking of mutex '#{name}' failed"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
else
|
72
|
+
raise MutexUnlockFailed, "unlocking of mutex '#{name}' failed"
|
64
73
|
end
|
65
74
|
end
|
66
75
|
|
@@ -75,7 +84,7 @@ module ActiveRecord
|
|
75
84
|
|
76
85
|
# Returns true if this mutex is unlocked at the moment.
|
77
86
|
def unlocked?
|
78
|
-
query("SELECT IS_FREE_LOCK(#{
|
87
|
+
query("SELECT IS_FREE_LOCK(#{quote(name)})") == 1
|
79
88
|
end
|
80
89
|
|
81
90
|
# Returns true if this mutex is locked at the moment.
|
@@ -85,7 +94,7 @@ module ActiveRecord
|
|
85
94
|
|
86
95
|
# Returns true if this mutex is locked by this database connection.
|
87
96
|
def aquired_lock?
|
88
|
-
query("SELECT CONNECTION_ID() = IS_USED_LOCK(#{
|
97
|
+
query("SELECT CONNECTION_ID() = IS_USED_LOCK(#{quote(name)})") == 1
|
89
98
|
end
|
90
99
|
|
91
100
|
# Returns true if this mutex is not locked by this database connection.
|
@@ -102,15 +111,45 @@ module ActiveRecord
|
|
102
111
|
|
103
112
|
private
|
104
113
|
|
105
|
-
def
|
114
|
+
def quote(value)
|
106
115
|
ActiveRecord::Base.connection.quote(value)
|
107
116
|
end
|
108
117
|
|
118
|
+
def counter
|
119
|
+
"@#{name}_mutex_counter"
|
120
|
+
end
|
121
|
+
|
122
|
+
def increase_counter
|
123
|
+
query("SET #{counter} = IF(#{counter} IS NULL OR #{counter} = 0, 1, #{counter} + 1)")
|
124
|
+
end
|
125
|
+
|
126
|
+
def decrease_counter
|
127
|
+
query("SET #{counter} = #{counter} - 1")
|
128
|
+
end
|
129
|
+
|
130
|
+
def counter_value
|
131
|
+
query("SELECT #{counter}").to_i
|
132
|
+
end
|
133
|
+
|
134
|
+
def counter_zero?
|
135
|
+
counter_value.zero?
|
136
|
+
end
|
137
|
+
|
109
138
|
def lock_with_timeout(opts = {})
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
139
|
+
if aquired_lock?
|
140
|
+
increase_counter
|
141
|
+
true
|
142
|
+
else
|
143
|
+
timeout = opts[:timeout] || 1
|
144
|
+
case query("SELECT GET_LOCK(#{quote(name)}, #{timeout})")
|
145
|
+
when 1
|
146
|
+
increase_counter
|
147
|
+
true
|
148
|
+
when 0
|
149
|
+
raise MutexLocked, "mutex '#{name}' is already locked"
|
150
|
+
when nil
|
151
|
+
raise MutexSystemError, "mutex '#{name}' not locked due to system error"
|
152
|
+
end
|
114
153
|
end
|
115
154
|
end
|
116
155
|
|
data/test/database_mutex_test.rb
CHANGED
@@ -65,30 +65,39 @@ class DatabaseMutexTest < Test::Unit::TestCase
|
|
65
65
|
def test_lock
|
66
66
|
mutex = Implementation.new(:name => 'Lock')
|
67
67
|
assert mutex.unlocked?
|
68
|
+
assert_equal 0, mutex.send(:counter_value)
|
68
69
|
assert mutex.lock
|
69
70
|
assert mutex.locked?
|
70
71
|
assert mutex.aquired_lock?
|
72
|
+
assert_equal 1, mutex.send(:counter_value)
|
71
73
|
assert mutex.lock
|
74
|
+
assert_equal 2, mutex.send(:counter_value)
|
72
75
|
end
|
73
76
|
|
74
77
|
def test_unlock
|
75
78
|
mutex = Implementation.new(:name => 'Unlock')
|
76
79
|
assert_raises(ActiveRecord::DatabaseMutex::MutexUnlockFailed) { mutex.unlock }
|
80
|
+
assert_equal 0, mutex.send(:counter_value)
|
77
81
|
assert mutex.lock
|
78
82
|
assert mutex.locked?
|
79
83
|
assert mutex.aquired_lock?
|
84
|
+
assert_equal 1, mutex.send(:counter_value)
|
80
85
|
assert mutex.unlock
|
81
86
|
assert mutex.unlocked?
|
87
|
+
assert_equal 0, mutex.send(:counter_value)
|
82
88
|
assert_raises(ActiveRecord::DatabaseMutex::MutexUnlockFailed) { mutex.unlock }
|
83
89
|
end
|
84
90
|
|
85
91
|
def test_synchronize
|
86
92
|
mutex = Implementation.new(:name => 'Sync1')
|
87
93
|
assert mutex.unlocked?
|
94
|
+
assert_equal 0, mutex.send(:counter_value)
|
88
95
|
mutex.synchronize do
|
89
96
|
assert mutex.locked?
|
97
|
+
assert_equal 1, mutex.send(:counter_value)
|
90
98
|
end
|
91
99
|
assert mutex.unlocked?
|
100
|
+
assert_equal 0, mutex.send(:counter_value)
|
92
101
|
end
|
93
102
|
|
94
103
|
def test_synchronize_exception
|
@@ -110,14 +119,24 @@ class DatabaseMutexTest < Test::Unit::TestCase
|
|
110
119
|
def test_synchronize_nested
|
111
120
|
mutex = Implementation.new(:name => 'Sync3')
|
112
121
|
assert mutex.unlocked?
|
122
|
+
assert mutex.send(:counter_zero?)
|
123
|
+
assert_equal 0, mutex.send(:counter_value)
|
113
124
|
mutex.synchronize do
|
114
125
|
assert mutex.locked?
|
126
|
+
assert !mutex.send(:counter_zero?)
|
127
|
+
assert_equal 1, mutex.send(:counter_value)
|
115
128
|
mutex.synchronize do
|
116
129
|
assert mutex.locked?
|
130
|
+
assert !mutex.send(:counter_zero?)
|
131
|
+
assert_equal 2, mutex.send(:counter_value)
|
117
132
|
end
|
118
133
|
assert mutex.locked?
|
134
|
+
assert !mutex.send(:counter_zero?)
|
135
|
+
assert_equal 1, mutex.send(:counter_value)
|
119
136
|
end
|
120
137
|
assert mutex.unlocked?
|
138
|
+
assert mutex.send(:counter_zero?)
|
139
|
+
assert_equal 0, mutex.send(:counter_value)
|
121
140
|
end
|
122
141
|
|
123
142
|
def test_synchronize_already_locked
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_record_mutex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Florian Frank
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gem_hadar
|