Skip to content

Commit 5a198dc

Browse files
author
Agshin Guliyev
committed
Expose configured backlog timeout in LifoBlockingLimiter
1 parent 26e9fca commit 5a198dc

File tree

2 files changed

+56
-9
lines changed

2 files changed

+56
-9
lines changed

concurrency-limits-core/src/main/java/com/netflix/concurrency/limits/limiter/LifoBlockingLimiter.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ public static class Builder<ContextT> {
4040

4141
private final Limiter<ContextT> delegate;
4242
private int maxBacklogSize = 100;
43-
private Function<ContextT, Long> maxBacklogTimeoutMillis = context -> 1_000L;
43+
private Long fixedBacklogTimeoutMillis = 1_000L;
44+
private Function<ContextT, Long> maxBacklogTimeoutMillis =
45+
context -> fixedBacklogTimeoutMillis;
4446

4547
private Builder(Limiter<ContextT> delegate) {
4648
this.delegate = delegate;
@@ -87,6 +89,7 @@ public Builder<ContextT> backlogTimeout(long timeout, TimeUnit units) {
8789
*/
8890
public Builder<ContextT> backlogTimeoutMillis(long timeout) {
8991
this.maxBacklogTimeoutMillis = context -> timeout;
92+
this.fixedBacklogTimeoutMillis = timeout;
9093
return this;
9194
}
9295

@@ -99,6 +102,7 @@ public Builder<ContextT> backlogTimeoutMillis(long timeout) {
99102
*/
100103
public Builder<ContextT> backlogTimeout(Function<ContextT, Long> mapper, TimeUnit units) {
101104
this.maxBacklogTimeoutMillis = context -> units.toMillis(mapper.apply(context));
105+
this.fixedBacklogTimeoutMillis = null;
102106
return this;
103107
}
104108

@@ -142,14 +146,35 @@ public void set(Optional<Listener> listener) {
142146

143147
private final int backlogSize;
144148

149+
/**
150+
* Function that computes the backlog timeout in milliseconds based on the
151+
* request context. By default, this returns the fixed timeout.
152+
*/
145153
private final Function<ContextT, Long> backlogTimeoutMillis;
146154

155+
/**
156+
* Fixed backlog timeout in milliseconds fixed for this limiter.
157+
* <p>
158+
* This is primarily intended for introspection and serialization. By
159+
* default, the backlog timeout is 1 second.
160+
*/
161+
private final Long fixedBacklogTimeoutMillis;
162+
147163
private final Object lock = new Object();
148164

149165
private LifoBlockingLimiter(Builder<ContextT> builder) {
150166
this.delegate = builder.delegate;
151167
this.backlogSize = builder.maxBacklogSize;
152168
this.backlogTimeoutMillis = builder.maxBacklogTimeoutMillis;
169+
this.fixedBacklogTimeoutMillis = builder.fixedBacklogTimeoutMillis;
170+
}
171+
172+
/**
173+
* Returns the fixed backlog timeout in milliseconds, or null if the
174+
* timeout is derived from the request context.
175+
*/
176+
public Long getFixedBacklogTimeoutMillis() {
177+
return this.fixedBacklogTimeoutMillis;
153178
}
154179

155180
private Optional<Listener> tryAcquire(ContextT context) {

concurrency-limits-core/src/test/java/com/netflix/concurrency/limits/limiter/LifoBlockingLimiterTest.java

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,11 @@ public void verifyFifoOrder() {
155155

156156
// Make sure all requests finished
157157
futures.forEach(future -> {
158-
try {
159-
future.get();
160-
} catch (Exception e) {
161-
}
162-
});
158+
try {
159+
future.get();
160+
} catch (Exception e) {
161+
}
162+
});
163163

164164
// Verify that results are in reverse order
165165
Assert.assertEquals(Arrays.asList(4, 3, 2, 1, 0), values);
@@ -171,9 +171,9 @@ public void verifyFifoOrder() {
171171
public void timeoutAcquireRaceCondition() throws InterruptedException, ExecutionException {
172172
// a limiter with a short timeout, and large backlog (we don't want it to hit that limit)
173173
LifoBlockingLimiter<Void> limiter = LifoBlockingLimiter.newBuilder(simpleLimiter)
174-
.backlogSize(1000)
175-
.backlogTimeout(10, TimeUnit.MILLISECONDS)
176-
.build();
174+
.backlogSize(1000)
175+
.backlogTimeout(10, TimeUnit.MILLISECONDS)
176+
.build();
177177

178178
// acquire all except one token
179179
acquireN(limiter, 3);
@@ -210,6 +210,28 @@ public void timeoutAcquireRaceCondition() throws InterruptedException, Execution
210210
}
211211
}
212212

213+
@Test
214+
public void fixedTimeoutExposedWhenConfigured() {
215+
LifoBlockingLimiter<Void> limiter = LifoBlockingLimiter
216+
.newBuilder(simpleLimiter)
217+
.backlogSize(10)
218+
.backlogTimeoutMillis(250)
219+
.build();
220+
221+
Assert.assertEquals(Long.valueOf(250L), limiter.getFixedBacklogTimeoutMillis());
222+
}
223+
224+
@Test
225+
public void fixedTimeoutIsNullForDynamicBacklogTimeout() {
226+
LifoBlockingLimiter<Void> limiter = LifoBlockingLimiter
227+
.newBuilder(simpleLimiter)
228+
.backlogSize(10)
229+
.backlogTimeout(context -> 50L, TimeUnit.MILLISECONDS)
230+
.build();
231+
232+
Assert.assertNull(limiter.getFixedBacklogTimeoutMillis());
233+
}
234+
213235
private List<Optional<Limiter.Listener>> acquireN(Limiter<Void> limiter, int N) {
214236
return IntStream.range(0, N)
215237
.mapToObj(i -> limiter.acquire(null))

0 commit comments

Comments
 (0)