Skip to content

Commit d6b189a

Browse files
authored
Extract methods for easier reuse/overriding (#1788)
* Extract methods for easier reuse/overriding * PR feedback
1 parent 8e90acd commit d6b189a

File tree

2 files changed

+64
-43
lines changed

2 files changed

+64
-43
lines changed

zuul-core/src/main/java/com/netflix/zuul/netty/connectionpool/DefaultClientChannelManager.java

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@
4141
import io.netty.channel.EventLoop;
4242
import io.netty.handler.timeout.IdleStateHandler;
4343
import io.netty.util.concurrent.Promise;
44+
import org.slf4j.Logger;
45+
import org.slf4j.LoggerFactory;
46+
47+
import javax.annotation.Nullable;
4448
import java.net.InetAddress;
4549
import java.net.InetSocketAddress;
4650
import java.net.SocketAddress;
@@ -50,9 +54,6 @@
5054
import java.util.concurrent.TimeUnit;
5155
import java.util.concurrent.atomic.AtomicInteger;
5256
import java.util.concurrent.atomic.AtomicReference;
53-
import javax.annotation.Nullable;
54-
import org.slf4j.Logger;
55-
import org.slf4j.LoggerFactory;
5657

5758
/**
5859
@@ -214,26 +215,23 @@ public boolean release(final PooledConnection conn) {
214215

215216
boolean released = false;
216217

217-
// if the connection has been around too long (i.e. too many requests), then close it
218-
// TODO(argha-c): Document what is a reasonable default here, and the class of origins that optimizes for
219-
final boolean connExpiredLifetime = conn.getUsageCount() > connPoolConfig.getMaxRequestsPerConnection();
220-
if (conn.isShouldClose() || connExpiredLifetime) {
218+
219+
if (conn.isShouldClose()) {
221220
// Close and discard the connection, as it has been flagged (possibly due to receiving a non-channel error
222221
// like a 503).
223222
conn.setInPool(false);
224223
conn.close();
225-
if (connExpiredLifetime) {
226-
closeExpiredConnLifetimeCounter.increment();
227-
LOG.debug(
228-
"[{}] closing conn lifetime expired, usage: {}",
229-
conn.getChannel().id(),
230-
conn.getUsageCount());
231-
} else {
232224
LOG.debug(
233225
"[{}] closing conn flagged to be closed",
234226
conn.getChannel().id());
235-
}
236-
227+
} else if(isConnectionExpired(conn.getUsageCount())) {
228+
conn.setInPool(false);
229+
conn.close();
230+
closeExpiredConnLifetimeCounter.increment();
231+
LOG.debug(
232+
"[{}] closing conn lifetime expired, usage: {}",
233+
conn.getChannel().id(),
234+
conn.getUsageCount());
237235
} else if (connPoolConfig.isCloseOnCircuitBreakerEnabled() && discoveryResult.isCircuitBreakerTripped()) {
238236
LOG.debug(
239237
"[{}] closing conn, server circuit breaker tripped",
@@ -270,6 +268,12 @@ public boolean release(final PooledConnection conn) {
270268
return released;
271269
}
272270

271+
protected boolean isConnectionExpired(long usageCount) {
272+
// if the connection has been around too long (i.e. too many requests), then close it
273+
// TODO(argha-c): Document what is a reasonable default here, and the class of origins that optimizes for
274+
return usageCount > connPoolConfig.getMaxRequestsPerConnection();
275+
}
276+
273277
protected void updateServerStatsOnRelease(final PooledConnection conn) {
274278
final DiscoveryResult discoveryResult = conn.getServer();
275279
discoveryResult.decrementActiveRequestsCount();

zuul-core/src/main/java/com/netflix/zuul/netty/connectionpool/PerServerConnectionPool.java

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
import io.netty.handler.codec.DecoderException;
2929
import io.netty.util.AttributeKey;
3030
import io.netty.util.concurrent.Promise;
31+
import org.slf4j.Logger;
32+
import org.slf4j.LoggerFactory;
33+
34+
import javax.annotation.Nullable;
3135
import java.net.InetAddress;
3236
import java.net.InetSocketAddress;
3337
import java.net.SocketAddress;
@@ -37,9 +41,6 @@
3741
import java.util.concurrent.ConcurrentLinkedDeque;
3842
import java.util.concurrent.atomic.AtomicInteger;
3943
import java.util.concurrent.atomic.AtomicReference;
40-
import javax.annotation.Nullable;
41-
import org.slf4j.Logger;
42-
import org.slf4j.LoggerFactory;
4344

4445
/**
4546
@@ -166,12 +167,7 @@ public Promise<PooledConnection> acquire(
166167
final PooledConnection conn = tryGettingFromConnectionPool(eventLoop);
167168
if (conn != null) {
168169
// There was a pooled connection available, so use this one.
169-
conn.startRequestTimer();
170-
conn.incrementUsageCount();
171-
conn.getChannel().read();
172-
onAcquire(conn, passport);
173-
initPooledConnection(conn, promise);
174-
selectedHostAddr.set(getSelectedHostString(serverAddr));
170+
reusePooledConnection(passport, selectedHostAddr, conn, promise);
175171
} else {
176172
// connection pool empty, create new connection using client connection factory.
177173
tryMakingNewConnection(eventLoop, promise, passport, selectedHostAddr);
@@ -180,6 +176,15 @@ public Promise<PooledConnection> acquire(
180176
return promise;
181177
}
182178

179+
protected void reusePooledConnection(CurrentPassport passport, AtomicReference<? super InetAddress> selectedHostAddr, PooledConnection conn, Promise<PooledConnection> promise) {
180+
conn.startRequestTimer();
181+
conn.incrementUsageCount();
182+
conn.getChannel().read();
183+
onAcquire(conn, passport);
184+
initPooledConnection(conn, promise);
185+
selectedHostAddr.set(getSelectedHostString(serverAddr));
186+
}
187+
183188
protected void updateServerStatsOnAcquire() {
184189
server.incrementActiveRequestsCount();
185190
}
@@ -232,21 +237,8 @@ protected void tryMakingNewConnection(
232237
Promise<PooledConnection> promise,
233238
CurrentPassport passport,
234239
AtomicReference<? super InetAddress> selectedHostAddr) {
235-
// Enforce MaxConnectionsPerHost config.
236-
int maxConnectionsPerHost = config.maxConnectionsPerHost();
237-
int openAndOpeningConnectionCount = server.getOpenConnectionsCount() + connCreationsInProgress.get();
238-
if (maxConnectionsPerHost != -1 && openAndOpeningConnectionCount >= maxConnectionsPerHost) {
239-
maxConnsPerHostExceededCounter.increment();
240-
promise.setFailure(new OriginConnectException(
241-
"maxConnectionsPerHost=" + maxConnectionsPerHost + ", connectionsPerHost="
242-
+ openAndOpeningConnectionCount,
243-
OutboundErrorType.ORIGIN_SERVER_MAX_CONNS));
244-
LOG.warn(
245-
"Unable to create new connection because at MaxConnectionsPerHost! maxConnectionsPerHost={}, connectionsPerHost={}, host={}origin={}",
246-
maxConnectionsPerHost,
247-
openAndOpeningConnectionCount,
248-
server.getServerId(),
249-
config.getOriginName());
240+
241+
if (!isWithinConnectionLimit(promise)) {
250242
return;
251243
}
252244

@@ -281,6 +273,27 @@ protected void tryMakingNewConnection(
281273
}
282274
}
283275

276+
protected boolean isWithinConnectionLimit(Promise<PooledConnection> promise) {
277+
// Enforce MaxConnectionsPerHost config.
278+
int maxConnectionsPerHost = config.maxConnectionsPerHost();
279+
int openAndOpeningConnectionCount = server.getOpenConnectionsCount() + connCreationsInProgress.get();
280+
if (maxConnectionsPerHost != -1 && openAndOpeningConnectionCount >= maxConnectionsPerHost) {
281+
maxConnsPerHostExceededCounter.increment();
282+
promise.setFailure(new OriginConnectException(
283+
"maxConnectionsPerHost=" + maxConnectionsPerHost + ", connectionsPerHost="
284+
+ openAndOpeningConnectionCount,
285+
OutboundErrorType.ORIGIN_SERVER_MAX_CONNS));
286+
LOG.warn(
287+
"Unable to create new connection because at MaxConnectionsPerHost! maxConnectionsPerHost={}, connectionsPerHost={}, host={}origin={}",
288+
maxConnectionsPerHost,
289+
openAndOpeningConnectionCount,
290+
server.getServerId(),
291+
config.getOriginName());
292+
return false;
293+
}
294+
return true;
295+
}
296+
284297
protected ChannelFuture connectToServer(EventLoop eventLoop, CurrentPassport passport, SocketAddress serverAddr) {
285298
return connectionFactory.connect(eventLoop, serverAddr, passport, this);
286299
}
@@ -354,8 +367,7 @@ public boolean release(PooledConnection conn) {
354367
CurrentPassport passport = CurrentPassport.fromChannel(conn.getChannel());
355368

356369
// Discard conn if already at least above waterline in the pool already for this server.
357-
int poolWaterline = config.perServerWaterline();
358-
if (poolWaterline > -1 && connections.size() >= poolWaterline) {
370+
if (isOverPerServerWaterline(connections.size())) {
359371
closeAboveHighWaterMarkCounter.increment();
360372
conn.close();
361373
conn.setInPool(false);
@@ -375,6 +387,11 @@ else if (connections.offer(conn)) {
375387
}
376388
}
377389

390+
protected boolean isOverPerServerWaterline(int connectionsInPool) {
391+
int poolWaterline = config.perServerWaterline();
392+
return poolWaterline > -1 && connectionsInPool >= poolWaterline;
393+
}
394+
378395
@Override
379396
public boolean remove(PooledConnection conn) {
380397
if (conn == null) {
@@ -428,7 +445,7 @@ public int getConnsInUse() {
428445
}
429446

430447
@Nullable
431-
private static InetAddress getSelectedHostString(SocketAddress addr) {
448+
protected InetAddress getSelectedHostString(SocketAddress addr) {
432449
if (addr instanceof InetSocketAddress) {
433450
return ((InetSocketAddress) addr).getAddress();
434451
} else {

0 commit comments

Comments
 (0)