ruby_redis_lock 0.1.0 → 0.1.1

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.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.loadpath +5 -5
  4. data/.project +17 -17
  5. data/.rspec +3 -0
  6. data/Gemfile +4 -4
  7. data/Gemfile.lock +4 -0
  8. data/Readme.md +83 -85
  9. data/lib/ruby_redis_lock/ruby_redis_lock.rb +55 -65
  10. data/lib/ruby_redis_lock/version.rb +3 -0
  11. data/lib/ruby_redis_lock.rb +8 -8
  12. data/redis_test.bat +1 -1
  13. data/ruby_redis_lock.gemspec +24 -21
  14. data/spec/{acquire_lock_spec.rb → lib/acquire_lock_spec.rb} +43 -43
  15. data/spec/{lock_spec.rb → lib/lock_spec.rb} +72 -72
  16. data/spec/{release_lock_spec.rb → lib/release_lock_spec.rb} +21 -21
  17. data/spec/{try_acquire_lock_spec.rb → lib/try_acquire_lock_spec.rb} +30 -30
  18. data/spec/spec_config.rb +10 -0
  19. data/spec/spec_helper.rb +11 -20
  20. data/test.conf +1 -1
  21. metadata +27 -70
  22. data/coverage/.resultset.json +0 -240
  23. data/coverage/assets/0.5.3/app.js +0 -88
  24. data/coverage/assets/0.5.3/fancybox/blank.gif +0 -0
  25. data/coverage/assets/0.5.3/fancybox/fancy_close.png +0 -0
  26. data/coverage/assets/0.5.3/fancybox/fancy_loading.png +0 -0
  27. data/coverage/assets/0.5.3/fancybox/fancy_nav_left.png +0 -0
  28. data/coverage/assets/0.5.3/fancybox/fancy_nav_right.png +0 -0
  29. data/coverage/assets/0.5.3/fancybox/fancy_shadow_e.png +0 -0
  30. data/coverage/assets/0.5.3/fancybox/fancy_shadow_n.png +0 -0
  31. data/coverage/assets/0.5.3/fancybox/fancy_shadow_ne.png +0 -0
  32. data/coverage/assets/0.5.3/fancybox/fancy_shadow_nw.png +0 -0
  33. data/coverage/assets/0.5.3/fancybox/fancy_shadow_s.png +0 -0
  34. data/coverage/assets/0.5.3/fancybox/fancy_shadow_se.png +0 -0
  35. data/coverage/assets/0.5.3/fancybox/fancy_shadow_sw.png +0 -0
  36. data/coverage/assets/0.5.3/fancybox/fancy_shadow_w.png +0 -0
  37. data/coverage/assets/0.5.3/fancybox/fancy_title_left.png +0 -0
  38. data/coverage/assets/0.5.3/fancybox/fancy_title_main.png +0 -0
  39. data/coverage/assets/0.5.3/fancybox/fancy_title_over.png +0 -0
  40. data/coverage/assets/0.5.3/fancybox/fancy_title_right.png +0 -0
  41. data/coverage/assets/0.5.3/fancybox/fancybox-x.png +0 -0
  42. data/coverage/assets/0.5.3/fancybox/fancybox-y.png +0 -0
  43. data/coverage/assets/0.5.3/fancybox/fancybox.png +0 -0
  44. data/coverage/assets/0.5.3/fancybox/jquery.fancybox-1.3.1.css +0 -363
  45. data/coverage/assets/0.5.3/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
  46. data/coverage/assets/0.5.3/favicon_green.png +0 -0
  47. data/coverage/assets/0.5.3/favicon_red.png +0 -0
  48. data/coverage/assets/0.5.3/favicon_yellow.png +0 -0
  49. data/coverage/assets/0.5.3/highlight.css +0 -129
  50. data/coverage/assets/0.5.3/highlight.pack.js +0 -1
  51. data/coverage/assets/0.5.3/jquery-1.6.2.min.js +0 -18
  52. data/coverage/assets/0.5.3/jquery.dataTables.min.js +0 -152
  53. data/coverage/assets/0.5.3/jquery.timeago.js +0 -141
  54. data/coverage/assets/0.5.3/jquery.url.js +0 -174
  55. data/coverage/assets/0.5.3/loading.gif +0 -0
  56. data/coverage/assets/0.5.3/magnify.png +0 -0
  57. data/coverage/assets/0.5.3/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  58. data/coverage/assets/0.5.3/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  59. data/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  60. data/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  61. data/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  62. data/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  63. data/coverage/assets/0.5.3/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  64. data/coverage/assets/0.5.3/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  65. data/coverage/assets/0.5.3/smoothness/images/ui-icons_222222_256x240.png +0 -0
  66. data/coverage/assets/0.5.3/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  67. data/coverage/assets/0.5.3/smoothness/images/ui-icons_454545_256x240.png +0 -0
  68. data/coverage/assets/0.5.3/smoothness/images/ui-icons_888888_256x240.png +0 -0
  69. data/coverage/assets/0.5.3/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  70. data/coverage/assets/0.5.3/smoothness/jquery-ui-1.8.4.custom.css +0 -295
  71. data/coverage/assets/0.5.3/stylesheet.css +0 -383
  72. data/coverage/index.html +0 -1575
  73. data/ruby_redis_lock.rdb +0 -1
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e55f4562edfe070bce4409e5ac5f80599b44d1b02fad75ca5beeab86afcfb43a
4
+ data.tar.gz: 37730f073baa006452b6c47141cecc1171f241e150957408fa9fad769f180a0d
5
+ SHA512:
6
+ metadata.gz: 8324228d9255e2720a994930ca6670706f58f2bf74b827651e49a4d121df757df9b0b782df8b997b8cebcb5a4bd52e04c45097c11ef154e36161658a1fa4adce
7
+ data.tar.gz: '0792e704125408ffbc7b11a21b71865e27b620b5653ea78d5e67d10dd0a737259125191fbbd4d398481a292c597a2f44cf1832da48a513aa11ef35a7e2d51109'
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .commit-msg*
2
+ coverage
data/.loadpath CHANGED
@@ -1,5 +1,5 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <loadpath>
3
- <pathentry path="" type="src"/>
4
- <pathentry path="org.rubypeople.rdt.launching.RUBY_CONTAINER" type="con"/>
5
- </loadpath>
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <loadpath>
3
+ <pathentry path="" type="src"/>
4
+ <pathentry path="org.rubypeople.rdt.launching.RUBY_CONTAINER" type="con"/>
5
+ </loadpath>
data/.project CHANGED
@@ -1,17 +1,17 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <projectDescription>
3
- <name>ruby_redis_lock</name>
4
- <comment></comment>
5
- <projects>
6
- </projects>
7
- <buildSpec>
8
- <buildCommand>
9
- <name>org.rubypeople.rdt.core.rubybuilder</name>
10
- <arguments>
11
- </arguments>
12
- </buildCommand>
13
- </buildSpec>
14
- <natures>
15
- <nature>org.rubypeople.rdt.core.rubynature</nature>
16
- </natures>
17
- </projectDescription>
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <projectDescription>
3
+ <name>ruby_redis_lock</name>
4
+ <comment></comment>
5
+ <projects>
6
+ </projects>
7
+ <buildSpec>
8
+ <buildCommand>
9
+ <name>org.rubypeople.rdt.core.rubybuilder</name>
10
+ <arguments>
11
+ </arguments>
12
+ </buildCommand>
13
+ </buildSpec>
14
+ <natures>
15
+ <nature>org.rubypeople.rdt.core.rubynature</nature>
16
+ </natures>
17
+ </projectDescription>
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile CHANGED
@@ -1,5 +1,5 @@
1
- source 'http://rubygems.org'
2
-
3
- gem 'rspec'
4
- gem 'redis', :git=> 'git://github.com/ezmobius/redis-rb.git'
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'rspec'
4
+ gem 'redis', :git=> 'git://github.com/ezmobius/redis-rb.git'
5
5
  gem 'simplecov'
