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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1623bce6a4448a47c0f7244284c37a68b40a9fb3
4
- data.tar.gz: c4b81eada8d4cf229eda2854308da3f7a13d13d3
3
+ metadata.gz: 3af785ef3147f838f184baa9f7843efd53b8e825
4
+ data.tar.gz: 43c060bb7b1440a18c3c651dc5d348d072bf58cb
5
5
  SHA512:
6
- metadata.gz: eb8b6a9996aeacd61f13101c8c84d0becdddd62caaaa2672f926934fb2f7ea2c5c403d50ff8ceb756c321bf2d9d77eaac2bc4c81ef9fc66bb220e8fa135543e7
7
- data.tar.gz: 127921d87034603b81452a88bf578913f5b6cdaac722fd9bb8f05b43ba16c6e7ab05eab3c395b1297f72b8f6f097b538623342c357d36e8be3ca1c8b7b5d6135
6
+ metadata.gz: 44ebab072cb5ce6790ca98770f87ab47e31acdcf1f6c0f2d2a72682f3e7d87724532e7ba6ec2df8db520098cd28ed0fa61639fd4ce6e6161149d677dbaf78dac
7
+ data.tar.gz: f5268918d45c633d082f225bef6c69e5391d19e2e9b0a70163159ca5ed18172886203fe304c85ced60c9386ea7ee60fab4a7a9d275b989a41e68c46facf88b71
@@ -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 = key
17
- @crc = convert_to_crc(key)
18
- @lockspace = (options[:lockspace] || 1)
19
- @blocking = !!options[:blocking]
20
- @locked = false
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
- sleep 0.005
42
+ break if break_at && break_at < Time.now
43
+ sleep @block_spin_wait
37
44
  end
38
45
 
39
46
  if @locked
@@ -1,3 +1,3 @@
1
1
  class Locker
2
- VERSION = "0.3.2"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -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.3.2
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-04-07 00:00:00.000000000 Z
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.4.8
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