Merge multiple SendReceiptActions to same recipient to only send one receipt

This commit is contained in:
AsamK 2021-11-12 12:10:46 +01:00
parent b7005884fd
commit b78573021d
4 changed files with 38 additions and 11 deletions

View file

@ -52,9 +52,15 @@
{ {
"pattern":"\\Qcom/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GR\\E" "pattern":"\\Qcom/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_GR\\E"
}, },
{
"pattern":"\\Qcom/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IL\\E"
},
{ {
"pattern":"\\Qcom/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IN\\E" "pattern":"\\Qcom/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IN\\E"
}, },
{
"pattern":"\\Qcom/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_IT\\E"
},
{ {
"pattern":"\\Qcom/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PA\\E" "pattern":"\\Qcom/google/i18n/phonenumbers/data/PhoneNumberMetadataProto_PA\\E"
}, },

View file

@ -1028,7 +1028,8 @@ public class ManagerImpl implements Manager {
) throws IOException { ) throws IOException {
retryFailedReceivedMessages(handler); retryFailedReceivedMessages(handler);
Set<HandleAction> queuedActions = new HashSet<>(); // Use a Map here because java Set doesn't have a get method ...
Map<HandleAction, HandleAction> queuedActions = new HashMap<>();
final var signalWebSocket = dependencies.getSignalWebSocket(); final var signalWebSocket = dependencies.getSignalWebSocket();
signalWebSocket.connect(); signalWebSocket.connect();
@ -1057,7 +1058,7 @@ public class ManagerImpl implements Manager {
logger.debug("New message received from server"); logger.debug("New message received from server");
} else { } else {
logger.debug("Received indicator that server queue is empty"); logger.debug("Received indicator that server queue is empty");
handleQueuedActions(queuedActions); handleQueuedActions(queuedActions.keySet());
queuedActions.clear(); queuedActions.clear();
hasCaughtUpWithOldMessages = true; hasCaughtUpWithOldMessages = true;
@ -1098,11 +1099,18 @@ public class ManagerImpl implements Manager {
} }
final var result = incomingMessageHandler.handleEnvelope(envelope, ignoreAttachments, handler); final var result = incomingMessageHandler.handleEnvelope(envelope, ignoreAttachments, handler);
queuedActions.addAll(result.first()); for (final var h : result.first()) {
final var existingAction = queuedActions.get(h);
if (existingAction == null) {
queuedActions.put(h, h);
} else {
existingAction.mergeOther(h);
}
}
final var exception = result.second(); final var exception = result.second();
if (hasCaughtUpWithOldMessages) { if (hasCaughtUpWithOldMessages) {
handleQueuedActions(queuedActions); handleQueuedActions(queuedActions.keySet());
queuedActions.clear(); queuedActions.clear();
} }
if (cachedMessage[0] != null) { if (cachedMessage[0] != null) {
@ -1123,7 +1131,7 @@ public class ManagerImpl implements Manager {
} }
} }
} }
handleQueuedActions(queuedActions); handleQueuedActions(queuedActions.keySet());
queuedActions.clear(); queuedActions.clear();
dependencies.getSignalWebSocket().disconnect(); dependencies.getSignalWebSocket().disconnect();
} }

View file

@ -5,4 +5,7 @@ import org.asamk.signal.manager.jobs.Context;
public interface HandleAction { public interface HandleAction {
void execute(Context context) throws Throwable; void execute(Context context) throws Throwable;
default void mergeOther(HandleAction action) {
}
} }

View file

@ -3,34 +3,44 @@ package org.asamk.signal.manager.actions;
import org.asamk.signal.manager.jobs.Context; import org.asamk.signal.manager.jobs.Context;
import org.asamk.signal.manager.storage.recipients.RecipientId; import org.asamk.signal.manager.storage.recipients.RecipientId;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
public class SendReceiptAction implements HandleAction { public class SendReceiptAction implements HandleAction {
private final RecipientId recipientId; private final RecipientId recipientId;
private final long timestamp; private final List<Long> timestamps = new ArrayList<>();
public SendReceiptAction(final RecipientId recipientId, final long timestamp) { public SendReceiptAction(final RecipientId recipientId, final long timestamp) {
this.recipientId = recipientId; this.recipientId = recipientId;
this.timestamp = timestamp; this.timestamps.add(timestamp);
} }
@Override @Override
public void execute(Context context) throws Throwable { public void execute(Context context) throws Throwable {
context.getSendHelper().sendDeliveryReceipt(recipientId, List.of(timestamp)); context.getSendHelper().sendDeliveryReceipt(recipientId, timestamps);
}
@Override
public void mergeOther(final HandleAction action) {
if (action instanceof SendReceiptAction sendReceiptAction) {
this.timestamps.addAll(sendReceiptAction.timestamps);
}
} }
@Override @Override
public boolean equals(final Object o) { public boolean equals(final Object o) {
if (this == o) return true; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
final var that = (SendReceiptAction) o; final SendReceiptAction that = (SendReceiptAction) o;
return timestamp == that.timestamp && recipientId.equals(that.recipientId); // Using only recipientId here on purpose
return recipientId.equals(that.recipientId);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(recipientId, timestamp); // Using only recipientId here on purpose
return Objects.hash(recipientId);
} }
} }