[AB-244] always loading the member for giving experience, members are not in cache just for writing a message

This commit is contained in:
Sheldan
2021-05-01 12:52:45 +02:00
parent fa864f85dd
commit 3559a823fc

View File

@@ -152,31 +152,52 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
public CompletableFuture<Void> handleExperienceGain(List<ServerExperience> servers) { public CompletableFuture<Void> handleExperienceGain(List<ServerExperience> servers) {
List<ExperienceGainResult> resultFutures = new ArrayList<>(); List<ExperienceGainResult> resultFutures = new ArrayList<>();
List<CompletableFuture<RoleCalculationResult>> futures = new ArrayList<>(); List<CompletableFuture<RoleCalculationResult>> futures = new ArrayList<>();
CompletableFuture<Void> experienceFuture = new CompletableFuture<>();
// TODO what if there are a lot in here...., transaction size etc
servers.forEach(serverExp -> {
List<CompletableFuture<Member>> memberFutures = new ArrayList<>();
serverExp.getUserInServerIds().forEach(userInAServerId -> {
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(userInAServerId);
CompletableFuture<Member> memberFuture = memberService.getMemberInServerAsync(userInAServer);
memberFutures.add(memberFuture);
});
FutureUtils.toSingleFutureGeneric(memberFutures).whenComplete((unused, throwable) -> {
self.updateFoundMembers(memberFutures, serverExp.getServerId(), resultFutures, futures);
experienceFuture.complete(null);
});
});
return experienceFuture
.thenCompose(unused -> FutureUtils.toSingleFutureGeneric(futures))
.whenComplete((unused, throwable) -> self.persistExperienceChanges(resultFutures));
}
@Transactional
public void updateFoundMembers(List<CompletableFuture<Member>> memberFutures, Long serverId, List<ExperienceGainResult> resultFutures, List<CompletableFuture<RoleCalculationResult>> futures) {
List<AExperienceLevel> levels = experienceLevelManagementService.getLevelConfig(); List<AExperienceLevel> levels = experienceLevelManagementService.getLevelConfig();
SystemConfigProperty defaultExpMultiplier = defaultConfigManagementService.getDefaultConfig(ExperienceFeatureConfig.EXP_MULTIPLIER_KEY); SystemConfigProperty defaultExpMultiplier = defaultConfigManagementService.getDefaultConfig(ExperienceFeatureConfig.EXP_MULTIPLIER_KEY);
SystemConfigProperty defaultMinExp = defaultConfigManagementService.getDefaultConfig(ExperienceFeatureConfig.MIN_EXP_KEY); SystemConfigProperty defaultMinExp = defaultConfigManagementService.getDefaultConfig(ExperienceFeatureConfig.MIN_EXP_KEY);
SystemConfigProperty defaultMaxExp = defaultConfigManagementService.getDefaultConfig(ExperienceFeatureConfig.MAX_EXP_KEY); SystemConfigProperty defaultMaxExp = defaultConfigManagementService.getDefaultConfig(ExperienceFeatureConfig.MAX_EXP_KEY);
// TODO what if there are a lot in here...., transaction size etc AServer server = serverManagementService.loadOrCreate(serverId);
servers.forEach(serverExp -> { log.info("Handling {} experience for server {}", memberFutures.size(), serverId);
AServer server = serverManagementService.loadOrCreate(serverExp.getServerId()); int minExp = configService.getLongValue(ExperienceFeatureConfig.MIN_EXP_KEY, serverId, defaultMinExp.getLongValue()).intValue();
log.info("Handling {} experience for server {}", serverExp.getUserInServerIds().size(), serverExp.getServerId()); int maxExp = configService.getLongValue(ExperienceFeatureConfig.MAX_EXP_KEY, serverId, defaultMaxExp.getLongValue()).intValue();
int minExp = configService.getLongValue(ExperienceFeatureConfig.MIN_EXP_KEY, serverExp.getServerId(), defaultMinExp.getLongValue()).intValue(); Double multiplier = configService.getDoubleValue(ExperienceFeatureConfig.EXP_MULTIPLIER_KEY, serverId, defaultExpMultiplier.getDoubleValue());
int maxExp = configService.getLongValue(ExperienceFeatureConfig.MAX_EXP_KEY, serverExp.getServerId(), defaultMaxExp.getLongValue()).intValue(); PrimitiveIterator.OfInt iterator = new Random().ints(memberFutures.size(), minExp, maxExp + 1).iterator();
Double multiplier = configService.getDoubleValue(ExperienceFeatureConfig.EXP_MULTIPLIER_KEY, serverExp.getServerId(), defaultExpMultiplier.getDoubleValue()); levels.sort(Comparator.comparing(AExperienceLevel::getExperienceNeeded));
PrimitiveIterator.OfInt iterator = new Random().ints(serverExp.getUserInServerIds().size(), minExp, maxExp + 1).iterator(); List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRolesForServer(server);
levels.sort(Comparator.comparing(AExperienceLevel::getExperienceNeeded)); List<ADisabledExpRole> disabledExpRoles = disabledExpRoleManagementService.getDisabledRolesForServer(server);
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRolesForServer(server); List<ARole> disabledRoles = disabledExpRoles.stream().map(ADisabledExpRole::getRole).collect(Collectors.toList());
List<ADisabledExpRole> disabledExpRoles = disabledExpRoleManagementService.getDisabledRolesForServer(server); roles.sort(Comparator.comparing(role -> role.getLevel().getLevel()));
List<ARole> disabledRoles = disabledExpRoles.stream().map(ADisabledExpRole::getRole).collect(Collectors.toList()); memberFutures.forEach(future -> {
roles.sort(Comparator.comparing(role -> role.getLevel().getLevel())); if(!future.isCompletedExceptionally()) {
serverExp.getUserInServerIds().forEach(userInAServerId -> {
Integer gainedExperience = iterator.next(); Integer gainedExperience = iterator.next();
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(userInAServerId);
gainedExperience = (int) Math.floor(gainedExperience * multiplier); gainedExperience = (int) Math.floor(gainedExperience * multiplier);
Member member = memberService.getMemberInServer(userInAServer); Member member = future.join();
if(member != null && !roleService.hasAnyOfTheRoles(member, disabledRoles)) { AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(member);
if(!roleService.hasAnyOfTheRoles(member, disabledRoles)) {
log.debug("Handling {}. The user gains {}", userInAServer.getUserReference().getId(), gainedExperience); log.debug("Handling {}. The user gains {}", userInAServer.getUserReference().getId(), gainedExperience);
Optional<AUserExperience> aUserExperienceOptional = userExperienceManagementService.findByUserInServerIdOptional(userInAServerId); Optional<AUserExperience> aUserExperienceOptional = userExperienceManagementService.findByUserInServerIdOptional(userInAServer.getUserInServerId());
if(aUserExperienceOptional.isPresent()) { if(aUserExperienceOptional.isPresent()) {
AUserExperience aUserExperience = aUserExperienceOptional.get(); AUserExperience aUserExperience = aUserExperienceOptional.get();
if(Boolean.FALSE.equals(aUserExperience.getExperienceGainDisabled())) { if(Boolean.FALSE.equals(aUserExperience.getExperienceGainDisabled())) {
@@ -218,14 +239,10 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
futures.add(resultFuture); futures.add(resultFuture);
} }
} else { } else {
log.debug("User {} has a role which makes the user unable to gain experience or the member could not be found in the server.", userInAServer.getUserInServerId()); log.info("User {} has a role which makes the user unable to gain experience.", userInAServer.getUserInServerId());
} }
}); }
}); });
return FutureUtils.toSingleFutureGeneric(futures).thenAccept(aVoid ->
self.persistExperienceChanges(resultFutures)
);
} }
/** /**
@@ -240,17 +257,6 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
* @return A {@link CompletableFuture future} containing the {@link RoleCalculationResult result} of the role calculation, which completes after the user has been awarded the role. * @return A {@link CompletableFuture future} containing the {@link RoleCalculationResult result} of the role calculation, which completes after the user has been awarded the role.
*/ */
private CompletableFuture<RoleCalculationResult> applyInitialRole(AUserInAServer aUserInAServer, List<AExperienceRole> roles, Integer currentLevel) { private CompletableFuture<RoleCalculationResult> applyInitialRole(AUserInAServer aUserInAServer, List<AExperienceRole> roles, Integer currentLevel) {
// we are in the process of attributing experience, which means the member should have send a message, therefore is in the case
// if the member is actually _not_ in the guild anymore (would mean, joined, send a message, and left immediately) this check is required
// this is backed by the cache
if(!memberService.isUserInGuild(aUserInAServer)) {
log.debug("User {} is not in server {} anymore. No role calculation done.", aUserInAServer.getUserInServerId(), aUserInAServer.getServerReference().getId());
return CompletableFuture.completedFuture(RoleCalculationResult
.builder()
.userInServerId(aUserInAServer.getUserInServerId())
.experienceRoleId(null)
.build());
}
AExperienceRole role = experienceRoleService.calculateRole(roles, currentLevel); AExperienceRole role = experienceRoleService.calculateRole(roles, currentLevel);
if(role == null) { if(role == null) {
log.debug("No experience role calculated. Applying none to user {} in server {}.", log.debug("No experience role calculated. Applying none to user {} in server {}.",