Skip to content

Commit be4a626

Browse files
AIMD limit now correctly releases permits when token is used. (#9421) (#9425)
Added tests for AIMD and Fixed limit to validate this. Signed-off-by: Tomas Langer <[email protected]> Co-authored-by: Tomas Langer <[email protected]>
1 parent 9687f37 commit be4a626

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed

common/concurrency/limits/src/main/java/io/helidon/common/concurrency/limits/AimdLimitImpl.java

+12-3
Original file line numberDiff line numberDiff line change
@@ -176,18 +176,27 @@ private AimdToken(Supplier<Long> clock, AtomicInteger concurrentRequests) {
176176

177177
@Override
178178
public void dropped() {
179-
updateWithSample(startTime, clock.get(), currentRequests, false);
179+
try {
180+
updateWithSample(startTime, clock.get(), currentRequests, false);
181+
} finally {
182+
AimdLimitImpl.this.semaphore.release();
183+
}
180184
}
181185

182186
@Override
183187
public void ignore() {
184188
concurrentRequests.decrementAndGet();
189+
AimdLimitImpl.this.semaphore.release();
185190
}
186191

187192
@Override
188193
public void success() {
189-
updateWithSample(startTime, clock.get(), currentRequests, true);
190-
concurrentRequests.decrementAndGet();
194+
try {
195+
updateWithSample(startTime, clock.get(), currentRequests, true);
196+
concurrentRequests.decrementAndGet();
197+
} finally {
198+
AimdLimitImpl.this.semaphore.release();
199+
}
191200
}
192201
}
193202
}

common/concurrency/limits/src/test/java/io/helidon/common/concurrency/limits/AimdLimitTest.java

+16
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package io.helidon.common.concurrency.limits;
1818

1919
import java.time.Duration;
20+
import java.util.Optional;
2021
import java.util.concurrent.CountDownLatch;
2122
import java.util.concurrent.ExecutorService;
2223
import java.util.concurrent.Executors;
@@ -26,6 +27,7 @@
2627
import org.junit.jupiter.api.Test;
2728

2829
import static org.hamcrest.CoreMatchers.is;
30+
import static org.hamcrest.CoreMatchers.not;
2931
import static org.hamcrest.MatcherAssert.assertThat;
3032
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
3133
import static org.hamcrest.Matchers.lessThanOrEqualTo;
@@ -165,4 +167,18 @@ public void testSemaphoreReleased() throws Exception {
165167
limit.invoke(() -> {});
166168
}
167169
}
170+
171+
@Test
172+
public void testSemaphoreReleasedWithToken() {
173+
Limit limit = AimdLimit.builder()
174+
.minLimit(5)
175+
.initialLimit(5)
176+
.build();
177+
178+
for (int i = 0; i < 5000; i++) {
179+
Optional<LimitAlgorithm.Token> token = limit.tryAcquire();
180+
assertThat(token, not(Optional.empty()));
181+
token.get().success();
182+
}
183+
}
168184
}

common/concurrency/limits/src/test/java/io/helidon/common/concurrency/limits/FixedLimitTest.java

+17
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.time.Duration;
2020
import java.util.ArrayList;
2121
import java.util.List;
22+
import java.util.Optional;
2223
import java.util.concurrent.CountDownLatch;
2324
import java.util.concurrent.TimeUnit;
2425
import java.util.concurrent.atomic.AtomicInteger;
@@ -28,6 +29,7 @@
2829
import org.junit.jupiter.api.Test;
2930

3031
import static org.hamcrest.CoreMatchers.is;
32+
import static org.hamcrest.CoreMatchers.not;
3133
import static org.hamcrest.MatcherAssert.assertThat;
3234
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
3335
import static org.hamcrest.Matchers.hasSize;
@@ -208,4 +210,19 @@ public void testSemaphoreReleasedWithQueue() throws Exception {
208210
});
209211
}
210212
}
213+
214+
@Test
215+
public void testSemaphoreReleasedWithToken() {
216+
Limit limit = FixedLimit.builder()
217+
.permits(5)
218+
.queueLength(10)
219+
.queueTimeout(Duration.ofMillis(100))
220+
.build();
221+
222+
for (int i = 0; i < 5000; i++) {
223+
Optional<LimitAlgorithm.Token> token = limit.tryAcquire();
224+
assertThat(token, not(Optional.empty()));
225+
token.get().success();
226+
}
227+
}
211228
}

0 commit comments

Comments
 (0)