data/Gemfile.lock CHANGED
@@ -23,9 +23,13 @@ GEM
23
23
  simplecov-html (0.5.3)
24
24
 
25
25
  PLATFORMS
26
+ ruby
26
27
  x86-mingw32
27
28
 
28
29
  DEPENDENCIES
29
30
  redis!
30
31
  rspec
31
32
  simplecov
33
+
34
+ BUNDLED WITH
35
+ 1.16.1
data/Readme.md CHANGED
@@ -1,85 +1,83 @@
1
- Ruby-Redis-Lock - Distributed lock for Ruby (using Redis)
2
- =======================================================
3
-
4
- A distributed lock that utilizes Redis.
5
- It also handles failures.
6
- If a process acquires a lock for more than some period of time (default is 60 seconds),
7
- the lock is automatically released.
8
-
9
- Basically, it follows the algorithm explained here: http://redis.io/commands/setnx
10
-
11
- Nevertheless, the algorithm on releasing a lock is improved. Please the comments in http://redis.io/commands/setnx
12
-
13
- The example of using it:
14
-
15
- ```ruby
16
-
17
- $redis = Redis.new
18
-
19
- $redis.lock('some_name', 60, 10) do
20
-
21
- #
22
- # Do some tasks here
23
- #
24
-
25
- end
26
-
27
- ```
28
-
29
- The API is below:
30
-
31
- ```ruby
32
- lock(lock_name, processing_timeout=60, acquiring_timout=10)
33
- ```
34
-
35
- You can change processing_timeout and acquiring_timeout.
36
-
37
- The lock will be expired after it has been acquired for a period of time longer than processing_timeout (in seconds).
38
-
39
- An error will be raised if the lock cannot be acquired within acquiring_timeout (in seconds).
40
-
41
- Installation
42
- ------------------
43
-
44
- You can install it directly by:
45
-
46
- ```sh
47
- gem install ruby_redis_lock
48
- ```
49
-
50
- or put it in your Gemfile:
51
-
52
- ```sh
53
- gen 'ruby_redis_lock'
54
- ```
55
-
56
- Help me
57
- --------------
58
-
59
- 1. Clone the project
60
- 2. Install all dependencies with
61
-
62
- ```
63
- bundle install
64
- ```
65
-
66
- 3. Start Redis and running all test cases
67
-
68
- ```
69
- bundle exec rspec spec/*
70
- ```
71
-
72
- 4. Add a feature, if everything is ok
73
- 5. Write tests for the feature
74
- 6. Send me a pull request
75
-
76
-
77
- Author
78
- ------------
79
- Tanin Na Nakorn
80
-
81
-
82
- Boring legal stuff
83
- -------------------
84
-
85
- You can do whatever you want with it
1
+ Ruby-Redis-Lock - Distributed lock for Ruby (using Redis)
2
+ =======================================================
3
+
4
+ A distributed lock that utilizes Redis.
5
+ It also handles failures.
6
+ If a process acquires a lock for more than some period of time (default is 60 seconds),
7
+ the lock is automatically released.
8
+
9
+ Basically, it follows the algorithm explained here: http://redis.io/commands/setnx
10
+
11
+ I believe it is an optimistic locking algorithm.
12
+
13
+ Nevertheless, the algorithm on releasing a lock is improved. Please the comments in http://redis.io/commands/setnx
14
+
15
+ The example of using it:
16
+
17
+ ```ruby
18
+
19
+ $redis = Redis.new
20
+
21
+ $redis.lock('some_name', 60, 10) do
22
+
23
+ #
24
+ # Do some tasks here
25
+ #
26
+
27
+ end
28
+
29
+ ```
30
+
31
+ The API is below:
32
+
33
+ ```ruby
34
+ lock(lock_name, processing_timeout=60, acquiring_timout=10)
35
+ ```
36
+
37
+ You can change processing_timeout and acquiring_timeout.
38
+
39
+ The lock will be expired after it has been acquired for a period of time longer than processing_timeout (in seconds).
40
+
41
+ An error will be raised if the lock cannot be acquired within acquiring_timeout (in seconds).
42
+
43
+ Installation
44
+ ------------------
45
+
46
+ You can install it directly by:
47
+
48
+ ```sh
49
+ gem install ruby_redis_lock
50
+ ```
51
+
52
+ or put it in your Gemfile:
53
+
54
+ ```sh
55
+ gem 'ruby_redis_lock'
56
+ ```
57
+
58
+ Help me
59
+ --------------
60
+
61
+ 1. Fork the project
62
+ 2. Install all dependencies with
63
+ ```
64
+ bundle install
65
+ ```
66
+ 3. Start Redis and running all test cases
67
+ ```
68
+ bundle exec rspec spec/*
69
+ ```
70
+ 4. Add a feature, if everything is ok
71
+ 5. Write tests for the feature
72
+ 6. Send me a pull request
73
+
74
+
75
+ Author
76
+ ------------
77
+ Tanin Na Nakorn
78
+
79
+
80
+ Boring legal stuff
81
+ -------------------
82
+
83
+ You can do whatever you want with it
@@ -1,66 +1,56 @@
1
- module RubyRedisLock
2
-
3
-
4
- def lock(lock_name, processing_timeout=60, acquiring_timout=10)
5
- acquire_lock(lock_name, processing_timeout, acquiring_timout)
6
- yield
7
- ensure
8
- release_lock(lock_name, processing_timeout)
9
- end
10
-
11
-
12
- private
13
- def acquire_lock(lock_name, processing_timeout=60, acquiring_timeout=10)
14
-
15
- start_time = Time.now.to_i
16
-
17
- while !try_acquire_lock(lock_name, processing_timeout)
18
-
19
- sleep(rand(100).to_f/100.0)
20
-
21
- if (Time.now.to_i - start_time) > acquiring_timeout
22
- raise Exception, "Acquiring lock timeout > #{acquiring_timeout} seconds"
23
- end
24
-
25
- end
26
-
27
- return true
28
-
29
- end
30
-
31
- def try_acquire_lock(lock_name, processing_timeout=60)
32
-
33
- ret = self.setnx(ruby_redis_lock_key(lock_name), "#{Time.now.to_i + processing_timeout}")
34
- return true if ret == true
35
-
36
- expiration = self.get(ruby_redis_lock_key(lock_name)).to_i
37
- return false if Time.now.to_i < expiration
38
-
39
- previous_expiration = self.getset(ruby_redis_lock_key(lock_name), "#{Time.now.to_i + processing_timeout}").to_i
40
- return true if expiration == previous_expiration
41
-
42
- return false
43
-
44
- end
45
-
46
- def release_lock(lock_name, processing_timeout=60)
47
-
48
- expiration = self.get(ruby_redis_lock_key(lock_name)).to_i
49
- return false if Time.now.to_i > expiration
50
-
51
- previous_expiration = self.getset(ruby_redis_lock_key(lock_name), "#{Time.now.to_i + processing_timeout}").to_i
52
-
53
- if expiration == previous_expiration # it still owns the lock
54
- self.del(ruby_redis_lock_key(lock_name))
55
- return true
56
- end
57
-
58
- return false
59
- end
60
-
61
- def ruby_redis_lock_key(lock_name)
62
- "RubyRedisLock:#{lock_name}"
63
- end
64
-
65
-
1
+ module RubyRedisLock
2
+
3
+ LockAcquisitionTimeoutException = Class.new(StandardError)
4
+
5
+ def lock(lock_name, processing_timeout=60, acquiring_timout=10)
6
+ lock_acquired = acquire_lock(lock_name, processing_timeout, acquiring_timout)
7
+ yield
8
+ ensure
9
+ release_lock(lock_name, processing_timeout) if lock_acquired
10
+ end
11
+
12
+ private
13
+
14
+ def acquire_lock(lock_name, processing_timeout=60, acquiring_timeout=10)
15
+ start_time = Time.now.to_i
16
+ while !try_acquire_lock(lock_name, processing_timeout)
17
+ sleep 0.5
18
+ if (Time.now.to_i - start_time) > acquiring_timeout
19
+ raise LockAcquisitionTimeoutException, "Acquiring lock timeout > #{acquiring_timeout} seconds"
20
+ end
21
+ end
22
+ true
23
+ end
24
+
25
+ def try_acquire_lock(lock_name, processing_timeout=60)
26
+ ret = self.setnx(ruby_redis_lock_key(lock_name), "#{Time.now.to_i + processing_timeout}")
27
+ return true if ret == true
28
+
29
+ expiration = self.get(ruby_redis_lock_key(lock_name)).to_i
30
+ return false if Time.now.to_i < expiration
31
+
32
+ previous_expiration = self.getset(ruby_redis_lock_key(lock_name), "#{Time.now.to_i + processing_timeout}").to_i
33
+ return true if expiration == previous_expiration
34
+
35
+ false
36
+ end
37
+
38
+ def release_lock(lock_name, processing_timeout=60)
39
+ expiration = self.get(ruby_redis_lock_key(lock_name)).to_i
40
+ return false if Time.now.to_i > expiration
41
+
42
+ previous_expiration = self.getset(ruby_redis_lock_key(lock_name), "#{Time.now.to_i + processing_timeout}").to_i
43
+
44
+ if expiration == previous_expiration # it still owns the lock
45
+ self.del(ruby_redis_lock_key(lock_name))
46
+ return true
47
+ end
48
+
49
+ false
50
+ end
51
+
52
+ def ruby_redis_lock_key(lock_name)
53
+ "RubyRedisLock:#{lock_name}"
54
+ end
55
+
66
56
  end
