active_record_mutex 0.0.1 → 1.0.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/.gitignore +2 -2
- data/README.rdoc +2 -9
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/active_record_mutex.gemspec +16 -16
- data/lib/active_record/database_mutex/implementation.rb +111 -0
- data/lib/active_record/{mutex → database_mutex}/version.rb +3 -3
- data/lib/active_record/database_mutex.rb +42 -0
- data/lib/active_record/mutex.rb +1 -148
- data/lib/active_record_mutex.rb +1 -1
- data/test/mutex_test.rb +15 -12
- metadata +79 -78
data/.gitignore
CHANGED
data/README.rdoc
CHANGED
@@ -2,16 +2,9 @@
|
|
2
2
|
|
3
3
|
== Description
|
4
4
|
|
5
|
-
This gem provides a Mutex that is based on
|
5
|
+
This gem provides a Mutex that is based on ActiveRecord's database connection.
|
6
6
|
(At the moment this only works for Mysql.) It can be used to synchronise
|
7
|
-
|
8
|
-
|
9
|
-
== Download
|
10
|
-
|
11
|
-
The latest version of the <b>active_record_mutex</b> source archive can be
|
12
|
-
found at
|
13
|
-
|
14
|
-
* http://www.ping.de/~flori
|
7
|
+
ruby processes (also on different hosts) via the connected database.
|
15
8
|
|
16
9
|
== Installation
|
17
10
|
|
data/Rakefile
CHANGED
@@ -4,7 +4,7 @@ require 'gem_hadar'
|
|
4
4
|
|
5
5
|
GemHadar do
|
6
6
|
name 'active_record_mutex'
|
7
|
-
path_name 'active_record/
|
7
|
+
path_name 'active_record/database_mutex'
|
8
8
|
author 'Florian Frank'
|
9
9
|
email 'flori@ping.de'
|
10
10
|
homepage "http://github.com/flori/#{name}"
|
@@ -15,6 +15,6 @@ GemHadar do
|
|
15
15
|
ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock'
|
16
16
|
readme 'README.rdoc'
|
17
17
|
|
18
|
-
dependency 'mysql2', '~>0.
|
18
|
+
dependency 'mysql2', '~>0.3.0'
|
19
19
|
dependency 'activerecord'
|
20
20
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
1.0.0
|
data/active_record_mutex.gemspec
CHANGED
@@ -1,38 +1,38 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
|
-
s.name =
|
5
|
-
s.version = "0.0
|
4
|
+
s.name = "active_record_mutex"
|
5
|
+
s.version = "1.0.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Florian Frank"]
|
9
|
-
s.date =
|
10
|
-
s.description =
|
11
|
-
s.email =
|
12
|
-
s.extra_rdoc_files = ["README.rdoc", "lib/active_record/mutex/
|
13
|
-
s.files = [".gitignore", "CHANGES", "Gemfile", "README.rdoc", "Rakefile", "VERSION", "active_record_mutex.gemspec", "lib/active_record/
|
14
|
-
s.homepage =
|
9
|
+
s.date = "2012-05-07"
|
10
|
+
s.description = "Mutex that can be used to synchronise ruby processes via an ActiveRecord datababase connection. (Only Mysql is supported at the moment.)"
|
11
|
+
s.email = "flori@ping.de"
|
12
|
+
s.extra_rdoc_files = ["README.rdoc", "lib/active_record_mutex.rb", "lib/active_record/mutex.rb", "lib/active_record/database_mutex.rb", "lib/active_record/database_mutex/version.rb", "lib/active_record/database_mutex/implementation.rb"]
|
13
|
+
s.files = [".gitignore", "CHANGES", "Gemfile", "README.rdoc", "Rakefile", "VERSION", "active_record_mutex.gemspec", "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", "test/mutex_test.rb"]
|
14
|
+
s.homepage = "http://github.com/flori/active_record_mutex"
|
15
15
|
s.rdoc_options = ["--title", "ActiveRecordMutex - Implementation of a Mutex for Active Record", "--main", "README.rdoc"]
|
16
16
|
s.require_paths = ["lib"]
|
17
|
-
s.rubygems_version =
|
18
|
-
s.summary =
|
17
|
+
s.rubygems_version = "1.8.24"
|
18
|
+
s.summary = "Implementation of a Mutex for Active Record"
|
19
19
|
s.test_files = ["test/mutex_test.rb"]
|
20
20
|
|
21
21
|
if s.respond_to? :specification_version then
|
22
22
|
s.specification_version = 3
|
23
23
|
|
24
24
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
25
|
-
s.add_development_dependency(%q<gem_hadar>, ["~> 0.0.
|
26
|
-
s.add_runtime_dependency(%q<mysql2>, ["~> 0.
|
25
|
+
s.add_development_dependency(%q<gem_hadar>, ["~> 0.0.12"])
|
26
|
+
s.add_runtime_dependency(%q<mysql2>, ["~> 0.3.0"])
|
27
27
|
s.add_runtime_dependency(%q<activerecord>, [">= 0"])
|
28
28
|
else
|
29
|
-
s.add_dependency(%q<gem_hadar>, ["~> 0.0.
|
30
|
-
s.add_dependency(%q<mysql2>, ["~> 0.
|
29
|
+
s.add_dependency(%q<gem_hadar>, ["~> 0.0.12"])
|
30
|
+
s.add_dependency(%q<mysql2>, ["~> 0.3.0"])
|
31
31
|
s.add_dependency(%q<activerecord>, [">= 0"])
|
32
32
|
end
|
33
33
|
else
|
34
|
-
s.add_dependency(%q<gem_hadar>, ["~> 0.0.
|
35
|
-
s.add_dependency(%q<mysql2>, ["~> 0.
|
34
|
+
s.add_dependency(%q<gem_hadar>, ["~> 0.0.12"])
|
35
|
+
s.add_dependency(%q<mysql2>, ["~> 0.3.0"])
|
36
36
|
s.add_dependency(%q<activerecord>, [">= 0"])
|
37
37
|
end
|
38
38
|
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module DatabaseMutex
|
3
|
+
class Implementation
|
4
|
+
# Creates a mutex with the name given with the option :name.
|
5
|
+
def initialize(opts = {})
|
6
|
+
@name = opts[:name] or raise ArgumentError, "mutex requires a :name argument"
|
7
|
+
end
|
8
|
+
|
9
|
+
# Returns the name of this mutex as given as a constructor argument.
|
10
|
+
attr_reader :name
|
11
|
+
|
12
|
+
# Locks the mutex if it isn't already locked via another database
|
13
|
+
# connection and yields to the given block. After executing the block's
|
14
|
+
# content the mutex is unlocked (only if it was locked by this
|
15
|
+
# synchronize method before).
|
16
|
+
#
|
17
|
+
# If the mutex was already locked by another database connection the
|
18
|
+
# method blocks until it could aquire the lock and only then the block's
|
19
|
+
# content is executed. If the mutex was already locked by the current database
|
20
|
+
# connection then the block's content is run and the the mutex isn't
|
21
|
+
# unlocked afterwards.
|
22
|
+
#
|
23
|
+
# If a value in seconds is passed to the :timeout option the blocking
|
24
|
+
# ends after that many seconds and the method returns immediately if the
|
25
|
+
# lock couldn't be aquired during that time.
|
26
|
+
def synchronize(opts = {})
|
27
|
+
locked_before = aquired_lock?
|
28
|
+
lock opts
|
29
|
+
yield
|
30
|
+
rescue ActiveRecord::DatabaseMutex::MutexLocked
|
31
|
+
return nil
|
32
|
+
ensure
|
33
|
+
locked_before or unlock
|
34
|
+
end
|
35
|
+
|
36
|
+
# Locks the mutex and returns true if successful. If the mutex is
|
37
|
+
# already locked and the timeout in seconds is given as the :timeout
|
38
|
+
# option, this method raises a MutexLocked exception after that many
|
39
|
+
# seconds. If the :timeout option wasn't given, this method blocks until
|
40
|
+
# the lock could be aquired.
|
41
|
+
def lock(opts = {})
|
42
|
+
if opts[:timeout]
|
43
|
+
lock_with_timeout opts
|
44
|
+
else
|
45
|
+
begin
|
46
|
+
lock_with_timeout :timeout => 1
|
47
|
+
rescue MutexLocked
|
48
|
+
retry
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Unlocks the mutex and returns true if successful. Otherwise this method
|
54
|
+
# raises a MutexLocked exception.
|
55
|
+
def unlock(*)
|
56
|
+
case query("SELECT RELEASE_LOCK(#{ActiveRecord::Base.quote_value(name)})")
|
57
|
+
when 1 then true
|
58
|
+
when 0, nil then raise MutexUnlockFailed, "unlocking of mutex '#{name}' failed"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns true if this mutex is unlocked at the moment.
|
63
|
+
def unlocked?
|
64
|
+
query("SELECT IS_FREE_LOCK(#{ActiveRecord::Base.quote_value(name)})") == 1
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns true if this mutex is locked at the moment.
|
68
|
+
def locked?
|
69
|
+
not unlocked?
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns true if this mutex is locked by this database connection.
|
73
|
+
def aquired_lock?
|
74
|
+
query("SELECT CONNECTION_ID() = IS_USED_LOCK(#{ActiveRecord::Base.quote_value(name)})") == 1
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns true if this mutex is not locked by this database connection.
|
78
|
+
def not_aquired_lock?
|
79
|
+
not aquired_lock?
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns a string representation of this DatabaseMutex instance.
|
83
|
+
def to_s
|
84
|
+
"#<#{self.class} #{name}>"
|
85
|
+
end
|
86
|
+
|
87
|
+
alias inspect to_s
|
88
|
+
|
89
|
+
private
|
90
|
+
|
91
|
+
def lock_with_timeout(opts = {})
|
92
|
+
timeout = opts[:timeout] || 1
|
93
|
+
case query("SELECT GET_LOCK(#{ActiveRecord::Base.quote_value(name)}, #{timeout})")
|
94
|
+
when 1 then true
|
95
|
+
when 0 then raise MutexLocked, "mutex '#{name}' is already locked"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def query(sql)
|
100
|
+
if result = ActiveRecord::Base.connection.execute(sql)
|
101
|
+
result = result.first.first.to_i
|
102
|
+
$DEBUG and warn %{query("#{sql}") = #{result}}
|
103
|
+
end
|
104
|
+
result
|
105
|
+
rescue ActiveRecord::StatementInvalid
|
106
|
+
nil
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
@@ -1,6 +1,6 @@
|
|
1
|
-
module ActiveRecord::
|
2
|
-
# ActiveRecord::
|
3
|
-
VERSION = '0.0
|
1
|
+
module ActiveRecord::DatabaseMutex
|
2
|
+
# ActiveRecord::DatabaseMutex version
|
3
|
+
VERSION = '1.0.0'
|
4
4
|
VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
|
5
5
|
VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
|
6
6
|
VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'active_record/database_mutex/version'
|
3
|
+
require 'active_record/database_mutex/implementation'
|
4
|
+
|
5
|
+
module ActiveRecord
|
6
|
+
# This module is mixed into ActiveRecord::Base to provide the mutex methods
|
7
|
+
# that return a mutex for a particular ActiveRecord::Base subclass/instance.
|
8
|
+
module DatabaseMutex
|
9
|
+
# This is the base exception of all mutex exceptions.
|
10
|
+
class MutexError < ActiveRecordError; end
|
11
|
+
|
12
|
+
# This exception is raised if a mutex of the given name isn't locked at the
|
13
|
+
# moment and unlock was called.
|
14
|
+
class MutexUnlockFailed < MutexError; end
|
15
|
+
|
16
|
+
# This exception is raised if a mutex of the given name is locked at the
|
17
|
+
# moment and lock was called again.
|
18
|
+
class MutexLocked < MutexError; end
|
19
|
+
|
20
|
+
def self.included(modul)
|
21
|
+
modul.instance_eval do
|
22
|
+
extend ClassMethods
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module ClassMethods
|
27
|
+
# Returns a mutex instance for this ActiveRecord subclass.
|
28
|
+
def mutex
|
29
|
+
@mutex ||= Implementation.new(:name => name)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns a mutex instance for this ActiveRecord instance.
|
34
|
+
def mutex
|
35
|
+
@mutex ||= Implementation.new(:name => self.class.name)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
ActiveRecord::Base.class_eval do
|
41
|
+
include ActiveRecord::DatabaseMutex
|
42
|
+
end
|
data/lib/active_record/mutex.rb
CHANGED
@@ -1,148 +1 @@
|
|
1
|
-
require 'active_record'
|
2
|
-
require 'active_record/mutex/version'
|
3
|
-
|
4
|
-
module ActiveRecord
|
5
|
-
# This module is mixed into ActiveRecord::Base to provide the mutex methods
|
6
|
-
# that return a mutex for a particular ActiveRecord::Base subclass/instance.
|
7
|
-
module Mutex
|
8
|
-
# This is the base exception of all mutex exceptions.
|
9
|
-
class MutexError < ActiveRecordError; end
|
10
|
-
|
11
|
-
# This exception is raised if a mutex of the given name isn't locked at the
|
12
|
-
# moment and unlock was called.
|
13
|
-
class MutexUnlockFailed < MutexError; end
|
14
|
-
|
15
|
-
# This exception is raised if a mutex of the given name is locked at the
|
16
|
-
# moment and lock was called again.
|
17
|
-
class MutexLocked < MutexError; end
|
18
|
-
|
19
|
-
def self.included(modul)
|
20
|
-
modul.instance_eval do
|
21
|
-
extend ClassMethods
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
module ClassMethods
|
26
|
-
# Returns a mutex instance for this ActiveRecord subclass.
|
27
|
-
def mutex
|
28
|
-
@mutex ||= Mutex.new(:name => name)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# Returns a mutex instance for this ActiveRecord instance.
|
33
|
-
def mutex
|
34
|
-
@mutex ||= Mutex.new(:name => self.class.name)
|
35
|
-
end
|
36
|
-
|
37
|
-
class Mutex
|
38
|
-
# Creates a mutex with the name given with the option :name.
|
39
|
-
def initialize(opts = {})
|
40
|
-
@name = opts[:name] or raise ArgumentError, "Mutex requires a :name argument"
|
41
|
-
end
|
42
|
-
|
43
|
-
# Returns the name of this mutex as given as a constructor argument.
|
44
|
-
attr_reader :name
|
45
|
-
|
46
|
-
# Locks the mutex if it isn't already locked via another database
|
47
|
-
# connection and yields to the given block. After executing the block's
|
48
|
-
# content the mutex is unlocked (only if it was locked by this
|
49
|
-
# synchronize method before).
|
50
|
-
#
|
51
|
-
# If the mutex was already locked by another database connection the
|
52
|
-
# method blocks until it could aquire the lock and only then the block's
|
53
|
-
# content is executed. If the mutex was already locked by the current database
|
54
|
-
# connection then the block's content is run and the the mutex isn't
|
55
|
-
# unlocked afterwards.
|
56
|
-
#
|
57
|
-
# If a value in seconds is passed to the :timeout option the blocking
|
58
|
-
# ends after that many seconds and the method returns immediately if the
|
59
|
-
# lock couldn't be aquired during that time.
|
60
|
-
def synchronize(opts = {})
|
61
|
-
locked_before = aquired_lock?
|
62
|
-
lock opts
|
63
|
-
yield
|
64
|
-
rescue ActiveRecord::Mutex::MutexLocked
|
65
|
-
return nil
|
66
|
-
ensure
|
67
|
-
locked_before or unlock
|
68
|
-
end
|
69
|
-
|
70
|
-
# Locks the mutex and returns true if successful. If the mutex is
|
71
|
-
# already locked and the timeout in seconds is given as the :timeout
|
72
|
-
# option, this method raises a MutexLocked exception after that many
|
73
|
-
# seconds. If the :timeout option wasn't given, this method blocks until
|
74
|
-
# the lock could be aquired.
|
75
|
-
def lock(opts = {})
|
76
|
-
if opts[:timeout]
|
77
|
-
lock_with_timeout opts
|
78
|
-
else
|
79
|
-
begin
|
80
|
-
lock_with_timeout :timeout => 1
|
81
|
-
rescue MutexLocked
|
82
|
-
retry
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
# Unlocks the mutex and returns true if successful. Otherwise this method
|
88
|
-
# raises a MutexLocked exception.
|
89
|
-
def unlock(*)
|
90
|
-
case query("SELECT RELEASE_LOCK(#{ActiveRecord::Base.quote_value(name)})")
|
91
|
-
when 1 then true
|
92
|
-
when 0, nil then raise MutexUnlockFailed, "unlocking of mutex '#{name}' failed"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
# Returns true if this mutex is unlocked at the moment.
|
97
|
-
def unlocked?
|
98
|
-
query("SELECT IS_FREE_LOCK(#{ActiveRecord::Base.quote_value(name)})") == 1
|
99
|
-
end
|
100
|
-
|
101
|
-
# Returns true if this mutex is locked at the moment.
|
102
|
-
def locked?
|
103
|
-
not unlocked?
|
104
|
-
end
|
105
|
-
|
106
|
-
# Returns true if this mutex is locked by this database connection.
|
107
|
-
def aquired_lock?
|
108
|
-
query("SELECT CONNECTION_ID() = IS_USED_LOCK(#{ActiveRecord::Base.quote_value(name)})") == 1
|
109
|
-
end
|
110
|
-
|
111
|
-
# Returns true if this mutex is not locked by this database connection.
|
112
|
-
def not_aquired_lock?
|
113
|
-
not aquired_lock?
|
114
|
-
end
|
115
|
-
|
116
|
-
# Returns a string representation of this Mutex instance.
|
117
|
-
def to_s
|
118
|
-
"#<#{self.class} #{name}>"
|
119
|
-
end
|
120
|
-
|
121
|
-
alias inspect to_s
|
122
|
-
|
123
|
-
private
|
124
|
-
|
125
|
-
def lock_with_timeout(opts = {})
|
126
|
-
timeout = opts[:timeout] || 1
|
127
|
-
case query("SELECT GET_LOCK(#{ActiveRecord::Base.quote_value(name)}, #{timeout})")
|
128
|
-
when 1 then true
|
129
|
-
when 0 then raise MutexLocked, "mutex '#{name}' is already locked"
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
def query(sql)
|
134
|
-
if result = ActiveRecord::Base.connection.execute(sql)
|
135
|
-
result = result.first.first.to_i
|
136
|
-
$DEBUG and warn %{query("#{sql}") = #{result}}
|
137
|
-
end
|
138
|
-
result
|
139
|
-
rescue ActiveRecord::StatementInvalid
|
140
|
-
nil
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
ActiveRecord::Base.class_eval do
|
147
|
-
include ActiveRecord::Mutex
|
148
|
-
end
|
1
|
+
require 'active_record/database_mutex'
|
data/lib/active_record_mutex.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require 'active_record/
|
1
|
+
require 'active_record/database_mutex'
|
data/test/mutex_test.rb
CHANGED
@@ -3,16 +3,19 @@ require 'rubygems'
|
|
3
3
|
|
4
4
|
require 'active_record'
|
5
5
|
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
6
|
-
require 'active_record/
|
6
|
+
require 'active_record/database_mutex'
|
7
7
|
|
8
8
|
ActiveRecord::Base.establish_connection(
|
9
9
|
:adapter => "mysql2",
|
10
10
|
:database => ENV['DATABASE'] || "test",
|
11
11
|
:username => ENV['USER'],
|
12
|
-
:password => ENV['PASSWORD']
|
12
|
+
:password => ENV['PASSWORD'],
|
13
|
+
:host => ENV['HOST'] || 'localhost'
|
13
14
|
)
|
14
15
|
|
15
16
|
class MutexTest < Test::Unit::TestCase
|
17
|
+
include ActiveRecord::DatabaseMutex
|
18
|
+
|
16
19
|
class Foo < ActiveRecord::Base; end
|
17
20
|
|
18
21
|
def setup
|
@@ -29,20 +32,20 @@ class MutexTest < Test::Unit::TestCase
|
|
29
32
|
|
30
33
|
def test_exported_methods
|
31
34
|
mutex = Foo.mutex
|
32
|
-
assert_kind_of ActiveRecord::
|
35
|
+
assert_kind_of ActiveRecord::DatabaseMutex::Implementation, mutex
|
33
36
|
assert_equal mutex.name, Foo.name
|
34
37
|
mutex = Foo.new.mutex
|
35
|
-
assert_kind_of ActiveRecord::
|
38
|
+
assert_kind_of ActiveRecord::DatabaseMutex::Implementation, mutex
|
36
39
|
assert_equal mutex.name, Foo.name
|
37
40
|
end
|
38
41
|
|
39
42
|
def test_create
|
40
|
-
mutex =
|
43
|
+
mutex = Implementation.new(:name => 'Create')
|
41
44
|
assert_equal 'Create', mutex.name
|
42
45
|
end
|
43
46
|
|
44
47
|
def test_lock
|
45
|
-
mutex =
|
48
|
+
mutex = Implementation.new(:name => 'Lock')
|
46
49
|
assert mutex.unlocked?
|
47
50
|
assert mutex.lock
|
48
51
|
assert mutex.locked?
|
@@ -51,18 +54,18 @@ class MutexTest < Test::Unit::TestCase
|
|
51
54
|
end
|
52
55
|
|
53
56
|
def test_unlock
|
54
|
-
mutex =
|
55
|
-
assert_raises(ActiveRecord::
|
57
|
+
mutex = Implementation.new(:name => 'Unlock')
|
58
|
+
assert_raises(ActiveRecord::DatabaseMutex::MutexUnlockFailed) { mutex.unlock }
|
56
59
|
assert mutex.lock
|
57
60
|
assert mutex.locked?
|
58
61
|
assert mutex.aquired_lock?
|
59
62
|
assert mutex.unlock
|
60
63
|
assert mutex.unlocked?
|
61
|
-
assert_raises(ActiveRecord::
|
64
|
+
assert_raises(ActiveRecord::DatabaseMutex::MutexUnlockFailed) { mutex.unlock }
|
62
65
|
end
|
63
66
|
|
64
67
|
def test_synchronize
|
65
|
-
mutex =
|
68
|
+
mutex = Implementation.new(:name => 'Sync1')
|
66
69
|
assert mutex.unlocked?
|
67
70
|
mutex.synchronize do
|
68
71
|
assert mutex.locked?
|
@@ -71,7 +74,7 @@ class MutexTest < Test::Unit::TestCase
|
|
71
74
|
end
|
72
75
|
|
73
76
|
def test_synchronize_exception
|
74
|
-
mutex =
|
77
|
+
mutex = Implementation.new(:name => 'Sync2')
|
75
78
|
exception = Class.new StandardError
|
76
79
|
begin
|
77
80
|
assert mutex.unlocked?
|
@@ -87,7 +90,7 @@ class MutexTest < Test::Unit::TestCase
|
|
87
90
|
end
|
88
91
|
|
89
92
|
def test_synchronize_nested
|
90
|
-
mutex =
|
93
|
+
mutex = Implementation.new(:name => 'Sync3')
|
91
94
|
assert mutex.unlocked?
|
92
95
|
mutex.synchronize do
|
93
96
|
assert mutex.locked?
|
metadata
CHANGED
@@ -1,80 +1,83 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_record_mutex
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
- 1
|
10
|
-
version: 0.0.1
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Florian Frank
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-05-07 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: gem_hadar
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
18
|
+
requirements:
|
26
19
|
- - ~>
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
segments:
|
30
|
-
- 0
|
31
|
-
- 0
|
32
|
-
- 6
|
33
|
-
version: 0.0.6
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.0.12
|
34
22
|
type: :development
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: mysql2
|
38
23
|
prerelease: false
|
39
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.0.12
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: mysql2
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
40
33
|
none: false
|
41
|
-
requirements:
|
34
|
+
requirements:
|
42
35
|
- - ~>
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
|
45
|
-
segments:
|
46
|
-
- 0
|
47
|
-
- 2
|
48
|
-
- 11
|
49
|
-
version: 0.2.11
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.3.0
|
50
38
|
type: :runtime
|
51
|
-
version_requirements: *id002
|
52
|
-
- !ruby/object:Gem::Dependency
|
53
|
-
name: activerecord
|
54
39
|
prerelease: false
|
55
|
-
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
56
41
|
none: false
|
57
|
-
requirements:
|
58
|
-
- -
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.3.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: activerecord
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
64
54
|
type: :runtime
|
65
|
-
|
66
|
-
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: Mutex that can be used to synchronise ruby processes via an ActiveRecord
|
63
|
+
datababase connection. (Only Mysql is supported at the moment.)
|
67
64
|
email: flori@ping.de
|
68
65
|
executables: []
|
69
|
-
|
70
66
|
extensions: []
|
71
|
-
|
72
|
-
extra_rdoc_files:
|
67
|
+
extra_rdoc_files:
|
73
68
|
- README.rdoc
|
74
|
-
-
|
75
|
-
|
76
|
-
-
|
77
|
-
|
69
|
+
- !binary |-
|
70
|
+
bGliL2FjdGl2ZV9yZWNvcmRfbXV0ZXgucmI=
|
71
|
+
- !binary |-
|
72
|
+
bGliL2FjdGl2ZV9yZWNvcmQvbXV0ZXgucmI=
|
73
|
+
- !binary |-
|
74
|
+
bGliL2FjdGl2ZV9yZWNvcmQvZGF0YWJhc2VfbXV0ZXgucmI=
|
75
|
+
- !binary |-
|
76
|
+
bGliL2FjdGl2ZV9yZWNvcmQvZGF0YWJhc2VfbXV0ZXgvdmVyc2lvbi5yYg==
|
77
|
+
- !binary |-
|
78
|
+
bGliL2FjdGl2ZV9yZWNvcmQvZGF0YWJhc2VfbXV0ZXgvaW1wbGVtZW50YXRp
|
79
|
+
b24ucmI=
|
80
|
+
files:
|
78
81
|
- .gitignore
|
79
82
|
- CHANGES
|
80
83
|
- Gemfile
|
@@ -82,45 +85,43 @@ files:
|
|
82
85
|
- Rakefile
|
83
86
|
- VERSION
|
84
87
|
- active_record_mutex.gemspec
|
88
|
+
- lib/active_record/database_mutex.rb
|
89
|
+
- lib/active_record/database_mutex/implementation.rb
|
90
|
+
- lib/active_record/database_mutex/version.rb
|
85
91
|
- lib/active_record/mutex.rb
|
86
|
-
- lib/active_record/mutex/version.rb
|
87
92
|
- lib/active_record_mutex.rb
|
88
93
|
- test/mutex_test.rb
|
89
94
|
homepage: http://github.com/flori/active_record_mutex
|
90
95
|
licenses: []
|
91
|
-
|
92
96
|
post_install_message:
|
93
|
-
rdoc_options:
|
97
|
+
rdoc_options:
|
94
98
|
- --title
|
95
99
|
- ActiveRecordMutex - Implementation of a Mutex for Active Record
|
96
100
|
- --main
|
97
101
|
- README.rdoc
|
98
|
-
require_paths:
|
102
|
+
require_paths:
|
99
103
|
- lib
|
100
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
101
105
|
none: false
|
102
|
-
requirements:
|
103
|
-
- -
|
104
|
-
- !ruby/object:Gem::Version
|
105
|
-
|
106
|
-
segments:
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
segments:
|
107
111
|
- 0
|
108
|
-
|
109
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
hash: 3312352777987471418
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
114
|
none: false
|
111
|
-
requirements:
|
112
|
-
- -
|
113
|
-
- !ruby/object:Gem::Version
|
114
|
-
|
115
|
-
segments:
|
116
|
-
- 0
|
117
|
-
version: "0"
|
115
|
+
requirements:
|
116
|
+
- - ! '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
118
119
|
requirements: []
|
119
|
-
|
120
120
|
rubyforge_project:
|
121
|
-
rubygems_version: 1.
|
121
|
+
rubygems_version: 1.8.24
|
122
122
|
signing_key:
|
123
123
|
specification_version: 3
|
124
124
|
summary: Implementation of a Mutex for Active Record
|
125
|
-
test_files:
|
126
|
-
-
|
125
|
+
test_files:
|
126
|
+
- !binary |-
|
127
|
+
dGVzdC9tdXRleF90ZXN0LnJi
|