[AB-228] fixing member sometimes unavailable in reaction events

This commit is contained in:
Sheldan
2021-04-11 14:31:11 +02:00
parent b589e88ad4
commit 23379e4498
2 changed files with 31 additions and 25 deletions

View File

@@ -6,7 +6,9 @@ import dev.sheldan.abstracto.core.models.cache.CachedMessage;
import dev.sheldan.abstracto.core.models.cache.CachedReactions; import dev.sheldan.abstracto.core.models.cache.CachedReactions;
import dev.sheldan.abstracto.core.models.listener.ReactionAddedModel; import dev.sheldan.abstracto.core.models.listener.ReactionAddedModel;
import dev.sheldan.abstracto.core.service.*; import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent; import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter; import net.dv8tion.jda.api.hooks.ListenerAdapter;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -16,6 +18,7 @@ import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@@ -53,15 +56,15 @@ public class AsyncReactionAddedListenerBean extends ListenerAdapter {
if(event.getUserIdLong() == event.getJDA().getSelfUser().getIdLong()) { if(event.getUserIdLong() == event.getJDA().getSelfUser().getIdLong()) {
return; return;
} }
CompletableFuture<Member> memberFuture = event.retrieveMember().submit();
CompletableFuture<CachedMessage> asyncMessageFromCache = messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong()); CompletableFuture<CachedMessage> asyncMessageFromCache = messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong());
asyncMessageFromCache.thenAccept(cachedMessage -> CompletableFuture<CachedReactions> reactionCacheFuture = cacheEntityService.getCachedReactionFromReaction(event.getReaction());
cacheEntityService.getCachedReactionFromReaction(event.getReaction()).thenAccept(reaction -> FutureUtils.toSingleFuture(Arrays.asList(asyncMessageFromCache, memberFuture, reactionCacheFuture)).thenAccept(aVoid -> {
self.callAddedListeners(event, cachedMessage, reaction) CachedMessage cachedMessage = asyncMessageFromCache.join();
).exceptionally(throwable -> { CachedReactions reaction = reactionCacheFuture.join();
log.error("Failed to handle add reaction to message {} ", event.getMessageIdLong(), throwable); Member member = memberFuture.join();
return null; self.callAddedListeners(event, cachedMessage, reaction, member);
}) }).exceptionally(throwable -> {
).exceptionally(throwable -> {
log.error("Message retrieval {} from cache failed. ", event.getMessageIdLong(), throwable); log.error("Message retrieval {} from cache failed. ", event.getMessageIdLong(), throwable);
return null; return null;
}); });
@@ -83,20 +86,20 @@ public class AsyncReactionAddedListenerBean extends ListenerAdapter {
} }
@Transactional @Transactional
public void callAddedListeners(GuildMessageReactionAddEvent event, CachedMessage cachedMessage, CachedReactions reaction) { public void callAddedListeners(GuildMessageReactionAddEvent event, CachedMessage cachedMessage, CachedReactions reaction, Member member) {
ServerUser serverUser = ServerUser.builder().serverId(event.getGuild().getIdLong()).userId(event.getUserIdLong()).build(); ServerUser serverUser = ServerUser.builder().serverId(event.getGuild().getIdLong()).userId(event.getUserIdLong()).build();
addReactionIfNotThere(cachedMessage, reaction, serverUser); addReactionIfNotThere(cachedMessage, reaction, serverUser);
ReactionAddedModel model = getModel(event, cachedMessage, serverUser); ReactionAddedModel model = getModel(event, cachedMessage, serverUser, member);
messageCache.putMessageInCache(cachedMessage); messageCache.putMessageInCache(cachedMessage);
listenerList.forEach(asyncReactionAddedListener -> listenerService.executeFeatureAwareListener(asyncReactionAddedListener, model, reactionAddedTaskExecutor)); listenerList.forEach(asyncReactionAddedListener -> listenerService.executeFeatureAwareListener(asyncReactionAddedListener, model, reactionAddedTaskExecutor));
} }
private ReactionAddedModel getModel(GuildMessageReactionAddEvent event, CachedMessage cachedMessage, ServerUser userReacting) { private ReactionAddedModel getModel(GuildMessageReactionAddEvent event, CachedMessage cachedMessage, ServerUser userReacting, Member member) {
return ReactionAddedModel return ReactionAddedModel
.builder() .builder()
.reaction(event.getReaction()) .reaction(event.getReaction())
.message(cachedMessage) .message(cachedMessage)
.memberReacting(event.getMember()) .memberReacting(member)
.userReacting(userReacting) .userReacting(userReacting)
.build(); .build();
} }

View File

@@ -8,7 +8,9 @@ import dev.sheldan.abstracto.core.models.listener.ReactionAddedModel;
import dev.sheldan.abstracto.core.service.*; import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService; import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.utils.BeanUtils; import dev.sheldan.abstracto.core.utils.BeanUtils;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent; import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter; import net.dv8tion.jda.api.hooks.ListenerAdapter;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -17,6 +19,7 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@@ -59,16 +62,16 @@ public class ReactionAddedListenerBean extends ListenerAdapter {
if(event.getUserIdLong() == botService.getInstance().getSelfUser().getIdLong()) { if(event.getUserIdLong() == botService.getInstance().getSelfUser().getIdLong()) {
return; return;
} }
CompletableFuture<Member> memberFuture = event.retrieveMember().submit();
CompletableFuture<CachedMessage> asyncMessageFromCache = messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong()); CompletableFuture<CachedMessage> asyncMessageFromCache = messageCache.getMessageFromCache(event.getGuild().getIdLong(), event.getChannel().getIdLong(), event.getMessageIdLong());
asyncMessageFromCache.thenAccept(cachedMessage -> CompletableFuture<CachedReactions> reactionCacheFuture = cacheEntityService.getCachedReactionFromReaction(event.getReaction());
cacheEntityService.getCachedReactionFromReaction(event.getReaction()).thenAccept(reaction -> { FutureUtils.toSingleFuture(Arrays.asList(asyncMessageFromCache, memberFuture, reactionCacheFuture)).thenAccept(aVoid -> {
self.callAddedListeners(event, cachedMessage, reaction); CachedMessage cachedMessage = asyncMessageFromCache.join();
messageCache.putMessageInCache(cachedMessage); CachedReactions reaction = reactionCacheFuture.join();
}).exceptionally(throwable -> { Member member = memberFuture.join();
log.error("Failed to handle add reaction to message {} ", event.getMessageIdLong(), throwable); self.callAddedListeners(event, cachedMessage, reaction, member);
return null; messageCache.putMessageInCache(cachedMessage);
}) }).exceptionally(throwable -> {
).exceptionally(throwable -> {
log.error("Message retrieval {} from cache failed. ", event.getMessageIdLong(), throwable); log.error("Message retrieval {} from cache failed. ", event.getMessageIdLong(), throwable);
return null; return null;
}); });
@@ -90,19 +93,19 @@ public class ReactionAddedListenerBean extends ListenerAdapter {
} }
@Transactional @Transactional
public void callAddedListeners(@Nonnull GuildMessageReactionAddEvent event, CachedMessage cachedMessage, CachedReactions reaction) { public void callAddedListeners(@Nonnull GuildMessageReactionAddEvent event, CachedMessage cachedMessage, CachedReactions reaction, Member member) {
ServerUser serverUser = ServerUser.builder().serverId(cachedMessage.getServerId()).userId(event.getUserIdLong()).build(); ServerUser serverUser = ServerUser.builder().serverId(cachedMessage.getServerId()).userId(event.getUserIdLong()).build();
addReactionIfNotThere(cachedMessage, reaction, serverUser); addReactionIfNotThere(cachedMessage, reaction, serverUser);
ReactionAddedModel model = getModel(event, cachedMessage, serverUser); ReactionAddedModel model = getModel(event, cachedMessage, serverUser, member);
addedListenerList.forEach(reactedAddedListener -> listenerService.executeFeatureAwareListener(reactedAddedListener, model)); addedListenerList.forEach(reactedAddedListener -> listenerService.executeFeatureAwareListener(reactedAddedListener, model));
} }
private ReactionAddedModel getModel(GuildMessageReactionAddEvent event, CachedMessage cachedMessage, ServerUser userReacting) { private ReactionAddedModel getModel(GuildMessageReactionAddEvent event, CachedMessage cachedMessage, ServerUser userReacting, Member member) {
return ReactionAddedModel return ReactionAddedModel
.builder() .builder()
.reaction(event.getReaction()) .reaction(event.getReaction())
.message(cachedMessage) .message(cachedMessage)
.memberReacting(event.getMember()) .memberReacting(member)
.userReacting(userReacting) .userReacting(userReacting)
.build(); .build();
} }