locker 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/locker/advisory.rb +13 -6
- data/lib/locker/version.rb +1 -1
- data/spec/locker/advisory_spec.rb +21 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3af785ef3147f838f184baa9f7843efd53b8e825
|
4
|
+
data.tar.gz: 43c060bb7b1440a18c3c651dc5d348d072bf58cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44ebab072cb5ce6790ca98770f87ab47e31acdcf1f6c0f2d2a72682f3e7d87724532e7ba6ec2df8db520098cd28ed0fa61639fd4ce6e6161149d677dbaf78dac
|
7
|
+
data.tar.gz: f5268918d45c633d082f225bef6c69e5391d19e2e9b0a70163159ca5ed18172886203fe304c85ced60c9386ea7ee60fab4a7a9d275b989a41e68c46facf88b71
|
data/lib/locker/advisory.rb
CHANGED
@@ -13,11 +13,13 @@ class Locker
|
|
13
13
|
def initialize(key, options={})
|
14
14
|
raise ArgumentError, "key must be a string" unless key.is_a?(String)
|
15
15
|
|
16
|
-
@key
|
17
|
-
@crc
|
18
|
-
@lockspace
|
19
|
-
@blocking
|
20
|
-
@locked
|
16
|
+
@key = key
|
17
|
+
@crc = convert_to_crc(key)
|
18
|
+
@lockspace = (options[:lockspace] || 1)
|
19
|
+
@blocking = !!options[:blocking]
|
20
|
+
@locked = false
|
21
|
+
@block_timeout = options[:block_timeout]
|
22
|
+
@block_spin_wait = options[:block_spin_wait] || 0.005
|
21
23
|
|
22
24
|
if !@lockspace.is_a?(Integer) || @lockspace < MIN_LOCK || @lockspace > MAX_LOCK
|
23
25
|
raise ArgumentError, "The :lockspace option must be an integer between #{MIN_LOCK} and #{MAX_LOCK}"
|
@@ -32,8 +34,13 @@ class Locker
|
|
32
34
|
def run(&block)
|
33
35
|
connection = ActiveRecord::Base.connection_pool.checkout
|
34
36
|
connection.transaction :requires_new => true do
|
37
|
+
if @blocking && @block_timeout
|
38
|
+
break_at = Time.now + @block_timeout
|
39
|
+
end
|
40
|
+
|
35
41
|
while !get(connection) && @blocking
|
36
|
-
|
42
|
+
break if break_at && break_at < Time.now
|
43
|
+
sleep @block_spin_wait
|
37
44
|
end
|
38
45
|
|
39
46
|
if @locked
|
data/lib/locker/version.rb
CHANGED
@@ -72,6 +72,27 @@ describe Locker::Advisory do
|
|
72
72
|
expect(lock1_result).to be true
|
73
73
|
expect(lock2_result).to be true
|
74
74
|
end
|
75
|
+
|
76
|
+
it "blocks with a timeout" do
|
77
|
+
started_at = Time.now
|
78
|
+
t1 = Thread.new do
|
79
|
+
Locker::Advisory.run("foo") do
|
80
|
+
sleep 2
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
t2 = Thread.new do
|
85
|
+
sleep 0.5
|
86
|
+
Locker::Advisory.run("foo", :blocking => true, :block_timeout => 1) do
|
87
|
+
sleep 10 # never hits this
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
expect(t1.value).to be(true)
|
92
|
+
expect(t2.value).to be(false)
|
93
|
+
|
94
|
+
expect(Time.now - started_at).to be < 2.5
|
95
|
+
end
|
75
96
|
end
|
76
97
|
|
77
98
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: locker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Sutton
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-06-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -114,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
114
114
|
version: '0'
|
115
115
|
requirements: []
|
116
116
|
rubyforge_project: locker
|
117
|
-
rubygems_version: 2.
|
117
|
+
rubygems_version: 2.6.2
|
118
118
|
signing_key:
|
119
119
|
specification_version: 4
|
120
120
|
summary: Locker is a locking mechanism for limiting the concurrency of ruby code using
|