Reuse/extend lifetime of Redis singleton resources

This commit is contained in:
Jon Chambers 2025-07-03 11:32:30 -04:00 committed by ravi-signal
parent b81cd9ec61
commit 3e80669f4e
2 changed files with 22 additions and 22 deletions

View File

@ -33,9 +33,8 @@ public class LocalFaultTolerantRedisClientFactory implements FaultTolerantRedisC
if (shutdownHookConfigured.compareAndSet(false, true)) { if (shutdownHookConfigured.compareAndSet(false, true)) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> { Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try { try {
REDIS_SERVER_EXTENSION.afterEach(null); REDIS_SERVER_EXTENSION.close();
REDIS_SERVER_EXTENSION.afterAll(null); } catch (Throwable e) {
} catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
})); }));

View File

@ -8,12 +8,10 @@ package org.whispersystems.textsecuregcm.redis;
import static org.junit.jupiter.api.Assumptions.assumeFalse; import static org.junit.jupiter.api.Assumptions.assumeFalse;
import io.lettuce.core.RedisURI; import io.lettuce.core.RedisURI;
import io.lettuce.core.resource.ClientResources;
import java.io.IOException; import java.io.IOException;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.time.Duration; import java.time.Duration;
import io.lettuce.core.resource.ClientResources;
import org.junit.jupiter.api.extension.AfterAllCallback;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ExtensionContext;
@ -22,11 +20,12 @@ import org.whispersystems.textsecuregcm.configuration.RetryConfiguration;
import redis.embedded.RedisServer; import redis.embedded.RedisServer;
import redis.embedded.exceptions.EmbeddedRedisException; import redis.embedded.exceptions.EmbeddedRedisException;
public class RedisServerExtension implements BeforeAllCallback, BeforeEachCallback, AfterAllCallback, AfterEachCallback { public class RedisServerExtension implements BeforeAllCallback, BeforeEachCallback, ExtensionContext.Store.CloseableResource {
private static RedisServer redisServer; private static RedisServer redisServer;
private static ClientResources redisClientResources;
private FaultTolerantRedisClient faultTolerantRedisClient; private FaultTolerantRedisClient faultTolerantRedisClient;
private ClientResources redisClientResources;
public static class RedisServerExtensionBuilder { public static class RedisServerExtensionBuilder {
@ -46,14 +45,18 @@ public class RedisServerExtension implements BeforeAllCallback, BeforeEachCallba
public void beforeAll(final ExtensionContext context) throws Exception { public void beforeAll(final ExtensionContext context) throws Exception {
assumeFalse(System.getProperty("os.name").equalsIgnoreCase("windows")); assumeFalse(System.getProperty("os.name").equalsIgnoreCase("windows"));
redisServer = RedisServer.builder() if (redisServer == null) {
.setting("appendonly no") redisServer = RedisServer.builder()
.setting("save \"\"") .setting("appendonly no")
.setting("dir " + System.getProperty("java.io.tmpdir")) .setting("save \"\"")
.port(getAvailablePort()) .setting("dir " + System.getProperty("java.io.tmpdir"))
.build(); .port(getAvailablePort())
.build();
startWithRetries(3); redisClientResources = ClientResources.builder().build();
startWithRetries(3);
}
} }
public static RedisURI getRedisURI() { public static RedisURI getRedisURI() {
@ -62,7 +65,6 @@ public class RedisServerExtension implements BeforeAllCallback, BeforeEachCallba
@Override @Override
public void beforeEach(final ExtensionContext context) { public void beforeEach(final ExtensionContext context) {
redisClientResources = ClientResources.builder().build();
final CircuitBreakerConfiguration circuitBreakerConfig = new CircuitBreakerConfiguration(); final CircuitBreakerConfiguration circuitBreakerConfig = new CircuitBreakerConfiguration();
circuitBreakerConfig.setWaitDurationInOpenState(Duration.ofMillis(500)); circuitBreakerConfig.setWaitDurationInOpenState(Duration.ofMillis(500));
faultTolerantRedisClient = new FaultTolerantRedisClient("test-redis-client", faultTolerantRedisClient = new FaultTolerantRedisClient("test-redis-client",
@ -76,15 +78,14 @@ public class RedisServerExtension implements BeforeAllCallback, BeforeEachCallba
} }
@Override @Override
public void afterEach(final ExtensionContext context) throws InterruptedException { public void close() throws Throwable {
redisClientResources.shutdown().await();
}
@Override
public void afterAll(final ExtensionContext context) {
if (redisServer != null) { if (redisServer != null) {
redisClientResources.shutdown().await();
redisServer.stop(); redisServer.stop();
} }
redisClientResources = null;
redisServer = null;
} }
public FaultTolerantRedisClient getRedisClient() { public FaultTolerantRedisClient getRedisClient() {