lock_method 0.1.2 → 0.1.3
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/lib/lock_method.rb +1 -0
- data/lib/lock_method/lock.rb +4 -4
- data/lib/lock_method/version.rb +1 -1
- data/test/helper.rb +24 -0
- data/test/shared_tests.rb +19 -0
- data/test/test_memcached_storage.rb +1 -1
- metadata +6 -6
data/README.rdoc
CHANGED
@@ -28,6 +28,10 @@ Just in case, you can clear them
|
|
28
28
|
|
29
29
|
my_blog.clear_method_lock :get_latest_entries
|
30
30
|
|
31
|
+
== Real-world usage
|
32
|
+
|
33
|
+
In production use at {carbon.brighterplanet.com}[http://carbon.brighterplanet.com], the Brighter Planet emission estimate web service.
|
34
|
+
|
31
35
|
== Ignores arguments when locking a method
|
32
36
|
|
33
37
|
lock_method ignores arguments when locking. So if you call Foo.bar(:a), calls to Foo.bar(:b) will be locked until the first call finishes.
|
@@ -44,6 +48,10 @@ Ideally, you should try to make a <tt>String</tt> or a <tt>Hash</tt> and call th
|
|
44
48
|
|
45
49
|
Note: this is NOT the same thing as <tt>#to_hash</tt>! That returns a <tt>Hash</tt>... but what we want is an integer "hash code."
|
46
50
|
|
51
|
+
== Defining #method_lock_hash instead of #hash
|
52
|
+
|
53
|
+
If you don't want to modify #hash, you can use #method_lock_hash instead.
|
54
|
+
|
47
55
|
== Configuration (and supported cache clients)
|
48
56
|
|
49
57
|
The default is to use filesystem lockfiles, usually in <tt>/tmp/lock_method/*</tt>.
|
data/lib/lock_method.rb
CHANGED
data/lib/lock_method/lock.rb
CHANGED
@@ -7,10 +7,10 @@ module LockMethod
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
def klass_name(obj)
|
10
|
-
obj.is_a?(::Class) ? obj.to_s : obj.class.to_s
|
10
|
+
(obj.is_a?(::Class) or obj.is_a?(::Module)) ? obj.to_s : obj.class.to_s
|
11
11
|
end
|
12
12
|
def method_delimiter(obj)
|
13
|
-
obj.is_a?(::Class) ? '.' : '#'
|
13
|
+
(obj.is_a?(::Class) or obj.is_a?(::Module)) ? '.' : '#'
|
14
14
|
end
|
15
15
|
def method_signature(obj, method_id)
|
16
16
|
[ klass_name(obj), method_id ].join method_delimiter(obj)
|
@@ -85,7 +85,7 @@ module LockMethod
|
|
85
85
|
end
|
86
86
|
|
87
87
|
def cache_key
|
88
|
-
if obj.is_a? ::
|
88
|
+
if obj.is_a?(::Class) or obj.is_a?(::Module)
|
89
89
|
[ 'LockMethod', 'Lock', method_signature ].join ','
|
90
90
|
else
|
91
91
|
[ 'LockMethod', 'Lock', method_signature, obj_hash ].join ','
|
@@ -93,7 +93,7 @@ module LockMethod
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def obj_hash
|
96
|
-
@obj_hash ||= obj.hash
|
96
|
+
@obj_hash ||= obj.respond_to?(:method_lock_hash) ? obj.method_lock_hash : obj.hash
|
97
97
|
end
|
98
98
|
|
99
99
|
def in_force?
|
data/lib/lock_method/version.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -26,10 +26,19 @@ class Blog1
|
|
26
26
|
end
|
27
27
|
lock_method :get_latest_entries2, 5 # second
|
28
28
|
def hash
|
29
|
+
raise "Used hash"
|
30
|
+
end
|
31
|
+
def method_lock_hash
|
29
32
|
name.hash
|
30
33
|
end
|
31
34
|
end
|
32
35
|
|
36
|
+
class Blog1a < Blog1
|
37
|
+
def method_lock_hash
|
38
|
+
raise "Used method_lock_hash"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
33
42
|
class Blog2
|
34
43
|
class << self
|
35
44
|
def get_latest_entries
|
@@ -45,6 +54,21 @@ class Blog2
|
|
45
54
|
end
|
46
55
|
end
|
47
56
|
|
57
|
+
module BlogM
|
58
|
+
def self.get_latest_entries
|
59
|
+
sleep 8
|
60
|
+
'danke schoen'
|
61
|
+
end
|
62
|
+
def self.get_latest_entries2
|
63
|
+
sleep 8
|
64
|
+
["voo vaa #{name}"]
|
65
|
+
end
|
66
|
+
class << self
|
67
|
+
lock_method :get_latest_entries
|
68
|
+
lock_method :get_latest_entries2, 5 # second
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
48
72
|
class Test::Unit::TestCase
|
49
73
|
|
50
74
|
end
|
data/test/shared_tests.rb
CHANGED
@@ -29,6 +29,25 @@ module SharedTests
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
def test_module_method_locked_by_normally_terminating_process
|
33
|
+
pid = Kernel.fork { BlogM.get_latest_entries }
|
34
|
+
|
35
|
+
# give it a bit of time to lock
|
36
|
+
sleep 1
|
37
|
+
|
38
|
+
# the blocker won't have finished
|
39
|
+
assert_raises(LockMethod::Locked) do
|
40
|
+
BlogM.get_latest_entries
|
41
|
+
end
|
42
|
+
|
43
|
+
# let the blocker finish
|
44
|
+
Process.wait pid
|
45
|
+
|
46
|
+
assert_nothing_raised do
|
47
|
+
BlogM.get_latest_entries
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
32
51
|
def test_locked_by_SIGKILLed_process
|
33
52
|
pid = Kernel.fork { Blog2.get_latest_entries }
|
34
53
|
|
@@ -4,7 +4,7 @@ require 'memcached'
|
|
4
4
|
|
5
5
|
class TestMemcachedStorage < Test::Unit::TestCase
|
6
6
|
def setup
|
7
|
-
my_cache = Memcached.new 'localhost:11211'
|
7
|
+
my_cache = Memcached.new 'localhost:11211', :retry_timeout => 1, :server_failure_limit => 25
|
8
8
|
my_cache.flush
|
9
9
|
LockMethod.config.storage = my_cache
|
10
10
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lock_method
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 3
|
10
|
+
version: 0.1.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Seamus Abshere
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-03-
|
18
|
+
date: 2011-03-12 23:00:00 -06:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -145,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
145
|
requirements: []
|
146
146
|
|
147
147
|
rubyforge_project: lock_method
|
148
|
-
rubygems_version: 1.
|
148
|
+
rubygems_version: 1.6.2
|
149
149
|
signing_key:
|
150
150
|
specification_version: 3
|
151
151
|
summary: Lets you lock methods (to memcached, redis, etc.) as though you had a lockfile for each one
|