distributed_mutex 1.0.2 → 1.1.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.
- data/VERSION +1 -1
- data/lib/distributed_mutex.rb +5 -3
- data/lib/mutex_lock_release_failure.rb +6 -0
- data/lib/mysql_mutex.rb +62 -16
- metadata +4 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0
|
1
|
+
1.1.0
|
data/lib/distributed_mutex.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'mutex_lock_timeout'
|
2
|
+
require 'mutex_lock_release_failure'
|
2
3
|
|
3
4
|
class DistributedMutex < Mutex
|
4
5
|
|
@@ -16,7 +17,8 @@ class DistributedMutex < Mutex
|
|
16
17
|
end
|
17
18
|
|
18
19
|
def lock
|
19
|
-
|
20
|
+
@locked = get_lock
|
21
|
+
if true == @locked
|
20
22
|
true
|
21
23
|
else
|
22
24
|
if @exception_on_timeout
|
@@ -56,12 +58,12 @@ class DistributedMutex < Mutex
|
|
56
58
|
end
|
57
59
|
|
58
60
|
def unlock
|
59
|
-
if
|
61
|
+
if locked?
|
60
62
|
if release_lock
|
61
63
|
@locked = false
|
62
64
|
true
|
63
65
|
else
|
64
|
-
|
66
|
+
raise MutexLockReleaseFailure
|
65
67
|
end
|
66
68
|
else
|
67
69
|
false
|
data/lib/mysql_mutex.rb
CHANGED
@@ -3,40 +3,82 @@ require 'distributed_mutex'
|
|
3
3
|
|
4
4
|
class MySQLMutex < DistributedMutex
|
5
5
|
|
6
|
-
|
6
|
+
@@thread_locks = Hash.new { |h,k| h[k] = Hash.new(0) } # Accounting for nested locks.
|
7
7
|
|
8
8
|
def initialize(key, timeout = DEFAULT_TIMEOUT, exception_on_timeout = DEFAULT_EXCEPTION_ON_TIMEOUT, connection = ActiveRecord::Base.connection)
|
9
|
+
super(key, timeout, exception_on_timeout)
|
9
10
|
@connection = connection
|
10
|
-
@
|
11
|
-
@get_sql = ActiveRecord::Base.send(:sanitize_sql_array,["SELECT
|
11
|
+
@connection_id = connection.show_variable('pseudo_thread_id')
|
12
|
+
@get_sql = ActiveRecord::Base.send(:sanitize_sql_array,["SELECT GET_LOCK(?,?)", key, timeout])
|
12
13
|
@release_sql = ActiveRecord::Base.send(:sanitize_sql_array,["SELECT RELEASE_LOCK(?)", key])
|
13
|
-
super(key, timeout, exception_on_timeout)
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.active_locks
|
17
|
-
@active_locks
|
18
14
|
end
|
19
15
|
|
20
16
|
def self.synchronize(key, timeout = DEFAULT_TIMEOUT, exception_on_timeout = DEFAULT_TIMEOUT, con = ActiveRecord::Base.connection, &block)
|
21
17
|
mutex = new(key, timeout, exception_on_timeout, con)
|
22
|
-
@active_locks[key] = timeout
|
23
18
|
mutex.synchronize(&block)
|
24
|
-
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.active_locks
|
22
|
+
@@thread_locks
|
25
23
|
end
|
26
24
|
|
27
25
|
private
|
28
26
|
|
29
27
|
def get_lock
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
if thread_lock_count > 0
|
29
|
+
increment_thread_lock_count
|
30
|
+
true
|
31
|
+
else
|
32
|
+
get_lock = @connection.select_value(@get_sql)
|
33
|
+
|
34
|
+
if defined?(Rails)
|
35
|
+
Rails.logger.debug("MySQLMutex: GET_LOCK=#{get_lock}")
|
36
|
+
end
|
37
|
+
|
38
|
+
if '1' == get_lock
|
39
|
+
increment_thread_lock_count
|
40
|
+
true
|
41
|
+
else
|
42
|
+
false
|
43
|
+
end
|
44
|
+
end
|
33
45
|
end
|
34
46
|
|
35
47
|
def release_lock
|
36
|
-
if
|
37
|
-
|
38
|
-
else
|
48
|
+
if thread_lock_count > 1
|
49
|
+
decrement_thread_lock_count
|
39
50
|
true
|
51
|
+
elsif thread_lock_count > 0
|
52
|
+
lock_release = @connection.select_value(@release_sql)
|
53
|
+
|
54
|
+
if defined?(Rails)
|
55
|
+
Rails.logger.debug("MySQLMutex: RELEASE_LOCK=#{lock_release}")
|
56
|
+
end
|
57
|
+
|
58
|
+
if '1' == lock_release
|
59
|
+
decrement_thread_lock_count
|
60
|
+
true
|
61
|
+
else
|
62
|
+
false
|
63
|
+
end
|
64
|
+
else
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def thread_lock_count
|
70
|
+
@@thread_locks[@connection_id][self.key]
|
71
|
+
end
|
72
|
+
|
73
|
+
def increment_thread_lock_count
|
74
|
+
@@thread_locks[@connection_id][self.key] += 1
|
75
|
+
end
|
76
|
+
|
77
|
+
def decrement_thread_lock_count
|
78
|
+
@@thread_locks[@connection_id][self.key] -= 1
|
79
|
+
|
80
|
+
if 0 == @@thread_locks[@connection_id][self.key]
|
81
|
+
@@thread_locks[@connection_id].delete(self.key)
|
40
82
|
end
|
41
83
|
end
|
42
84
|
|
@@ -44,6 +86,10 @@ end
|
|
44
86
|
|
45
87
|
at_exit do
|
46
88
|
locks = MySQLMutex.active_locks
|
89
|
+
locks.delete_if do |k, v|
|
90
|
+
v.empty?
|
91
|
+
end
|
92
|
+
|
47
93
|
if locks.size > 0
|
48
94
|
if defined?(Rails)
|
49
95
|
Rails.logger.error("MySQLMutex: Locks still active! - #{locks.inspect}")
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 1
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
|
9
|
-
version: 1.0.2
|
9
|
+
version: 1.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Birkir A. Barkarson
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-12-
|
17
|
+
date: 2010-12-10 00:00:00 +09:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
@@ -33,6 +33,7 @@ files:
|
|
33
33
|
- init.rb
|
34
34
|
- lib/distributed_mutex.rb
|
35
35
|
- lib/global_mutex.rb
|
36
|
+
- lib/mutex_lock_release_failure.rb
|
36
37
|
- lib/mutex_lock_timeout.rb
|
37
38
|
- lib/mysql_mutex.rb
|
38
39
|
- rails/init.rb
|