mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-04-18 04:50:38 +00:00
[AB-xxx] try for instrumenting
This commit is contained in:
@@ -27,6 +27,8 @@ import dev.sheldan.abstracto.experience.service.ExperienceLevelService;
|
||||
import dev.sheldan.abstracto.experience.service.management.UserExperienceManagementService;
|
||||
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
|
||||
import dev.sheldan.abstracto.core.templating.service.TemplateService;
|
||||
import io.micrometer.tracing.Span;
|
||||
import io.micrometer.tracing.Tracer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
@@ -83,11 +85,14 @@ public class Rank extends AbstractConditionableCommand {
|
||||
@Value("${abstracto.experience.leaderboard.externalUrl}")
|
||||
private String leaderboardExternalURL;
|
||||
|
||||
@Autowired
|
||||
private Tracer tracer;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
Member targetMember = !parameters.isEmpty() ? (Member) parameters.get(0) : commandContext.getAuthor();
|
||||
if(!targetMember.getGuild().equals(commandContext.getGuild())) {
|
||||
if (!targetMember.getGuild().equals(commandContext.getGuild())) {
|
||||
throw new EntityGuildMismatchException();
|
||||
}
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(targetMember);
|
||||
@@ -97,10 +102,13 @@ public class Rank extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.member(targetMember)
|
||||
.build();
|
||||
Span span = tracer.currentSpan();
|
||||
return future.thenCompose(leaderBoardEntryModel -> {
|
||||
try (Tracer.SpanInScope ws = tracer.withSpan(span)) {
|
||||
MessageToSend messageToSend = self.renderMessageToSend(targetMember, rankModel, leaderBoardEntryModel.get(0));
|
||||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()));
|
||||
}).thenApply(result -> CommandResult.fromIgnored());
|
||||
}
|
||||
}).thenApply(result -> CommandResult.fromIgnored());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -133,7 +141,7 @@ public class Rank extends AbstractConditionableCommand {
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
Member targetMember;
|
||||
if(slashCommandParameterService.hasCommandOption(MEMBER_PARAMETER, event)) {
|
||||
if (slashCommandParameterService.hasCommandOption(MEMBER_PARAMETER, event)) {
|
||||
targetMember = slashCommandParameterService.getCommandOption(MEMBER_PARAMETER, event, Member.class);
|
||||
} else {
|
||||
targetMember = event.getMember();
|
||||
@@ -145,9 +153,12 @@ public class Rank extends AbstractConditionableCommand {
|
||||
.builder()
|
||||
.member(targetMember)
|
||||
.build();
|
||||
Span span = tracer.currentSpan();
|
||||
return future.thenCompose(leaderBoardEntryModel -> {
|
||||
MessageToSend messageToSend = self.renderMessageToSend(targetMember, rankModel, leaderBoardEntryModel.get(0));
|
||||
return interactionService.replyMessageToSend(messageToSend, event);
|
||||
try (Tracer.SpanInScope ws = tracer.withSpan(span)) {
|
||||
MessageToSend messageToSend = self.renderMessageToSend(targetMember, rankModel, leaderBoardEntryModel.get(0));
|
||||
return interactionService.replyMessageToSend(messageToSend, event);
|
||||
}
|
||||
}).thenApply(result -> CommandResult.fromIgnored());
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@ import dev.sheldan.abstracto.core.service.MemberService;
|
||||
import dev.sheldan.abstracto.experience.model.LeaderBoard;
|
||||
import dev.sheldan.abstracto.experience.model.LeaderBoardEntry;
|
||||
import dev.sheldan.abstracto.experience.model.template.LeaderBoardEntryModel;
|
||||
import dev.sheldan.abstracto.experience.service.management.UserExperienceManagementService;
|
||||
import io.micrometer.tracing.Span;
|
||||
import io.micrometer.tracing.Tracer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -29,10 +30,7 @@ public class LeaderBoardModelConverter {
|
||||
private MemberService memberService;
|
||||
|
||||
@Autowired
|
||||
private UserExperienceManagementService userExperienceManagementService;
|
||||
|
||||
@Autowired
|
||||
private LeaderBoardModelConverter self;
|
||||
private Tracer tracer;
|
||||
|
||||
/**
|
||||
* Converts the complete {@link LeaderBoard leaderBoard} into a list of {@link LeaderBoardEntryModel leaderbaordEntryModels} which contain additional
|
||||
@@ -62,12 +60,15 @@ public class LeaderBoardModelConverter {
|
||||
.build();
|
||||
})
|
||||
.collect(Collectors.toMap(LeaderBoardEntryModel::getUserId, Function.identity()));
|
||||
Span span = tracer.currentSpan();
|
||||
return memberService.getMembersInServerAsync(serverId, userIds).thenApply(members -> {
|
||||
members.forEach(member -> models.get(member.getIdLong()).setMember(member));
|
||||
return new ArrayList<>(models.values())
|
||||
.stream()
|
||||
.sorted(Comparator.comparing(LeaderBoardEntryModel::getRank)).
|
||||
collect(Collectors.toList());
|
||||
try (Tracer.SpanInScope ws = tracer.withSpan(span)) {
|
||||
members.forEach(member -> models.get(member.getIdLong()).setMember(member));
|
||||
return new ArrayList<>(models.values())
|
||||
.stream()
|
||||
.sorted(Comparator.comparing(LeaderBoardEntryModel::getRank)).
|
||||
collect(Collectors.toList());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import dev.sheldan.abstracto.core.listener.sync.jda.MessageReceivedListener;
|
||||
import dev.sheldan.abstracto.core.models.listener.MessageReceivedModel;
|
||||
import dev.sheldan.abstracto.experience.config.ExperienceFeatureDefinition;
|
||||
import dev.sheldan.abstracto.experience.service.AUserExperienceService;
|
||||
import io.micrometer.tracing.Span;
|
||||
import io.micrometer.tracing.Tracer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -23,17 +25,26 @@ public class ExperienceTrackerListener implements AsyncMessageReceivedListener {
|
||||
@Autowired
|
||||
private AUserExperienceService userExperienceService;
|
||||
|
||||
@Autowired
|
||||
private Tracer tracer;
|
||||
|
||||
@Override
|
||||
public DefaultListenerResult execute(MessageReceivedModel model) {
|
||||
Message message = model.getMessage();
|
||||
if(!message.isFromGuild() || message.isWebhookMessage() || message.getType().isSystem() || message.getAuthor().isBot()) {
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
if(userExperienceService.experienceGainEnabledInChannel(message.getChannel())) {
|
||||
userExperienceService.addExperience(message.getMember(), model.getMessage());
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
} else {
|
||||
return DefaultListenerResult.IGNORED;
|
||||
Span newSpan = tracer.nextSpan().name("experience-tracker");
|
||||
try (Tracer.SpanInScope ws = this.tracer.withSpan(newSpan.start())) {
|
||||
Message message = model.getMessage();
|
||||
if(!message.isFromGuild() || message.isWebhookMessage() || message.getType().isSystem() || message.getAuthor().isBot()) {
|
||||
newSpan.end();
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
if(userExperienceService.experienceGainEnabledInChannel(message.getChannel())) {
|
||||
userExperienceService.addExperience(message.getMember(), model.getMessage()).whenComplete((unused, throwable) -> {
|
||||
newSpan.end();
|
||||
});
|
||||
return DefaultListenerResult.PROCESSED;
|
||||
} else {
|
||||
return DefaultListenerResult.IGNORED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.sheldan.abstracto.experience.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.metric.service.MetricUtils;
|
||||
import dev.sheldan.abstracto.core.models.database.*;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.models.template.display.RoleDisplay;
|
||||
@@ -25,6 +26,8 @@ import dev.sheldan.abstracto.experience.service.management.DisabledExpRoleManage
|
||||
import dev.sheldan.abstracto.experience.service.management.ExperienceLevelManagementService;
|
||||
import dev.sheldan.abstracto.experience.service.management.ExperienceRoleManagementService;
|
||||
import dev.sheldan.abstracto.experience.service.management.UserExperienceManagementService;
|
||||
import io.micrometer.tracing.Span;
|
||||
import io.micrometer.tracing.Tracer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
@@ -114,8 +117,11 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
@Qualifier("experienceUpdateExecutor")
|
||||
private TaskExecutor experienceUpdateExecutor;
|
||||
|
||||
@Autowired
|
||||
private Tracer tracer;
|
||||
|
||||
@Override
|
||||
public void addExperience(Member member, Message message) {
|
||||
public CompletableFuture<Void> addExperience(Member member, Message message) {
|
||||
runTimeExperienceService.takeLock();
|
||||
try {
|
||||
Map<Long, Map<Long, Instant>> runtimeExperience = runTimeExperienceService.getRuntimeExperience();
|
||||
@@ -141,7 +147,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
// we store when the user is eligible for experience _again_
|
||||
Long maxSeconds = configService.getLongValueOrConfigDefault(EXP_COOLDOWN_SECONDS_KEY, serverId);
|
||||
serverExperience.put(userId, Instant.now().plus(maxSeconds, ChronoUnit.SECONDS));
|
||||
CompletableFuture.runAsync(() -> self.addExperienceToMember(member, message), experienceUpdateExecutor).exceptionally(throwable -> {
|
||||
return CompletableFuture.runAsync(() -> self.addExperienceToMember(member, message), MetricUtils.wrapExecutor(experienceUpdateExecutor)).exceptionally(throwable -> {
|
||||
log.error("Failed to add experience to member {} in server {}.", message.getAuthor().getId(), message.getGuild().getIdLong(), throwable);
|
||||
return null;
|
||||
});
|
||||
@@ -149,6 +155,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
} finally {
|
||||
runTimeExperienceService.releaseLock();
|
||||
}
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
|
||||
@@ -297,37 +304,43 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void addExperienceToMember(Member member, Message message) {
|
||||
long serverId = member.getGuild().getIdLong();
|
||||
AServer server = serverManagementService.loadOrCreate(serverId);
|
||||
List<ADisabledExpRole> disabledExpRoles = disabledExpRoleManagementService.getDisabledRolesForServer(server);
|
||||
List<ARole> disabledRoles = disabledExpRoles
|
||||
.stream()
|
||||
.map(ADisabledExpRole::getRole)
|
||||
.collect(Collectors.toList());
|
||||
if(roleService.hasAnyOfTheRoles(member, disabledRoles)) {
|
||||
log.debug("User {} has a experience disable role in server {} - not giving any experience.", member.getIdLong(), serverId);
|
||||
return;
|
||||
}
|
||||
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(member);
|
||||
Long userInServerId = userInAServer.getUserInServerId();
|
||||
Optional<AUserExperience> aUserExperienceOptional = userExperienceManagementService.findByUserInServerIdOptional(userInAServer.getUserInServerId());
|
||||
AUserExperience aUserExperience = aUserExperienceOptional.orElseGet(() -> userExperienceManagementService.createUserInServer(userInAServer));
|
||||
if(Boolean.FALSE.equals(aUserExperience.getExperienceGainDisabled())) {
|
||||
List<AExperienceLevel> levels = experienceLevelManagementService.getLevelConfig();
|
||||
levels.sort(Comparator.comparing(AExperienceLevel::getExperienceNeeded));
|
||||
public CompletableFuture<Void> addExperienceToMember(Member member, Message message) {
|
||||
CompletableFuture<Void> notificationFuture = CompletableFuture.completedFuture(null);
|
||||
CompletableFuture<Void> levelActionFuture = CompletableFuture.completedFuture(null);
|
||||
CompletableFuture<Void> roleFuture = CompletableFuture.completedFuture(null);
|
||||
Span newSpan = tracer.nextSpan().name("experience-adding");
|
||||
try (Tracer.SpanInScope ws = this.tracer.withSpan(newSpan.start())) {
|
||||
long serverId = member.getGuild().getIdLong();
|
||||
AServer server = serverManagementService.loadOrCreate(serverId);
|
||||
List<ADisabledExpRole> disabledExpRoles = disabledExpRoleManagementService.getDisabledRolesForServer(server);
|
||||
List<ARole> disabledRoles = disabledExpRoles
|
||||
.stream()
|
||||
.map(ADisabledExpRole::getRole)
|
||||
.collect(Collectors.toList());
|
||||
if (roleService.hasAnyOfTheRoles(member, disabledRoles)) {
|
||||
log.debug("User {} has a experience disable role in server {} - not giving any experience.", member.getIdLong(), serverId);
|
||||
newSpan.end();
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(member);
|
||||
Long userInServerId = userInAServer.getUserInServerId();
|
||||
Optional<AUserExperience> aUserExperienceOptional = userExperienceManagementService.findByUserInServerIdOptional(userInAServer.getUserInServerId());
|
||||
AUserExperience aUserExperience = aUserExperienceOptional.orElseGet(() -> userExperienceManagementService.createUserInServer(userInAServer));
|
||||
if (Boolean.FALSE.equals(aUserExperience.getExperienceGainDisabled())) {
|
||||
List<AExperienceLevel> levels = experienceLevelManagementService.getLevelConfig();
|
||||
levels.sort(Comparator.comparing(AExperienceLevel::getExperienceNeeded));
|
||||
|
||||
Long minExp = configService.getLongValueOrConfigDefault(ExperienceFeatureConfig.MIN_EXP_KEY, serverId);
|
||||
Long maxExp = configService.getLongValueOrConfigDefault(ExperienceFeatureConfig.MAX_EXP_KEY, serverId);
|
||||
Double multiplier = configService.getDoubleValueOrConfigDefault(ExperienceFeatureConfig.EXP_MULTIPLIER_KEY, serverId);
|
||||
Long experienceRange = maxExp - minExp + 1;
|
||||
Long gainedExperience = (secureRandom.nextInt(experienceRange.intValue()) + minExp);
|
||||
gainedExperience = (long) Math.floor(gainedExperience * multiplier);
|
||||
Long minExp = configService.getLongValueOrConfigDefault(ExperienceFeatureConfig.MIN_EXP_KEY, serverId);
|
||||
Long maxExp = configService.getLongValueOrConfigDefault(ExperienceFeatureConfig.MAX_EXP_KEY, serverId);
|
||||
Double multiplier = configService.getDoubleValueOrConfigDefault(ExperienceFeatureConfig.EXP_MULTIPLIER_KEY, serverId);
|
||||
Long experienceRange = maxExp - minExp + 1;
|
||||
Long gainedExperience = (secureRandom.nextInt(experienceRange.intValue()) + minExp);
|
||||
gainedExperience = (long) Math.floor(gainedExperience * multiplier);
|
||||
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRolesForServer(server);
|
||||
roles.sort(Comparator.comparing(role -> role.getLevel().getLevel()));
|
||||
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRolesForServer(server);
|
||||
roles.sort(Comparator.comparing(role -> role.getLevel().getLevel()));
|
||||
|
||||
log.debug("Handling {}. The user gains {}.", userInServerId, gainedExperience);
|
||||
log.debug("Handling {}. The user gains {}.", userInServerId, gainedExperience);
|
||||
|
||||
Long oldExperience = aUserExperience.getExperience();
|
||||
Long newExperienceCount = oldExperience + gainedExperience;
|
||||
@@ -415,6 +428,9 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
} else {
|
||||
log.debug("Experience gain was disabled. User did not gain any experience.");
|
||||
}
|
||||
return CompletableFuture.allOf(notificationFuture, levelActionFuture, roleFuture).whenComplete((unused, throwable) -> {
|
||||
newSpan.end();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
*/
|
||||
public interface AUserExperienceService {
|
||||
String EXPERIENCE_GAIN_CHANNEL_GROUP_KEY = "experienceGain";
|
||||
void addExperience(Member member, Message message);
|
||||
CompletableFuture<Void> addExperience(Member member, Message message);
|
||||
|
||||
/**
|
||||
* Calculates the appropriate level for the given experience amount according to the given {@link AExperienceLevel levels}
|
||||
|
||||
Reference in New Issue
Block a user