active_record_mutex 2.2.1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bae4a0303c87496334623532cdf84ebe36965400
4
- data.tar.gz: 3ff1f5b3142972f9e38b35dd6384efdc6141756f
3
+ metadata.gz: 82a2b14490ab51a0627c72260226d1742b1c0441
4
+ data.tar.gz: c487aa29472b77887e5dec81cd7f624676091d4a
5
5
  SHA512:
6
- metadata.gz: c6925871418c55c987de96784403d27b959af95bd07a5f27b9dbf97f9bcb5cf844875279aff404c9e39173af238dccec9b2a04f6c12513e712465430ac977d46
7
- data.tar.gz: ffa0d076563b3e3b86b66528c36b6c1eb95ddc597196036d34db6f5020c4f3d58aa58c430bd70a791a439f9a81d412cd42be81c0b8e0e3533b6b96f8e669a655
6
+ metadata.gz: 52337abd846212ae910f0d66ba99b39e35e02ad55a540e952dcbee8f195ec4c74d5dbc5f507d2f3dfa9e8b1189c6ba4e245805015893f561fdcd8c1eea4ca8fc
7
+ data.tar.gz: cbaceacb0cb2e06fef1b1d4a89b5940400e2a06213d7ab031f22f5151087357d0f5e8e092b9acdff49de08a8b133a8647ee064f8b9dea0fafbb82b8b85f9e4f8
data/README.md CHANGED
@@ -40,13 +40,6 @@ create Mutex instance like this:
40
40
 
41
41
  Now you can send all messages directly to the Mutex instance.
42
42
 
43
- ## Changes
44
-
45
- * 2016-08-19 Make locks rails environments independent
46
- * 2014-12-12 Release 2.0.0
47
- * 2014-12-12 Add license information
48
- * 2014-12-09 Adapt to newer Rails versions' API
49
-
50
43
  ## Download
51
44
 
52
45
  The homepage of this library is located at
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.2.1
1
+ 2.3.0
@@ -1,14 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: active_record_mutex 2.2.1 ruby lib
2
+ # stub: active_record_mutex 2.3.0 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "active_record_mutex"
6
- s.version = "2.2.1"
6
+ s.version = "2.3.0"
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib"]
10
10
  s.authors = ["Florian Frank"]
11
- s.date = "2016-08-19"
11
+ s.date = "2016-08-23"
12
12
  s.description = "Mutex that can be used to synchronise ruby processes via an ActiveRecord datababase connection. (Only Mysql is supported at the moment.)"
13
13
  s.email = "flori@ping.de"
14
14
  s.extra_rdoc_files = ["README.md", "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"]
@@ -29,7 +29,7 @@ module ActiveRecord
29
29
  rescue ActiveRecord::DatabaseMutex::MutexLocked
30
30
  return nil
31
31
  ensure
32
- locked && unlock
32
+ locked and unlock
33
33
  end
34
34
 
35
35
  # Locks the mutex and returns true if successful. If the mutex is
@@ -58,9 +58,18 @@ module ActiveRecord
58
58
  # Unlocks the mutex and returns true if successful. Otherwise this method
59
59
  # raises a MutexLocked exception.
60
60
  def unlock(*)
61
- case query("SELECT RELEASE_LOCK(#{quote_value(name)})")
62
- when 1 then true
63
- when 0, nil then raise MutexUnlockFailed, "unlocking of mutex '#{name}' failed"
61
+ if aquired_lock?
62
+ decrease_counter
63
+ if counter_zero?
64
+ case query("SELECT RELEASE_LOCK(#{quote(name)})")
65
+ when 1
66
+ true
67
+ when 0, nil
68
+ raise MutexUnlockFailed, "unlocking of mutex '#{name}' failed"
69
+ end
70
+ end
71
+ else
72
+ raise MutexUnlockFailed, "unlocking of mutex '#{name}' failed"
64
73
  end
65
74
  end
66
75
 
@@ -75,7 +84,7 @@ module ActiveRecord
75
84
 
76
85
  # Returns true if this mutex is unlocked at the moment.
77
86
  def unlocked?
78
- query("SELECT IS_FREE_LOCK(#{quote_value(name)})") == 1
87
+ query("SELECT IS_FREE_LOCK(#{quote(name)})") == 1
79
88
  end
80
89
 
81
90
  # Returns true if this mutex is locked at the moment.
@@ -85,7 +94,7 @@ module ActiveRecord
85
94
 
86
95
  # Returns true if this mutex is locked by this database connection.
87
96
  def aquired_lock?
88
- query("SELECT CONNECTION_ID() = IS_USED_LOCK(#{quote_value(name)})") == 1
97
+ query("SELECT CONNECTION_ID() = IS_USED_LOCK(#{quote(name)})") == 1
89
98
  end
90
99
 
91
100
  # Returns true if this mutex is not locked by this database connection.
@@ -102,15 +111,45 @@ module ActiveRecord
102
111
 
103
112
  private
104
113
 
105
- def quote_value(value)
114
+ def quote(value)
106
115
  ActiveRecord::Base.connection.quote(value)
107
116
  end
108
117
 
