From ff676b29e6d65d5ac77cb5ac49d094f79f472c44 Mon Sep 17 00:00:00 2001 From: Sheldan <5037282+Sheldan@users.noreply.github.com> Date: Sun, 4 Apr 2021 22:28:21 +0200 Subject: [PATCH] [AB-219] fixing cached message content not being updated merging message updated listeners adding clearing message cache to clear cache listener --- .../listener/ClearMessageCacheListener.java | 23 +++++++ .../jda => }/MessageUpdatedListenerBean.java | 35 ++++++++-- .../jda/AsyncMessageUpdatedListenerBean.java | 67 ------------------- .../core/service/MessageCacheBean.java | 7 ++ .../abstracto/core/service/MessageCache.java | 1 + 5 files changed, 61 insertions(+), 72 deletions(-) create mode 100644 abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/ClearMessageCacheListener.java rename abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/{sync/jda => }/MessageUpdatedListenerBean.java (70%) delete mode 100644 abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/async/jda/AsyncMessageUpdatedListenerBean.java diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/ClearMessageCacheListener.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/ClearMessageCacheListener.java new file mode 100644 index 000000000..1bd851841 --- /dev/null +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/ClearMessageCacheListener.java @@ -0,0 +1,23 @@ +package dev.sheldan.abstracto.core.listener; + +import dev.sheldan.abstracto.core.listener.async.entity.AsyncCacheClearingListener; +import dev.sheldan.abstracto.core.models.listener.VoidListenerModel; +import dev.sheldan.abstracto.core.service.MessageCache; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class ClearMessageCacheListener implements AsyncCacheClearingListener { + + @Autowired + private MessageCache messageCache; + + @Override + public DefaultListenerResult execute(VoidListenerModel model) { + log.debug("Executing clear message cache listener."); + messageCache.clearCache(); + return DefaultListenerResult.PROCESSED; + } +} diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/sync/jda/MessageUpdatedListenerBean.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/MessageUpdatedListenerBean.java similarity index 70% rename from abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/sync/jda/MessageUpdatedListenerBean.java rename to abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/MessageUpdatedListenerBean.java index 91d4fad59..152bf8533 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/sync/jda/MessageUpdatedListenerBean.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/MessageUpdatedListenerBean.java @@ -1,6 +1,7 @@ -package dev.sheldan.abstracto.core.listener.sync.jda; +package dev.sheldan.abstracto.core.listener; -import dev.sheldan.abstracto.core.listener.ListenerService; +import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageTextUpdatedListener; +import dev.sheldan.abstracto.core.listener.sync.jda.MessageTextUpdatedListener; import dev.sheldan.abstracto.core.metric.service.CounterMetric; import dev.sheldan.abstracto.core.metric.service.MetricService; import dev.sheldan.abstracto.core.metric.service.MetricTag; @@ -13,6 +14,8 @@ import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.events.message.guild.GuildMessageUpdateEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.task.TaskExecutor; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @@ -40,6 +43,13 @@ public class MessageUpdatedListenerBean extends ListenerAdapter { @Autowired private ListenerService listenerService; + @Autowired(required = false) + private List asyncListenerList; + + @Autowired + @Qualifier("messageUpdatedExecutor") + private TaskExecutor messageUpdatedExecutor; + @Autowired private MetricService metricService; @@ -53,11 +63,17 @@ public class MessageUpdatedListenerBean extends ListenerAdapter { @Transactional public void onGuildMessageUpdate(@Nonnull GuildMessageUpdateEvent event) { metricService.incrementCounter(MESSAGE_UPDATED_COUNTER); - if(listenerList == null) return; Message message = event.getMessage(); messageCache.getMessageFromCache(message.getGuild().getIdLong(), message.getTextChannel().getIdLong(), event.getMessageIdLong()).thenAccept(cachedMessage -> { - self.executeListener(cachedMessage, event); - messageCache.putMessageInCache(message); + try { + executeAsyncListeners(event, cachedMessage); + if (listenerList != null) { + self.executeListener(cachedMessage, event); + } + } finally { + cachedMessage.setContent(message.getContentRaw()); + messageCache.putMessageInCache(cachedMessage); + } }).exceptionally(throwable -> { log.error("Message retrieval {} from cache failed. ", event.getMessage().getId(), throwable); return null; @@ -67,6 +83,7 @@ public class MessageUpdatedListenerBean extends ListenerAdapter { @Transactional public void executeListener(CachedMessage cachedMessage, GuildMessageUpdateEvent event) { + if(listenerList == null) return; MessageTextUpdatedModel model = getModel(event, cachedMessage); listenerList.forEach(messageTextUpdatedListener -> listenerService.executeFeatureAwareListener(messageTextUpdatedListener, model)); } @@ -79,6 +96,14 @@ public class MessageUpdatedListenerBean extends ListenerAdapter { .build(); } + private void executeAsyncListeners(GuildMessageUpdateEvent event, CachedMessage oldMessage) { + if(asyncListenerList == null) return; + MessageTextUpdatedModel model = getModel(event, oldMessage); + asyncListenerList.forEach(messageTextUpdatedListener -> + listenerService.executeFeatureAwareListener(messageTextUpdatedListener, model, messageUpdatedExecutor) + ); + } + @PostConstruct public void postConstruct() { metricService.registerCounter(MESSAGE_UPDATED_COUNTER, "Messages updated"); diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/async/jda/AsyncMessageUpdatedListenerBean.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/async/jda/AsyncMessageUpdatedListenerBean.java deleted file mode 100644 index dd5a141db..000000000 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/listener/async/jda/AsyncMessageUpdatedListenerBean.java +++ /dev/null @@ -1,67 +0,0 @@ -package dev.sheldan.abstracto.core.listener.async.jda; - -import dev.sheldan.abstracto.core.listener.ListenerService; -import dev.sheldan.abstracto.core.models.cache.CachedMessage; -import dev.sheldan.abstracto.core.models.listener.MessageTextUpdatedModel; -import dev.sheldan.abstracto.core.service.MessageCache; -import lombok.extern.slf4j.Slf4j; -import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.events.message.guild.GuildMessageUpdateEvent; -import net.dv8tion.jda.api.hooks.ListenerAdapter; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.core.task.TaskExecutor; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - - -@Component -@Slf4j -public class AsyncMessageUpdatedListenerBean extends ListenerAdapter { - @Autowired(required = false) - private List listener; - - @Autowired - private MessageCache messageCache; - - @Autowired - private AsyncMessageUpdatedListenerBean self; - - @Autowired - @Qualifier("messageUpdatedExecutor") - private TaskExecutor messageUpdatedExecutor; - - @Autowired - private ListenerService listenerService; - - @Override - @Transactional - public void onGuildMessageUpdate(GuildMessageUpdateEvent event) { - if(listener == null) return; - Message message = event.getMessage(); - messageCache.getMessageFromCache(message.getGuild().getIdLong(), message.getTextChannel().getIdLong(), event.getMessageIdLong()) - .thenAcceptBoth(messageCache.putMessageInCache(message), (oldCache, newCache) -> self.executeListeners(event, oldCache)) - .exceptionally(throwable -> { - log.error("Message retrieval {} from cache failed. ", event.getMessage().getId(), throwable); - return null; - }); - } - - public void executeListeners(GuildMessageUpdateEvent event, CachedMessage oldMessage) { - MessageTextUpdatedModel model = getModel(event, oldMessage); - listener.forEach(messageTextUpdatedListener -> - listenerService.executeFeatureAwareListener(messageTextUpdatedListener, model, messageUpdatedExecutor) - ); - } - - private MessageTextUpdatedModel getModel(GuildMessageUpdateEvent event, CachedMessage oldMessage) { - return MessageTextUpdatedModel - .builder() - .after(event.getMessage()) - .before(oldMessage) - .build(); - } - -} diff --git a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/MessageCacheBean.java b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/MessageCacheBean.java index 21a6e161b..3b1facb58 100644 --- a/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/MessageCacheBean.java +++ b/abstracto-application/core/core-impl/src/main/java/dev/sheldan/abstracto/core/service/MessageCacheBean.java @@ -9,6 +9,7 @@ import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.TextChannel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.context.annotation.Lazy; @@ -102,5 +103,11 @@ public class MessageCacheBean implements MessageCache { return future; } + @Override + @CacheEvict(allEntries = true) + public void clearCache() { + log.info("Clearing message cache."); + } + } diff --git a/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/service/MessageCache.java b/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/service/MessageCache.java index e9195ebfa..aa07ce1d0 100644 --- a/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/service/MessageCache.java +++ b/abstracto-application/core/core-int/src/main/java/dev/sheldan/abstracto/core/service/MessageCache.java @@ -11,4 +11,5 @@ public interface MessageCache { CompletableFuture getMessageFromCache(Message message); CompletableFuture putMessageInCache(CachedMessage message); CompletableFuture loadMessage(Long guildId, Long textChannelId, Long messageId); + void clearCache(); }