distributed_mutex 1.0.1 → 1.0.2
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/README.rdoc +8 -0
- data/Rakefile +3 -3
- data/VERSION +1 -1
- data/lib/mysql_mutex.rb +25 -0
- data/spec/mysql_mutex_spec.rb +85 -0
- metadata +11 -24
- data/.gitignore +0 -1
data/README.rdoc
CHANGED
@@ -18,6 +18,14 @@ framework.
|
|
18
18
|
|
19
19
|
script/plugin install git://github.com/birkirb/distributed_mutex.git
|
20
20
|
|
21
|
+
== Gem Install
|
22
|
+
|
23
|
+
gem install distributed_mutex
|
24
|
+
|
25
|
+
To add the plugin to your rails project, add the following to your config/environments.rb:
|
26
|
+
|
27
|
+
config.gem(:distributed_mutex)
|
28
|
+
|
21
29
|
== Copyright
|
22
30
|
|
23
31
|
Author:: Birkir A. Barkarson <birkirb@stoicviking.net>
|
data/Rakefile
CHANGED
@@ -5,12 +5,12 @@ begin
|
|
5
5
|
Jeweler::Tasks.new do |s|
|
6
6
|
s.name = %q{distributed_mutex}
|
7
7
|
s.authors = ["Birkir A. Barkarson"]
|
8
|
-
s.description = %q{Framework for using a distributed mutex
|
9
|
-
s.summary =
|
8
|
+
s.description = %q{Framework for using a distributed mutex along with an implementation of a mutex stored on a MySQL database.}
|
9
|
+
s.summary = %q{API for using a unique mutex across all instances of your application.}
|
10
10
|
s.email = %q{birkirb@stoicviking.net}
|
11
11
|
s.has_rdoc = true
|
12
12
|
s.homepage = %q{http://github.com/birkirb/distributed_mutex}
|
13
|
-
|
13
|
+
# s.add_dependency(%q<activerecord>, ["> 1.2"])
|
14
14
|
end
|
15
15
|
rescue LoadError
|
16
16
|
puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.2
|
data/lib/mysql_mutex.rb
CHANGED
@@ -3,6 +3,8 @@ require 'distributed_mutex'
|
|
3
3
|
|
4
4
|
class MySQLMutex < DistributedMutex
|
5
5
|
|
6
|
+
@active_locks = Hash.new
|
7
|
+
|
6
8
|
def initialize(key, timeout = DEFAULT_TIMEOUT, exception_on_timeout = DEFAULT_EXCEPTION_ON_TIMEOUT, connection = ActiveRecord::Base.connection)
|
7
9
|
@connection = connection
|
8
10
|
@lock_was_free = false
|
@@ -11,9 +13,15 @@ class MySQLMutex < DistributedMutex
|
|
11
13
|
super(key, timeout, exception_on_timeout)
|
12
14
|
end
|
13
15
|
|
16
|
+
def self.active_locks
|
17
|
+
@active_locks
|
18
|
+
end
|
19
|
+
|
14
20
|
def self.synchronize(key, timeout = DEFAULT_TIMEOUT, exception_on_timeout = DEFAULT_TIMEOUT, con = ActiveRecord::Base.connection, &block)
|
15
21
|
mutex = new(key, timeout, exception_on_timeout, con)
|
22
|
+
@active_locks[key] = timeout
|
16
23
|
mutex.synchronize(&block)
|
24
|
+
@active_locks.delete(key)
|
17
25
|
end
|
18
26
|
|
19
27
|
private
|
@@ -33,3 +41,20 @@ class MySQLMutex < DistributedMutex
|
|
33
41
|
end
|
34
42
|
|
35
43
|
end
|
44
|
+
|
45
|
+
at_exit do
|
46
|
+
locks = MySQLMutex.active_locks
|
47
|
+
if locks.size > 0
|
48
|
+
if defined?(Rails)
|
49
|
+
Rails.logger.error("MySQLMutex: Locks still active! - #{locks.inspect}")
|
50
|
+
else
|
51
|
+
STDERR.puts("MySQLMutex: Locks still active! - #{locks.inspect}")
|
52
|
+
end
|
53
|
+
else
|
54
|
+
if defined?(Rails)
|
55
|
+
Rails.logger.debug("MySQLMutex: All locks released.")
|
56
|
+
else
|
57
|
+
STDERR.puts("MySQLMutex: All locks released.")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/spec/mysql_mutex_spec.rb
CHANGED
@@ -133,4 +133,89 @@ describe MySQLMutex, 'with a lock on an open mysql connection' do
|
|
133
133
|
|
134
134
|
sub_thread_executed.should == true
|
135
135
|
end
|
136
|
+
|
137
|
+
it 'should released nested synchronized locks and block a second thread which times out' do
|
138
|
+
sub_thread_executed = false
|
139
|
+
main_thread_completed = false
|
140
|
+
final_thread_completed = false
|
141
|
+
|
142
|
+
begin
|
143
|
+
thread_2 = Thread.new do
|
144
|
+
con = ActiveRecord::Base.mysql_connection(ActiveRecord::Base.configurations['test'])
|
145
|
+
sleep 0.1
|
146
|
+
MySQLMutex.synchronize('test', 1, true, con) do
|
147
|
+
sub_thread_executed = true
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
thread_1 = Thread.new do
|
152
|
+
con = ActiveRecord::Base.mysql_connection(ActiveRecord::Base.configurations['test'])
|
153
|
+
MySQLMutex.synchronize('test', 1, true, con) do
|
154
|
+
MySQLMutex.synchronize('test', 1, true, con) do
|
155
|
+
sleep 3
|
156
|
+
main_thread_completed = true
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
lambda do
|
162
|
+
thread_2.join
|
163
|
+
end.should raise_error(MutexLockTimeout)
|
164
|
+
|
165
|
+
thread_1.join
|
166
|
+
|
167
|
+
con = ActiveRecord::Base.mysql_connection(ActiveRecord::Base.configurations['test'])
|
168
|
+
MySQLMutex.synchronize('test', 1, true, con) do
|
169
|
+
final_thread_completed = true
|
170
|
+
end
|
171
|
+
rescue => err
|
172
|
+
fail(err)
|
173
|
+
end
|
174
|
+
|
175
|
+
sub_thread_executed.should == false
|
176
|
+
main_thread_completed.should == true
|
177
|
+
final_thread_completed.should == true
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'should released nested synchronized locks throwing an error and block a second accessing before the error' do
|
181
|
+
final_thread_completed = false
|
182
|
+
|
183
|
+
begin
|
184
|
+
thread_2 = Thread.new do
|
185
|
+
con = ActiveRecord::Base.mysql_connection(ActiveRecord::Base.configurations['test'])
|
186
|
+
sleep 0.1
|
187
|
+
MySQLMutex.synchronize('test', 1, true, con) do
|
188
|
+
raise 'Boom 2!'
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
thread_1 = Thread.new do
|
193
|
+
con = ActiveRecord::Base.mysql_connection(ActiveRecord::Base.configurations['test'])
|
194
|
+
MySQLMutex.synchronize('test', 1, true, con) do
|
195
|
+
MySQLMutex.synchronize('test', 1, true, con) do
|
196
|
+
sleep 3
|
197
|
+
raise 'Boom 1!'
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
lambda do
|
203
|
+
thread_2.join
|
204
|
+
end.should raise_error(MutexLockTimeout)
|
205
|
+
|
206
|
+
lambda do
|
207
|
+
thread_1.join
|
208
|
+
end.should raise_error(RuntimeError, 'Boom 1!')
|
209
|
+
|
210
|
+
con = ActiveRecord::Base.mysql_connection(ActiveRecord::Base.configurations['test'])
|
211
|
+
MySQLMutex.synchronize('test', 1, true, con) do
|
212
|
+
final_thread_completed = true
|
213
|
+
end
|
214
|
+
rescue => err
|
215
|
+
fail(err)
|
216
|
+
end
|
217
|
+
|
218
|
+
final_thread_completed.should == true
|
219
|
+
end
|
220
|
+
|
136
221
|
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 1.0.
|
8
|
+
- 2
|
9
|
+
version: 1.0.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Birkir A. Barkarson
|
@@ -14,23 +14,11 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-12-06 00:00:00 +09:00
|
18
18
|
default_executable:
|
19
|
-
dependencies:
|
20
|
-
|
21
|
-
|
22
|
-
prerelease: false
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
-
requirements:
|
25
|
-
- - ">="
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
segments:
|
28
|
-
- 1
|
29
|
-
- 2
|
30
|
-
version: "1.2"
|
31
|
-
type: :runtime
|
32
|
-
version_requirements: *id001
|
33
|
-
description: Framework for using a distributed mutex. Implementation of a mutex stored on a MySQL database.
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Framework for using a distributed mutex along with an implementation of a mutex stored on a MySQL database.
|
34
22
|
email: birkirb@stoicviking.net
|
35
23
|
executables: []
|
36
24
|
|
@@ -39,7 +27,6 @@ extensions: []
|
|
39
27
|
extra_rdoc_files:
|
40
28
|
- README.rdoc
|
41
29
|
files:
|
42
|
-
- .gitignore
|
43
30
|
- README.rdoc
|
44
31
|
- Rakefile
|
45
32
|
- VERSION
|
@@ -58,8 +45,8 @@ homepage: http://github.com/birkirb/distributed_mutex
|
|
58
45
|
licenses: []
|
59
46
|
|
60
47
|
post_install_message:
|
61
|
-
rdoc_options:
|
62
|
-
|
48
|
+
rdoc_options: []
|
49
|
+
|
63
50
|
require_paths:
|
64
51
|
- lib
|
65
52
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -82,8 +69,8 @@ rubyforge_project:
|
|
82
69
|
rubygems_version: 1.3.6
|
83
70
|
signing_key:
|
84
71
|
specification_version: 3
|
85
|
-
summary:
|
72
|
+
summary: API for using a unique mutex across all instances of your application.
|
86
73
|
test_files:
|
87
|
-
- spec/spec_helper.rb
|
88
|
-
- spec/mysql_mutex_spec.rb
|
89
74
|
- spec/global_mutex_spec.rb
|
75
|
+
- spec/mysql_mutex_spec.rb
|
76
|
+
- spec/spec_helper.rb
|
data/.gitignore
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
spec/config/database.yml
|