mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-21 23:18:05 +01:00
Reduce contention when updating device.lastSeen
This commit is contained in:
@@ -44,13 +44,13 @@ class BaseAccountAuthenticatorTest {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
accountsManager = mock(AccountsManager.class);
|
||||
clock = mock(Clock.class);
|
||||
baseAccountAuthenticator = new BaseAccountAuthenticator(accountsManager, clock);
|
||||
accountsManager = mock(AccountsManager.class);
|
||||
clock = mock(Clock.class);
|
||||
baseAccountAuthenticator = new BaseAccountAuthenticator(accountsManager, clock);
|
||||
|
||||
acct1 = new Account("+14088675309", AuthHelper.getRandomUUID(random), Set.of(new Device(1, null, null, null,
|
||||
acct1 = new Account("+14088675309", AuthHelper.getRandomUUID(random), Set.of(new Device(1, null, null, null,
|
||||
null, null, null, false, 0, null, yesterday, 0, null, 0, null)), null);
|
||||
acct2 = new Account("+14098675309", AuthHelper.getRandomUUID(random), Set.of(new Device(1, null, null, null,
|
||||
acct2 = new Account("+14098675309", AuthHelper.getRandomUUID(random), Set.of(new Device(1, null, null, null,
|
||||
null, null, null, false, 0, null, yesterday, 0, null, 0, null)), null);
|
||||
oldAccount = new Account("+14108675309", AuthHelper.getRandomUUID(random), Set.of(new Device(1, null, null, null,
|
||||
null, null, null, false, 0, null, oldTime, 0, null, 0, null)), null);
|
||||
@@ -68,8 +68,8 @@ class BaseAccountAuthenticatorTest {
|
||||
final Account updatedAcct1 = baseAccountAuthenticator.updateLastSeen(acct1, device1);
|
||||
final Account updatedAcct2 = baseAccountAuthenticator.updateLastSeen(acct2, device2);
|
||||
|
||||
verify(accountsManager, never()).updateDevice(eq(acct1), anyLong(), any());
|
||||
verify(accountsManager).updateDevice(eq(acct2), anyLong(), any());
|
||||
verify(accountsManager, never()).updateDeviceLastSeen(eq(acct1), any(), anyLong());
|
||||
verify(accountsManager).updateDeviceLastSeen(eq(acct2), eq(device2), anyLong());
|
||||
|
||||
assertThat(device1.getLastSeen()).isEqualTo(yesterday);
|
||||
assertThat(device2.getLastSeen()).isEqualTo(today);
|
||||
@@ -88,8 +88,8 @@ class BaseAccountAuthenticatorTest {
|
||||
final Account updatedAcct1 = baseAccountAuthenticator.updateLastSeen(acct1, device1);
|
||||
final Account updatedAcct2 = baseAccountAuthenticator.updateLastSeen(acct2, device2);
|
||||
|
||||
verify(accountsManager, never()).updateDevice(eq(acct1), anyLong(), any());
|
||||
verify(accountsManager, never()).updateDevice(eq(acct2), anyLong(), any());
|
||||
verify(accountsManager, never()).updateDeviceLastSeen(eq(acct1), any(), anyLong());
|
||||
verify(accountsManager, never()).updateDeviceLastSeen(eq(acct2), any(), anyLong());
|
||||
|
||||
assertThat(device1.getLastSeen()).isEqualTo(yesterday);
|
||||
assertThat(device2.getLastSeen()).isEqualTo(yesterday);
|
||||
@@ -108,8 +108,8 @@ class BaseAccountAuthenticatorTest {
|
||||
final Account updatedAcct1 = baseAccountAuthenticator.updateLastSeen(acct1, device1);
|
||||
final Account updatedAcct2 = baseAccountAuthenticator.updateLastSeen(acct2, device2);
|
||||
|
||||
verify(accountsManager).updateDevice(eq(acct1), anyLong(), any());
|
||||
verify(accountsManager).updateDevice(eq(acct2), anyLong(), any());
|
||||
verify(accountsManager).updateDeviceLastSeen(eq(acct1), eq(device1), anyLong());
|
||||
verify(accountsManager).updateDeviceLastSeen(eq(acct2), eq(device2), anyLong());
|
||||
|
||||
assertThat(device1.getLastSeen()).isEqualTo(today);
|
||||
assertThat(device2.getLastSeen()).isEqualTo(today);
|
||||
@@ -126,7 +126,7 @@ class BaseAccountAuthenticatorTest {
|
||||
|
||||
baseAccountAuthenticator.updateLastSeen(oldAccount, device);
|
||||
|
||||
verify(accountsManager).updateDevice(eq(oldAccount), anyLong(), any());
|
||||
verify(accountsManager).updateDeviceLastSeen(eq(oldAccount), eq(device), anyLong());
|
||||
|
||||
assertThat(device.getLastSeen()).isEqualTo(today);
|
||||
}
|
||||
|
||||
@@ -641,4 +641,28 @@ class AccountsManagerTest {
|
||||
Arguments.of(false, true, true),
|
||||
Arguments.of(true, false, true));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void testUpdateDeviceLastSeen(final boolean expectUpdate, final long initialLastSeen, final long updatedLastSeen) {
|
||||
final Account account = new Account("+14152222222", UUID.randomUUID(), new HashSet<>(), new byte[16]);
|
||||
final Device device = new Device(Device.MASTER_ID, "device", "token", "salt", null, null, null, true, 1,
|
||||
new SignedPreKey(1, "key", "sig"), initialLastSeen, 0,
|
||||
"OWT", 0, new DeviceCapabilities());
|
||||
account.addDevice(device);
|
||||
|
||||
accountsManager.updateDeviceLastSeen(account, device, updatedLastSeen);
|
||||
|
||||
assertEquals(expectUpdate ? updatedLastSeen : initialLastSeen, device.getLastSeen());
|
||||
verify(accounts, expectUpdate ? times(1) : never()).update(account);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static Stream<Arguments> testUpdateDeviceLastSeen() {
|
||||
return Stream.of(
|
||||
Arguments.of(true, 1, 2),
|
||||
Arguments.of(false, 1, 1),
|
||||
Arguments.of(false, 2, 1)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.mockito.MockingDetails;
|
||||
import org.mockito.stubbing.Stubbing;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
import org.whispersystems.textsecuregcm.util.SystemMapper;
|
||||
|
||||
public class AccountsHelper {
|
||||
@@ -51,6 +52,13 @@ public class AccountsHelper {
|
||||
|
||||
return markStale ? copyAndMarkStale(account) : account;
|
||||
});
|
||||
|
||||
when(mockAccountsManager.updateDeviceLastSeen(any(), any(), anyLong())).thenAnswer(answer -> {
|
||||
|
||||
answer.getArgument(1, Device.class).setLastSeen(answer.getArgument(2, Long.class));
|
||||
return mockAccountsManager.update(answer.getArgument(0, Account.class), account -> {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static void setupMockGet(final AccountsManager mockAccountsManager, final Set<Account> mockAccounts) {
|
||||
|
||||
Reference in New Issue
Block a user