mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-20 21:58:02 +01:00
Restore Redis retries for select operations
This commit is contained in:
@@ -13,6 +13,7 @@ import java.io.UncheckedIOException;
|
||||
import java.time.Clock;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
@@ -30,11 +31,12 @@ public abstract class BaseRateLimiters<T extends RateLimiterDescriptor> {
|
||||
final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager,
|
||||
final ClusterLuaScript validateScript,
|
||||
final FaultTolerantRedisClusterClient cacheCluster,
|
||||
final ScheduledExecutorService retryExecutor,
|
||||
final Clock clock) {
|
||||
this.rateLimiterByDescriptor = Arrays.stream(values)
|
||||
.map(descriptor -> Pair.of(
|
||||
descriptor,
|
||||
createForDescriptor(descriptor, dynamicConfigurationManager, validateScript, cacheCluster, clock)))
|
||||
createForDescriptor(descriptor, dynamicConfigurationManager, validateScript, cacheCluster, retryExecutor, clock)))
|
||||
.collect(Collectors.toUnmodifiableMap(Pair::getKey, Pair::getValue));
|
||||
}
|
||||
|
||||
@@ -56,9 +58,10 @@ public abstract class BaseRateLimiters<T extends RateLimiterDescriptor> {
|
||||
final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager,
|
||||
final ClusterLuaScript validateScript,
|
||||
final FaultTolerantRedisClusterClient cacheCluster,
|
||||
final ScheduledExecutorService retryExecutor,
|
||||
final Clock clock) {
|
||||
final Supplier<RateLimiterConfig> configResolver =
|
||||
() -> dynamicConfigurationManager.getConfiguration().getLimits().getOrDefault(descriptor.id(), descriptor.defaultConfig());
|
||||
return new DynamicRateLimiter(descriptor.id(), configResolver, validateScript, cacheCluster, clock);
|
||||
return new DynamicRateLimiter(descriptor.id(), configResolver, validateScript, cacheCluster, retryExecutor, clock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,11 +14,13 @@ import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.function.Supplier;
|
||||
import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException;
|
||||
import org.whispersystems.textsecuregcm.metrics.MetricsUtil;
|
||||
import org.whispersystems.textsecuregcm.redis.ClusterLuaScript;
|
||||
import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisClusterClient;
|
||||
import org.whispersystems.textsecuregcm.util.CircuitBreakerUtil;
|
||||
import org.whispersystems.textsecuregcm.util.ExceptionUtils;
|
||||
import org.whispersystems.textsecuregcm.util.Util;
|
||||
|
||||
@@ -30,22 +32,26 @@ public class DynamicRateLimiter implements RateLimiter {
|
||||
private final ClusterLuaScript validateScript;
|
||||
|
||||
private final FaultTolerantRedisClusterClient cluster;
|
||||
private final ScheduledExecutorService retryExecutor;
|
||||
|
||||
private final Counter limitExceededCounter;
|
||||
|
||||
private final Clock clock;
|
||||
|
||||
private static final String RETRY_NAME = DynamicRateLimiter.class.getSimpleName();
|
||||
|
||||
public DynamicRateLimiter(
|
||||
final String name,
|
||||
final Supplier<RateLimiterConfig> configResolver,
|
||||
final ClusterLuaScript validateScript,
|
||||
final FaultTolerantRedisClusterClient cluster,
|
||||
final ScheduledExecutorService retryExecutor,
|
||||
final Clock clock) {
|
||||
this.name = requireNonNull(name);
|
||||
this.configResolver = requireNonNull(configResolver);
|
||||
this.validateScript = requireNonNull(validateScript);
|
||||
this.cluster = requireNonNull(cluster);
|
||||
this.retryExecutor = requireNonNull(retryExecutor);
|
||||
this.clock = requireNonNull(clock);
|
||||
this.limitExceededCounter = Metrics.counter(MetricsUtil.name(getClass(), "exceeded"), "rateLimiterName", name);
|
||||
}
|
||||
@@ -129,13 +135,15 @@ public class DynamicRateLimiter implements RateLimiter {
|
||||
|
||||
@Override
|
||||
public void clear(final String key) {
|
||||
cluster.useCluster(connection -> connection.sync().del(bucketName(name, key)));
|
||||
CircuitBreakerUtil.getGeneralRedisRetry(RETRY_NAME)
|
||||
.executeRunnable(() -> cluster.useCluster(connection -> connection.sync().del(bucketName(name, key))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletionStage<Void> clearAsync(final String key) {
|
||||
return cluster.withCluster(connection -> connection.async().del(bucketName(name, key)))
|
||||
.thenRun(Util.NOOP);
|
||||
return CircuitBreakerUtil.getGeneralRedisRetry(RETRY_NAME)
|
||||
.executeCompletionStage(retryExecutor, () -> cluster.withCluster(connection -> connection.async().del(bucketName(name, key)))
|
||||
.thenRun(Util.NOOP));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.whispersystems.textsecuregcm.limits;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import java.time.Clock;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
||||
import org.whispersystems.textsecuregcm.redis.ClusterLuaScript;
|
||||
import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisClusterClient;
|
||||
@@ -77,9 +78,10 @@ public class RateLimiters extends BaseRateLimiters<RateLimiters.For> {
|
||||
|
||||
public static RateLimiters create(
|
||||
final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager,
|
||||
final FaultTolerantRedisClusterClient cacheCluster) {
|
||||
final FaultTolerantRedisClusterClient cacheCluster,
|
||||
final ScheduledExecutorService retryExecutor) {
|
||||
return new RateLimiters(
|
||||
dynamicConfigurationManager, defaultScript(cacheCluster), cacheCluster, Clock.systemUTC());
|
||||
dynamicConfigurationManager, defaultScript(cacheCluster), cacheCluster, retryExecutor, Clock.systemUTC());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -87,8 +89,9 @@ public class RateLimiters extends BaseRateLimiters<RateLimiters.For> {
|
||||
final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager,
|
||||
final ClusterLuaScript validateScript,
|
||||
final FaultTolerantRedisClusterClient cacheCluster,
|
||||
final ScheduledExecutorService retryExecutor,
|
||||
final Clock clock) {
|
||||
super(For.values(), dynamicConfigurationManager, validateScript, cacheCluster, clock);
|
||||
super(For.values(), dynamicConfigurationManager, validateScript, cacheCluster, retryExecutor, clock);
|
||||
}
|
||||
|
||||
public RateLimiter getAllocateDeviceLimiter() {
|
||||
|
||||
Reference in New Issue
Block a user