mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-20 06:28:01 +01:00
Publish "messages persisted" events when unlocking queues after a persistence run
This commit is contained in:
committed by
Jon Chambers
parent
084607f359
commit
562b495a18
@@ -58,11 +58,6 @@ public class PubSubClientEventManager extends RedisClusterPubSubAdapter<byte[],
|
||||
.build()
|
||||
.toByteArray();
|
||||
|
||||
private final byte[] MESSAGES_PERSISTED_EVENT_BYTES = ClientEvent.newBuilder()
|
||||
.setMessagesPersisted(MessagesPersistedEvent.getDefaultInstance())
|
||||
.build()
|
||||
.toByteArray();
|
||||
|
||||
@Nullable
|
||||
private FaultTolerantPubSubClusterConnection<byte[], byte[]> pubSubConnection;
|
||||
|
||||
@@ -224,25 +219,6 @@ public class PubSubClientEventManager extends RedisClusterPubSubAdapter<byte[],
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes an event notifying a specific device that messages have been persisted from short-term to long-term
|
||||
* storage.
|
||||
*
|
||||
* @param accountIdentifier the account identifier for which messages have been persisted
|
||||
* @param deviceId the ID of the device within the target account
|
||||
*
|
||||
* @return a future that completes when the event has been published
|
||||
*/
|
||||
public CompletionStage<Void> handleMessagesPersisted(final UUID accountIdentifier, final byte deviceId) {
|
||||
if (pubSubConnection == null) {
|
||||
throw new IllegalStateException("Presence manager not started");
|
||||
}
|
||||
|
||||
return pubSubConnection.withPubSubConnection(connection ->
|
||||
connection.async().spublish(getClientEventChannel(accountIdentifier, deviceId), MESSAGES_PERSISTED_EVENT_BYTES))
|
||||
.thenRun(Util.NOOP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether a client with the given account/device is connected to this presence manager instance.
|
||||
*
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
||||
import org.whispersystems.textsecuregcm.entities.MessageProtos;
|
||||
import org.whispersystems.textsecuregcm.push.PubSubClientEventManager;
|
||||
import org.whispersystems.textsecuregcm.util.Util;
|
||||
import software.amazon.awssdk.services.dynamodb.model.ItemCollectionSizeLimitExceededException;
|
||||
|
||||
@@ -31,7 +30,6 @@ public class MessagePersister implements Managed {
|
||||
private final MessagesCache messagesCache;
|
||||
private final MessagesManager messagesManager;
|
||||
private final AccountsManager accountsManager;
|
||||
private final PubSubClientEventManager pubSubClientEventManager;
|
||||
|
||||
private final Duration persistDelay;
|
||||
|
||||
@@ -63,9 +61,9 @@ public class MessagePersister implements Managed {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MessagePersister.class);
|
||||
|
||||
public MessagePersister(final MessagesCache messagesCache, final MessagesManager messagesManager,
|
||||
public MessagePersister(final MessagesCache messagesCache,
|
||||
final MessagesManager messagesManager,
|
||||
final AccountsManager accountsManager,
|
||||
final PubSubClientEventManager pubSubClientEventManager,
|
||||
final DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager,
|
||||
final Duration persistDelay,
|
||||
final int dedicatedProcessWorkerThreadCount
|
||||
@@ -74,7 +72,6 @@ public class MessagePersister implements Managed {
|
||||
this.messagesCache = messagesCache;
|
||||
this.messagesManager = messagesManager;
|
||||
this.accountsManager = accountsManager;
|
||||
this.pubSubClientEventManager = pubSubClientEventManager;
|
||||
this.persistDelay = persistDelay;
|
||||
this.workerThreads = new Thread[dedicatedProcessWorkerThreadCount];
|
||||
|
||||
@@ -211,7 +208,6 @@ public class MessagePersister implements Managed {
|
||||
maybeUnlink(account, deviceId); // may throw, in which case we'll retry later by the usual mechanism
|
||||
} finally {
|
||||
messagesCache.unlockQueueForPersistence(accountUuid, deviceId);
|
||||
pubSubClientEventManager.handleMessagesPersisted(accountUuid, deviceId);
|
||||
sample.stop(persistQueueTimer);
|
||||
}
|
||||
|
||||
|
||||
@@ -125,6 +125,7 @@ public class MessagesCache {
|
||||
private final MessagesCacheRemoveQueueScript removeQueueScript;
|
||||
private final MessagesCacheGetQueuesToPersistScript getQueuesToPersistScript;
|
||||
private final MessagesCacheRemoveRecipientViewFromMrmDataScript removeRecipientViewFromMrmDataScript;
|
||||
private final MessagesCacheUnlockQueueScript unlockQueueScript;
|
||||
|
||||
private final Timer insertTimer = Metrics.timer(name(MessagesCache.class, "insert"));
|
||||
private final Timer insertSharedMrmPayloadTimer = Metrics.timer(name(MessagesCache.class, "insertSharedMrmPayload"));
|
||||
@@ -176,7 +177,8 @@ public class MessagesCache {
|
||||
new MessagesCacheRemoveByGuidScript(redisCluster),
|
||||
new MessagesCacheRemoveQueueScript(redisCluster),
|
||||
new MessagesCacheGetQueuesToPersistScript(redisCluster),
|
||||
new MessagesCacheRemoveRecipientViewFromMrmDataScript(redisCluster)
|
||||
new MessagesCacheRemoveRecipientViewFromMrmDataScript(redisCluster),
|
||||
new MessagesCacheUnlockQueueScript(redisCluster)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -190,8 +192,8 @@ public class MessagesCache {
|
||||
final MessagesCacheGetItemsScript getItemsScript, final MessagesCacheRemoveByGuidScript removeByGuidScript,
|
||||
final MessagesCacheRemoveQueueScript removeQueueScript,
|
||||
final MessagesCacheGetQueuesToPersistScript getQueuesToPersistScript,
|
||||
final MessagesCacheRemoveRecipientViewFromMrmDataScript removeRecipientViewFromMrmDataScript)
|
||||
throws IOException {
|
||||
final MessagesCacheRemoveRecipientViewFromMrmDataScript removeRecipientViewFromMrmDataScript,
|
||||
final MessagesCacheUnlockQueueScript unlockQueueScript) throws IOException {
|
||||
|
||||
this.redisCluster = redisCluster;
|
||||
this.clock = clock;
|
||||
@@ -209,6 +211,7 @@ public class MessagesCache {
|
||||
this.removeQueueScript = removeQueueScript;
|
||||
this.getQueuesToPersistScript = getQueuesToPersistScript;
|
||||
this.removeRecipientViewFromMrmDataScript = removeRecipientViewFromMrmDataScript;
|
||||
this.unlockQueueScript = unlockQueueScript;
|
||||
}
|
||||
|
||||
public boolean insert(final UUID messageGuid,
|
||||
@@ -599,8 +602,7 @@ public class MessagesCache {
|
||||
}
|
||||
|
||||
void unlockQueueForPersistence(final UUID accountUuid, final byte deviceId) {
|
||||
redisCluster.useBinaryCluster(
|
||||
connection -> connection.sync().del(getPersistInProgressKey(accountUuid, deviceId)));
|
||||
unlockQueueScript.execute(accountUuid, deviceId);
|
||||
}
|
||||
|
||||
static byte[] getMessageQueueKey(final UUID accountUuid, final byte deviceId) {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2024 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.storage;
|
||||
|
||||
import io.lettuce.core.ScriptOutputType;
|
||||
import org.whispersystems.textsecuregcm.push.ClientEvent;
|
||||
import org.whispersystems.textsecuregcm.push.MessagesPersistedEvent;
|
||||
import org.whispersystems.textsecuregcm.push.PubSubClientEventManager;
|
||||
import org.whispersystems.textsecuregcm.redis.ClusterLuaScript;
|
||||
import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisClusterClient;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Unlocks a message queue for persistence/message retrieval.
|
||||
*/
|
||||
class MessagesCacheUnlockQueueScript {
|
||||
|
||||
private final ClusterLuaScript unlockQueueScript;
|
||||
|
||||
private final List<byte[]> MESSAGES_PERSISTED_EVENT_ARGS = List.of(ClientEvent.newBuilder()
|
||||
.setMessagesPersisted(MessagesPersistedEvent.getDefaultInstance())
|
||||
.build()
|
||||
.toByteArray()); // eventPayload
|
||||
|
||||
MessagesCacheUnlockQueueScript(final FaultTolerantRedisClusterClient redisCluster) throws IOException {
|
||||
this.unlockQueueScript =
|
||||
ClusterLuaScript.fromResource(redisCluster, "lua/unlock_queue.lua", ScriptOutputType.STATUS);
|
||||
}
|
||||
|
||||
void execute(final UUID accountIdentifier, final byte deviceId) {
|
||||
final List<byte[]> keys = List.of(
|
||||
MessagesCache.getPersistInProgressKey(accountIdentifier, deviceId), // persistInProgressKey
|
||||
PubSubClientEventManager.getClientEventChannel(accountIdentifier, deviceId) // eventChannelKey
|
||||
);
|
||||
|
||||
unlockQueueScript.executeBinary(keys, MESSAGES_PERSISTED_EVENT_ARGS);
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,6 @@ record CommandDependencies(
|
||||
ReportMessageManager reportMessageManager,
|
||||
MessagesCache messagesCache,
|
||||
MessagesManager messagesManager,
|
||||
PubSubClientEventManager pubSubClientEventManager,
|
||||
KeysManager keysManager,
|
||||
APNSender apnSender,
|
||||
FcmSender fcmSender,
|
||||
@@ -269,7 +268,6 @@ record CommandDependencies(
|
||||
reportMessageManager,
|
||||
messagesCache,
|
||||
messagesManager,
|
||||
pubSubClientEventManager,
|
||||
keys,
|
||||
apnSender,
|
||||
fcmSender,
|
||||
|
||||
@@ -63,7 +63,6 @@ public class MessagePersisterServiceCommand extends ServerCommand<WhisperServerC
|
||||
final MessagePersister messagePersister = new MessagePersister(deps.messagesCache(),
|
||||
deps.messagesManager(),
|
||||
deps.accountsManager(),
|
||||
deps.pubSubClientEventManager(),
|
||||
deps.dynamicConfigurationManager(),
|
||||
Duration.ofMinutes(configuration.getMessageCacheConfiguration().getPersistDelayMinutes()),
|
||||
namespace.getInt(WORKER_COUNT));
|
||||
|
||||
Reference in New Issue
Block a user