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"; private static final String NAME = "Report";
// statistic constants
private static final int ABUSE_BAN_THRESHOLD = 1; private static final int ABUSE_BAN_THRESHOLD = 1;
private JavaPlugin _javaPlugin; private JavaPlugin _javaPlugin;
@ -295,10 +294,13 @@ public class ReportManager
_reportRepository.getOngoingReport(playerId) _reportRepository.getOngoingReport(playerId)
.thenCompose(_reportRepository::getReport) .thenCompose(_reportRepository::getReport)
.thenAccept(report -> { .thenAccept(report ->
{
if (report != null) 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) _reportRepository.getOngoingReport(playerId)
.thenCompose(_reportRepository::getReport) .thenCompose(_reportRepository::getReport)
.thenAccept(report -> { .thenAccept(report ->
{
if (report != null) 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 mineplex.serverdata.database.DBPool;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin; 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" + private static final String GET_ACCOUNT_UUID = "SELECT id, uuid FROM accounts" +
" WHERE id IN (%s);"; " WHERE id IN (%s);";
private final Map<Integer, Report> _cachedReports = new HashMap<>();
public ReportRepository(JavaPlugin plugin) public ReportRepository(JavaPlugin plugin)
{ {
super(plugin, DBPool.getAccount()); super(plugin, DBPool.getAccount());
@ -136,6 +139,12 @@ public class ReportRepository extends MinecraftRepository
public CompletableFuture<Report> getReport(int reportId) public CompletableFuture<Report> getReport(int reportId)
{ {
if (reportId != -1) if (reportId != -1)
{
if (_cachedReports.containsKey(reportId))
{
return CompletableFuture.completedFuture(_cachedReports.get(reportId));
}
else
{ {
return CompletableFuture.supplyAsync(() -> return CompletableFuture.supplyAsync(() ->
{ {
@ -169,6 +178,14 @@ public class ReportRepository extends MinecraftRepository
report.setReportResult(new ReportResult(resultType, reason, closedTime)); report.setReportResult(new ReportResult(resultType, reason, closedTime));
} }
shouldCacheReport(report).thenAccept(shouldCache ->
{
if (shouldCache)
{
_cachedReports.put(reportId, report);
}
});
return report; return report;
} }
} }
@ -180,6 +197,7 @@ public class ReportRepository extends MinecraftRepository
return null; return null;
}); });
} }
}
else else
{ {
return CompletableFuture.completedFuture(null); 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) public CompletableFuture<String> getAccountName(int accountId)
{ {
return CompletableFuture.supplyAsync(() -> return CompletableFuture.supplyAsync(() ->