Remove dynamic configuration feature flags; add `DynamicMessagePersisterConfiguration`
This commit is contained in:
parent
41a113e22c
commit
a6f9409a39
|
@ -5,7 +5,6 @@ import com.google.common.annotations.VisibleForTesting;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
|
||||||
public class DynamicConfiguration {
|
public class DynamicConfiguration {
|
||||||
|
@ -30,9 +29,6 @@ public class DynamicConfiguration {
|
||||||
@Valid
|
@Valid
|
||||||
private DynamicPaymentsConfiguration payments = new DynamicPaymentsConfiguration();
|
private DynamicPaymentsConfiguration payments = new DynamicPaymentsConfiguration();
|
||||||
|
|
||||||
@JsonProperty
|
|
||||||
private Set<String> featureFlags = Collections.emptySet();
|
|
||||||
|
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
@Valid
|
@Valid
|
||||||
private DynamicTwilioConfiguration twilio = new DynamicTwilioConfiguration();
|
private DynamicTwilioConfiguration twilio = new DynamicTwilioConfiguration();
|
||||||
|
@ -64,6 +60,10 @@ public class DynamicConfiguration {
|
||||||
@Valid
|
@Valid
|
||||||
DynamicAbusiveHostRulesConfiguration abusiveHostRules = new DynamicAbusiveHostRulesConfiguration();
|
DynamicAbusiveHostRulesConfiguration abusiveHostRules = new DynamicAbusiveHostRulesConfiguration();
|
||||||
|
|
||||||
|
@JsonProperty
|
||||||
|
@Valid
|
||||||
|
DynamicMessagePersisterConfiguration messagePersister = new DynamicMessagePersisterConfiguration();
|
||||||
|
|
||||||
public Optional<DynamicExperimentEnrollmentConfiguration> getExperimentEnrollmentConfiguration(
|
public Optional<DynamicExperimentEnrollmentConfiguration> getExperimentEnrollmentConfiguration(
|
||||||
final String experimentName) {
|
final String experimentName) {
|
||||||
return Optional.ofNullable(experiments.get(experimentName));
|
return Optional.ofNullable(experiments.get(experimentName));
|
||||||
|
@ -86,10 +86,6 @@ public class DynamicConfiguration {
|
||||||
return payments;
|
return payments;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getActiveFeatureFlags() {
|
|
||||||
return featureFlags;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DynamicTwilioConfiguration getTwilioConfiguration() {
|
public DynamicTwilioConfiguration getTwilioConfiguration() {
|
||||||
return twilio;
|
return twilio;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +111,9 @@ public class DynamicConfiguration {
|
||||||
return pushLatency;
|
return pushLatency;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicUakMigrationConfiguration getUakMigrationConfiguration() { return uakMigrationConfiguration; }
|
public DynamicUakMigrationConfiguration getUakMigrationConfiguration() {
|
||||||
|
return uakMigrationConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
public DynamicTurnConfiguration getTurnConfiguration() {
|
public DynamicTurnConfiguration getTurnConfiguration() {
|
||||||
return turn;
|
return turn;
|
||||||
|
@ -124,4 +122,8 @@ public class DynamicConfiguration {
|
||||||
public DynamicAbusiveHostRulesConfiguration getAbusiveHostRules() {
|
public DynamicAbusiveHostRulesConfiguration getAbusiveHostRules() {
|
||||||
return abusiveHostRules;
|
return abusiveHostRules;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DynamicMessagePersisterConfiguration getMessagePersisterConfiguration() {
|
||||||
|
return messagePersister;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022 Signal Messenger, LLC
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.whispersystems.textsecuregcm.configuration.dynamic;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
public class DynamicMessagePersisterConfiguration {
|
||||||
|
|
||||||
|
@JsonProperty
|
||||||
|
private boolean persistenceEnabled = true;
|
||||||
|
|
||||||
|
public boolean isPersistenceEnabled() {
|
||||||
|
return persistenceEnabled;
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,7 +50,6 @@ public class MessagePersister implements Managed {
|
||||||
|
|
||||||
private static final long EXCEPTION_PAUSE_MILLIS = Duration.ofSeconds(3).toMillis();
|
private static final long EXCEPTION_PAUSE_MILLIS = Duration.ofSeconds(3).toMillis();
|
||||||
|
|
||||||
private static final String DISABLE_PERSISTER_FEATURE_FLAG = "DISABLE_MESSAGE_PERSISTER";
|
|
||||||
private static final int WORKER_THREAD_COUNT = 4;
|
private static final int WORKER_THREAD_COUNT = 4;
|
||||||
|
|
||||||
private static final int CONSECUTIVE_EMPTY_CACHE_REMOVAL_LIMIT = 3;
|
private static final int CONSECUTIVE_EMPTY_CACHE_REMOVAL_LIMIT = 3;
|
||||||
|
@ -69,10 +68,8 @@ public class MessagePersister implements Managed {
|
||||||
for (int i = 0; i < workerThreads.length; i++) {
|
for (int i = 0; i < workerThreads.length; i++) {
|
||||||
workerThreads[i] = new Thread(() -> {
|
workerThreads[i] = new Thread(() -> {
|
||||||
while (running) {
|
while (running) {
|
||||||
if (dynamicConfigurationManager.getConfiguration().getActiveFeatureFlags()
|
if (dynamicConfigurationManager.getConfiguration().getMessagePersisterConfiguration()
|
||||||
.contains(DISABLE_PERSISTER_FEATURE_FLAG)) {
|
.isPersistenceEnabled()) {
|
||||||
Util.sleep(1000);
|
|
||||||
} else {
|
|
||||||
try {
|
try {
|
||||||
final int queuesPersisted = persistNextQueues(Instant.now());
|
final int queuesPersisted = persistNextQueues(Instant.now());
|
||||||
queueCountHistogram.update(queuesPersisted);
|
queueCountHistogram.update(queuesPersisted);
|
||||||
|
@ -84,6 +81,8 @@ public class MessagePersister implements Managed {
|
||||||
logger.warn("Failed to persist queues", t);
|
logger.warn("Failed to persist queues", t);
|
||||||
Util.sleep(EXCEPTION_PAUSE_MILLIS);
|
Util.sleep(EXCEPTION_PAUSE_MILLIS);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Util.sleep(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, "MessagePersisterWorker-" + i);
|
}, "MessagePersisterWorker-" + i);
|
||||||
|
|
|
@ -201,29 +201,6 @@ class DynamicConfigurationTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void testParseFeatureFlags() throws JsonProcessingException {
|
|
||||||
{
|
|
||||||
final String emptyConfigYaml = REQUIRED_CONFIG.concat("test: true");
|
|
||||||
final DynamicConfiguration emptyConfig =
|
|
||||||
DynamicConfigurationManager.parseConfiguration(emptyConfigYaml, DynamicConfiguration.class).orElseThrow();
|
|
||||||
|
|
||||||
assertTrue(emptyConfig.getActiveFeatureFlags().isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
final String featureFlagYaml = REQUIRED_CONFIG.concat("""
|
|
||||||
featureFlags:
|
|
||||||
- testFlag
|
|
||||||
""");
|
|
||||||
|
|
||||||
final DynamicConfiguration emptyConfig =
|
|
||||||
DynamicConfigurationManager.parseConfiguration(featureFlagYaml, DynamicConfiguration.class).orElseThrow();
|
|
||||||
|
|
||||||
assertTrue(emptyConfig.getActiveFeatureFlags().contains("testFlag"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testParseTwilioConfiguration() throws JsonProcessingException {
|
void testParseTwilioConfiguration() throws JsonProcessingException {
|
||||||
{
|
{
|
||||||
|
@ -435,6 +412,43 @@ class DynamicConfigurationTest {
|
||||||
assertThat(turnConfiguration.getUriConfigs().get(1).getEnrolledNumbers()).containsExactly("+15555555555");
|
assertThat(turnConfiguration.getUriConfigs().get(1).getEnrolledNumbers()).containsExactly("+15555555555");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testMessagePersister() throws JsonProcessingException {
|
||||||
|
{
|
||||||
|
final String emptyConfigYaml = REQUIRED_CONFIG.concat("test: true");
|
||||||
|
final DynamicConfiguration emptyConfig =
|
||||||
|
DynamicConfigurationManager.parseConfiguration(emptyConfigYaml, DynamicConfiguration.class).orElseThrow();
|
||||||
|
|
||||||
|
assertTrue(emptyConfig.getMessagePersisterConfiguration().isPersistenceEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final String messagePersisterEnabledYaml = REQUIRED_CONFIG.concat("""
|
||||||
|
messagePersister:
|
||||||
|
persistenceEnabled: true
|
||||||
|
""");
|
||||||
|
|
||||||
|
final DynamicConfiguration config =
|
||||||
|
DynamicConfigurationManager.parseConfiguration(messagePersisterEnabledYaml, DynamicConfiguration.class)
|
||||||
|
.orElseThrow();
|
||||||
|
|
||||||
|
assertTrue(config.getMessagePersisterConfiguration().isPersistenceEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
final String messagePersisterDisabledYaml = REQUIRED_CONFIG.concat("""
|
||||||
|
messagePersister:
|
||||||
|
persistenceEnabled: false
|
||||||
|
""");
|
||||||
|
|
||||||
|
final DynamicConfiguration config =
|
||||||
|
DynamicConfigurationManager.parseConfiguration(messagePersisterDisabledYaml, DynamicConfiguration.class)
|
||||||
|
.orElseThrow();
|
||||||
|
|
||||||
|
assertFalse(config.getMessagePersisterConfiguration().isPersistenceEnabled());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,8 +120,9 @@ class DynamicConfigurationManagerTest {
|
||||||
configurationToken("1").build()))
|
configurationToken("1").build()))
|
||||||
.thenReturn(GetLatestConfigurationResponse.builder()
|
.thenReturn(GetLatestConfigurationResponse.builder()
|
||||||
.configuration(SdkBytes.fromUtf8String("""
|
.configuration(SdkBytes.fromUtf8String("""
|
||||||
featureFlags:
|
experiments:
|
||||||
- testFlag
|
test:
|
||||||
|
enrollmentPercentage: 50
|
||||||
captcha:
|
captcha:
|
||||||
scoreFloor: 1.0
|
scoreFloor: 1.0
|
||||||
"""))
|
"""))
|
||||||
|
@ -139,10 +140,12 @@ class DynamicConfigurationManagerTest {
|
||||||
assertTimeoutPreemptively(Duration.ofSeconds(5), () -> {
|
assertTimeoutPreemptively(Duration.ofSeconds(5), () -> {
|
||||||
// we should eventually get the updated config (or the test will timeout)
|
// we should eventually get the updated config (or the test will timeout)
|
||||||
dynamicConfigurationManager.start();
|
dynamicConfigurationManager.start();
|
||||||
while (dynamicConfigurationManager.getConfiguration().getActiveFeatureFlags().isEmpty()) {
|
while (dynamicConfigurationManager.getConfiguration().getExperimentEnrollmentConfiguration("test").isEmpty()) {
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
}
|
}
|
||||||
assertThat(dynamicConfigurationManager.getConfiguration().getActiveFeatureFlags()).containsExactly("testFlag");
|
assertThat(
|
||||||
|
dynamicConfigurationManager.getConfiguration().getExperimentEnrollmentConfiguration("test").get()
|
||||||
|
.getEnrollmentPercentage()).isEqualTo(50);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue