mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-03-11 01:36:33 +00:00
[AB-209] adding cleanup job for old embedded messages, this job deletes the entries from the database and removes reactions
reducing thread count for listener executor and scheduling fixing channel deletion listener not being part of a transaction
This commit is contained in:
@@ -38,6 +38,12 @@
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.scheduling</groupId>
|
||||
<artifactId>scheduling-int</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.core</groupId>
|
||||
<artifactId>metrics-int</artifactId>
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package dev.sheldan.abstracto.linkembed.job;
|
||||
|
||||
import dev.sheldan.abstracto.linkembed.service.MessageEmbedService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.quartz.DisallowConcurrentExecution;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.quartz.PersistJobDataAfterExecution;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Slf4j
|
||||
@DisallowConcurrentExecution
|
||||
@Component
|
||||
@PersistJobDataAfterExecution
|
||||
public class LinkEmbedCleanupJob extends QuartzJobBean {
|
||||
|
||||
@Autowired
|
||||
private MessageEmbedService messageEmbedService;
|
||||
|
||||
@Override
|
||||
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||
try {
|
||||
log.info("Executing link embed clean up job.");
|
||||
messageEmbedService.cleanUpOldMessageEmbeds();
|
||||
} catch (Exception exception) {
|
||||
log.error("Link embed cleanup job failed.", exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,12 @@ package dev.sheldan.abstracto.linkembed.repository;
|
||||
import dev.sheldan.abstracto.linkembed.model.database.EmbeddedMessage;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
public interface EmbeddedMessageRepository extends JpaRepository<EmbeddedMessage, Long> {
|
||||
|
||||
EmbeddedMessage findByEmbeddingMessageId(Long messageId);
|
||||
List<EmbeddedMessage> findByCreatedLessThan(Instant date);
|
||||
void deleteByEmbeddingMessageIdIn(List<Long> embeddedMessageId);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.linkembed.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.template.listener.MessageEmbeddedModel;
|
||||
@@ -9,22 +10,31 @@ import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import dev.sheldan.abstracto.linkembed.model.MessageEmbedLink;
|
||||
import dev.sheldan.abstracto.linkembed.model.database.EmbeddedMessage;
|
||||
import dev.sheldan.abstracto.linkembed.service.management.MessageEmbedPostManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@@ -68,6 +78,15 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
||||
@Autowired
|
||||
private ReactionService reactionService;
|
||||
|
||||
@Autowired
|
||||
private MessageService messageService;
|
||||
|
||||
@Autowired
|
||||
private EmoteService emoteService;
|
||||
|
||||
@Value("${abstracto.feature.linkEmbed.removalDays}")
|
||||
private Long embedRemovalDays;
|
||||
|
||||
@Override
|
||||
public List<MessageEmbedLink> getLinksInMessage(String message) {
|
||||
List<MessageEmbedLink> links = new ArrayList<>();
|
||||
@@ -97,7 +116,6 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
||||
linksToEmbed.forEach(messageEmbedLink ->
|
||||
messageCache.getMessageFromCache(messageEmbedLink.getServerId(), messageEmbedLink.getChannelId(), messageEmbedLink.getMessageId())
|
||||
.thenAccept(cachedMessage -> self.embedLink(cachedMessage, target, userEmbeddingUserInServerId, embeddingMessage)
|
||||
|
||||
).exceptionally(throwable -> {
|
||||
log.error("Message embedding from cache failed for message {}.", messageEmbedLink.getMessageId(), throwable);
|
||||
return null;
|
||||
@@ -113,6 +131,60 @@ public class MessageEmbedServiceBean implements MessageEmbedService {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> cleanUpOldMessageEmbeds() {
|
||||
Instant oldestDate = Instant.now().truncatedTo(ChronoUnit.DAYS).minus(embedRemovalDays, ChronoUnit.DAYS);
|
||||
List<EmbeddedMessage> embeddedMessages = messageEmbedPostManagementService.getEmbeddedMessagesOlderThan(oldestDate);
|
||||
if(embeddedMessages.isEmpty()) {
|
||||
log.info("No embedded messages to clean up.");
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
log.info("Cleaning up {} embedded embeddedMessages", embeddedMessages.size());
|
||||
List<ServerChannelMessage> serverChannelMessages = embeddedMessages.stream().map(embeddedMessage ->
|
||||
ServerChannelMessage
|
||||
.builder()
|
||||
.serverId(embeddedMessage.getEmbeddedServer().getId())
|
||||
.channelId(embeddedMessage.getEmbeddedChannel().getId())
|
||||
.messageId(embeddedMessage.getEmbeddingMessageId())
|
||||
.build()
|
||||
)
|
||||
.collect(Collectors.toList());
|
||||
List<Long> embeddedMessagesHandled = embeddedMessages
|
||||
.stream()
|
||||
.map(EmbeddedMessage::getEmbeddingMessageId)
|
||||
.collect(Collectors.toList());
|
||||
List<CompletableFuture<Message>> messageFutures = messageService.retrieveMessages(serverChannelMessages);
|
||||
CompletableFutureList<Message> future = new CompletableFutureList<>(messageFutures);
|
||||
return future.getMainFuture()
|
||||
.handle((unused, throwable) -> self.removeReactions(future.getObjects()))
|
||||
.thenCompose(Function.identity())
|
||||
// deleting the messages from db regardless of exceptions, at most the reaction remains
|
||||
.whenComplete((unused, throwable) -> self.deleteEmbeddedMessages(embeddedMessagesHandled))
|
||||
.exceptionally(throwable -> {
|
||||
log.error("Failed to clean up embedded messages.", throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> removeReactions(List<Message> allMessages) {
|
||||
List<CompletableFuture<Void>> removalFutures = new ArrayList<>();
|
||||
Map<Long, List<Message>> groupedPerServer = allMessages
|
||||
.stream()
|
||||
.collect(Collectors.groupingBy(message -> message.getGuild().getIdLong()));
|
||||
groupedPerServer.forEach((serverId, serverMessages) -> {
|
||||
// we assume the emote remained the same
|
||||
CompletableFutureList<Void> removalFuture = reactionService.removeReactionFromMessagesWithFutureWithFutureList(serverMessages, REMOVAL_EMOTE);
|
||||
removalFutures.add(removalFuture.getMainFuture());
|
||||
});
|
||||
return FutureUtils.toSingleFutureGeneric(removalFutures);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteEmbeddedMessages(List<Long> embeddedMessagesToDelete) {
|
||||
messageEmbedPostManagementService.deleteEmbeddedMessagesViaId(embeddedMessagesToDelete);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public CompletableFuture<Void> sendEmbeddingMessage(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, MessageEmbeddedModel messageEmbeddedModel) {
|
||||
MessageToSend embed = templateService.renderEmbedTemplate(MESSAGE_EMBED_TEMPLATE, messageEmbeddedModel, target.getGuild().getIdLong());
|
||||
|
||||
@@ -16,6 +16,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
@@ -76,4 +78,15 @@ public class MessageEmbedPostManagementServiceBean implements MessageEmbedPostMa
|
||||
embeddedMessageRepository.delete(embeddedMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EmbeddedMessage> getEmbeddedMessagesOlderThan(Instant date) {
|
||||
return embeddedMessageRepository.findByCreatedLessThan(date);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteEmbeddedMessagesViaId(List<Long> embeddingMessageId) {
|
||||
log.info("Deleting {} embedded messages from db.", embeddingMessageId.size());
|
||||
embeddedMessageRepository.deleteByEmbeddingMessageIdIn(embeddingMessageId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
abstracto.featureFlags.linkEmbeds.featureName=linkEmbeds
|
||||
abstracto.featureFlags.linkEmbeds.enabled=false
|
||||
|
||||
|
||||
abstracto.feature.linkEmbed.removalDays=1
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../dbchangelog-3.8.xsd" >
|
||||
<include file="link-embed-seedData/data.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<include file="linkEmbedCleanupJob.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext ../../dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro ../../dbchangelog-3.8.xsd" >
|
||||
<changeSet author="Sheldan" id="linkEmbed-cleanup-insert">
|
||||
<insert tableName="scheduler_job">
|
||||
<column name="name" value="linkEmbedCleanupJob"/>
|
||||
<column name="group_name" value="linkEmbed"/>
|
||||
<column name="clazz" value="dev.sheldan.abstracto.linkembed.job.LinkEmbedCleanupJob"/>
|
||||
<column name="active" value="true"/>
|
||||
<column name="cron_expression" value="0 0 0 * * ?"/>
|
||||
<column name="recovery" value="false"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -7,4 +7,5 @@
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog-3.8.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog-3.8.xsd" >
|
||||
<include file="1.0-link-embed/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.2.8-link-embed/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -12,4 +12,5 @@ public interface MessageEmbedService {
|
||||
List<MessageEmbedLink> getLinksInMessage(String message);
|
||||
void embedLinks(List<MessageEmbedLink> linksToEmbed, TextChannel target, Long userEmbeddingUserInServerId, Message embeddingMessage);
|
||||
CompletableFuture<Void> embedLink(CachedMessage cachedMessage, TextChannel target, Long userEmbeddingUserInServerId, Message embeddingMessage);
|
||||
CompletableFuture<Void> cleanUpOldMessageEmbeds();
|
||||
}
|
||||
|
||||
@@ -5,10 +5,14 @@ import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.linkembed.model.database.EmbeddedMessage;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface MessageEmbedPostManagementService {
|
||||
void createMessageEmbed(CachedMessage embeddedMessage, Message messageContainingEmbed, AUserInAServer cause);
|
||||
Optional<EmbeddedMessage> findEmbeddedPostByMessageId(Long messageId);
|
||||
void deleteEmbeddedMessage(EmbeddedMessage embeddedMessage);
|
||||
List<EmbeddedMessage> getEmbeddedMessagesOlderThan(Instant date);
|
||||
void deleteEmbeddedMessagesViaId(List<Long> embeddingMessageId);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ public class ReminderJob extends QuartzJobBean {
|
||||
log.info("Executing reminder job for reminder {}", reminderId);
|
||||
reminderService.executeReminder(reminderId);
|
||||
} catch (Exception e) {
|
||||
log.error("Reminder job failed to execute.", e);
|
||||
log.error("Reminder job failed.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ 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 org.springframework.transaction.event.TransactionalEventListener;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@@ -32,8 +33,16 @@ public class AsyncAChannelDeletedListenerBean extends ListenerAdapter {
|
||||
@Qualifier("aChannelDeletedExecutor")
|
||||
private TaskExecutor channelDeletedExecutor;
|
||||
|
||||
@Autowired
|
||||
private AsyncAChannelDeletedListenerBean self;
|
||||
|
||||
@Override
|
||||
public void onTextChannelDelete(@Nonnull TextChannelDeleteEvent event) {
|
||||
self.deleteChannelInDb(event);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteChannelInDb(TextChannelDeleteEvent event) {
|
||||
channelManagementService.markAsDeleted(event.getChannel().getIdLong());
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package dev.sheldan.abstracto.core.service;
|
||||
import dev.sheldan.abstracto.core.metric.service.CounterMetric;
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricService;
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricTag;
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
@@ -18,8 +19,12 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static dev.sheldan.abstracto.core.config.MetricConstants.DISCORD_API_INTERACTION_METRIC;
|
||||
import static dev.sheldan.abstracto.core.config.MetricConstants.INTERACTION_TYPE;
|
||||
@@ -40,6 +45,9 @@ public class MessageServiceBean implements MessageService {
|
||||
@Autowired
|
||||
private MetricService metricService;
|
||||
|
||||
@Autowired
|
||||
private GuildService guildService;
|
||||
|
||||
public static final CounterMetric MESSAGE_SEND_METRIC = CounterMetric
|
||||
.builder()
|
||||
.name(DISCORD_API_INTERACTION_METRIC)
|
||||
@@ -110,6 +118,26 @@ public class MessageServiceBean implements MessageService {
|
||||
.thenCompose(o -> channelService.sendTextToChannel(text, o));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CompletableFuture<Message>> retrieveMessages(List<ServerChannelMessage> messages) {
|
||||
List<CompletableFuture<Message>> messageFutures = new ArrayList<>();
|
||||
Map<Long, List<ServerChannelMessage>> serverMessages = messages
|
||||
.stream()
|
||||
.collect(Collectors.groupingBy(ServerChannelMessage::getServerId));
|
||||
serverMessages.forEach((serverId, channelMessagesNonGrouped) -> {
|
||||
Guild guild = guildService.getGuildById(serverId);
|
||||
Map<Long, List<ServerChannelMessage>> channelMessages = channelMessagesNonGrouped
|
||||
.stream()
|
||||
.collect(Collectors.groupingBy(ServerChannelMessage::getChannelId));
|
||||
channelMessages.forEach((channelId, serverChannelMessages) -> {
|
||||
MessageChannel channel = guild.getTextChannelById(channelId);
|
||||
serverChannelMessages.forEach(serverChannelMessage ->
|
||||
messageFutures.add(channelService.retrieveMessageInChannel(channel, serverChannelMessage.getMessageId())));
|
||||
});
|
||||
});
|
||||
return messageFutures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Message> sendTemplateToUser(User user, String template, Object model) {
|
||||
String message = templateService.renderTemplate(template, model);
|
||||
|
||||
@@ -11,6 +11,7 @@ import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedReaction;
|
||||
import dev.sheldan.abstracto.core.models.database.AEmote;
|
||||
import dev.sheldan.abstracto.core.service.management.EmoteManagementService;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
import dev.sheldan.abstracto.core.utils.FutureUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
@@ -316,6 +317,15 @@ public class ReactionServiceBean implements ReactionService {
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeReactionOfUserFromMessageWithFuture(AEmote emote, Long serverId, Long channelId, Long messageId) {
|
||||
Integer emoteId = emote.getId();
|
||||
CompletableFuture<Message> messageFuture = channelService.retrieveMessageInChannel(serverId, channelId, messageId);
|
||||
return messageFuture.thenCompose(message ->
|
||||
self.removeReactionFromMessageWithFuture(emoteId, message)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeReactionOfUserFromMessageWithFuture(AEmote emote, Long serverId, Long channelId, Long messageId, Member member) {
|
||||
Integer emoteId = emote.getId();
|
||||
@@ -374,6 +384,44 @@ public class ReactionServiceBean implements ReactionService {
|
||||
return futures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CompletableFuture<Void>> removeReactionFromMessagesWithFuture(List<Message> messages, Integer emoteId) {
|
||||
AEmote emote = emoteManagementService.loadEmote(emoteId);
|
||||
return removeReactionFromMessagesWithFuture(messages, emote);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CompletableFuture<Void>> removeReactionFromMessagesWithFuture(List<Message> messages, AEmote emote) {
|
||||
List<CompletableFuture<Void>> removalFutures = new ArrayList<>();
|
||||
messages.forEach(message -> removalFutures.add(removeReactionFromMessageWithFuture(emote, message)));
|
||||
return removalFutures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFutureList<Void> removeReactionFromMessagesWithFutureWithFutureList(List<Message> messages, Integer emoteId) {
|
||||
List<CompletableFuture<Void>> allFutures = removeReactionFromMessagesWithFuture(messages, emoteId);
|
||||
return new CompletableFutureList<>(allFutures);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFutureList<Void> removeReactionFromMessagesWithFutureWithFutureList(List<Message> messages, String emoteKey) {
|
||||
List<CompletableFuture<Void>> allFutures = removeReactionFromMessagesWithFuture(messages, emoteKey);
|
||||
return new CompletableFutureList<>(allFutures);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CompletableFuture<Void>> removeReactionFromMessagesWithFuture(List<Message> messages, String emoteKey) {
|
||||
AEmote emote = emoteService.getEmoteOrDefaultEmote(emoteKey, messages.get(0).getGuild().getIdLong());
|
||||
return removeReactionFromMessagesWithFuture(messages, emote);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFutureList<Void> removeReactionFromMessagesWithFutureWithFutureList(List<Message> messages, AEmote emote) {
|
||||
List<CompletableFuture<Void>> removalFutures = new ArrayList<>();
|
||||
messages.forEach(message -> removalFutures.add(removeReactionFromMessageWithFuture(emote, message)));
|
||||
return new CompletableFutureList<>(removalFutures);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
metricService.registerCounter(REACTION_ADDED_METRIC, "Reactions added");
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
abstracto.listener.default.maxPoolSize=5
|
||||
abstracto.listener.default.maxPoolSize=2
|
||||
abstracto.listener.default.corePoolSize=1
|
||||
abstracto.listener.default.keepAliveSeconds=60
|
||||
|
||||
|
||||
abstracto.listener.joinListener.maxPoolSize=5
|
||||
abstracto.listener.joinListener.corePoolSize=1
|
||||
abstracto.listener.joinListener.keepAliveSeconds=60
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerChannelMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
@@ -11,6 +12,7 @@ import net.dv8tion.jda.api.entities.User;
|
||||
import net.dv8tion.jda.api.requests.restaction.AuditableRestAction;
|
||||
import net.dv8tion.jda.api.requests.restaction.MessageAction;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface MessageService {
|
||||
@@ -22,6 +24,7 @@ public interface MessageService {
|
||||
void updateStatusMessage(MessageChannel channel, Long messageId, MessageToSend messageToSend);
|
||||
CompletableFuture<Message> sendMessageToUser(AUserInAServer userInAServer, String text);
|
||||
CompletableFuture<Message> sendSimpleTemplateToUser(Long userId, String templateKey);
|
||||
List<CompletableFuture<Message>> retrieveMessages(List<ServerChannelMessage> messages);
|
||||
CompletableFuture<Message> sendTemplateToUser(User user, String template, Object model);
|
||||
CompletableFuture<Void> sendEmbedToUser(User user, String template, Object model);
|
||||
CompletableFuture<Message> sendEmbedToUserWithMessage(User user, String template, Object model);
|
||||
|
||||
@@ -5,6 +5,7 @@ import dev.sheldan.abstracto.core.models.cache.CachedEmote;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedMessage;
|
||||
import dev.sheldan.abstracto.core.models.cache.CachedReaction;
|
||||
import dev.sheldan.abstracto.core.models.database.AEmote;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
|
||||
import java.util.List;
|
||||
@@ -42,6 +43,7 @@ public interface ReactionService {
|
||||
CompletableFuture<Void> clearReactionFromMessageWithFuture(Integer emoteId, Message message);
|
||||
CompletableFuture<Void> removeReactionFromMessageWithFuture(AEmote emote, Long serverId, Long channelId, Long messageId);
|
||||
CompletableFuture<Void> removeReactionOfUserFromMessageWithFuture(AEmote emote, Long serverId, Long channelId, Long messageId, Long userId);
|
||||
CompletableFuture<Void> removeReactionOfUserFromMessageWithFuture(AEmote emote, Long serverId, Long channelId, Long messageId);
|
||||
CompletableFuture<Void> removeReactionOfUserFromMessageWithFuture(AEmote emote, Long serverId, Long channelId, Long messageId, Member member);
|
||||
CompletableFuture<Void> removeReactionOfUserFromMessageWithFuture(AEmote emote, Message message, Member member);
|
||||
CompletableFuture<Void> removeReactionOfUserFromMessageWithFuture(Integer emoteId, Message message, Member member);
|
||||
@@ -49,4 +51,10 @@ public interface ReactionService {
|
||||
CompletableFuture<Void> removeReactionOfUserFromMessageWithFuture(Integer emoteId, Message message, Long userId);
|
||||
CompletableFuture<Void> clearReactionFromMessageWithFuture(AEmote emote, Long serverId, Long channelId, Long messageId);
|
||||
List<CompletableFuture<Void>> addReactionsToMessageWithFuture(List<String> emoteKeys, Long serverId, Message message);
|
||||
List<CompletableFuture<Void>> removeReactionFromMessagesWithFuture(List<Message> messages, Integer emoteId);
|
||||
List<CompletableFuture<Void>> removeReactionFromMessagesWithFuture(List<Message> messages, AEmote emote);
|
||||
CompletableFutureList<Void> removeReactionFromMessagesWithFutureWithFutureList(List<Message> messages, Integer emoteId);
|
||||
CompletableFutureList<Void> removeReactionFromMessagesWithFutureWithFutureList(List<Message> messages, String emoteKey);
|
||||
List<CompletableFuture<Void>> removeReactionFromMessagesWithFuture(List<Message> messages, String emoteKey);
|
||||
CompletableFutureList<Void> removeReactionFromMessagesWithFutureWithFutureList(List<Message> messages, AEmote emote);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,11 @@ public class CompletableFutureList<T> {
|
||||
if(!future.isCompletedExceptionally()) {
|
||||
result.add(future.join());
|
||||
} else {
|
||||
log.warn("Future completed with exception {}.", future.join());
|
||||
try {
|
||||
future.join();
|
||||
} catch (Exception exception) {
|
||||
log.warn("Future completed with exception.", exception);
|
||||
}
|
||||
}
|
||||
});
|
||||
return result;
|
||||
|
||||
@@ -5,7 +5,7 @@ spring.quartz.jdbc.initialize-schema=never
|
||||
spring.quartz.properties.org.quartz.scheduler.instanceName=quartz-abstracto-app
|
||||
spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO
|
||||
spring.quartz.properties.org.quartz.scheduler.instanceIdGenerator.class=dev.sheldan.abstracto.scheduling.service.IdGenerationService
|
||||
spring.quartz.properties.org.quartz.threadPool.threadCount=20
|
||||
spring.quartz.properties.org.quartz.threadPool.threadCount=3
|
||||
spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
|
||||
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
|
||||
spring.quartz.properties.org.quartz.jobStore.useProperties=true
|
||||
|
||||
Reference in New Issue
Block a user