berater 0.1.3 → 0.1.4
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/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
|