118
+ def counter
119
+ "@#{name}_mutex_counter"
120
+ end
121
+
122
+ def increase_counter
123
+ query("SET #{counter} = IF(#{counter} IS NULL OR #{counter} = 0, 1, #{counter} + 1)")
124
+ end
125
+
126
+ def decrease_counter
127
+ query("SET #{counter} = #{counter} - 1")
128
+ end
129
+
130
+ def counter_value
131
+ query("SELECT #{counter}").to_i
132
+ end
133
+
134
+ def counter_zero?
135
+ counter_value.zero?
136
+ end
137
+
109
138
  def lock_with_timeout(opts = {})
110
- timeout = opts[:timeout] || 1
111
- case query("SELECT GET_LOCK(#{quote_value(name)}, #{timeout})")
112
- when 1 then true
113
- when 0 then raise MutexLocked, "mutex '#{name}' is already locked"
139
+ if aquired_lock?
140
+ increase_counter
141
+ true
142
+ else
143
+ timeout = opts[:timeout] || 1
144
+ case query("SELECT GET_LOCK(#{quote(name)}, #{timeout})")
145
+ when 1
146
+ increase_counter
147
+ true
148
+ when 0
149
+ raise MutexLocked, "mutex '#{name}' is already locked"
150
+ when nil
151
+ raise MutexSystemError, "mutex '#{name}' not locked due to system error"
152
+ end
114
153
  end
115
154
  end
116
155
 
@@ -1,6 +1,6 @@
1
1
  module ActiveRecord::DatabaseMutex
2
2
  # ActiveRecord::DatabaseMutex version
3
- VERSION = '2.2.1'
3
+ VERSION = '2.3.0'
4
4
  VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
@@ -19,6 +19,8 @@ module ActiveRecord
19
19
 
20
20
  class MutexInvalidState < MutexError; end
21
21
 
22
+ class MutexSystemError < MutexError; end
23
+
22
24
  def self.included(modul)
23
25
  modul.instance_eval do
24
26
  extend ClassMethods
@@ -65,30 +65,39 @@ class DatabaseMutexTest < Test::Unit::TestCase
65
65
  def test_lock
66
66
  mutex = Implementation.new(:name => 'Lock')
67
67
  assert mutex.unlocked?
68
+ assert_equal 0, mutex.send(:counter_value)
68
69
  assert mutex.lock
69
70
  assert mutex.locked?
70
71
  assert mutex.aquired_lock?
72
+ assert_equal 1, mutex.send(:counter_value)
71
73
  assert mutex.lock
74
+ assert_equal 2, mutex.send(:counter_value)
72
75
  end
73
76
 
74
77
  def test_unlock
75
78
  mutex = Implementation.new(:name => 'Unlock')
76
79
  assert_raises(ActiveRecord::DatabaseMutex::MutexUnlockFailed) { mutex.unlock }
80
+ assert_equal 0, mutex.send(:counter_value)
77
81
  assert mutex.lock
78
82
  assert mutex.locked?
79
83
  assert mutex.aquired_lock?
84
+ assert_equal 1, mutex.send(:counter_value)
80
85
  assert mutex.unlock
81
86
  assert mutex.unlocked?
87
+ assert_equal 0, mutex.send(:counter_value)
82
88
  assert_raises(ActiveRecord::DatabaseMutex::MutexUnlockFailed) { mutex.unlock }
83
89
  end
84
90
 
85
91
  def test_synchronize
86
92
  mutex = Implementation.new(:name => 'Sync1')
87
93
  assert mutex.unlocked?
94
+ assert_equal 0, mutex.send(:counter_value)
88
95
  mutex.synchronize do
89
96
  assert mutex.locked?
97
+ assert_equal 1, mutex.send(:counter_value)
90
98
  end
91
99
  assert mutex.unlocked?
100
+ assert_equal 0, mutex.send(:counter_value)
92
101
  end
93
102
 
94
103
  def test_synchronize_exception
@@ -110,14 +119,24 @@ class DatabaseMutexTest < Test::Unit::TestCase
110
119
  def test_synchronize_nested
111
120
  mutex = Implementation.new(:name => 'Sync3')
112
121
  assert mutex.unlocked?
122
+ assert mutex.send(:counter_zero?)
123
+ assert_equal 0, mutex.send(:counter_value)
113
124
  mutex.synchronize do
114
125
  assert mutex.locked?
126
+ assert !mutex.send(:counter_zero?)
127
+ assert_equal 1, mutex.send(:counter_value)
115
128
  mutex.synchronize do
116
129
  assert mutex.locked?
130
+ assert !mutex.send(:counter_zero?)
131
+ assert_equal 2, mutex.send(:counter_value)
117
132
  end
118
133
  assert mutex.locked?
134
+ assert !mutex.send(:counter_zero?)
135
+ assert_equal 1, mutex.send(:counter_value)
119
136
  end
120
137
  assert mutex.unlocked?
138
+ assert mutex.send(:counter_zero?)
139
+ assert_equal 0, mutex.send(:counter_value)
121
140
  end
122
141
 
123
142
  def test_synchronize_already_locked
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_mutex
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-19 00:00:00.000000000 Z
11
+ date: 2016-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gem_hadar