mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-19 23:48:01 +01:00
Distinguish local vs remote in ClientPresenceManager#disconnectPresence
This commit is contained in:
@@ -5,10 +5,14 @@
|
||||
|
||||
package org.whispersystems.textsecuregcm.auth;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import static org.whispersystems.textsecuregcm.metrics.MetricsUtil.name;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
import io.micrometer.core.instrument.Metrics;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import javax.ws.rs.container.ResourceInfo;
|
||||
import javax.ws.rs.core.Context;
|
||||
import org.glassfish.jersey.server.monitoring.RequestEvent;
|
||||
import org.glassfish.jersey.server.monitoring.RequestEvent.Type;
|
||||
import org.glassfish.jersey.server.monitoring.RequestEventListener;
|
||||
@@ -16,11 +20,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.textsecuregcm.push.ClientPresenceManager;
|
||||
|
||||
import javax.ws.rs.container.ResourceInfo;
|
||||
import javax.ws.rs.core.Context;
|
||||
|
||||
import static org.whispersystems.textsecuregcm.metrics.MetricsUtil.name;
|
||||
|
||||
public class WebsocketRefreshRequestEventListener implements RequestEventListener {
|
||||
|
||||
private final ClientPresenceManager clientPresenceManager;
|
||||
@@ -60,7 +59,7 @@ public class WebsocketRefreshRequestEventListener implements RequestEventListene
|
||||
.forEach(pair -> {
|
||||
try {
|
||||
displacedDevices.incrementAndGet();
|
||||
clientPresenceManager.displacePresence(pair.first(), pair.second());
|
||||
clientPresenceManager.disconnectPresence(pair.first(), pair.second());
|
||||
} catch (final Exception e) {
|
||||
logger.error("Could not displace device presence", e);
|
||||
}
|
||||
|
||||
@@ -171,8 +171,16 @@ public class ClientPresenceManager extends RedisClusterPubSubAdapter<String, Str
|
||||
}
|
||||
}
|
||||
|
||||
public void displacePresence(final UUID accountUuid, final long deviceId) {
|
||||
displacePresence(getPresenceKey(accountUuid, deviceId));
|
||||
public void disconnectPresence(final UUID accountUuid, final long deviceId) {
|
||||
final String presenceKey = getPresenceKey(accountUuid, deviceId);
|
||||
|
||||
if (isLocallyPresent(accountUuid, deviceId)) {
|
||||
displacePresence(presenceKey);
|
||||
}
|
||||
|
||||
// If connected locally, we still need to clean up the presence key.
|
||||
// If connected remotely, the other server will get a keyspace message and handle the disconnect
|
||||
presenceCluster.useCluster(connection -> connection.sync().del(presenceKey));
|
||||
}
|
||||
|
||||
private void displacePresence(final String presenceKey) {
|
||||
@@ -268,18 +276,22 @@ public class ClientPresenceManager extends RedisClusterPubSubAdapter<String, Str
|
||||
public void message(final RedisClusterNode node, final String channel, final String message) {
|
||||
pubSubMessageMeter.mark();
|
||||
|
||||
if ("set".equals(message) && channel.startsWith("__keyspace@0__:presence::{")) {
|
||||
// Another process has overwritten this presence key, which means the client has connected to another host.
|
||||
// At this point, we're on a Lettuce IO thread and need to dispatch to a separate thread before making
|
||||
// synchronous Lettuce calls to avoid deadlocking.
|
||||
keyspaceNotificationExecutorService.execute(() -> {
|
||||
try {
|
||||
displacePresence(channel.substring("__keyspace@0__:".length()));
|
||||
remoteDisplacementMeter.mark();
|
||||
} catch (final Exception e) {
|
||||
log.warn("Error displacing presence", e);
|
||||
}
|
||||
});
|
||||
if (channel.startsWith("__keyspace@0__:presence::{")) {
|
||||
if ("set".equals(message) || "del".equals(message)) {
|
||||
// for "set", another process has overwritten this presence key, which means the client has connected to another host.
|
||||
// for "del", another process has indicated the client should be disconnected
|
||||
|
||||
// At this point, we're on a Lettuce IO thread and need to dispatch to a separate thread before making
|
||||
// synchronous Lettuce calls to avoid deadlocking.
|
||||
keyspaceNotificationExecutorService.execute(() -> {
|
||||
try {
|
||||
displacePresence(channel.substring("__keyspace@0__:".length()));
|
||||
remoteDisplacementMeter.mark();
|
||||
} catch (final Exception e) {
|
||||
log.warn("Error displacing presence", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -552,7 +552,7 @@ public class AccountsManager {
|
||||
|
||||
RedisOperation.unchecked(() ->
|
||||
account.getDevices().forEach(device ->
|
||||
clientPresenceManager.displacePresence(account.getUuid(), device.getId())));
|
||||
clientPresenceManager.disconnectPresence(account.getUuid(), device.getId())));
|
||||
}
|
||||
|
||||
private String getAccountMapKey(String key) {
|
||||
|
||||
Reference in New Issue
Block a user