mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-21 03:38:07 +01:00
Use central registries for Retry and CircuitBreaker instances
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package org.whispersystems.textsecuregcm.redis;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
|
||||
import io.lettuce.core.ClientOptions;
|
||||
import io.lettuce.core.RedisClient;
|
||||
@@ -15,8 +16,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration;
|
||||
import org.whispersystems.textsecuregcm.configuration.RedisConfiguration;
|
||||
import org.whispersystems.textsecuregcm.util.CircuitBreakerUtil;
|
||||
|
||||
public class FaultTolerantRedisClient {
|
||||
|
||||
@@ -38,14 +39,17 @@ public class FaultTolerantRedisClient {
|
||||
this(name, clientResourcesBuilder,
|
||||
RedisUriUtil.createRedisUriWithTimeout(redisConfiguration.getUri(), redisConfiguration.getTimeout()),
|
||||
redisConfiguration.getTimeout(),
|
||||
redisConfiguration.getCircuitBreakerConfiguration());
|
||||
redisConfiguration.getCircuitBreakerConfigurationName() != null
|
||||
? CircuitBreakerUtil.getCircuitBreakerRegistry().circuitBreaker(name + "-breaker", redisConfiguration.getCircuitBreakerConfigurationName())
|
||||
: CircuitBreakerUtil.getCircuitBreakerRegistry().circuitBreaker(name + "-breaker"));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
FaultTolerantRedisClient(String name,
|
||||
final ClientResources.Builder clientResourcesBuilder,
|
||||
final RedisURI redisUri,
|
||||
final Duration commandTimeout,
|
||||
final CircuitBreakerConfiguration circuitBreakerConfiguration) {
|
||||
final CircuitBreaker circuitBreaker) {
|
||||
|
||||
this.name = name;
|
||||
|
||||
@@ -73,7 +77,7 @@ public class FaultTolerantRedisClient {
|
||||
this.stringConnection = redisClient.connect();
|
||||
this.binaryConnection = redisClient.connect(ByteArrayCodec.INSTANCE);
|
||||
|
||||
this.circuitBreaker = CircuitBreaker.of(name + "-breaker", circuitBreakerConfiguration.toCircuitBreakerConfig());
|
||||
this.circuitBreaker = circuitBreaker;
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration;
|
||||
import javax.annotation.Nullable;
|
||||
import org.whispersystems.textsecuregcm.configuration.RedisClusterConfiguration;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
@@ -57,7 +57,7 @@ public class FaultTolerantRedisClusterClient {
|
||||
Collections.singleton(RedisUriUtil.createRedisUriWithTimeout(clusterConfiguration.getConfigurationUri(),
|
||||
clusterConfiguration.getTimeout())),
|
||||
clusterConfiguration.getTimeout(),
|
||||
clusterConfiguration.getCircuitBreakerConfiguration());
|
||||
clusterConfiguration.getCircuitBreakerConfigurationName());
|
||||
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class FaultTolerantRedisClusterClient {
|
||||
final ClientResources.Builder clientResourcesBuilder,
|
||||
final Iterable<RedisURI> redisUris,
|
||||
final Duration commandTimeout,
|
||||
final CircuitBreakerConfiguration circuitBreakerConfig) {
|
||||
@Nullable final String circuitBreakerConfigurationName) {
|
||||
|
||||
this.name = name;
|
||||
|
||||
@@ -83,7 +83,7 @@ public class FaultTolerantRedisClusterClient {
|
||||
});
|
||||
|
||||
final LettuceShardCircuitBreaker lettuceShardCircuitBreaker = new LettuceShardCircuitBreaker(name,
|
||||
circuitBreakerConfig.toCircuitBreakerConfig(), Schedulers.newSingle("topology-changed-" + name, true));
|
||||
circuitBreakerConfigurationName, Schedulers.newSingle("topology-changed-" + name, true));
|
||||
this.clusterClient = RedisClusterClient.create(
|
||||
clientResourcesBuilder.nettyCustomizer(lettuceShardCircuitBreaker).
|
||||
build(),
|
||||
|
||||
@@ -8,7 +8,6 @@ package org.whispersystems.textsecuregcm.redis;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import io.github.resilience4j.circuitbreaker.CallNotPermittedException;
|
||||
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
|
||||
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
|
||||
import io.lettuce.core.RedisNoScriptException;
|
||||
import io.lettuce.core.cluster.event.ClusterTopologyChangedEvent;
|
||||
import io.lettuce.core.cluster.models.partitions.RedisClusterNode;
|
||||
@@ -31,6 +30,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
import javax.annotation.Nullable;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -54,7 +54,8 @@ public class LettuceShardCircuitBreaker implements NettyCustomizer {
|
||||
private static final Logger logger = LoggerFactory.getLogger(LettuceShardCircuitBreaker.class);
|
||||
|
||||
private final String clusterName;
|
||||
private final CircuitBreakerConfig circuitBreakerConfig;
|
||||
@Nullable
|
||||
private final String circuitBreakerConfigurationName;
|
||||
private final Scheduler scheduler;
|
||||
// this set will be shared with all child channel breakers
|
||||
private final Set<String> upstreamAddresses = ConcurrentHashMap.newKeySet();
|
||||
@@ -62,10 +63,12 @@ public class LettuceShardCircuitBreaker implements NettyCustomizer {
|
||||
// resources, which cannot be built without this NettyCustomizer
|
||||
private EventBus eventBus;
|
||||
|
||||
public LettuceShardCircuitBreaker(final String clusterName, final CircuitBreakerConfig circuitBreakerConfig,
|
||||
public LettuceShardCircuitBreaker(final String clusterName,
|
||||
@Nullable final String circuitBreakerConfigurationName,
|
||||
final Scheduler scheduler) {
|
||||
|
||||
this.clusterName = clusterName;
|
||||
this.circuitBreakerConfig = circuitBreakerConfig;
|
||||
this.circuitBreakerConfigurationName = circuitBreakerConfigurationName;
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
@@ -110,7 +113,7 @@ public class LettuceShardCircuitBreaker implements NettyCustomizer {
|
||||
}
|
||||
|
||||
final ChannelCircuitBreakerHandler channelCircuitBreakerHandler = new ChannelCircuitBreakerHandler(clusterName,
|
||||
circuitBreakerConfig, upstreamAddresses, eventBus, scheduler);
|
||||
circuitBreakerConfigurationName, upstreamAddresses, eventBus, scheduler);
|
||||
|
||||
final String commandHandlerName = StreamSupport.stream(channel.pipeline().spliterator(), false)
|
||||
.filter(entry -> entry.getValue() instanceof CommandHandler)
|
||||
@@ -127,7 +130,7 @@ public class LettuceShardCircuitBreaker implements NettyCustomizer {
|
||||
private static final String CLUSTER_TAG_NAME = "cluster";
|
||||
|
||||
private final String clusterName;
|
||||
private final CircuitBreakerConfig circuitBreakerConfig;
|
||||
@Nullable private final String circuitBreakerConfigurationName;
|
||||
private final AtomicBoolean registeredMetrics = new AtomicBoolean(false);
|
||||
private final Set<String> upstreamAddresses;
|
||||
|
||||
@@ -136,11 +139,12 @@ public class LettuceShardCircuitBreaker implements NettyCustomizer {
|
||||
@VisibleForTesting
|
||||
CircuitBreaker breaker;
|
||||
|
||||
public ChannelCircuitBreakerHandler(final String name, final CircuitBreakerConfig circuitBreakerConfig,
|
||||
public ChannelCircuitBreakerHandler(final String name,
|
||||
@Nullable final String circuitBreakerConfigurationName,
|
||||
final Set<String> upstreamAddresses,
|
||||
final EventBus eventBus, final Scheduler scheduler) {
|
||||
this.clusterName = name;
|
||||
this.circuitBreakerConfig = circuitBreakerConfig;
|
||||
this.circuitBreakerConfigurationName = circuitBreakerConfigurationName;
|
||||
this.upstreamAddresses = upstreamAddresses;
|
||||
|
||||
eventBus.get()
|
||||
@@ -183,7 +187,12 @@ public class LettuceShardCircuitBreaker implements NettyCustomizer {
|
||||
|
||||
// In some cases, like the default connection, the remote address includes the DNS hostname, which we want to exclude.
|
||||
shardAddress = StringUtils.substringAfter(remoteAddress.toString(), "/");
|
||||
breaker = CircuitBreaker.of("%s/%s-breaker".formatted(clusterName, shardAddress), circuitBreakerConfig);
|
||||
|
||||
final String circuitBreakerName = "%s/%s-breaker".formatted(clusterName, shardAddress);
|
||||
|
||||
breaker = circuitBreakerConfigurationName != null
|
||||
? CircuitBreakerUtil.getCircuitBreakerRegistry().circuitBreaker(circuitBreakerName, circuitBreakerConfigurationName)
|
||||
: CircuitBreakerUtil.getCircuitBreakerRegistry().circuitBreaker(circuitBreakerName);
|
||||
|
||||
if (upstreamAddresses.contains(shardAddress)) {
|
||||
registerMetrics();
|
||||
|
||||
Reference in New Issue
Block a user