Remove an unused rate limiter

This commit is contained in:
Jon Chambers
2022-02-23 10:21:29 -05:00
committed by Chris Eager
parent f3457502a6
commit 3a1c716c73
4 changed files with 0 additions and 169 deletions

View File

@@ -1,89 +0,0 @@
/*
* Copyright 2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.limits;
import java.time.Duration;
import org.whispersystems.textsecuregcm.configuration.RateLimitsConfiguration.CardinalityRateLimitConfiguration;
import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException;
import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisCluster;
/**
* A cardinality rate limiter prevents an actor from taking some action if that actor has attempted to take that action
* on too many targets in a fixed period of time. Behind the scenes, we estimate the target count using a
* hyper-log-log data structure; as a consequence, the number of targets is an approximation, and this rate limiter
* should not be used in cases where precise time or target limits are required.
*/
public class CardinalityRateLimiter {
private final FaultTolerantRedisCluster cacheCluster;
private final String name;
private final Duration ttl;
private final int defaultMaxCardinality;
public CardinalityRateLimiter(final FaultTolerantRedisCluster cacheCluster, final String name, final Duration ttl, final int defaultMaxCardinality) {
this.cacheCluster = cacheCluster;
this.name = name;
this.ttl = ttl;
this.defaultMaxCardinality = defaultMaxCardinality;
}
public void validate(final String key, final String target, final int maxCardinality) throws RateLimitExceededException {
final boolean rateLimitExceeded = cacheCluster.withCluster(connection -> {
final String hllKey = getHllKey(key);
final boolean changed = connection.sync().pfadd(hllKey, target) == 1;
final long cardinality = connection.sync().pfcount(hllKey);
final boolean mayNeedExpiration = changed && cardinality == 1;
// If the set already existed, we can assume it already had an expiration time and can save a round trip by
// skipping the ttl check.
if (mayNeedExpiration && connection.sync().ttl(hllKey) == -1) {
connection.sync().expire(hllKey, ttl.toSeconds());
}
return cardinality > maxCardinality;
});
if (rateLimitExceeded) {
long remainingTtl = getRemainingTtl(key);
throw new RateLimitExceededException(remainingTtl >= 0 ? Duration.ofSeconds(remainingTtl) : null);
}
}
private String getHllKey(final String key) {
return "hll_rate_limit::" + name + "::" + key;
}
public Duration getInitialTtl() {
return ttl;
}
/**
* Get the remaining ttl for the specified key
*
* @param key with timeout to check
* @return the ttl, or negative in the case of error
*/
public long getRemainingTtl(final String key) {
// ttl() returns -2 if key does not exist, -1 if key has no expiration
return cacheCluster.withCluster(connection -> connection.sync().ttl(getHllKey(key)));
}
public int getDefaultMaxCardinality() {
return defaultMaxCardinality;
}
public boolean hasConfiguration(final CardinalityRateLimitConfiguration configuration) {
return defaultMaxCardinality == configuration.getMaxCardinality() && ttl.equals(configuration.getTtl());
}
}