Several sender key performance improvements.

- Remove extra unnecessary sync message
- Add a bulk session retrieval method
- Do the encrypt in a transaction
This commit is contained in:
Greyson Parrelli
2021-08-23 11:05:06 -04:00
committed by Alex Hart
parent 194975d068
commit 2068fa8041
7 changed files with 93 additions and 26 deletions

View File

@@ -2,6 +2,8 @@ package org.whispersystems.signalservice.api;
import org.whispersystems.libsignal.state.SignalProtocolStore;
import java.io.Closeable;
/**
* And extension of the normal protocol store interface that has additional methods that are needed
* in the service layer, but not the protocol layer.
@@ -11,4 +13,13 @@ public interface SignalServiceDataStore extends SignalProtocolStore, SignalServi
* @return True if the active account has linked devices, otherwise false.
*/
boolean isMultiDevice();
/**
* @return Begins a transaction to improve the performance of multiple storage operations happening in a row.
*/
Transaction beginTransaction();
interface Transaction extends Closeable {
void close();
}
}

View File

@@ -122,7 +122,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -132,7 +131,6 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
/**
@@ -1667,7 +1665,6 @@ public class SignalServiceMessageSender {
.distinct()
.map(SignalServiceAddress::new)
.collect(Collectors.toList());
if (needsSenderKey.size() > 0) {
Log.i(TAG, "[sendGroupMessage] Need to send the distribution message to " + needsSenderKey.size() + " addresses.");
SenderKeyDistributionMessage message = getOrCreateNewGroupSession(distributionId);
@@ -1767,23 +1764,22 @@ public class SignalServiceMessageSender {
}
private GroupTargetInfo buildGroupTargetInfo(List<SignalServiceAddress> recipients) {
Set<SignalProtocolAddress> destinations = new LinkedHashSet<>();
List<String> addressNames = recipients.stream().map(SignalServiceAddress::getIdentifier).collect(Collectors.toList());
Set<SignalProtocolAddress> destinations = store.getAllAddressesWithActiveSessions(addressNames);
Map<String, List<Integer>> devicesByAddressName = new HashMap<>();
for (SignalProtocolAddress destination : destinations) {
List<Integer> devices = devicesByAddressName.containsKey(destination.getName()) ? devicesByAddressName.get(destination.getName()) : new LinkedList<>();
devices.add(destination.getDeviceId());
devicesByAddressName.put(destination.getName(), devices);
}
Map<SignalServiceAddress, List<Integer>> recipientDevices = new HashMap<>();
for (SignalServiceAddress recipient : recipients) {
List<Integer> devices = recipientDevices.containsKey(recipient) ? recipientDevices.get(recipient) : new LinkedList<>();
destinations.add(new SignalProtocolAddress(recipient.getUuid().toString(), SignalServiceAddress.DEFAULT_DEVICE_ID));
devices.add(SignalServiceAddress.DEFAULT_DEVICE_ID);
for (int deviceId : store.getSubDeviceSessions(recipient.getIdentifier())) {
if (store.containsSession(new SignalProtocolAddress(recipient.getIdentifier(), deviceId))) {
destinations.add(new SignalProtocolAddress(recipient.getUuid().toString(), deviceId));
devices.add(deviceId);
}
if (devicesByAddressName.containsKey(recipient.getIdentifier())) {
recipientDevices.put(recipient, devicesByAddressName.get(recipient.getIdentifier()));
}
recipientDevices.put(recipient, devices);
}
return new GroupTargetInfo(new ArrayList<>(destinations), recipientDevices);
@@ -2057,8 +2053,7 @@ public class SignalServiceMessageSender {
return content;
}
public static interface EventListener {
public void onSecurityEvent(SignalServiceAddress address);
public interface EventListener {
void onSecurityEvent(SignalServiceAddress address);
}
}

View File

@@ -3,10 +3,14 @@ package org.whispersystems.signalservice.api;
import org.whispersystems.libsignal.SignalProtocolAddress;
import org.whispersystems.libsignal.state.SessionStore;
import java.util.List;
import java.util.Set;
/**
* And extension of the normal protocol session store interface that has additional methods that are
* needed in the service layer, but not the protocol layer.
*/
public interface SignalServiceSessionStore extends SessionStore {
void archiveSession(SignalProtocolAddress address);
Set<SignalProtocolAddress> getAllAddressesWithActiveSessions(List<String> addressNames);
}