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 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