Put message persisters behind feature flags.
This commit is contained in:
parent
cd4b85b0b5
commit
2b50367d7f
|
@ -332,8 +332,8 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||||
TurnTokenGenerator turnTokenGenerator = new TurnTokenGenerator(config.getTurnConfiguration());
|
TurnTokenGenerator turnTokenGenerator = new TurnTokenGenerator(config.getTurnConfiguration());
|
||||||
RecaptchaClient recaptchaClient = new RecaptchaClient(config.getRecaptchaConfiguration().getSecret());
|
RecaptchaClient recaptchaClient = new RecaptchaClient(config.getRecaptchaConfiguration().getSecret());
|
||||||
|
|
||||||
MessagePersister messagePersister = new MessagePersister(messagesClient, messagesManager, pubSubManager, pushSender, accountsManager,config.getMessageCacheConfiguration().getPersistDelayMinutes(), TimeUnit.MINUTES);
|
MessagePersister messagePersister = new MessagePersister(messagesClient, messagesManager, pubSubManager, pushSender, accountsManager, featureFlagsManager, config.getMessageCacheConfiguration().getPersistDelayMinutes(), TimeUnit.MINUTES);
|
||||||
RedisClusterMessagePersister clusterMessagePersister = new RedisClusterMessagePersister(clusterMessagesCache, messages, pubSubManager, pushSender, accountsManager, Duration.ofMinutes(config.getMessageCacheConfiguration().getPersistDelayMinutes()));
|
RedisClusterMessagePersister clusterMessagePersister = new RedisClusterMessagePersister(clusterMessagesCache, messages, pubSubManager, pushSender, accountsManager, featureFlagsManager, Duration.ofMinutes(config.getMessageCacheConfiguration().getPersistDelayMinutes()));
|
||||||
|
|
||||||
DirectoryReconciliationClient directoryReconciliationClient = new DirectoryReconciliationClient(config.getDirectoryConfiguration().getDirectoryServerConfiguration());
|
DirectoryReconciliationClient directoryReconciliationClient = new DirectoryReconciliationClient(config.getDirectoryConfiguration().getDirectoryServerConfiguration());
|
||||||
|
|
||||||
|
|
|
@ -53,16 +53,20 @@ public class MessagePersister implements Managed, Runnable {
|
||||||
private final PubSubManager pubSubManager;
|
private final PubSubManager pubSubManager;
|
||||||
private final PushSender pushSender;
|
private final PushSender pushSender;
|
||||||
private final AccountsManager accountsManager;
|
private final AccountsManager accountsManager;
|
||||||
|
private final FeatureFlagsManager featureFlagsManager;
|
||||||
|
|
||||||
private final LuaScript getQueuesScript;
|
private final LuaScript getQueuesScript;
|
||||||
|
|
||||||
private boolean finished = false;
|
private boolean finished = false;
|
||||||
|
|
||||||
|
private static final String DISABLE_PERSISTENCE_FLAG = "disable-singleton-persister";
|
||||||
|
|
||||||
public MessagePersister(final ReplicatedJedisPool jedisPool,
|
public MessagePersister(final ReplicatedJedisPool jedisPool,
|
||||||
final MessagesManager messagesManager,
|
final MessagesManager messagesManager,
|
||||||
final PubSubManager pubSubManager,
|
final PubSubManager pubSubManager,
|
||||||
final PushSender pushSender,
|
final PushSender pushSender,
|
||||||
final AccountsManager accountsManager,
|
final AccountsManager accountsManager,
|
||||||
|
final FeatureFlagsManager featureFlagsManager,
|
||||||
final long delayTime,
|
final long delayTime,
|
||||||
final TimeUnit delayTimeUnit)
|
final TimeUnit delayTimeUnit)
|
||||||
throws IOException
|
throws IOException
|
||||||
|
@ -73,6 +77,7 @@ public class MessagePersister implements Managed, Runnable {
|
||||||
this.pubSubManager = pubSubManager;
|
this.pubSubManager = pubSubManager;
|
||||||
this.pushSender = pushSender;
|
this.pushSender = pushSender;
|
||||||
this.accountsManager = accountsManager;
|
this.accountsManager = accountsManager;
|
||||||
|
this.featureFlagsManager = featureFlagsManager;
|
||||||
|
|
||||||
this.delayTime = delayTime;
|
this.delayTime = delayTime;
|
||||||
this.delayTimeUnit = delayTimeUnit;
|
this.delayTimeUnit = delayTimeUnit;
|
||||||
|
@ -87,6 +92,7 @@ public class MessagePersister implements Managed, Runnable {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while (running.get()) {
|
while (running.get()) {
|
||||||
|
if (!featureFlagsManager.isFeatureFlagActive(DISABLE_PERSISTENCE_FLAG)) {
|
||||||
try {
|
try {
|
||||||
List<byte[]> queuesToPersist = getQueuesToPersist();
|
List<byte[]> queuesToPersist = getQueuesToPersist();
|
||||||
queueCountHistogram.update(queuesToPersist.size());
|
queueCountHistogram.update(queuesToPersist.size());
|
||||||
|
@ -105,6 +111,12 @@ public class MessagePersister implements Managed, Runnable {
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
logger.error("Exception while persisting: ", t);
|
logger.error("Exception while persisting: ", t);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
Thread.sleep(10_000);
|
||||||
|
} catch (final InterruptedException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
|
|
|
@ -30,6 +30,7 @@ public class RedisClusterMessagePersister implements Managed {
|
||||||
private final PubSubManager pubSubManager;
|
private final PubSubManager pubSubManager;
|
||||||
private final PushSender pushSender;
|
private final PushSender pushSender;
|
||||||
private final AccountsManager accountsManager;
|
private final AccountsManager accountsManager;
|
||||||
|
private final FeatureFlagsManager featureFlagsManager;
|
||||||
|
|
||||||
private final Duration persistDelay;
|
private final Duration persistDelay;
|
||||||
|
|
||||||
|
@ -46,15 +47,17 @@ public class RedisClusterMessagePersister implements Managed {
|
||||||
static final int QUEUE_BATCH_LIMIT = 100;
|
static final int QUEUE_BATCH_LIMIT = 100;
|
||||||
static final int MESSAGE_BATCH_LIMIT = 100;
|
static final int MESSAGE_BATCH_LIMIT = 100;
|
||||||
|
|
||||||
|
static final String ENABLE_PERSISTENCE_FLAG = "enable-cluster-persister";
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(RedisClusterMessagePersister.class);
|
private static final Logger logger = LoggerFactory.getLogger(RedisClusterMessagePersister.class);
|
||||||
|
|
||||||
public RedisClusterMessagePersister(final RedisClusterMessagesCache messagesCache, final Messages messagesDatabase, final PubSubManager pubSubManager, final PushSender pushSender, final AccountsManager accountsManager, final Duration persistDelay) {
|
public RedisClusterMessagePersister(final RedisClusterMessagesCache messagesCache, final Messages messagesDatabase, final PubSubManager pubSubManager, final PushSender pushSender, final AccountsManager accountsManager, final FeatureFlagsManager featureFlagsManager, final Duration persistDelay) {
|
||||||
this.messagesCache = messagesCache;
|
this.messagesCache = messagesCache;
|
||||||
this.messagesDatabase = messagesDatabase;
|
this.messagesDatabase = messagesDatabase;
|
||||||
this.pubSubManager = pubSubManager;
|
this.pubSubManager = pubSubManager;
|
||||||
this.pushSender = pushSender;
|
this.pushSender = pushSender;
|
||||||
this.accountsManager = accountsManager;
|
this.accountsManager = accountsManager;
|
||||||
|
this.featureFlagsManager = featureFlagsManager;
|
||||||
this.persistDelay = persistDelay;
|
this.persistDelay = persistDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +72,10 @@ public class RedisClusterMessagePersister implements Managed {
|
||||||
|
|
||||||
workerThread = new Thread(() -> {
|
workerThread = new Thread(() -> {
|
||||||
while (running) {
|
while (running) {
|
||||||
|
if (featureFlagsManager.isFeatureFlagActive(ENABLE_PERSISTENCE_FLAG)) {
|
||||||
persistNextQueues(Instant.now());
|
persistNextQueues(Instant.now());
|
||||||
|
}
|
||||||
|
|
||||||
Util.sleep(100);
|
Util.sleep(100);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -130,7 +136,7 @@ public class RedisClusterMessagePersister implements Managed {
|
||||||
messagesCache.lockQueueForPersistence(queue);
|
messagesCache.lockQueueForPersistence(queue);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/* int messageCount = 0;
|
int messageCount = 0;
|
||||||
List<MessageProtos.Envelope> messages;
|
List<MessageProtos.Envelope> messages;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -146,7 +152,7 @@ public class RedisClusterMessagePersister implements Managed {
|
||||||
}
|
}
|
||||||
} while (!messages.isEmpty());
|
} while (!messages.isEmpty());
|
||||||
|
|
||||||
queueSizeHistogram.update(messageCount); */
|
queueSizeHistogram.update(messageCount);
|
||||||
} finally {
|
} finally {
|
||||||
messagesCache.unlockQueueForPersistence(queue);
|
messagesCache.unlockQueueForPersistence(queue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import com.google.protobuf.ByteString;
|
||||||
import io.lettuce.core.cluster.SlotHash;
|
import io.lettuce.core.cluster.SlotHash;
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.whispersystems.textsecuregcm.entities.MessageProtos;
|
import org.whispersystems.textsecuregcm.entities.MessageProtos;
|
||||||
import org.whispersystems.textsecuregcm.push.PushSender;
|
import org.whispersystems.textsecuregcm.push.PushSender;
|
||||||
|
@ -29,7 +28,6 @@ import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@Ignore
|
|
||||||
public class RedisClusterMessagePersisterTest extends AbstractRedisClusterTest {
|
public class RedisClusterMessagePersisterTest extends AbstractRedisClusterTest {
|
||||||
|
|
||||||
private ExecutorService notificationExecutorService;
|
private ExecutorService notificationExecutorService;
|
||||||
|
@ -50,6 +48,9 @@ public class RedisClusterMessagePersisterTest extends AbstractRedisClusterTest {
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
|
|
||||||
|
final FeatureFlagsManager featureFlagsManager = mock(FeatureFlagsManager.class);
|
||||||
|
when(featureFlagsManager.isFeatureFlagActive(RedisClusterMessagePersister.ENABLE_PERSISTENCE_FLAG)).thenReturn(true);
|
||||||
|
|
||||||
messagesDatabase = mock(Messages.class);
|
messagesDatabase = mock(Messages.class);
|
||||||
accountsManager = mock(AccountsManager.class);
|
accountsManager = mock(AccountsManager.class);
|
||||||
pubSubManager = mock(PubSubManager.class);
|
pubSubManager = mock(PubSubManager.class);
|
||||||
|
@ -61,7 +62,7 @@ public class RedisClusterMessagePersisterTest extends AbstractRedisClusterTest {
|
||||||
|
|
||||||
notificationExecutorService = Executors.newSingleThreadExecutor();
|
notificationExecutorService = Executors.newSingleThreadExecutor();
|
||||||
messagesCache = new RedisClusterMessagesCache(getRedisCluster(), notificationExecutorService);
|
messagesCache = new RedisClusterMessagesCache(getRedisCluster(), notificationExecutorService);
|
||||||
messagePersister = new RedisClusterMessagePersister(messagesCache, messagesDatabase, pubSubManager, mock(PushSender.class), accountsManager, PERSIST_DELAY);
|
messagePersister = new RedisClusterMessagePersister(messagesCache, messagesDatabase, pubSubManager, mock(PushSender.class), accountsManager, featureFlagsManager, PERSIST_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -136,6 +137,7 @@ public class RedisClusterMessagePersisterTest extends AbstractRedisClusterTest {
|
||||||
verify(messagesDatabase, times(queueCount * messagesPerQueue)).store(any(UUID.class), any(MessageProtos.Envelope.class), anyString(), anyLong());
|
verify(messagesDatabase, times(queueCount * messagesPerQueue)).store(any(UUID.class), any(MessageProtos.Envelope.class), anyString(), anyLong());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("SameParameterValue")
|
||||||
private static String generateRandomQueueNameForSlot(final int slot) {
|
private static String generateRandomQueueNameForSlot(final int slot) {
|
||||||
final UUID uuid = UUID.randomUUID();
|
final UUID uuid = UUID.randomUUID();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue