Set TCP timeout on Redis clients

This commit is contained in:
Katherine
2025-09-08 12:37:03 -04:00
committed by GitHub
parent dc3920a99c
commit b2dd315177
5 changed files with 56 additions and 9 deletions

View File

@@ -69,14 +69,17 @@ public class FaultTolerantRedisClient {
redisUri.setLibraryVersion(null);
this.redisClient = RedisClient.create(clientResourcesBuilder.build(), redisUri);
this.redisClient.setOptions(ClientOptions.builder()
final ClientOptions.Builder clientOptionsBuilder = ClientOptions.builder()
.disconnectedBehavior(ClientOptions.DisconnectedBehavior.REJECT_COMMANDS)
// for asynchronous commands
.timeoutOptions(TimeoutOptions.builder()
.fixedTimeout(commandTimeout)
.build())
.publishOnScheduler(true)
.build());
.publishOnScheduler(true);
NettyUtil.setSocketTimeoutsIfApplicable(clientOptionsBuilder);
this.redisClient.setOptions(clientOptionsBuilder.build());
this.stringConnection = redisClient.connect();
this.binaryConnection = redisClient.connect(ByteArrayCodec.INSTANCE);

View File

@@ -89,7 +89,8 @@ public class FaultTolerantRedisClusterClient {
clientResourcesBuilder.nettyCustomizer(lettuceShardCircuitBreaker).
build(),
redisUris);
this.clusterClient.setOptions(ClusterClientOptions.builder()
final ClusterClientOptions.Builder clusterClientOptionsBuilder = ClusterClientOptions.builder()
.disconnectedBehavior(ClientOptions.DisconnectedBehavior.REJECT_COMMANDS)
.validateClusterNodeMembership(false)
.topologyRefreshOptions(ClusterTopologyRefreshOptions.builder()
@@ -99,8 +100,11 @@ public class FaultTolerantRedisClusterClient {
.timeoutOptions(TimeoutOptions.builder()
.fixedTimeout(commandTimeout)
.build())
.publishOnScheduler(true)
.build());
.publishOnScheduler(true);
NettyUtil.setSocketTimeoutsIfApplicable(clusterClientOptionsBuilder);
this.clusterClient.setOptions(clusterClientOptionsBuilder.build());
this.stringConnection = clusterClient.connect();
this.binaryConnection = clusterClient.connect(ByteArrayCodec.INSTANCE);

View File

@@ -0,0 +1,34 @@
/*
* Copyright 2025 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.redis;
import io.lettuce.core.ClientOptions;
import io.lettuce.core.SocketOptions;
import io.lettuce.core.resource.EpollProvider;
import java.time.Duration;
public class NettyUtil {
static final Duration TCP_KEEPALIVE_IDLE = Duration.ofSeconds(30);
static final Duration TCP_KEEPALIVE_INTERVAL = Duration.ofSeconds(30);
static final Duration TCP_USER_TIMEOUT = Duration.ofSeconds(30);
static void setSocketTimeoutsIfApplicable(final ClientOptions.Builder clientOptionsBuilder) {
if (EpollProvider.isAvailable()) {
// These socket options are only available with epoll native transport.
clientOptionsBuilder.socketOptions(SocketOptions.builder()
.keepAlive(SocketOptions.KeepAliveOptions.builder()
.interval(TCP_KEEPALIVE_INTERVAL)
.idle(TCP_KEEPALIVE_IDLE)
.enable()
.build())
.tcpUserTimeout(SocketOptions.TcpUserTimeoutOptions.builder()
.enable()
.tcpUserTimeout(TCP_USER_TIMEOUT)
.build())
.build());
}
}
}