mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-19 18:08:03 +01:00
Delay processing FCM uninstalled feedback
Check to make sure client is not still active before unregistering, since FCM feedback seems to be often erroneous
This commit is contained in:
@@ -210,7 +210,8 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||
ActiveUserCounter activeUserCounter = new ActiveUserCounter(config.getMetricsFactory(), cacheClient);
|
||||
DirectoryReconciler directoryReconciler = new DirectoryReconciler(directoryReconciliationClient, directory);
|
||||
AccountCleaner accountCleaner = new AccountCleaner(accountsManager, directoryQueue);
|
||||
List<AccountDatabaseCrawlerListener> accountDatabaseCrawlerListeners = Arrays.asList(activeUserCounter, directoryReconciler, accountCleaner);
|
||||
PushFeedbackProcessor pushFeedbackProcessor = new PushFeedbackProcessor(accountsManager, directoryQueue);
|
||||
List<AccountDatabaseCrawlerListener> accountDatabaseCrawlerListeners = List.of(pushFeedbackProcessor, activeUserCounter, directoryReconciler, accountCleaner);
|
||||
|
||||
AccountDatabaseCrawlerCache accountDatabaseCrawlerCache = new AccountDatabaseCrawlerCache(cacheClient);
|
||||
AccountDatabaseCrawler accountDatabaseCrawler = new AccountDatabaseCrawler(accounts, accountDatabaseCrawlerCache, accountDatabaseCrawlerListeners, config.getAccountDatabaseCrawlerConfiguration().getChunkSize(), config.getAccountDatabaseCrawlerConfiguration().getChunkIntervalMs());
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
import org.whispersystems.textsecuregcm.util.Constants;
|
||||
import org.whispersystems.textsecuregcm.util.Util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
@@ -111,19 +112,20 @@ public class GCMSender implements Managed {
|
||||
GcmMessage message = (GcmMessage)result.getContext();
|
||||
logger.warn("Got GCM unregistered notice! " + message.getGcmId());
|
||||
|
||||
// Optional<Account> account = getAccountForEvent(message);
|
||||
//
|
||||
// if (account.isPresent()) {
|
||||
// Device device = account.get().getDevice(message.getDeviceId()).get();
|
||||
Optional<Account> account = getAccountForEvent(message);
|
||||
|
||||
if (account.isPresent()) {
|
||||
Device device = account.get().getDevice(message.getDeviceId()).get();
|
||||
device.setUninstalledFeedbackTimestamp(Util.todayInMillis());
|
||||
// device.setGcmId(null);
|
||||
// device.setFetchesMessages(false);
|
||||
//
|
||||
// accountsManager.update(account.get());
|
||||
//
|
||||
|
||||
accountsManager.update(account.get());
|
||||
|
||||
// if (!account.get().isActive()) {
|
||||
// directoryQueue.deleteRegisteredUser(account.get().getNumber());
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
unregistered.mark();
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public class Account implements Principal {
|
||||
}
|
||||
|
||||
public void removeDevice(long deviceId) {
|
||||
this.devices.remove(new Device(deviceId, null, null, null, null, null, null, null, false, 0, null, 0, 0, "NA", false));
|
||||
this.devices.remove(new Device(deviceId, null, null, null, null, null, null, null, false, 0, null, 0, 0, "NA", false, 0));
|
||||
}
|
||||
|
||||
public Set<Device> getDevices() {
|
||||
|
||||
@@ -55,6 +55,9 @@ public class Device {
|
||||
@JsonProperty
|
||||
private long pushTimestamp;
|
||||
|
||||
@JsonProperty
|
||||
private long uninstalledFeedback;
|
||||
|
||||
@JsonProperty
|
||||
private boolean fetchesMessages;
|
||||
|
||||
@@ -83,7 +86,7 @@ public class Device {
|
||||
String voipApnId, boolean fetchesMessages,
|
||||
int registrationId, SignedPreKey signedPreKey,
|
||||
long lastSeen, long created, String userAgent,
|
||||
boolean unauthenticatedDelivery)
|
||||
boolean unauthenticatedDelivery, long uninstalledFeedback)
|
||||
{
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
@@ -100,6 +103,7 @@ public class Device {
|
||||
this.created = created;
|
||||
this.userAgent = userAgent;
|
||||
this.unauthenticatedDelivery = unauthenticatedDelivery;
|
||||
this.uninstalledFeedback = uninstalledFeedback;
|
||||
}
|
||||
|
||||
public String getApnId() {
|
||||
@@ -122,6 +126,14 @@ public class Device {
|
||||
this.voipApnId = voipApnId;
|
||||
}
|
||||
|
||||
public void setUninstalledFeedbackTimestamp(long uninstalledFeedback) {
|
||||
this.uninstalledFeedback = uninstalledFeedback;
|
||||
}
|
||||
|
||||
public long getUninstalledFeedbackTimestamp() {
|
||||
return uninstalledFeedback;
|
||||
}
|
||||
|
||||
public void setLastSeen(long lastSeen) {
|
||||
this.lastSeen = lastSeen;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package org.whispersystems.textsecuregcm.storage;
|
||||
|
||||
import com.codahale.metrics.Meter;
|
||||
import com.codahale.metrics.MetricRegistry;
|
||||
import com.codahale.metrics.SharedMetricRegistries;
|
||||
import org.whispersystems.textsecuregcm.sqs.DirectoryQueue;
|
||||
import org.whispersystems.textsecuregcm.util.Constants;
|
||||
import org.whispersystems.textsecuregcm.util.Util;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.codahale.metrics.MetricRegistry.name;
|
||||
|
||||
public class PushFeedbackProcessor implements AccountDatabaseCrawlerListener {
|
||||
|
||||
private final MetricRegistry metricRegistry = SharedMetricRegistries.getOrCreate(Constants.METRICS_NAME);
|
||||
private final Meter expired = metricRegistry.meter(name(getClass(), "unregistered", "expired"));
|
||||
private final Meter recovered = metricRegistry.meter(name(getClass(), "unregistered", "recovered"));
|
||||
|
||||
private final AccountsManager accountsManager;
|
||||
private final DirectoryQueue directoryQueue;
|
||||
|
||||
public PushFeedbackProcessor(AccountsManager accountsManager, DirectoryQueue directoryQueue) {
|
||||
this.accountsManager = accountsManager;
|
||||
this.directoryQueue = directoryQueue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCrawlStart() {}
|
||||
|
||||
@Override
|
||||
public void onCrawlChunk(Optional<String> fromNumber, List<Account> chunkAccounts) {
|
||||
for (Account account : chunkAccounts) {
|
||||
boolean update = false;
|
||||
|
||||
for (Device device : account.getDevices()) {
|
||||
if (device.getUninstalledFeedbackTimestamp() != 0 &&
|
||||
device.getUninstalledFeedbackTimestamp() + TimeUnit.DAYS.toMillis(2) <= Util.todayInMillis())
|
||||
{
|
||||
if (device.getLastSeen() + TimeUnit.DAYS.toMillis(2) <= Util.todayInMillis()) {
|
||||
device.setGcmId(null);
|
||||
device.setApnId(null);
|
||||
device.setVoipApnId(null);
|
||||
device.setFetchesMessages(false);
|
||||
expired.mark();
|
||||
} else {
|
||||
device.setUninstalledFeedbackTimestamp(0);
|
||||
recovered.mark();
|
||||
}
|
||||
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (update) {
|
||||
accountsManager.update(account);
|
||||
|
||||
if (!account.isEnabled()) {
|
||||
directoryQueue.deleteRegisteredUser(account.getNumber());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCrawlEnd(Optional<String> fromNumber) {}
|
||||
}
|
||||
Reference in New Issue
Block a user