distributed_mutex 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
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. Implementation of a mutex stored on a MySQL database.}
9
- s.summary = s.description
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
- s.add_dependency(%q<activerecord>, [">= 1.2"])
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
+ 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
@@ -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
- - 1
9
- version: 1.0.1
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-03-05 00:00:00 +09:00
17
+ date: 2010-12-06 00:00:00 +09:00
18
18
  default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
21
- name: activerecord
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
- - --charset=UTF-8
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: Framework for using a distributed mutex. Implementation of a mutex stored on a MySQL database.
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