Implement report caching

This commit is contained in:
Keir Nellyer 2016-06-10 00:28:07 +01:00
parent 22dbcbf90d
commit 4503f12738
2 changed files with 141 additions and 39 deletions

View File

@ -47,7 +47,6 @@ public class ReportManager
{
private static final String NAME = "Report";
// statistic constants
private static final int ABUSE_BAN_THRESHOLD = 1;
private JavaPlugin _javaPlugin;
@ -295,10 +294,13 @@ public class ReportManager
_reportRepository.getOngoingReport(playerId)
.thenCompose(_reportRepository::getReport)
.thenAccept(report -> {
.thenAccept(report ->
{
if (report != null)
{
sendHandlerNotification(report, F.main(getReportPrefix(report), String.format("%s has re-joined the game.", player.getName())));
sendHandlerNotification(report,
F.main(getReportPrefix(report),
String.format("%s has re-joined the game.", player.getName())));
}
}
);
@ -310,13 +312,18 @@ public class ReportManager
_reportRepository.getOngoingReport(playerId)
.thenCompose(_reportRepository::getReport)
.thenAccept(report -> {
.thenAccept(report ->
{
if (report != null)
{
sendHandlerNotification(report, F.main(getReportPrefix(report), String.format("%s has left the game.", player.getName())));
sendHandlerNotification(report,
F.main(getReportPrefix(report),
String.format("%s has left the game.", player.getName())));
}
}
);
_reportRepository.clearCacheFor(_clientManager.getAccountId(player));
}
/**

View File

@ -24,6 +24,7 @@ import mineplex.core.database.MinecraftRepository;
import mineplex.serverdata.database.DBPool;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
/**
@ -82,6 +83,8 @@ public class ReportRepository extends MinecraftRepository
private static final String GET_ACCOUNT_UUID = "SELECT id, uuid FROM accounts" +
" WHERE id IN (%s);";
private final Map<Integer, Report> _cachedReports = new HashMap<>();
public ReportRepository(JavaPlugin plugin)
{
super(plugin, DBPool.getAccount());
@ -136,6 +139,12 @@ public class ReportRepository extends MinecraftRepository
public CompletableFuture<Report> getReport(int reportId)
{
if (reportId != -1)
{
if (_cachedReports.containsKey(reportId))
{
return CompletableFuture.completedFuture(_cachedReports.get(reportId));
}
else
{
return CompletableFuture.supplyAsync(() ->
{
@ -169,6 +178,14 @@ public class ReportRepository extends MinecraftRepository
report.setReportResult(new ReportResult(resultType, reason, closedTime));
}
shouldCacheReport(report).thenAccept(shouldCache ->
{
if (shouldCache)
{
_cachedReports.put(reportId, report);
}
});
return report;
}
}
@ -180,6 +197,7 @@ public class ReportRepository extends MinecraftRepository
return null;
});
}
}
else
{
return CompletableFuture.completedFuture(null);
@ -367,6 +385,83 @@ public class ReportRepository extends MinecraftRepository
});
}
/**
* Disposes of cached reports which are cached as a result of this user.
* This function is called when a user leaves the server.
*
* @param accountId the account id to clean the cached reports of
*/
protected void clearCacheFor(int accountId)
{
for (Map.Entry<Integer, Report> entry : new HashSet<>(_cachedReports.entrySet()))
{
int reportId = entry.getKey();
Report report = entry.getValue();
Optional<Integer> handlerIdOptional = report.getHandlerId();
CompletableFuture<Boolean> disposeCacheFuture = CompletableFuture.completedFuture(false);
if (report.getSuspectId() == accountId)
{
if (handlerIdOptional.isPresent())
{
disposeCacheFuture = checkUserOnline(handlerIdOptional.get());
}
else
{
// no handler so un-cache this report
disposeCacheFuture = CompletableFuture.completedFuture(true);
}
}
else if (handlerIdOptional.isPresent() && handlerIdOptional.get() == accountId)
{
disposeCacheFuture = checkUserOnline(report.getSuspectId());
}
disposeCacheFuture.thenAccept(dispose ->
{
if (dispose)
{
_cachedReports.remove(reportId);
}
});
}
}
/**
* Checks if either the suspect or handler (if any) are online.
* If either are online then this will return true, otherwise false.
*
* @param report the report to check if it should be cached
* @return true if this report should be cached, false otherwise
*/
private CompletableFuture<Boolean> shouldCacheReport(Report report)
{
return checkUserOnline(report.getSuspectId()).thenCompose(online ->
{
if (!online)
{
Optional<Integer> handlerIdOptional = report.getHandlerId();
if (handlerIdOptional.isPresent())
{
return checkUserOnline(handlerIdOptional.get());
}
else
{
return CompletableFuture.completedFuture(false);
}
}
return CompletableFuture.completedFuture(true);
});
}
private CompletableFuture<Boolean> checkUserOnline(int accountId)
{
return getAccountUUID(accountId).thenApply(Bukkit::getPlayer).thenApply(player -> player != null);
}
public CompletableFuture<String> getAccountName(int accountId)
{
return CompletableFuture.supplyAsync(() ->