[AB-184] adding various metrics to the system, organizing imports, changing some transactional behaviour

adding okhttp metrics, split bot service into multiple services (guild, message), unified some places that services are used in order to interact with the api, and not directly the objects (this is to make it easier for metric to be accurate)
This commit is contained in:
Sheldan
2021-01-29 17:46:41 +01:00
parent 2a2a3aea70
commit b838678c15
362 changed files with 3045 additions and 1573 deletions

View File

@@ -33,7 +33,7 @@ public class DisableExpGain extends AbstractConditionableCommand {
@Override
public CommandResult execute(CommandContext commandContext) {
Member para = (Member) commandContext.getParameters().getParameters().get(0);
AUserInAServer userInAServer = userInServerManagementService.loadUser(para);
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(para);
aUserExperienceService.disableExperienceForUser(userInAServer);
return CommandResult.fromSuccess();
}

View File

@@ -33,7 +33,7 @@ public class EnableExpGain extends AbstractConditionableCommand {
@Override
public CommandResult execute(CommandContext commandContext) {
Member para = (Member) commandContext.getParameters().getParameters().get(0);
AUserInAServer userInAServer = userInServerManagementService.loadUser(para);
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(para);
aUserExperienceService.enableExperienceForUser(userInAServer);
return CommandResult.fromSuccess();
}

View File

@@ -73,7 +73,7 @@ public class LeaderBoardCommand extends AbstractConditionableCommand {
List<CompletableFuture<LeaderBoardEntryModel>> completableFutures = converter.fromLeaderBoard(leaderBoard);
futures.addAll(completableFutures);
log.info("Rendering leaderboard for page {} in server {} for user {}.", page, commandContext.getAuthor().getId(), commandContext.getGuild().getId());
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(commandContext.getAuthor());
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(commandContext.getAuthor());
LeaderBoardEntry userRank = userExperienceService.getRankOfUserInServer(aUserInAServer);
CompletableFuture<LeaderBoardEntryModel> userRankFuture = converter.fromLeaderBoardEntry(userRank);
futures.add(userRankFuture);

View File

@@ -18,8 +18,8 @@ import dev.sheldan.abstracto.experience.models.LeaderBoardEntry;
import dev.sheldan.abstracto.experience.models.database.AUserExperience;
import dev.sheldan.abstracto.experience.models.templates.LeaderBoardEntryModel;
import dev.sheldan.abstracto.experience.models.templates.RankModel;
import dev.sheldan.abstracto.experience.service.ExperienceLevelService;
import dev.sheldan.abstracto.experience.service.AUserExperienceService;
import dev.sheldan.abstracto.experience.service.ExperienceLevelService;
import dev.sheldan.abstracto.experience.service.management.UserExperienceManagementService;
import dev.sheldan.abstracto.templating.model.MessageToSend;
import dev.sheldan.abstracto.templating.service.TemplateService;
@@ -67,7 +67,7 @@ public class Rank extends AbstractConditionableCommand {
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
RankModel rankModel = (RankModel) ContextConverter.slimFromCommandContext(commandContext, RankModel.class);
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(commandContext.getAuthor());
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(commandContext.getAuthor());
LeaderBoardEntry userRank = userExperienceService.getRankOfUserInServer(aUserInAServer);
CompletableFuture<LeaderBoardEntryModel> future = converter.fromLeaderBoardEntry(userRank);
return future.thenCompose(leaderBoardEntryModel ->
@@ -78,7 +78,7 @@ public class Rank extends AbstractConditionableCommand {
@Transactional
public CompletableFuture<Void> renderAndSendRank(CommandContext commandContext, RankModel rankModel, LeaderBoardEntryModel leaderBoardEntryModel) {
rankModel.setRankUser(leaderBoardEntryModel);
AUserInAServer aUserInAServer = userInServerManagementService.loadUser(commandContext.getAuthor());
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(commandContext.getAuthor());
AUserExperience experienceObj = userExperienceManagementService.findUserInServer(aUserInAServer);
log.info("Rendering rank for user {} in server {}.", commandContext.getAuthor().getId(), commandContext.getGuild().getId());
rankModel.setExperienceToNextLevel(experienceLevelService.calculateExperienceToNextLevel(experienceObj.getCurrentLevel().getLevel(), experienceObj.getExperience()));

View File

@@ -1,7 +1,7 @@
package dev.sheldan.abstracto.experience.converter;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.BotService;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.experience.models.LeaderBoard;
import dev.sheldan.abstracto.experience.models.LeaderBoardEntry;
import dev.sheldan.abstracto.experience.models.templates.LeaderBoardEntryModel;
@@ -22,7 +22,7 @@ import java.util.concurrent.CompletableFuture;
public class LeaderBoardModelConverter {
@Autowired
private BotService botService;
private MemberService memberService;
/**
* Converts the complete {@link LeaderBoard} into a list of {@link LeaderBoardEntryModel} which contain additional
@@ -50,7 +50,7 @@ public class LeaderBoardModelConverter {
*/
public CompletableFuture<LeaderBoardEntryModel> fromLeaderBoardEntry(LeaderBoardEntry leaderBoardEntry) {
AUserInAServer entryUser = leaderBoardEntry.getExperience().getUser();
return botService.getMemberInServerAsync(entryUser.getServerReference().getId(), entryUser.getUserReference().getId()).thenApply(member ->
return memberService.getMemberInServerAsync(entryUser.getServerReference().getId(), entryUser.getUserReference().getId()).thenApply(member ->
LeaderBoardEntryModel
.builder()
.experience(leaderBoardEntry.getExperience())

View File

@@ -13,8 +13,8 @@ import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
import java.time.Instant;
import java.util.Map;
import java.util.List;
import java.util.Map;
/**

View File

@@ -28,7 +28,7 @@ public class ExperienceTrackerListener implements AsyncMessageReceivedListener {
@Override
public void execute(CachedMessage message) {
AUserInAServer cause = userInServerManagementService.loadUser(message.getServerId(), message.getAuthor().getAuthorId());
AUserInAServer cause = userInServerManagementService.loadOrCreateUser(message.getServerId(), message.getAuthor().getAuthorId());
userExperienceService.addExperience(cause);
}

View File

@@ -34,7 +34,7 @@ public class JoiningUserRoleListener implements AsyncJoinListener {
@Override
public void execute(ServerUser serverUser) {
AUserInAServer userInAServer = userInServerManagementService.loadUser(serverUser.getServerId(), serverUser.getUserId());
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(serverUser.getServerId(), serverUser.getUserId());
AUserExperience userExperience = userExperienceManagementService.findUserInServer(userInAServer);
Long userInServerId = userInAServer.getUserInServerId();
if(userExperience != null) {

View File

@@ -1,8 +1,8 @@
package dev.sheldan.abstracto.experience.repository;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.experience.models.database.LeaderBoardEntryResult;
import dev.sheldan.abstracto.experience.models.database.AUserExperience;
import dev.sheldan.abstracto.experience.models.database.LeaderBoardEntryResult;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;

View File

@@ -69,7 +69,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
private UserInServerManagementService userInServerManagementService;
@Autowired
private BotService botService;
private MemberService memberService;
@Autowired
private RunTimeExperienceService runTimeExperienceService;
@@ -184,9 +184,9 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
roles.sort(Comparator.comparing(role -> role.getLevel().getLevel()));
serverExp.getUserInServerIds().forEach(userInAServerId -> {
Integer gainedExperience = iterator.next();
AUserInAServer userInAServer = userInServerManagementService.loadUser(userInAServerId);
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(userInAServerId);
gainedExperience = (int) Math.floor(gainedExperience * multiplier);
Member member = botService.getMemberInServer(userInAServer);
Member member = memberService.getMemberInServer(userInAServer);
if(member != null && !roleService.hasAnyOfTheRoles(member, disabledRoles)) {
log.trace("Handling {}. The user gains {}", userInAServer.getUserReference().getId(), gainedExperience);
Optional<AUserExperience> aUserExperienceOptional = userExperienceManagementService.findByUserInServerIdOptional(userInAServerId);
@@ -242,7 +242,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
}
private CompletableFuture<RoleCalculationResult> applyInitialRole(AUserInAServer aUserInAServer, List<AExperienceRole> roles, Integer currentLevel) {
if(!botService.isUserInGuild(aUserInAServer)) {
if(!memberService.isUserInGuild(aUserInAServer)) {
log.trace("User {} is not in server {} anymore. No role calculation done.", aUserInAServer.getUserInServerId(), aUserInAServer.getServerReference().getId());
return CompletableFuture.completedFuture(RoleCalculationResult
.builder()
@@ -277,7 +277,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
log.info("Storing {} experience gain results.", resultFutures.size());
HashMap<Long, List<AExperienceRole>> serverRoleMapping = new HashMap<>();
resultFutures.forEach(experienceGainResult -> {
AUserInAServer user = userInServerManagementService.loadUser(experienceGainResult.getUserInServerId());
AUserInAServer user = userInServerManagementService.loadOrCreateUser(experienceGainResult.getUserInServerId());
AUserExperience userExperience;
if(experienceGainResult.isCreateUserExperience()) {
userExperience = userExperienceManagementService.createUserInServer(user);
@@ -345,7 +345,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
// if the new role is already the one configured in the database
Long userId = user.getUserReference().getId();
Long oldUserExperienceRoleId = currentlyHasNoExperienceRole ? 0L : userExperience.getCurrentExperienceRole().getRole().getId();
return botService.getMemberInServerAsync(user).thenCompose(member -> {
return memberService.getMemberInServerAsync(user).thenCompose(member -> {
boolean userHasRoleAlready = roleService.memberHasRole(member, roleId);
boolean userHasOldRole = false;
boolean rolesChanged = true;
@@ -426,7 +426,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
public void syncRolesInStorage(List<RoleCalculationResult> results) {
results.forEach(result -> {
if(result != null) {
AUserInAServer user = userInServerManagementService.loadUser(result.getUserInServerId());
AUserInAServer user = userInServerManagementService.loadOrCreateUser(result.getUserInServerId());
AUserExperience userExperience = userExperienceManagementService.findUserInServer(user);
log.trace("Updating experience role for {} in server {} to {}", user.getUserInServerId(), user.getServerReference().getId(), result.getExperienceRoleId());
if(result.getExperienceRoleId() != null) {

View File

@@ -1,8 +1,12 @@
package dev.sheldan.abstracto.experience.service;
import dev.sheldan.abstracto.core.metrics.service.CounterMetric;
import dev.sheldan.abstracto.core.metrics.service.MetricService;
import dev.sheldan.abstracto.experience.models.ServerExperience;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -11,6 +15,16 @@ import java.util.concurrent.locks.ReentrantLock;
@Component
public class RunTimeExperienceService {
@Autowired
private MetricService metricService;
public static final String EXPERIENCE_RUNTIME_STORAGE = "experience.runtime.storage";
private static final CounterMetric EXPERIENCE_RUNTIME_STORAGE_METRIC = CounterMetric
.builder()
.name(EXPERIENCE_RUNTIME_STORAGE)
.build();
private Map<Long, List<ServerExperience>> runtimeExperience = new HashMap<>();
private static final Lock lock = new ReentrantLock();
public Map<Long, List<ServerExperience>> getRuntimeExperience() {
@@ -25,4 +39,12 @@ public class RunTimeExperienceService {
lock.unlock();
}
}
@PostConstruct
public void postConstruct() {
metricService.registerGauge(EXPERIENCE_RUNTIME_STORAGE_METRIC, runtimeExperience, serverList -> serverList.values().stream()
.mapToInt(minuteEntry -> minuteEntry.stream()
.mapToInt(individualServerList -> individualServerList.getUserInServerIds().size()).sum()).sum(),
"Number of entries in runtime experience storage");
}
}

View File

@@ -4,9 +4,9 @@ import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.exception.UserInServerNotFoundException;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.experience.models.database.LeaderBoardEntryResult;
import dev.sheldan.abstracto.experience.models.database.AExperienceLevel;
import dev.sheldan.abstracto.experience.models.database.AUserExperience;
import dev.sheldan.abstracto.experience.models.database.LeaderBoardEntryResult;
import dev.sheldan.abstracto.experience.repository.UserExperienceRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;