mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-21 02:08:03 +01:00
Migrate DynamicConfigurationManager to use java.util.concurrent
This commit is contained in:
@@ -315,11 +315,14 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||
|
||||
UncaughtExceptionHandler.register();
|
||||
|
||||
ScheduledExecutorService dynamicConfigurationExecutor = environment.lifecycle()
|
||||
.scheduledExecutorService(name(getClass(), "dynamicConfiguration-%d")).threads(1).build();
|
||||
|
||||
DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager =
|
||||
new DynamicConfigurationManager<>(config.getAppConfig().getApplication(),
|
||||
config.getAppConfig().getEnvironment(),
|
||||
config.getAppConfig().getConfigurationName(),
|
||||
DynamicConfiguration.class);
|
||||
DynamicConfiguration.class, dynamicConfigurationExecutor);
|
||||
dynamicConfigurationManager.start();
|
||||
|
||||
MetricsUtil.configureRegistries(config, environment, dynamicConfigurationManager);
|
||||
|
||||
@@ -13,6 +13,9 @@ import io.micrometer.core.instrument.Metrics;
|
||||
import java.time.Duration;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Validation;
|
||||
@@ -38,8 +41,9 @@ public class DynamicConfigurationManager<T> {
|
||||
|
||||
// Set on initial config fetch
|
||||
private final AtomicReference<T> configuration = new AtomicReference<>();
|
||||
private final CountDownLatch initialized = new CountDownLatch(1);
|
||||
private final ScheduledExecutorService scheduledExecutorService;
|
||||
private String configurationToken = null;
|
||||
private boolean initialized = false;
|
||||
|
||||
private static final Validator VALIDATOR = Validation.buildDefaultValidatorFactory().getValidator();
|
||||
|
||||
@@ -50,61 +54,48 @@ public class DynamicConfigurationManager<T> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(DynamicConfigurationManager.class);
|
||||
|
||||
public DynamicConfigurationManager(String application, String environment, String configurationName,
|
||||
Class<T> configurationClass) {
|
||||
Class<T> configurationClass, ScheduledExecutorService scheduledExecutorService) {
|
||||
this(AppConfigDataClient
|
||||
.builder()
|
||||
.overrideConfiguration(ClientOverrideConfiguration.builder()
|
||||
.apiCallTimeout(Duration.ofSeconds(10))
|
||||
.apiCallAttemptTimeout(Duration.ofSeconds(10)).build())
|
||||
.build(),
|
||||
application, environment, configurationName, configurationClass);
|
||||
application, environment, configurationName, configurationClass, scheduledExecutorService);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
DynamicConfigurationManager(AppConfigDataClient appConfigClient, String application, String environment,
|
||||
String configurationName, Class<T> configurationClass) {
|
||||
String configurationName, Class<T> configurationClass, ScheduledExecutorService scheduledExecutorService) {
|
||||
this.appConfigClient = appConfigClient;
|
||||
this.application = application;
|
||||
this.environment = environment;
|
||||
this.configurationName = configurationName;
|
||||
this.configurationClass = configurationClass;
|
||||
this.scheduledExecutorService = scheduledExecutorService;
|
||||
}
|
||||
|
||||
public T getConfiguration() {
|
||||
synchronized (this) {
|
||||
while (!initialized) {
|
||||
try {
|
||||
this.wait();
|
||||
} catch (final InterruptedException e) {
|
||||
logger.warn("Interrupted while waiting for initial configuration", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
initialized.await();
|
||||
} catch (InterruptedException e) {
|
||||
logger.warn("Interrupted while waiting for initial configuration", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return configuration.get();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
configuration.set(retrieveInitialDynamicConfiguration());
|
||||
synchronized (this) {
|
||||
this.initialized = true;
|
||||
this.notifyAll();
|
||||
}
|
||||
initialized.countDown();
|
||||
|
||||
final Thread workerThread = new Thread(() -> {
|
||||
while (true) {
|
||||
try {
|
||||
retrieveDynamicConfiguration().ifPresent(configuration::set);
|
||||
} catch (Exception e) {
|
||||
logger.warn("Error retrieving dynamic configuration", e);
|
||||
}
|
||||
|
||||
Util.sleep(5000);
|
||||
scheduledExecutorService.scheduleWithFixedDelay(() -> {
|
||||
try {
|
||||
retrieveDynamicConfiguration().ifPresent(configuration::set);
|
||||
} catch (Exception e) {
|
||||
logger.warn("Error retrieving dynamic configuration", e);
|
||||
}
|
||||
}, "DynamicConfigurationManagerWorker");
|
||||
|
||||
workerThread.setDaemon(true);
|
||||
workerThread.start();
|
||||
}, 0, 5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private Optional<T> retrieveDynamicConfiguration() throws JsonProcessingException {
|
||||
|
||||
@@ -98,6 +98,14 @@ public class AssignUsernameCommand extends EnvironmentCommand<WhisperServerConfi
|
||||
throws Exception {
|
||||
environment.getObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
|
||||
ScheduledExecutorService dynamicConfigurationExecutor = environment.lifecycle()
|
||||
.scheduledExecutorService(name(getClass(), "dynamicConfiguration-%d")).threads(1).build();
|
||||
|
||||
DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager = new DynamicConfigurationManager<>(
|
||||
configuration.getAppConfig().getApplication(), configuration.getAppConfig().getEnvironment(),
|
||||
configuration.getAppConfig().getConfigurationName(), DynamicConfiguration.class, dynamicConfigurationExecutor);
|
||||
dynamicConfigurationManager.start();
|
||||
|
||||
ClientResources redisClusterClientResources = ClientResources.builder().build();
|
||||
|
||||
FaultTolerantRedisCluster cacheCluster = new FaultTolerantRedisCluster("main_cache_cluster",
|
||||
@@ -128,11 +136,6 @@ public class AssignUsernameCommand extends EnvironmentCommand<WhisperServerConfi
|
||||
ExternalServiceCredentialsGenerator secureValueRecoveryCredentialsGenerator = SecureValueRecovery2Controller.credentialsGenerator(
|
||||
configuration.getSvr2Configuration());
|
||||
|
||||
DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager = new DynamicConfigurationManager<>(
|
||||
configuration.getAppConfig().getApplication(), configuration.getAppConfig().getEnvironment(),
|
||||
configuration.getAppConfig().getConfigurationName(), DynamicConfiguration.class);
|
||||
dynamicConfigurationManager.start();
|
||||
|
||||
ExperimentEnrollmentManager experimentEnrollmentManager = new ExperimentEnrollmentManager(
|
||||
dynamicConfigurationManager);
|
||||
|
||||
|
||||
@@ -72,9 +72,12 @@ record CommandDependencies(
|
||||
|
||||
environment.getObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
|
||||
ScheduledExecutorService dynamicConfigurationExecutor = environment.lifecycle()
|
||||
.scheduledExecutorService(name(name, "dynamicConfiguration-%d")).threads(1).build();
|
||||
|
||||
DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager = new DynamicConfigurationManager<>(
|
||||
configuration.getAppConfig().getApplication(), configuration.getAppConfig().getEnvironment(),
|
||||
configuration.getAppConfig().getConfigurationName(), DynamicConfiguration.class);
|
||||
configuration.getAppConfig().getConfigurationName(), DynamicConfiguration.class, dynamicConfigurationExecutor);
|
||||
dynamicConfigurationManager.start();
|
||||
|
||||
MetricsUtil.configureRegistries(configuration, environment, dynamicConfigurationManager);
|
||||
|
||||
Reference in New Issue
Block a user