locker 0.3.2 → 0.4.0
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.
- 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
|