apply editorconfig formatting

This commit is contained in:
Chris Eager 2021-09-27 16:45:38 -07:00 committed by Chris Eager
parent d1d6e5c652
commit 5189cbe5c7
2 changed files with 558 additions and 522 deletions

View File

@ -66,7 +66,8 @@ public class MessagesCache extends RedisClusterPubSubAdapter<String, String> imp
private final Timer getQueuesToPersistTimer = Metrics.timer(name(MessagesCache.class, "getQueuesToPersist")); private final Timer getQueuesToPersistTimer = Metrics.timer(name(MessagesCache.class, "getQueuesToPersist"));
private final Timer clearQueueTimer = Metrics.timer(name(MessagesCache.class, "clear")); private final Timer clearQueueTimer = Metrics.timer(name(MessagesCache.class, "clear"));
private final Counter pubSubMessageCounter = Metrics.counter(name(MessagesCache.class, "pubSubMessage")); private final Counter pubSubMessageCounter = Metrics.counter(name(MessagesCache.class, "pubSubMessage"));
private final Counter newMessageNotificationCounter = Metrics.counter(name(MessagesCache.class, "newMessageNotification")); private final Counter newMessageNotificationCounter = Metrics.counter(
name(MessagesCache.class, "newMessageNotification"));
private final Counter queuePersistedNotificationCounter = Metrics.counter( private final Counter queuePersistedNotificationCounter = Metrics.counter(
name(MessagesCache.class, "queuePersisted")); name(MessagesCache.class, "queuePersisted"));
private final Counter staleEphemeralMessagesCounter = Metrics.counter( private final Counter staleEphemeralMessagesCounter = Metrics.counter(
@ -87,7 +88,8 @@ public class MessagesCache extends RedisClusterPubSubAdapter<String, String> imp
private static final Logger logger = LoggerFactory.getLogger(MessagesCache.class); private static final Logger logger = LoggerFactory.getLogger(MessagesCache.class);
public MessagesCache(final FaultTolerantRedisCluster insertCluster, final FaultTolerantRedisCluster readDeleteCluster, final ExecutorService notificationExecutorService) throws IOException { public MessagesCache(final FaultTolerantRedisCluster insertCluster, final FaultTolerantRedisCluster readDeleteCluster,
final ExecutorService notificationExecutorService) throws IOException {
this.readDeleteCluster = readDeleteCluster; this.readDeleteCluster = readDeleteCluster;
this.pubSubConnection = readDeleteCluster.createPubSubConnection(); this.pubSubConnection = readDeleteCluster.createPubSubConnection();
@ -95,10 +97,13 @@ public class MessagesCache extends RedisClusterPubSubAdapter<String, String> imp
this.notificationExecutorService = notificationExecutorService; this.notificationExecutorService = notificationExecutorService;
this.insertScript = ClusterLuaScript.fromResource(insertCluster, "lua/insert_item.lua", ScriptOutputType.INTEGER); this.insertScript = ClusterLuaScript.fromResource(insertCluster, "lua/insert_item.lua", ScriptOutputType.INTEGER);
this.removeByGuidScript = ClusterLuaScript.fromResource(readDeleteCluster, "lua/remove_item_by_guid.lua", ScriptOutputType.MULTI); this.removeByGuidScript = ClusterLuaScript.fromResource(readDeleteCluster, "lua/remove_item_by_guid.lua",
ScriptOutputType.MULTI);
this.getItemsScript = ClusterLuaScript.fromResource(readDeleteCluster, "lua/get_items.lua", ScriptOutputType.MULTI); this.getItemsScript = ClusterLuaScript.fromResource(readDeleteCluster, "lua/get_items.lua", ScriptOutputType.MULTI);
this.removeQueueScript = ClusterLuaScript.fromResource(readDeleteCluster, "lua/remove_queue.lua", ScriptOutputType.STATUS); this.removeQueueScript = ClusterLuaScript.fromResource(readDeleteCluster, "lua/remove_queue.lua",
this.getQueuesToPersistScript = ClusterLuaScript.fromResource(readDeleteCluster, "lua/get_queues_to_persist.lua", ScriptOutputType.MULTI); ScriptOutputType.STATUS);
this.getQueuesToPersistScript = ClusterLuaScript.fromResource(readDeleteCluster, "lua/get_queues_to_persist.lua",
ScriptOutputType.MULTI);
} }
@Override @Override
@ -130,7 +135,8 @@ public class MessagesCache extends RedisClusterPubSubAdapter<String, String> imp
} }
} }
public long insert(final UUID guid, final UUID destinationUuid, final long destinationDevice, final MessageProtos.Envelope message) { public long insert(final UUID guid, final UUID destinationUuid, final long destinationDevice,
final MessageProtos.Envelope message) {
final MessageProtos.Envelope messageWithGuid = message.toBuilder().setServerGuid(guid.toString()).build(); final MessageProtos.Envelope messageWithGuid = message.toBuilder().setServerGuid(guid.toString()).build();
return (long) insertTimer.record(() -> return (long) insertTimer.record(() ->
insertScript.executeBinary(List.of(getMessageQueueKey(destinationUuid, destinationDevice), insertScript.executeBinary(List.of(getMessageQueueKey(destinationUuid, destinationDevice),
@ -171,17 +177,20 @@ public class MessagesCache extends RedisClusterPubSubAdapter<String, String> imp
} }
public boolean hasMessages(final UUID destinationUuid, final long destinationDevice) { public boolean hasMessages(final UUID destinationUuid, final long destinationDevice) {
return readDeleteCluster.withBinaryCluster(connection -> connection.sync().zcard(getMessageQueueKey(destinationUuid, destinationDevice)) > 0); return readDeleteCluster.withBinaryCluster(
connection -> connection.sync().zcard(getMessageQueueKey(destinationUuid, destinationDevice)) > 0);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<OutgoingMessageEntity> get(final UUID destinationUuid, final long destinationDevice, final int limit) { public List<OutgoingMessageEntity> get(final UUID destinationUuid, final long destinationDevice, final int limit) {
return getMessagesTimer.record(() -> { return getMessagesTimer.record(() -> {
final List<byte[]> queueItems = (List<byte[]>)getItemsScript.executeBinary(List.of(getMessageQueueKey(destinationUuid, destinationDevice), final List<byte[]> queueItems = (List<byte[]>) getItemsScript.executeBinary(
List.of(getMessageQueueKey(destinationUuid, destinationDevice),
getPersistInProgressKey(destinationUuid, destinationDevice)), getPersistInProgressKey(destinationUuid, destinationDevice)),
List.of(String.valueOf(limit).getBytes(StandardCharsets.UTF_8))); List.of(String.valueOf(limit).getBytes(StandardCharsets.UTF_8)));
final long earliestAllowableEphemeralTimestamp = System.currentTimeMillis() - MAX_EPHEMERAL_MESSAGE_DELAY.toMillis(); final long earliestAllowableEphemeralTimestamp =
System.currentTimeMillis() - MAX_EPHEMERAL_MESSAGE_DELAY.toMillis();
final List<OutgoingMessageEntity> messageEntities; final List<OutgoingMessageEntity> messageEntities;
final List<UUID> staleEphemeralMessageGuids = new ArrayList<>(); final List<UUID> staleEphemeralMessageGuids = new ArrayList<>();
@ -221,9 +230,12 @@ public class MessagesCache extends RedisClusterPubSubAdapter<String, String> imp
} }
@VisibleForTesting @VisibleForTesting
List<MessageProtos.Envelope> getMessagesToPersist(final UUID accountUuid, final long destinationDevice, final int limit) { List<MessageProtos.Envelope> getMessagesToPersist(final UUID accountUuid, final long destinationDevice,
final int limit) {
return getMessagesTimer.record(() -> { return getMessagesTimer.record(() -> {
final List<ScoredValue<byte[]>> scoredMessages = readDeleteCluster.withBinaryCluster(connection -> connection.sync().zrangeWithScores(getMessageQueueKey(accountUuid, destinationDevice), 0, limit)); final List<ScoredValue<byte[]>> scoredMessages = readDeleteCluster.withBinaryCluster(
connection -> connection.sync()
.zrangeWithScores(getMessageQueueKey(accountUuid, destinationDevice), 0, limit));
final List<MessageProtos.Envelope> envelopes = new ArrayList<>(scoredMessages.size()); final List<MessageProtos.Envelope> envelopes = new ArrayList<>(scoredMessages.size());
for (final ScoredValue<byte[]> scoredMessage : scoredMessages) { for (final ScoredValue<byte[]> scoredMessage : scoredMessages) {
@ -256,29 +268,36 @@ public class MessagesCache extends RedisClusterPubSubAdapter<String, String> imp
} }
int getNextSlotToPersist() { int getNextSlotToPersist() {
return (int)(readDeleteCluster.withCluster(connection -> connection.sync().incr(NEXT_SLOT_TO_PERSIST_KEY)) % SlotHash.SLOT_COUNT); return (int) (readDeleteCluster.withCluster(connection -> connection.sync().incr(NEXT_SLOT_TO_PERSIST_KEY))
% SlotHash.SLOT_COUNT);
} }
List<String> getQueuesToPersist(final int slot, final Instant maxTime, final int limit) { List<String> getQueuesToPersist(final int slot, final Instant maxTime, final int limit) {
//noinspection unchecked //noinspection unchecked
return getQueuesToPersistTimer.record(() -> (List<String>)getQueuesToPersistScript.execute(List.of(new String(getQueueIndexKey(slot), StandardCharsets.UTF_8)), return getQueuesToPersistTimer.record(() -> (List<String>) getQueuesToPersistScript.execute(
List.of(new String(getQueueIndexKey(slot), StandardCharsets.UTF_8)),
List.of(String.valueOf(maxTime.toEpochMilli()), List.of(String.valueOf(maxTime.toEpochMilli()),
String.valueOf(limit)))); String.valueOf(limit))));
} }
void addQueueToPersist(final UUID accountUuid, final long deviceId) { void addQueueToPersist(final UUID accountUuid, final long deviceId) {
readDeleteCluster.useBinaryCluster(connection -> connection.sync().zadd(getQueueIndexKey(accountUuid, deviceId), ZAddArgs.Builder.nx(), System.currentTimeMillis(), getMessageQueueKey(accountUuid, deviceId))); readDeleteCluster.useBinaryCluster(connection -> connection.sync()
.zadd(getQueueIndexKey(accountUuid, deviceId), ZAddArgs.Builder.nx(), System.currentTimeMillis(),
getMessageQueueKey(accountUuid, deviceId)));
} }
void lockQueueForPersistence(final UUID accountUuid, final long deviceId) { void lockQueueForPersistence(final UUID accountUuid, final long deviceId) {
readDeleteCluster.useBinaryCluster(connection -> connection.sync().setex(getPersistInProgressKey(accountUuid, deviceId), 30, LOCK_VALUE)); readDeleteCluster.useBinaryCluster(
connection -> connection.sync().setex(getPersistInProgressKey(accountUuid, deviceId), 30, LOCK_VALUE));
} }
void unlockQueueForPersistence(final UUID accountUuid, final long deviceId) { void unlockQueueForPersistence(final UUID accountUuid, final long deviceId) {
readDeleteCluster.useBinaryCluster(connection -> connection.sync().del(getPersistInProgressKey(accountUuid, deviceId))); readDeleteCluster.useBinaryCluster(
connection -> connection.sync().del(getPersistInProgressKey(accountUuid, deviceId)));
} }
public void addMessageAvailabilityListener(final UUID destinationUuid, final long deviceId, final MessageAvailabilityListener listener) { public void addMessageAvailabilityListener(final UUID destinationUuid, final long deviceId,
final MessageAvailabilityListener listener) {
final String queueName = getQueueName(destinationUuid, deviceId); final String queueName = getQueueName(destinationUuid, deviceId);
synchronized (messageListenersByQueueName) { synchronized (messageListenersByQueueName) {
@ -304,7 +323,8 @@ public class MessagesCache extends RedisClusterPubSubAdapter<String, String> imp
private void subscribeForKeyspaceNotifications(final String queueName) { private void subscribeForKeyspaceNotifications(final String queueName) {
final int slot = SlotHash.getSlot(queueName); final int slot = SlotHash.getSlot(queueName);
pubSubConnection.usePubSubConnection(connection -> connection.sync().nodes(node -> node.is(RedisClusterNode.NodeFlag.UPSTREAM) && node.hasSlot(slot)) pubSubConnection.usePubSubConnection(
connection -> connection.sync().nodes(node -> node.is(RedisClusterNode.NodeFlag.UPSTREAM) && node.hasSlot(slot))
.commands() .commands()
.subscribe(getKeyspaceChannels(queueName))); .subscribe(getKeyspaceChannels(queueName)));
} }

View File

@ -51,7 +51,8 @@ public class MessagesCacheTest extends AbstractRedisClusterTest {
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); super.setUp();
getRedisCluster().useCluster(connection -> connection.sync().upstream().commands().configSet("notify-keyspace-events", "Klgz")); getRedisCluster().useCluster(
connection -> connection.sync().upstream().commands().configSet("notify-keyspace-events", "Klgz"));
notificationExecutorService = Executors.newSingleThreadExecutor(); notificationExecutorService = Executors.newSingleThreadExecutor();
messagesCache = new MessagesCache(getRedisCluster(), getRedisCluster(), notificationExecutorService); messagesCache = new MessagesCache(getRedisCluster(), getRedisCluster(), notificationExecutorService);
@ -73,7 +74,8 @@ public class MessagesCacheTest extends AbstractRedisClusterTest {
@Parameters({"true", "false"}) @Parameters({"true", "false"})
public void testInsert(final boolean sealedSender) { public void testInsert(final boolean sealedSender) {
final UUID messageGuid = UUID.randomUUID(); final UUID messageGuid = UUID.randomUUID();
assertTrue(messagesCache.insert(messageGuid, DESTINATION_UUID, DESTINATION_DEVICE_ID, generateRandomMessage(messageGuid, sealedSender)) > 0); assertTrue(messagesCache.insert(messageGuid, DESTINATION_UUID, DESTINATION_DEVICE_ID,
generateRandomMessage(messageGuid, sealedSender)) > 0);
} }
@Test @Test
@ -82,7 +84,8 @@ public class MessagesCacheTest extends AbstractRedisClusterTest {
final MessageProtos.Envelope duplicateMessage = generateRandomMessage(duplicateGuid, false); final MessageProtos.Envelope duplicateMessage = generateRandomMessage(duplicateGuid, false);
final long firstId = messagesCache.insert(duplicateGuid, DESTINATION_UUID, DESTINATION_DEVICE_ID, duplicateMessage); final long firstId = messagesCache.insert(duplicateGuid, DESTINATION_UUID, DESTINATION_DEVICE_ID, duplicateMessage);
final long secondId = messagesCache.insert(duplicateGuid, DESTINATION_UUID, DESTINATION_DEVICE_ID, duplicateMessage); final long secondId = messagesCache.insert(duplicateGuid, DESTINATION_UUID, DESTINATION_DEVICE_ID,
duplicateMessage);
assertEquals(firstId, secondId); assertEquals(firstId, secondId);
} }
@ -97,7 +100,8 @@ public class MessagesCacheTest extends AbstractRedisClusterTest {
final MessageProtos.Envelope message = generateRandomMessage(messageGuid, sealedSender); final MessageProtos.Envelope message = generateRandomMessage(messageGuid, sealedSender);
messagesCache.insert(messageGuid, DESTINATION_UUID, DESTINATION_DEVICE_ID, message); messagesCache.insert(messageGuid, DESTINATION_UUID, DESTINATION_DEVICE_ID, message);
final Optional<OutgoingMessageEntity> maybeRemovedMessage = messagesCache.remove(DESTINATION_UUID, DESTINATION_DEVICE_ID, messageGuid); final Optional<OutgoingMessageEntity> maybeRemovedMessage = messagesCache.remove(DESTINATION_UUID,
DESTINATION_DEVICE_ID, messageGuid);
assertTrue(maybeRemovedMessage.isPresent()); assertTrue(maybeRemovedMessage.isPresent());
assertEquals(MessagesCache.constructEntityFromEnvelope(0, message), maybeRemovedMessage.get()); assertEquals(MessagesCache.constructEntityFromEnvelope(0, message), maybeRemovedMessage.get());
@ -117,7 +121,8 @@ public class MessagesCacheTest extends AbstractRedisClusterTest {
} }
assertEquals(Collections.emptyList(), messagesCache.remove(DESTINATION_UUID, DESTINATION_DEVICE_ID, assertEquals(Collections.emptyList(), messagesCache.remove(DESTINATION_UUID, DESTINATION_DEVICE_ID,
messagesToRemove.stream().map(message -> UUID.fromString(message.getServerGuid())).collect(Collectors.toList()))); messagesToRemove.stream().map(message -> UUID.fromString(message.getServerGuid()))
.collect(Collectors.toList())));
for (final MessageProtos.Envelope message : messagesToRemove) { for (final MessageProtos.Envelope message : messagesToRemove) {
messagesCache.insert(UUID.fromString(message.getServerGuid()), DESTINATION_UUID, DESTINATION_DEVICE_ID, message); messagesCache.insert(UUID.fromString(message.getServerGuid()), DESTINATION_UUID, DESTINATION_DEVICE_ID, message);
@ -128,12 +133,15 @@ public class MessagesCacheTest extends AbstractRedisClusterTest {
} }
final List<OutgoingMessageEntity> removedMessages = messagesCache.remove(DESTINATION_UUID, DESTINATION_DEVICE_ID, final List<OutgoingMessageEntity> removedMessages = messagesCache.remove(DESTINATION_UUID, DESTINATION_DEVICE_ID,
messagesToRemove.stream().map(message -> UUID.fromString(message.getServerGuid())).collect(Collectors.toList())); messagesToRemove.stream().map(message -> UUID.fromString(message.getServerGuid()))
.collect(Collectors.toList()));
assertEquals(messagesToRemove.stream().map(message -> MessagesCache.constructEntityFromEnvelope(0, message)).collect(Collectors.toList()), assertEquals(messagesToRemove.stream().map(message -> MessagesCache.constructEntityFromEnvelope(0, message))
.collect(Collectors.toList()),
removedMessages); removedMessages);
assertEquals(messagesToPreserve, messagesCache.getMessagesToPersist(DESTINATION_UUID, DESTINATION_DEVICE_ID, messageCount)); assertEquals(messagesToPreserve,
messagesCache.getMessagesToPersist(DESTINATION_UUID, DESTINATION_DEVICE_ID, messageCount));
} }
@Test @Test
@ -209,7 +217,8 @@ public class MessagesCacheTest extends AbstractRedisClusterTest {
return generateRandomMessage(messageGuid, sealedSender, serialTimestamp++); return generateRandomMessage(messageGuid, sealedSender, serialTimestamp++);
} }
private MessageProtos.Envelope generateRandomMessage(final UUID messageGuid, final boolean sealedSender, final long timestamp) { private MessageProtos.Envelope generateRandomMessage(final UUID messageGuid, final boolean sealedSender,
final long timestamp) {
final MessageProtos.Envelope.Builder envelopeBuilder = MessageProtos.Envelope.newBuilder() final MessageProtos.Envelope.Builder envelopeBuilder = MessageProtos.Envelope.newBuilder()
.setTimestamp(timestamp) .setTimestamp(timestamp)
.setServerTimestamp(timestamp) .setServerTimestamp(timestamp)
@ -234,19 +243,24 @@ public class MessagesCacheTest extends AbstractRedisClusterTest {
@Test @Test
public void testGetAccountFromQueueName() { public void testGetAccountFromQueueName() {
assertEquals(DESTINATION_UUID, assertEquals(DESTINATION_UUID,
MessagesCache.getAccountUuidFromQueueName(new String(MessagesCache.getMessageQueueKey(DESTINATION_UUID, DESTINATION_DEVICE_ID), StandardCharsets.UTF_8))); MessagesCache.getAccountUuidFromQueueName(
new String(MessagesCache.getMessageQueueKey(DESTINATION_UUID, DESTINATION_DEVICE_ID),
StandardCharsets.UTF_8)));
} }
@Test @Test
public void testGetDeviceIdFromQueueName() { public void testGetDeviceIdFromQueueName() {
assertEquals(DESTINATION_DEVICE_ID, assertEquals(DESTINATION_DEVICE_ID,
MessagesCache.getDeviceIdFromQueueName(new String(MessagesCache.getMessageQueueKey(DESTINATION_UUID, DESTINATION_DEVICE_ID), StandardCharsets.UTF_8))); MessagesCache.getDeviceIdFromQueueName(
new String(MessagesCache.getMessageQueueKey(DESTINATION_UUID, DESTINATION_DEVICE_ID),
StandardCharsets.UTF_8)));
} }
@Test @Test
public void testGetQueueNameFromKeyspaceChannel() { public void testGetQueueNameFromKeyspaceChannel() {
assertEquals("1b363a31-a429-4fb6-8959-984a025e72ff::7", assertEquals("1b363a31-a429-4fb6-8959-984a025e72ff::7",
MessagesCache.getQueueNameFromKeyspaceChannel("__keyspace@0__:user_queue::{1b363a31-a429-4fb6-8959-984a025e72ff::7}")); MessagesCache.getQueueNameFromKeyspaceChannel(
"__keyspace@0__:user_queue::{1b363a31-a429-4fb6-8959-984a025e72ff::7}"));
} }
@Test @Test
@ -254,7 +268,8 @@ public class MessagesCacheTest extends AbstractRedisClusterTest {
public void testGetQueuesToPersist(final boolean sealedSender) { public void testGetQueuesToPersist(final boolean sealedSender) {
final UUID messageGuid = UUID.randomUUID(); final UUID messageGuid = UUID.randomUUID();
messagesCache.insert(messageGuid, DESTINATION_UUID, DESTINATION_DEVICE_ID, generateRandomMessage(messageGuid, sealedSender)); messagesCache.insert(messageGuid, DESTINATION_UUID, DESTINATION_DEVICE_ID,
generateRandomMessage(messageGuid, sealedSender));
final int slot = SlotHash.getSlot(DESTINATION_UUID.toString() + "::" + DESTINATION_DEVICE_ID); final int slot = SlotHash.getSlot(DESTINATION_UUID.toString() + "::" + DESTINATION_DEVICE_ID);
assertTrue(messagesCache.getQueuesToPersist(slot + 1, Instant.now().plusSeconds(60), 100).isEmpty()); assertTrue(messagesCache.getQueuesToPersist(slot + 1, Instant.now().plusSeconds(60), 100).isEmpty());
@ -286,7 +301,8 @@ public class MessagesCacheTest extends AbstractRedisClusterTest {
}; };
messagesCache.addMessageAvailabilityListener(DESTINATION_UUID, DESTINATION_DEVICE_ID, listener); messagesCache.addMessageAvailabilityListener(DESTINATION_UUID, DESTINATION_DEVICE_ID, listener);
messagesCache.insert(messageGuid, DESTINATION_UUID, DESTINATION_DEVICE_ID, generateRandomMessage(messageGuid, true)); messagesCache.insert(messageGuid, DESTINATION_UUID, DESTINATION_DEVICE_ID,
generateRandomMessage(messageGuid, true));
synchronized (notified) { synchronized (notified) {
while (!notified.get()) { while (!notified.get()) {