lock_method 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -56,4 +56,5 @@ end
56
56
  unless ::Object.method_defined? :lock_method
57
57
  ::Object.send :include, ::LockMethod::InstanceMethods
58
58
  ::Class.send :include, ::LockMethod::ClassMethods
59
+ ::Module.extend ::LockMethod::ClassMethods
59
60
  end
@@ -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? ::Class
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?
@@ -1,3 +1,3 @@
1
1
  module LockMethod
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
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: 31
5
- prerelease: false
4
+ hash: 29
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 2
10
- version: 0.1.2
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-07 00:00:00 -06:00
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.3.7
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