@@ -0,0 +1,3 @@
1
+ module RubyRedisLock
2
+ VERSION = "0.1.1"
3
+ end
@@ -1,9 +1,9 @@
1
- require 'redis'
2
-
3
- require File.expand_path('../ruby_redis_lock/ruby_redis_lock', __FILE__)
4
-
5
-
6
- class Redis
7
- include RubyRedisLock
8
-
1
+ require 'redis'
2
+
3
+ require File.expand_path('../ruby_redis_lock/ruby_redis_lock', __FILE__)
4
+
5
+
6
+ class Redis
7
+ include RubyRedisLock
8
+
9
9
  end
data/redis_test.bat CHANGED
@@ -1,2 +1,2 @@
1
- "C:\redis\redis-server" test.conf
1
+ "C:\redis\redis-server" test.conf
2
2
  pause
@@ -1,21 +1,24 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
-
4
- Gem::Specification.new do |s|
5
- s.name = "ruby_redis_lock"
6
- s.version = "0.1.0"
7
- s.platform = Gem::Platform::RUBY
8
- s.authors = ["Tanin Na Nakorn"]
9
- s.email = ["tanin47@yahoo.com"]
10
- s.homepage = "http://github.com/tanin47/ruby_redis_lock"
11
- s.summary = %q{RubyRedisLock is a distributed lock for Ruby (using Redis)}
12
- s.description = %q{distributed lock for Ruby (using Redis)}
13
-
14
- s.rubyforge_project = "ruby_redis_lock"
15
-
16
- s.files = `git ls-files`.split("\n")
17
- s.test_files = `git ls-files -- {coverage,spec}/*`.split("\n")
18
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
- s.require_paths = ["lib"]
20
-
21
- end
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ruby_redis_lock/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "ruby_redis_lock"
7
+ spec.version = RubyRedisLock::VERSION
8
+ spec.platform = Gem::Platform::RUBY
9
+ spec.authors = ["Tanin Na Nakorn", "Mike Gregory"]
10
+ spec.email = ["tanin47@yahoo.com", "mgregory@carecloud.com"]
11
+ spec.homepage = "http://github.com/mgregory-carecloud/ruby_redis_lock"
12
+ spec.license = "MIT"
13
+
14
+ spec.summary = %q{RubyRedisLock is a distributed lock for Ruby (using Redis)}
15
+ spec.description = %q{distributed lock for Ruby (using Redis)}
16
+
17
+ spec.rubyforge_project = "ruby_redis_lock"
18
+
19
+ spec.files = `git ls-files`.split("\n")
20
+ spec.test_files = `git ls-files -- {coverage,spec}/**/*_spec.rb`.split("\n")
21
+ spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ end
@@ -1,44 +1,44 @@
1
- require 'spec_helper'
2
-
3
- describe 'acquire_lock' do
4
-
5
- it "acquires the lock if it does not exist" do
6
- @redis.send(:acquire_lock, "test").should == true
7
- end
8
-
9
- it "acquires the lock if it is expired" do
10
-
11
- @redis.send(:acquire_lock, "test", 0.1).should == true
12
-
13
- sleep(1)
14
- @redis.send(:acquire_lock, "test").should == true
15
-
16
- end
17
-
18
- it "raise errors when acquiring the lock takes too long" do
19
-
20
- @redis.send(:acquire_lock, "test", 60, 60).should == true
21
-
22
- lambda { @redis.send(:acquire_lock, "test", 60, 1) }.should raise_error
23
-
24
- end
25
-
26
- it "waits until the other thread finishes and acquire lock" do
27
-
28
- start_time = Time.now.to_i
29
- @redis.send(:acquire_lock, "test", 60, 60).should == true
30
-
31
- Thread.new {
32
- Thread.current.join(1)
33
- sleep(5)
34
- @redis.send(:release_lock, "test", 60).should == true
35
- }
36
-
37
- Thread.current.join(1)
38
- @redis.send(:acquire_lock, "test", 60, 20).should == true
39
-
40
- (Time.now.to_i - start_time).should be > 4
41
-
42
- end
43
-
1
+ require 'spec_helper'
2
+
3
+ describe 'acquire_lock' do
4
+
5
+ it "acquires the lock if it does not exist" do
6
+ @redis.send(:acquire_lock, "test").should == true
7
+ end
8
+
9
+ it "acquires the lock if it is expired" do
10
+
11
+ @redis.send(:acquire_lock, "test", 0.1).should == true
12
+
13
+ sleep(1)
14
+ @redis.send(:acquire_lock, "test").should == true
15
+
16
+ end
17
+
18
+ it "raise errors when acquiring the lock takes too long" do
19
+
20
+ @redis.send(:acquire_lock, "test", 60, 60).should == true
21
+
22
+ lambda { @redis.send(:acquire_lock, "test", 60, 1) }.should raise_error
23
+
24
+ end
25
+
26
+ it "waits until the other thread finishes and acquire lock" do
27
+
28
+ start_time = Time.now.to_i
29
+ @redis.send(:acquire_lock, "test", 60, 60).should == true
30
+
31
+ Thread.new {
32
+ Thread.current.join(1)
33
+ sleep(5)
34
+ @redis.send(:release_lock, "test", 60).should == true
35
+ }
36
+
37
+ Thread.current.join(1)
38
+ @redis.send(:acquire_lock, "test", 60, 20).should == true
39
+
40
+ (Time.now.to_i - start_time).should be > 4
41
+
42
+ end
43
+
44
44
  end