berater 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/berater/concurrency_limiter.rb +3 -3
- data/lib/berater/version.rb +1 -1
- data/spec/concurrency_limiter_spec.rb +33 -20
- data/spec/concurrency_lock_spec.rb +68 -26
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8ca6fba7e38a014eed325df41dda7372b41ff62d9e78b61565f4d915d8b4677
|
4
|
+
data.tar.gz: 1fae864b93de87ea3dc70531f3f8697e80af526aea53d8ddfe2076eac9bbd61d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b4b37134edece0657ea9be15119fe25b2208d554b9dbf56edd04f8e5acff77569022be025ec428b81ab1971171ae468e389a9568d7ad0163b0966e622a09f2e
|
7
|
+
data.tar.gz: bd927303eb1475e79a26161a184205008926f95c59a06eee43f453d5e464d15c205a91bffd36228ae28bc5d27f0fa32faebc7c5870ec5d1779bd6c57ecdc0fe2
|
@@ -55,7 +55,7 @@ module Berater
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def expired?
|
58
|
-
@locked_at + limiter.timeout < Time.now
|
58
|
+
limiter.timeout > 0 && @locked_at + limiter.timeout < Time.now
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -95,7 +95,7 @@ module Berater
|
|
95
95
|
|
96
96
|
count = count + 1
|
97
97
|
end
|
98
|
-
|
98
|
+
elseif capacity > 0 then
|
99
99
|
count = 1
|
100
100
|
lock = "1"
|
101
101
|
|
@@ -138,7 +138,7 @@ module Berater
|
|
138
138
|
begin
|
139
139
|
yield lock
|
140
140
|
ensure
|
141
|
-
release
|
141
|
+
lock.release
|
142
142
|
end
|
143
143
|
else
|
144
144
|
lock
|
data/lib/berater/version.rb
CHANGED
@@ -69,29 +69,42 @@ describe Berater::ConcurrencyLimiter do
|
|
69
69
|
expect {|b| limiter.limit(&b) }.to yield_control
|
70
70
|
end
|
71
71
|
|
72
|
-
it 'works many times if workers
|
72
|
+
it 'works many times if workers release locks' do
|
73
73
|
30.times do
|
74
74
|
expect {|b| limiter.limit(&b) }.to yield_control
|
75
75
|
end
|
76
|
+
|
77
|
+
30.times do
|
78
|
+
lock = limiter.limit
|
79
|
+
lock.release
|
80
|
+
end
|
76
81
|
end
|
77
82
|
|
78
83
|
it 'limits excessive calls' do
|
79
84
|
expect(limiter.limit).to be_a Berater::ConcurrencyLimiter::Lock
|
80
85
|
expect(limiter.limit).to be_a Berater::ConcurrencyLimiter::Lock
|
81
86
|
|
82
|
-
expect
|
87
|
+
expect(limiter).to be_incapacitated
|
83
88
|
end
|
84
89
|
|
85
90
|
it 'times out locks' do
|
86
91
|
expect(limiter.limit).to be_a Berater::ConcurrencyLimiter::Lock
|
87
92
|
expect(limiter.limit).to be_a Berater::ConcurrencyLimiter::Lock
|
88
|
-
expect
|
93
|
+
expect(limiter).to be_incapacitated
|
89
94
|
|
90
95
|
Timecop.travel(1)
|
91
96
|
|
92
97
|
expect(limiter.limit).to be_a Berater::ConcurrencyLimiter::Lock
|
93
98
|
expect(limiter.limit).to be_a Berater::ConcurrencyLimiter::Lock
|
94
|
-
expect
|
99
|
+
expect(limiter).to be_incapacitated
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'with capacity 0' do
|
103
|
+
let(:limiter) { described_class.new(0) }
|
104
|
+
|
105
|
+
it 'always fails' do
|
106
|
+
expect(limiter).to be_incapacitated
|
107
|
+
end
|
95
108
|
end
|
96
109
|
end
|
97
110
|
|
@@ -104,8 +117,8 @@ describe Berater::ConcurrencyLimiter do
|
|
104
117
|
it 'works as expected' do
|
105
118
|
expect(limiter_one.limit).to be_a Berater::ConcurrencyLimiter::Lock
|
106
119
|
|
107
|
-
expect
|
108
|
-
expect
|
120
|
+
expect(limiter_one).to be_incapacitated
|
121
|
+
expect(limiter_two).to be_incapacitated
|
109
122
|
end
|
110
123
|
end
|
111
124
|
|
@@ -145,22 +158,22 @@ describe Berater::ConcurrencyLimiter do
|
|
145
158
|
one_lock = limiter_one.limit
|
146
159
|
expect(one_lock).to be_a Berater::ConcurrencyLimiter::Lock
|
147
160
|
|
148
|
-
expect
|
149
|
-
expect
|
161
|
+
expect(limiter_one).to be_incapacitated
|
162
|
+
expect(limiter_two).not_to be_incapacitated
|
150
163
|
|
151
164
|
two_lock = limiter_two.limit
|
152
165
|
expect(two_lock).to be_a Berater::ConcurrencyLimiter::Lock
|
153
166
|
|
154
|
-
expect
|
155
|
-
expect
|
167
|
+
expect(limiter_one).to be_incapacitated
|
168
|
+
expect(limiter_two).to be_incapacitated
|
156
169
|
|
157
170
|
one_lock.release
|
158
|
-
expect
|
159
|
-
expect
|
171
|
+
expect(limiter_one).to be_incapacitated
|
172
|
+
expect(limiter_two).not_to be_incapacitated
|
160
173
|
|
161
174
|
two_lock.release
|
162
|
-
expect
|
163
|
-
expect
|
175
|
+
expect(limiter_one).not_to be_incapacitated
|
176
|
+
expect(limiter_two).not_to be_incapacitated
|
164
177
|
end
|
165
178
|
end
|
166
179
|
|
@@ -169,20 +182,20 @@ describe Berater::ConcurrencyLimiter do
|
|
169
182
|
let(:limiter_two) { described_class.new(1, key: :two) }
|
170
183
|
|
171
184
|
it 'works as expected' do
|
172
|
-
expect
|
173
|
-
expect
|
185
|
+
expect(limiter_one).not_to be_incapacitated
|
186
|
+
expect(limiter_two).not_to be_incapacitated
|
174
187
|
|
175
188
|
one_lock = limiter_one.limit
|
176
189
|
expect(one_lock).to be_a Berater::ConcurrencyLimiter::Lock
|
177
190
|
|
178
|
-
expect
|
179
|
-
expect
|
191
|
+
expect(limiter_one).to be_incapacitated
|
192
|
+
expect(limiter_two).not_to be_incapacitated
|
180
193
|
|
181
194
|
two_lock = limiter_two.limit
|
182
195
|
expect(two_lock).to be_a Berater::ConcurrencyLimiter::Lock
|
183
196
|
|
184
|
-
expect
|
185
|
-
expect
|
197
|
+
expect(limiter_one).to be_incapacitated
|
198
|
+
expect(limiter_two).to be_incapacitated
|
186
199
|
end
|
187
200
|
end
|
188
201
|
|
@@ -1,48 +1,90 @@
|
|
1
1
|
describe Berater::ConcurrencyLimiter::Lock do
|
2
|
-
subject { Berater.limit(1, timeout: 1) }
|
3
|
-
|
4
2
|
before { Berater.mode = :concurrency }
|
5
3
|
|
6
|
-
|
7
|
-
|
4
|
+
let(:limiter) { Berater.new(:concurrency, 3) }
|
5
|
+
|
6
|
+
describe '#contention' do
|
7
|
+
it 'tracks contention' do
|
8
|
+
lock_1 = limiter.limit
|
9
|
+
expect(lock_1.contention).to eq 1
|
10
|
+
|
11
|
+
lock_2 = limiter.limit
|
12
|
+
expect(lock_2.contention).to eq 2
|
8
13
|
|
9
|
-
|
10
|
-
|
14
|
+
limiter.limit do |lock_3|
|
15
|
+
expect(lock_3.contention).to eq 3
|
16
|
+
end
|
17
|
+
end
|
11
18
|
|
12
|
-
it
|
13
|
-
|
19
|
+
it 'works in block mode' do
|
20
|
+
lock_1 = limiter.limit
|
14
21
|
|
15
|
-
|
16
|
-
|
22
|
+
limiter.limit do |lock_2|
|
23
|
+
expect(lock_1.contention).to eq 1
|
24
|
+
expect(lock_2.contention).to eq 2
|
25
|
+
end
|
17
26
|
end
|
18
27
|
end
|
19
28
|
|
20
|
-
|
21
|
-
|
29
|
+
describe '#release' do
|
30
|
+
it 'can not be released twice' do
|
31
|
+
lock = limiter.limit
|
32
|
+
expect(lock.release).to be true
|
33
|
+
expect { lock.release }.to raise_error(RuntimeError, /already/)
|
34
|
+
end
|
22
35
|
|
23
|
-
it '
|
24
|
-
expect
|
36
|
+
it 'does not work in block mode' do
|
37
|
+
expect do
|
38
|
+
limiter.limit do |lock|
|
39
|
+
lock.release
|
40
|
+
end
|
41
|
+
end.to raise_error(RuntimeError, /already/)
|
25
42
|
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#released?' do
|
46
|
+
it 'works' do
|
47
|
+
lock = limiter.limit
|
48
|
+
expect(lock.released?).to be false
|
26
49
|
|
27
|
-
|
28
|
-
expect
|
50
|
+
lock.release
|
51
|
+
expect(lock.released?).to be true
|
29
52
|
end
|
30
53
|
|
31
|
-
it
|
54
|
+
it 'works in block mode' do
|
55
|
+
limiter.limit do |lock|
|
56
|
+
expect(lock.released?).to be false
|
57
|
+
end
|
58
|
+
end
|
32
59
|
end
|
33
60
|
|
34
|
-
describe '#
|
35
|
-
let(:
|
61
|
+
describe '#expired?' do
|
62
|
+
let!(:lock) { limiter.limit }
|
36
63
|
|
37
|
-
|
38
|
-
|
39
|
-
expect(lock_1.contention).to eq 1
|
64
|
+
context 'when timeout is not set' do
|
65
|
+
it { expect(limiter.timeout).to eq 0 }
|
40
66
|
|
41
|
-
|
42
|
-
|
67
|
+
it 'never expires' do
|
68
|
+
expect(lock.expired?).to be false
|
43
69
|
|
44
|
-
|
45
|
-
|
70
|
+
Timecop.travel(1_000)
|
71
|
+
|
72
|
+
expect(lock.expired?).to be false
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'when timeout is set and exceeded' do
|
77
|
+
before { Timecop.travel(1) }
|
78
|
+
|
79
|
+
let(:limiter) { Berater.new(:concurrency, 3, timeout: 1) }
|
80
|
+
|
81
|
+
it 'expires' do
|
82
|
+
expect(lock.expired?).to be true
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'fails to release' do
|
86
|
+
expect(lock.released?).to be false
|
87
|
+
expect { lock.release }.to raise_error(RuntimeError, /expired/)
|
46
88
|
end
|
47
89
|
end
|
48
90
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: berater
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Pepper
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-02-
|
11
|
+
date: 2021-02-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|