mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-02-04 14:31:34 +01:00
Removed UserData "dataCache" Map from DataCacheHandler
Removed Clear, Save & Get Queues. Renamed DataCacheHandler to DataCache Moved Process queue & Renamed to ProcessingQueue
This commit is contained in:
parent
67df66cc31
commit
bc7df57c40
@ -30,7 +30,7 @@ import main.java.com.djrapitops.plan.command.PlanCommand;
|
||||
import main.java.com.djrapitops.plan.command.commands.RegisterCommandFilter;
|
||||
import main.java.com.djrapitops.plan.data.additional.HookHandler;
|
||||
import main.java.com.djrapitops.plan.data.cache.AnalysisCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCache;
|
||||
import main.java.com.djrapitops.plan.data.cache.InspectCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.cache.PageCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.listeners.*;
|
||||
@ -40,6 +40,8 @@ import main.java.com.djrapitops.plan.database.databases.MySQLDB;
|
||||
import main.java.com.djrapitops.plan.database.databases.SQLiteDB;
|
||||
import main.java.com.djrapitops.plan.locale.Locale;
|
||||
import main.java.com.djrapitops.plan.locale.Msg;
|
||||
import main.java.com.djrapitops.plan.queue.processing.ProcessingQueue;
|
||||
import main.java.com.djrapitops.plan.queue.processing.Processor;
|
||||
import main.java.com.djrapitops.plan.ui.webserver.WebServer;
|
||||
import main.java.com.djrapitops.plan.ui.webserver.api.bukkit.*;
|
||||
import main.java.com.djrapitops.plan.utilities.Benchmark;
|
||||
@ -67,7 +69,8 @@ public class Plan extends BukkitPlugin<Plan> {
|
||||
|
||||
private API api;
|
||||
|
||||
private DataCacheHandler handler;
|
||||
private ProcessingQueue processingQueue;
|
||||
private DataCache handler;
|
||||
private InspectCacheHandler inspectCache;
|
||||
private AnalysisCacheHandler analysisCache;
|
||||
private HookHandler hookHandler; // Manages 3rd party data sources
|
||||
@ -141,6 +144,8 @@ public class Plan extends BukkitPlugin<Plan> {
|
||||
saveConfig();
|
||||
Benchmark.stop("Enable", "Copy default config");
|
||||
|
||||
processingQueue = new ProcessingQueue();
|
||||
|
||||
Benchmark.start("Init Database");
|
||||
Log.info(Locale.get(Msg.ENABLE_DB_INIT).toString());
|
||||
if (Check.errorIfFalse(initDatabase(), Locale.get(Msg.ENABLE_DB_FAIL_DISABLE_INFO).toString())) {
|
||||
@ -152,7 +157,7 @@ public class Plan extends BukkitPlugin<Plan> {
|
||||
Benchmark.stop("Enable", "Init Database");
|
||||
|
||||
Benchmark.start("Init DataCache");
|
||||
this.handler = new DataCacheHandler(this);
|
||||
this.handler = new DataCache(this);
|
||||
this.inspectCache = new InspectCacheHandler(this);
|
||||
this.analysisCache = new AnalysisCacheHandler(this);
|
||||
Benchmark.stop("Enable", "Init DataCache");
|
||||
@ -161,9 +166,6 @@ public class Plan extends BukkitPlugin<Plan> {
|
||||
registerListeners();
|
||||
|
||||
this.api = new API(this);
|
||||
Benchmark.start("Handle Reload");
|
||||
handler.handleReload();
|
||||
Benchmark.stop("Enable", "Handle Reload");
|
||||
|
||||
Benchmark.start("Analysis refresh task registration");
|
||||
// Analysis refresh settings
|
||||
@ -392,9 +394,9 @@ public class Plan extends BukkitPlugin<Plan> {
|
||||
/**
|
||||
* Used to access Cache.
|
||||
*
|
||||
* @return Current instance of the DataCacheHandler
|
||||
* @return Current instance of the DataCache
|
||||
*/
|
||||
public DataCacheHandler getHandler() {
|
||||
public DataCache getHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
@ -455,4 +457,12 @@ public class Plan extends BukkitPlugin<Plan> {
|
||||
public ServerVariableHolder getVariable() {
|
||||
return serverVariableHolder;
|
||||
}
|
||||
|
||||
public ProcessingQueue getProcessingQueue() {
|
||||
return processingQueue;
|
||||
}
|
||||
|
||||
public void addToProcessQueue(Processor processor) {
|
||||
processingQueue.addToQueue(processor);
|
||||
}
|
||||
}
|
||||
|
@ -95,57 +95,6 @@ public class API {
|
||||
return HtmlUtils.getInspectUrlWithProtocol(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a UserData object to be fetched from the database or cache if
|
||||
* the player is online.
|
||||
* <p>
|
||||
* The data will not be cached if it is not already cached.
|
||||
*
|
||||
* @param uuid UUID of the player.
|
||||
* @param processor Object implementing DBCallableProcessor, which
|
||||
* process (UserData data) method will be called.
|
||||
*/
|
||||
@Deprecated
|
||||
public void scheduleForGet(UUID uuid, DBCallableProcessor processor) {
|
||||
plugin.getHandler().getUserDataForProcessing(processor, uuid, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a HandlingInfo object to be processed.
|
||||
* <p>
|
||||
* UserData associated with the UUID of the HandlingInfo object will be
|
||||
* cached.
|
||||
*
|
||||
* @param info object that extends HandlingInfo.
|
||||
*/
|
||||
@Deprecated
|
||||
public void scheduleEventHandlingInfo(HandlingInfo info) {
|
||||
plugin.getHandler().addToPool(info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to cache a UserData object.
|
||||
* <p>
|
||||
* If data is already cached it will be overridden.
|
||||
*
|
||||
* @param data UserData object. Will be placed to the data.getUuid() key in
|
||||
* the cache.
|
||||
*/
|
||||
@Deprecated
|
||||
public void placeDataToCache(UserData data) {
|
||||
plugin.getHandler().cache(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to save the cached data to the database.
|
||||
* <p>
|
||||
* Should be only called from an Asynchronous thread.
|
||||
*/
|
||||
@Deprecated
|
||||
public void saveCachedData() {
|
||||
plugin.getHandler().saveCachedUserData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the UserData is cached to the InspectCache.
|
||||
*
|
||||
|
@ -82,7 +82,7 @@ public class ManageClearCommand extends SubCommand {
|
||||
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_START).parse());
|
||||
|
||||
if (database.removeAllData()) {
|
||||
plugin.getHandler().getDataCache().clear();
|
||||
// TODO Clear active session of all users & start new ones
|
||||
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_CLEAR_SUCCESS).toString());
|
||||
} else {
|
||||
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_FAIL).toString());
|
||||
|
@ -84,7 +84,7 @@ public class ManageRemoveCommand extends SubCommand {
|
||||
|
||||
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_START).parse());
|
||||
try {
|
||||
plugin.getHandler().getDataCache().remove(uuid);
|
||||
// TODO Clear active session of user & start new one
|
||||
if (plugin.getDB().removeAccount(uuid.toString())) {
|
||||
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_REMOVE_SUCCESS).parse(playerName, plugin.getDB().getConfigName()));
|
||||
} else {
|
||||
|
@ -2,6 +2,9 @@ package main.java.com.djrapitops.plan.data;
|
||||
|
||||
import main.java.com.djrapitops.plan.data.time.WorldTimes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class is used for storing start and end of a play session inside UserData
|
||||
* object.
|
||||
@ -10,40 +13,48 @@ import main.java.com.djrapitops.plan.data.time.WorldTimes;
|
||||
*/
|
||||
public class SessionData {
|
||||
|
||||
private WorldTimes worldTimes; // TODO add World Times to SessionData
|
||||
private final WorldTimes worldTimes; // TODO add World Times to SessionData
|
||||
private final long sessionStart;
|
||||
private long sessionEnd;
|
||||
// TODO Add kills & deaths to SessionData
|
||||
private final List<KillData> playerKills;
|
||||
private int mobKills;
|
||||
private int deaths;
|
||||
|
||||
|
||||
@Deprecated // TODO Remove
|
||||
public SessionData(long sessionStart) {
|
||||
worldTimes = null;
|
||||
this.sessionStart = 0;
|
||||
playerKills = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new session with given start and end of -1.
|
||||
*
|
||||
* @param sessionStart Epoch millisecond the session was started.
|
||||
*/
|
||||
public SessionData(long sessionStart) {
|
||||
public SessionData(long sessionStart, String world, String gm) {
|
||||
this.worldTimes = new WorldTimes(world, gm);
|
||||
this.sessionStart = sessionStart;
|
||||
this.sessionEnd = -1;
|
||||
playerKills = new ArrayList<>();
|
||||
mobKills = 0;
|
||||
deaths = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new session with given start and end.
|
||||
* Re-Creates a session data object for viewing.
|
||||
*
|
||||
* @param sessionStart Epoch millisecond the session was started.
|
||||
* @param sessionEnd Epoch millisecond the session ended.
|
||||
*/
|
||||
public SessionData(long sessionStart, long sessionEnd) {
|
||||
public SessionData(long sessionStart, long sessionEnd, WorldTimes worldTimes, List<KillData> playerKills, int mobKills, int deaths) {
|
||||
this.sessionStart = sessionStart;
|
||||
this.sessionEnd = sessionEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for copying the object.
|
||||
*
|
||||
* @param s SessionData to copy.
|
||||
*/
|
||||
public SessionData(SessionData s) {
|
||||
this.sessionStart = s.getSessionStart();
|
||||
this.sessionEnd = s.getSessionEnd();
|
||||
this.worldTimes = worldTimes;
|
||||
this.playerKills = playerKills;
|
||||
this.mobKills = mobKills;
|
||||
this.deaths = deaths;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,6 +66,16 @@ public class SessionData {
|
||||
*/
|
||||
public void endSession(long endOfSession) {
|
||||
sessionEnd = endOfSession;
|
||||
worldTimes.updateState(endOfSession);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of the session in milliseconds.
|
||||
*
|
||||
* @return Long in ms.
|
||||
*/
|
||||
public long getLength() {
|
||||
return sessionEnd - sessionStart;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,25 +96,12 @@ public class SessionData {
|
||||
return sessionEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of the session in milliseconds.
|
||||
*
|
||||
* @return Long in ms.
|
||||
*/
|
||||
public long getLength() {
|
||||
return sessionEnd - sessionStart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "s:" + sessionStart + " e:" + sessionEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the session start was before the end.
|
||||
*
|
||||
* @return Is the length positive?
|
||||
*/
|
||||
@Deprecated // TODO Remove
|
||||
public boolean isValid() {
|
||||
return sessionStart <= sessionEnd;
|
||||
}
|
||||
|
@ -247,6 +247,7 @@ public class UserData {
|
||||
*
|
||||
* @param session SessionData object
|
||||
*/
|
||||
@Deprecated
|
||||
public void addSession(SessionData session) {
|
||||
if (Verify.notNull(session) && session.isValid()) {
|
||||
sessions.add(session);
|
||||
|
232
Plan/src/main/java/com/djrapitops/plan/data/cache/DataCache.java
vendored
Normal file
232
Plan/src/main/java/com/djrapitops/plan/data/cache/DataCache.java
vendored
Normal file
@ -0,0 +1,232 @@
|
||||
package main.java.com.djrapitops.plan.data.cache;
|
||||
|
||||
import com.djrapitops.plugin.task.AbsRunnable;
|
||||
import com.djrapitops.plugin.utilities.player.IPlayer;
|
||||
import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.data.TPS;
|
||||
import main.java.com.djrapitops.plan.database.Database;
|
||||
import main.java.com.djrapitops.plan.locale.Locale;
|
||||
import main.java.com.djrapitops.plan.locale.Msg;
|
||||
import main.java.com.djrapitops.plan.queue.processing.Processor;
|
||||
import main.java.com.djrapitops.plan.utilities.Benchmark;
|
||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||
import main.java.com.djrapitops.plan.utilities.analysis.MathUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This Class contains the Cache.
|
||||
* <p>
|
||||
* It is used to store command use, active sessions and Unsaved TPS objects
|
||||
* objects in memory.
|
||||
* <p>
|
||||
* Its methods can be used to access all the data it stores and to clear them.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class DataCache extends SessionCache {
|
||||
|
||||
// Plan
|
||||
private final Plan plugin;
|
||||
private final Database db;
|
||||
|
||||
//Cache
|
||||
private Map<String, Integer> commandUse;
|
||||
private List<List<TPS>> unsavedTPSHistory;
|
||||
|
||||
// Queues
|
||||
|
||||
|
||||
// Variables
|
||||
private boolean periodicTaskIsSaving = false;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
* <p>
|
||||
* Gets the Database from the plugin. Starts the queues. Registers
|
||||
* Asynchronous Periodic Save Task
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public DataCache(Plan plugin) {
|
||||
super(); // Initializes Session & Location cache.
|
||||
|
||||
this.plugin = plugin;
|
||||
db = plugin.getDB();
|
||||
|
||||
commandUse = new HashMap<>();
|
||||
if (!getCommandUseFromDb()) {
|
||||
Log.error(Locale.get(Msg.ENABLE_DB_FAIL_DISABLE_INFO).toString());
|
||||
plugin.disablePlugin();
|
||||
return;
|
||||
}
|
||||
unsavedTPSHistory = new ArrayList<>();
|
||||
startAsyncPeriodicSaveTask();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get the initial commandUse Map from the database.
|
||||
*
|
||||
* @return Was the fetch successful?
|
||||
*/
|
||||
public boolean getCommandUseFromDb() {
|
||||
try {
|
||||
commandUse = db.getCommandUse();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to start the Asynchronous Save Task.
|
||||
*
|
||||
* @throws IllegalArgumentException BukkitRunnable was given wrong
|
||||
* parameters.
|
||||
* @throws IllegalStateException BukkitScheduler is in a wrong state.
|
||||
*/
|
||||
public void startAsyncPeriodicSaveTask() {
|
||||
DataCache handler = this;
|
||||
plugin.getRunnableFactory().createNew(new AbsRunnable("PeriodicCacheSaveTask") {
|
||||
private int timesSaved = 0;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (periodicTaskIsSaving) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
periodicTaskIsSaving = true;
|
||||
Log.debug("Database", "Periodic Cache Save");
|
||||
saveCommandUse();
|
||||
saveUnsavedTPSHistory();
|
||||
timesSaved++;
|
||||
} catch (Exception e) {
|
||||
Log.toLog(this.getClass().getName() + "(" + this.getName() + ")", e);
|
||||
} finally {
|
||||
periodicTaskIsSaving = false;
|
||||
}
|
||||
}
|
||||
}).runTaskTimerAsynchronously(60L * 20L * 5, 60L * 20L * 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves all data in the cache to Database and closes the database down.
|
||||
* <p>
|
||||
* Stops all tasks.
|
||||
* <p>
|
||||
* If processingQueue has unprocessed information, it will be processed.
|
||||
*/
|
||||
@Deprecated
|
||||
public void saveCacheOnDisable() { // TODO Rewrite
|
||||
long time = MiscUtils.getTime();
|
||||
Benchmark.start("Cache: SaveOnDisable");
|
||||
Benchmark.start("Cache: ProcessOnlineHandlingInfo");
|
||||
List<IPlayer> onlinePlayers = plugin.fetch().getOnlinePlayers();
|
||||
Log.debug("Online: " + onlinePlayers.size());
|
||||
for (IPlayer p : onlinePlayers) {
|
||||
UUID uuid = p.getUuid();
|
||||
endSession(uuid);
|
||||
String worldName = ((Player) p.getWrappedPlayerClass()).getWorld().getName();
|
||||
}
|
||||
// toProcess.sort(new HandlingInfoTimeComparator());
|
||||
Benchmark.stop("Cache: ProcessOnlineHandlingInfo");
|
||||
try {
|
||||
db.saveCommandUse(commandUse);
|
||||
} catch (SQLException e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
saveUnsavedTPSHistory();
|
||||
try {
|
||||
db.close();
|
||||
} catch (SQLException e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
Benchmark.stop("Cache: SaveOnDisable");
|
||||
}
|
||||
|
||||
private void processUnprocessedHandlingInfo(List<Processor> toProcess) {
|
||||
Log.debug("PROCESS: " + toProcess.size());
|
||||
for (Processor i : toProcess) {
|
||||
i.process();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the cached CommandUse.
|
||||
* <p>
|
||||
* Should be only called from an Asynchronous Thread.
|
||||
*/
|
||||
public void saveCommandUse() {
|
||||
try {
|
||||
db.saveCommandUse(new HashMap<>(commandUse));
|
||||
} catch (SQLException | NullPointerException e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void saveUnsavedTPSHistory() {
|
||||
List<TPS> averages = calculateAverageTpsForEachMinute();
|
||||
if (averages.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Log.debug("Database", "Periodic TPS Save: " + averages.size());
|
||||
db.getTpsTable().saveTPSData(averages);
|
||||
} catch (SQLException ex) {
|
||||
Log.toLog(this.getClass().getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private List<TPS> calculateAverageTpsForEachMinute() {
|
||||
final List<TPS> averages = new ArrayList<>();
|
||||
if (unsavedTPSHistory.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<List<TPS>> copy = new ArrayList<>(unsavedTPSHistory);
|
||||
|
||||
for (List<TPS> history : copy) {
|
||||
final long lastDate = history.get(history.size() - 1).getDate();
|
||||
final double averageTPS = MathUtils.round(MathUtils.averageDouble(history.stream().map(TPS::getTicksPerSecond)));
|
||||
final int averagePlayersOnline = (int) MathUtils.averageInt(history.stream().map(TPS::getPlayers));
|
||||
final double averageCPUUsage = MathUtils.round(MathUtils.averageDouble(history.stream().map(TPS::getCPUUsage)));
|
||||
final long averageUsedMemory = MathUtils.averageLong(history.stream().map(TPS::getUsedMemory));
|
||||
final int averageEntityCount = (int) MathUtils.averageInt(history.stream().map(TPS::getEntityCount));
|
||||
final int averageChunksLoaded = (int) MathUtils.averageInt(history.stream().map(TPS::getChunksLoaded));
|
||||
|
||||
averages.add(new TPS(lastDate, averageTPS, averagePlayersOnline, averageCPUUsage, averageUsedMemory, averageEntityCount, averageChunksLoaded));
|
||||
}
|
||||
unsavedTPSHistory.removeAll(copy);
|
||||
return averages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get the cached commandUse.
|
||||
*
|
||||
* @return Map with key:value - "/command":4
|
||||
*/
|
||||
public Map<String, Integer> getCommandUse() {
|
||||
return commandUse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to handle a command's execution.
|
||||
*
|
||||
* @param command "/command"
|
||||
*/
|
||||
public void handleCommand(String command) {
|
||||
int amount = commandUse.getOrDefault(command, 0);
|
||||
|
||||
commandUse.put(command, amount + 1);
|
||||
}
|
||||
|
||||
public void addTPSLastMinute(List<TPS> history) {
|
||||
// Copy the contents to avoid reference, thus making the whole calculation pointless.
|
||||
unsavedTPSHistory.add(new ArrayList<>(history));
|
||||
}
|
||||
}
|
@ -1,531 +0,0 @@
|
||||
package main.java.com.djrapitops.plan.data.cache;
|
||||
|
||||
import com.djrapitops.plugin.task.AbsRunnable;
|
||||
import com.djrapitops.plugin.utilities.player.IPlayer;
|
||||
import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.data.TPS;
|
||||
import main.java.com.djrapitops.plan.data.UserData;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.HandlingInfo;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.LogoutInfo;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.ReloadInfo;
|
||||
import main.java.com.djrapitops.plan.database.Database;
|
||||
import main.java.com.djrapitops.plan.locale.Locale;
|
||||
import main.java.com.djrapitops.plan.locale.Msg;
|
||||
import main.java.com.djrapitops.plan.queue.DataCacheClearQueue;
|
||||
import main.java.com.djrapitops.plan.queue.DataCacheGetQueue;
|
||||
import main.java.com.djrapitops.plan.queue.DataCacheProcessQueue;
|
||||
import main.java.com.djrapitops.plan.queue.DataCacheSaveQueue;
|
||||
import main.java.com.djrapitops.plan.queue.processing.Processor;
|
||||
import main.java.com.djrapitops.plan.utilities.Benchmark;
|
||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||
import main.java.com.djrapitops.plan.utilities.NewPlayerCreator;
|
||||
import main.java.com.djrapitops.plan.utilities.analysis.MathUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This Class contains the Cache.
|
||||
* <p>
|
||||
* This class is the main processing class that initialises Save, Clear, Process
|
||||
* and Get queue and Starts the asynchronous save task.
|
||||
* <p>
|
||||
* It is used to store command use, locations, active sessions and UserData
|
||||
* objects in memory.
|
||||
* <p>
|
||||
* Its methods can be used to access all the data it stores and to clear them.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class DataCacheHandler extends SessionCache {
|
||||
|
||||
// Cache
|
||||
private final Map<UUID, UserData> dataCache;
|
||||
|
||||
// Plan
|
||||
private final Plan plugin;
|
||||
private final Database db;
|
||||
|
||||
//Cache
|
||||
private Map<String, Integer> commandUse;
|
||||
private List<List<TPS>> unsavedTPSHistory;
|
||||
|
||||
// Queues
|
||||
private DataCacheSaveQueue saveTask;
|
||||
private DataCacheClearQueue clearTask;
|
||||
private DataCacheProcessQueue processTask;
|
||||
private DataCacheGetQueue getTask;
|
||||
|
||||
// Variables
|
||||
private boolean periodicTaskIsSaving = false;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
* <p>
|
||||
* Gets the Database from the plugin. Starts the queues. Registers
|
||||
* Asynchronous Periodic Save Task
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public DataCacheHandler(Plan plugin) {
|
||||
super(); // Initializes Session & Location cache.
|
||||
|
||||
this.plugin = plugin;
|
||||
db = plugin.getDB();
|
||||
|
||||
dataCache = new HashMap<>();
|
||||
startQueues();
|
||||
|
||||
commandUse = new HashMap<>();
|
||||
if (!getCommandUseFromDb()) {
|
||||
Log.error(Locale.get(Msg.ENABLE_DB_FAIL_DISABLE_INFO).toString());
|
||||
plugin.disablePlugin();
|
||||
return;
|
||||
}
|
||||
unsavedTPSHistory = new ArrayList<>();
|
||||
startAsyncPeriodicSaveTask();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get the initial commandUse Map from the database.
|
||||
*
|
||||
* @return Was the fetch successful?
|
||||
*/
|
||||
public boolean getCommandUseFromDb() {
|
||||
try {
|
||||
commandUse = db.getCommandUse();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to start all processing Queue Threads.
|
||||
*/
|
||||
public void startQueues() {
|
||||
getTask = new DataCacheGetQueue(plugin);
|
||||
processTask = new DataCacheProcessQueue();
|
||||
clearTask = new DataCacheClearQueue(this);
|
||||
saveTask = new DataCacheSaveQueue(plugin, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to start the Asynchronous Save Task.
|
||||
*
|
||||
* @throws IllegalArgumentException BukkitRunnable was given wrong
|
||||
* parameters.
|
||||
* @throws IllegalStateException BukkitScheduler is in a wrong state.
|
||||
*/
|
||||
public void startAsyncPeriodicSaveTask() {
|
||||
DataCacheHandler handler = this;
|
||||
plugin.getRunnableFactory().createNew(new AbsRunnable("PeriodicCacheSaveTask") {
|
||||
private int timesSaved = 0;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (periodicTaskIsSaving) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
periodicTaskIsSaving = true;
|
||||
Log.debug("Database", "Periodic Cache Save: " + dataCache.size());
|
||||
handler.saveHandlerDataToCache();
|
||||
handler.saveCachedUserData();
|
||||
saveCommandUse();
|
||||
saveUnsavedTPSHistory();
|
||||
timesSaved++;
|
||||
} catch (Exception e) {
|
||||
Log.toLog(this.getClass().getName() + "(" + this.getName() + ")", e);
|
||||
} finally {
|
||||
periodicTaskIsSaving = false;
|
||||
}
|
||||
}
|
||||
}).runTaskTimerAsynchronously(60L * 20L * 5, 60L * 20L * 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses Database or Cache to retrieve the UserData of a matching player.
|
||||
* <p>
|
||||
* Caches the data to the Cache if cache-parameter is true.
|
||||
*
|
||||
* @param processor DBCallableProcessor Object used to process the data
|
||||
* after it was retrieved
|
||||
* @param uuid Player's UUID
|
||||
* @param cache Whether or not the UserData will be Cached in this instance
|
||||
* of DataCacheHandler after it has been fetched (if not already fetched)
|
||||
*/
|
||||
public void getUserDataForProcessing(DBCallableProcessor processor, UUID uuid, boolean cache) {
|
||||
UserData uData = dataCache.get(uuid);
|
||||
if (uData == null) {
|
||||
if (cache) {
|
||||
DBCallableProcessor cacher = this::cache;
|
||||
getTask.scheduleForGet(uuid, cacher, processor);
|
||||
} else {
|
||||
getTask.scheduleForGet(uuid, processor);
|
||||
}
|
||||
} else {
|
||||
processor.process(uData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to Cache a UserData object to the Cache.
|
||||
* <p>
|
||||
* If a object already exists it will be replaced.
|
||||
*
|
||||
* @param data UserData object with the UUID inside used as key.
|
||||
*/
|
||||
public void cache(UserData data) {
|
||||
data.setOnline(true);
|
||||
dataCache.put(data.getUuid(), data);
|
||||
Log.debug("Added " + data.getUuid().toString() + " to Cache.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses Database or Cache to retrieve the UserData of a matching player.
|
||||
* <p>
|
||||
* Always Caches the data after retrieval (unless already cached)
|
||||
*
|
||||
* @param processor DBCallableProcessor Object used to process the data
|
||||
* after it was retrieved
|
||||
* @param uuid Player's UUID
|
||||
*/
|
||||
public void getUserDataForProcessing(DBCallableProcessor processor, UUID uuid) {
|
||||
getUserDataForProcessing(processor, uuid, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves all UserData in the cache to Database.
|
||||
* <p>
|
||||
* Should only be called from Async thread
|
||||
*/
|
||||
public void saveCachedUserData() {
|
||||
Set<UserData> data = new HashSet<>();
|
||||
data.addAll(dataCache.values());
|
||||
try {
|
||||
db.saveMultipleUserData(data);
|
||||
} catch (SQLException ex) {
|
||||
Log.toLog(this.getClass().getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to add event HandlingInfo to the processTask's pool.
|
||||
* <p>
|
||||
* Given HandlingInfo object's process method will be called.
|
||||
*
|
||||
* @param i Object that extends HandlingInfo.
|
||||
*/
|
||||
@Deprecated
|
||||
public void addToPool(HandlingInfo i) {
|
||||
if (i == null) {
|
||||
return;
|
||||
}
|
||||
processTask.addToQueue(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves all data in the cache to Database and closes the database down.
|
||||
* <p>
|
||||
* Stops all tasks.
|
||||
* <p>
|
||||
* If processTask has unprocessed information, it will be processed.
|
||||
*/
|
||||
public void saveCacheOnDisable() {
|
||||
long time = MiscUtils.getTime();
|
||||
Benchmark.start("Cache: SaveOnDisable");
|
||||
saveTask.stop();
|
||||
getTask.stop();
|
||||
clearTask.stop();
|
||||
List<Processor> toProcess = processTask.stopAndReturnLeftovers();
|
||||
Benchmark.start("Cache: ProcessOnlineHandlingInfo");
|
||||
Log.debug("ToProcess size: " + toProcess.size() + " DataCache size: " + dataCache.keySet().size());
|
||||
List<IPlayer> onlinePlayers = plugin.fetch().getOnlinePlayers();
|
||||
Log.debug("Online: " + onlinePlayers.size());
|
||||
for (IPlayer p : onlinePlayers) {
|
||||
UUID uuid = p.getUuid();
|
||||
endSession(uuid);
|
||||
String worldName = ((Player) p.getWrappedPlayerClass()).getWorld().getName();
|
||||
toProcess.add(new LogoutInfo(uuid, time, p.isBanned(), p.getGamemode().name(), getSession(uuid), worldName));
|
||||
}
|
||||
Log.debug("ToProcess size_AFTER: " + toProcess.size() + " DataCache size: " + dataCache.keySet().size());
|
||||
// toProcess.sort(new HandlingInfoTimeComparator());
|
||||
processUnprocessedHandlingInfo(toProcess);
|
||||
Benchmark.stop("Cache: ProcessOnlineHandlingInfo");
|
||||
List<UserData> data = new ArrayList<>();
|
||||
data.addAll(dataCache.values());
|
||||
Log.debug("SAVING, DataCache size: " + dataCache.keySet().size());
|
||||
try {
|
||||
db.saveCommandUse(commandUse);
|
||||
} catch (SQLException e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
try {
|
||||
db.saveMultipleUserData(data);
|
||||
} catch (SQLException e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
saveUnsavedTPSHistory();
|
||||
try {
|
||||
db.close();
|
||||
} catch (SQLException e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
Benchmark.stop("Cache: SaveOnDisable");
|
||||
}
|
||||
|
||||
private void processUnprocessedHandlingInfo(List<Processor> toProcess) {
|
||||
Log.debug("PROCESS: " + toProcess.size());
|
||||
for (Processor i : toProcess) {
|
||||
i.process();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the cached data of matching Player if it is in the cache.
|
||||
*
|
||||
* @param uuid Player's UUID
|
||||
*/
|
||||
public void saveCachedData(UUID uuid) {
|
||||
DBCallableProcessor saveProcessor = data -> {
|
||||
data.access();
|
||||
data.setClearAfterSave(true);
|
||||
saveTask.scheduleForSave(data);
|
||||
};
|
||||
getUserDataForProcessing(saveProcessor, uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the cached CommandUse.
|
||||
* <p>
|
||||
* Should be only called from an Asynchronous Thread.
|
||||
*/
|
||||
public void saveCommandUse() {
|
||||
try {
|
||||
db.saveCommandUse(new HashMap<>(commandUse));
|
||||
} catch (SQLException | NullPointerException e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void saveUnsavedTPSHistory() {
|
||||
List<TPS> averages = calculateAverageTpsForEachMinute();
|
||||
if (averages.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Log.debug("Database", "Periodic TPS Save: " + averages.size());
|
||||
db.getTpsTable().saveTPSData(averages);
|
||||
} catch (SQLException ex) {
|
||||
Log.toLog(this.getClass().getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private List<TPS> calculateAverageTpsForEachMinute() {
|
||||
final List<TPS> averages = new ArrayList<>();
|
||||
if (unsavedTPSHistory.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<List<TPS>> copy = new ArrayList<>(unsavedTPSHistory);
|
||||
|
||||
for (List<TPS> history : copy) {
|
||||
final long lastDate = history.get(history.size() - 1).getDate();
|
||||
final double averageTPS = MathUtils.round(MathUtils.averageDouble(history.stream().map(TPS::getTicksPerSecond)));
|
||||
final int averagePlayersOnline = (int) MathUtils.averageInt(history.stream().map(TPS::getPlayers));
|
||||
final double averageCPUUsage = MathUtils.round(MathUtils.averageDouble(history.stream().map(TPS::getCPUUsage)));
|
||||
final long averageUsedMemory = MathUtils.averageLong(history.stream().map(TPS::getUsedMemory));
|
||||
final int averageEntityCount = (int) MathUtils.averageInt(history.stream().map(TPS::getEntityCount));
|
||||
final int averageChunksLoaded = (int) MathUtils.averageInt(history.stream().map(TPS::getChunksLoaded));
|
||||
|
||||
averages.add(new TPS(lastDate, averageTPS, averagePlayersOnline, averageCPUUsage, averageUsedMemory, averageEntityCount, averageChunksLoaded));
|
||||
}
|
||||
unsavedTPSHistory.removeAll(copy);
|
||||
return averages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the calculations for all online players with ReloadInfo.
|
||||
*/
|
||||
public void saveHandlerDataToCache() {
|
||||
final List<IPlayer> onlinePlayers = plugin.fetch().getOnlinePlayers();
|
||||
onlinePlayers.forEach(p -> saveHandlerDataToCache(p, false));
|
||||
}
|
||||
|
||||
private void saveHandlerDataToCache(IPlayer p, boolean pool) {
|
||||
long time = MiscUtils.getTime();
|
||||
UUID uuid = p.getUuid();
|
||||
String worldName = ((Player) p.getWrappedPlayerClass()).getWorld().getName();
|
||||
ReloadInfo info = new ReloadInfo(uuid, time, p.getAddress().getAddress(), p.isBanned(), p.getDisplayName(), p.getGamemode().name(), worldName);
|
||||
if (!pool) {
|
||||
UserData data = dataCache.get(uuid);
|
||||
if (data != null) {
|
||||
info.process(data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
addToPool(info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules all UserData from the Cache to be cleared.
|
||||
*/
|
||||
public void clearCache() {
|
||||
clearTask.scheduleForClear(dataCache.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the matching UserData from the Cache if they're not online.
|
||||
*
|
||||
* @param uuid Player's UUID
|
||||
*/
|
||||
public void clearFromCache(UUID uuid) {
|
||||
if (plugin.fetch().isOnline(uuid)) {
|
||||
UserData data = dataCache.get(uuid);
|
||||
if (data != null) {
|
||||
data.setClearAfterSave(false);
|
||||
}
|
||||
} else {
|
||||
dataCache.remove(uuid);
|
||||
Log.debug("Cleared " + uuid.toString() + " from Cache.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a matching UserData object to be cleared from the cache.
|
||||
*
|
||||
* @param uuid Player's UUID.
|
||||
*/
|
||||
public void scheduldeForClear(UUID uuid) {
|
||||
clearTask.scheduleForClear(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether or not the UserData object is being accessed by save or
|
||||
* process tasks.
|
||||
*
|
||||
* @param uuid Player's UUID
|
||||
* @return true/false
|
||||
*/
|
||||
public boolean isDataAccessed(UUID uuid) {
|
||||
UserData userData = dataCache.get(uuid);
|
||||
if (userData == null) {
|
||||
return false;
|
||||
}
|
||||
/*TODO boolean isAccessed = (userData.isAccessed()) || saveTask.containsUUID(uuid) || processTask.containsUUID(uuid);
|
||||
if (isAccessed) {
|
||||
userData.setClearAfterSave(false);
|
||||
}
|
||||
return isAccessed;*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new UserData instance and saves it to the Database.
|
||||
*
|
||||
* @param player Player the new UserData is created for
|
||||
*/
|
||||
public void newPlayer(IPlayer player) {
|
||||
newPlayer(NewPlayerCreator.createNewPlayer(player));
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a new player's data to be saved to the Database.
|
||||
*
|
||||
* @param data UserData object to schedule for save.
|
||||
*/
|
||||
public void newPlayer(UserData data) {
|
||||
saveTask.scheduleNewPlayer(data);
|
||||
cache(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get the contents of the cache.
|
||||
*
|
||||
* @return The Map containing all Cached UserData
|
||||
*/
|
||||
public Map<UUID, UserData> getDataCache() {
|
||||
return dataCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get the cached commandUse.
|
||||
*
|
||||
* @return Map with key:value - "/command":4
|
||||
*/
|
||||
public Map<String, Integer> getCommandUse() {
|
||||
return commandUse;
|
||||
}
|
||||
|
||||
/**
|
||||
* If /reload is run this treats every online player as a new login.
|
||||
* <p>
|
||||
* Calls all the methods that are ran when PlayerJoinEvent is fired
|
||||
*/
|
||||
public void handleReload() {
|
||||
plugin.getRunnableFactory().createNew(new AbsRunnable("ReloadCacheUpdateTask") {
|
||||
@Override
|
||||
public void run() {
|
||||
final List<IPlayer> onlinePlayers = plugin.fetch().getOnlinePlayers();
|
||||
for (IPlayer player : onlinePlayers) {
|
||||
UUID uuid = player.getUuid();
|
||||
boolean isNewPlayer = !db.wasSeenBefore(uuid);
|
||||
if (isNewPlayer) {
|
||||
newPlayer(player);
|
||||
}
|
||||
startSession(uuid);
|
||||
saveHandlerDataToCache(player, true);
|
||||
}
|
||||
this.cancel();
|
||||
}
|
||||
}).runTaskAsynchronously();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to handle a command's execution.
|
||||
*
|
||||
* @param command "/command"
|
||||
*/
|
||||
public void handleCommand(String command) {
|
||||
int amount = commandUse.getOrDefault(command, 0);
|
||||
|
||||
commandUse.put(command, amount + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The SaveTask
|
||||
*/
|
||||
public DataCacheSaveQueue getSaveTask() {
|
||||
return saveTask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The ClearTask
|
||||
*/
|
||||
public DataCacheClearQueue getClearTask() {
|
||||
return clearTask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The ProcessTask
|
||||
*/
|
||||
public DataCacheProcessQueue getProcessTask() {
|
||||
return processTask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The GetTask
|
||||
*/
|
||||
public DataCacheGetQueue getGetTask() {
|
||||
return getTask;
|
||||
}
|
||||
|
||||
public void addTPSLastMinute(List<TPS> history) {
|
||||
// Copy the contents to avoid reference, thus making the whole calculation pointless.
|
||||
unsavedTPSHistory.add(new ArrayList<>(history));
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ import java.util.*;
|
||||
@Deprecated
|
||||
public class InspectCacheHandler {
|
||||
|
||||
private final DataCacheHandler handler;
|
||||
private final DataCache handler;
|
||||
private final Map<UUID, UserData> cache;
|
||||
private final Map<UUID, Long> cacheTimes;
|
||||
|
||||
@ -46,6 +46,7 @@ public class InspectCacheHandler {
|
||||
*
|
||||
* @param uuid UUID of the player.
|
||||
*/
|
||||
@Deprecated // Does not cache anything anymore // TODO Remove
|
||||
public void cache(UUID uuid) {
|
||||
DBCallableProcessor cacher = data -> {
|
||||
UserData userData = new UserData(data);
|
||||
@ -62,8 +63,6 @@ public class InspectCacheHandler {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
};
|
||||
|
||||
handler.getUserDataForProcessing(cacher, uuid, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,18 +73,7 @@ public class InspectCacheHandler {
|
||||
* @throws SQLException If Database is not properly enabled
|
||||
*/
|
||||
public void cacheAllUserData(Database db) throws SQLException {
|
||||
Set<UUID> cachedUserData = handler.getDataCache().keySet();
|
||||
for (UUID uuid : cachedUserData) {
|
||||
cache(uuid);
|
||||
}
|
||||
Set<UUID> savedUUIDs = new HashSet<>();
|
||||
try {
|
||||
savedUUIDs = db.getUsersTable().getSavedUUIDs();
|
||||
} catch (SQLException ex) {
|
||||
Log.toLog(this.getClass().getName(), ex);
|
||||
}
|
||||
savedUUIDs.removeAll(cachedUserData);
|
||||
List<UserData> userDataForUUIDS = db.getUserDataForUUIDS(savedUUIDs);
|
||||
List<UserData> userDataForUUIDS = db.getUserDataForUUIDS(db.getUsersTable().getSavedUUIDs());
|
||||
long time = MiscUtils.getTime();
|
||||
for (UserData uData : userDataForUUIDS) {
|
||||
UUID uuid = uData.getUuid();
|
||||
|
@ -2,7 +2,6 @@ package main.java.com.djrapitops.plan.data.cache;
|
||||
|
||||
import main.java.com.djrapitops.plan.data.SessionData;
|
||||
import main.java.com.djrapitops.plan.data.UserData;
|
||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -22,6 +21,18 @@ public class SessionCache {
|
||||
* Class Constructor.
|
||||
*/
|
||||
public SessionCache() {
|
||||
}
|
||||
|
||||
public void cacheSession(UUID uuid, SessionData session) {
|
||||
activeSessions.put(uuid, session);
|
||||
}
|
||||
|
||||
public void endSession(UUID uuid, long time) {
|
||||
SessionData session = activeSessions.get(uuid);
|
||||
if (session == null) {
|
||||
return;
|
||||
}
|
||||
session.endSession(time);
|
||||
|
||||
}
|
||||
|
||||
@ -30,9 +41,8 @@ public class SessionCache {
|
||||
*
|
||||
* @param uuid UUID of the player.
|
||||
*/
|
||||
@Deprecated
|
||||
public void startSession(UUID uuid) {
|
||||
SessionData session = new SessionData(MiscUtils.getTime());
|
||||
activeSessions.put(uuid, session);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -40,11 +50,8 @@ public class SessionCache {
|
||||
*
|
||||
* @param uuid UUID of the player.
|
||||
*/
|
||||
@Deprecated
|
||||
public void endSession(UUID uuid) {
|
||||
SessionData currentSession = activeSessions.get(uuid);
|
||||
if (currentSession != null) {
|
||||
currentSession.endSession(MiscUtils.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,6 +60,7 @@ public class SessionCache {
|
||||
* @param uuid UUID of the player.
|
||||
* @return SessionData or null if not cached.
|
||||
*/
|
||||
@Deprecated
|
||||
public SessionData getSession(UUID uuid) {
|
||||
return activeSessions.get(uuid);
|
||||
}
|
||||
@ -62,6 +70,7 @@ public class SessionCache {
|
||||
*
|
||||
* @param data UserData object a session should be added to.
|
||||
*/
|
||||
@Deprecated
|
||||
public void addSession(UserData data) {
|
||||
UUID uuid = data.getUuid();
|
||||
SessionData currentSession = activeSessions.get(uuid);
|
||||
@ -78,6 +87,7 @@ public class SessionCache {
|
||||
*
|
||||
* @return key:value UUID:SessionData
|
||||
*/
|
||||
@Deprecated
|
||||
public Map<UUID, SessionData> getActiveSessions() {
|
||||
return activeSessions;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import com.djrapitops.plugin.utilities.player.IOfflinePlayer;
|
||||
import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.data.UserData;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCache;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.HandlingInfo;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.InfoType;
|
||||
import main.java.com.djrapitops.plan.database.Database;
|
||||
@ -51,7 +51,7 @@ public abstract class Importer {
|
||||
plan.getAnalysisCache().disableAnalysisTemporarily();
|
||||
String processName = "Import, " + getClass().getSimpleName();
|
||||
try {
|
||||
DataCacheHandler handler = plan.getHandler();
|
||||
DataCache handler = plan.getHandler();
|
||||
Database db = plan.getDB();
|
||||
|
||||
Benchmark.start(processName);
|
||||
@ -103,7 +103,7 @@ public abstract class Importer {
|
||||
plan.getDB().saveMultipleUserData(newUsers);
|
||||
|
||||
for (UUID uuid : uuids) {
|
||||
handler.addToPool(importData(uuid, args));
|
||||
Plan.getInstance().addToProcessQueue(importData(uuid, args));
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
Log.toLog(this.getClass().getName(), ex);
|
||||
|
@ -1,6 +1,5 @@
|
||||
package main.java.com.djrapitops.plan.data.handling.info;
|
||||
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.data.UserData;
|
||||
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
|
||||
import main.java.com.djrapitops.plan.queue.processing.Processor;
|
||||
@ -14,7 +13,8 @@ import java.util.UUID;
|
||||
* @author Rsl1122
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public abstract class HandlingInfo extends Processor<UUID> implements DBCallableProcessor{
|
||||
// TODO Rewrite all HandlingInfo objects to only extend Processor
|
||||
public abstract class HandlingInfo extends Processor<UUID> implements DBCallableProcessor {
|
||||
|
||||
final UUID uuid;
|
||||
final InfoType type;
|
||||
@ -63,7 +63,6 @@ public abstract class HandlingInfo extends Processor<UUID> implements DBCallable
|
||||
}
|
||||
|
||||
public void process() {
|
||||
Plan.getInstance().getHandler().getUserDataForProcessing(this, uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,6 @@
|
||||
package main.java.com.djrapitops.plan.data.listeners;
|
||||
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.ChatInfo;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -16,7 +15,7 @@ import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
*/
|
||||
public class PlanChatListener implements Listener {
|
||||
|
||||
private final DataCacheHandler handler;
|
||||
private Plan plugin;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
@ -24,7 +23,7 @@ public class PlanChatListener implements Listener {
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public PlanChatListener(Plan plugin) {
|
||||
handler = plugin.getHandler();
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -39,6 +38,6 @@ public class PlanChatListener implements Listener {
|
||||
}
|
||||
|
||||
Player p = event.getPlayer();
|
||||
handler.addToPool(new ChatInfo(p.getUniqueId(), p.getDisplayName()));
|
||||
plugin.addToProcessQueue(new ChatInfo(p.getUniqueId(), p.getDisplayName()));
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.Permissions;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.Settings;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCache;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -20,7 +20,7 @@ import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
public class PlanCommandPreprocessListener implements Listener {
|
||||
|
||||
private final Plan plugin;
|
||||
private final DataCacheHandler handler;
|
||||
private final DataCache handler;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
|
@ -1,7 +1,6 @@
|
||||
package main.java.com.djrapitops.plan.data.listeners;
|
||||
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.handling.KillHandling;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.DeathInfo;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.KillInfo;
|
||||
@ -22,7 +21,7 @@ import org.bukkit.event.entity.EntityDeathEvent;
|
||||
*/
|
||||
public class PlanDeathEventListener implements Listener {
|
||||
|
||||
private final DataCacheHandler handler;
|
||||
private final Plan plugin;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
@ -30,7 +29,7 @@ public class PlanDeathEventListener implements Listener {
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public PlanDeathEventListener(Plan plugin) {
|
||||
this.handler = plugin.getHandler();
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,7 +44,7 @@ public class PlanDeathEventListener implements Listener {
|
||||
LivingEntity dead = event.getEntity();
|
||||
|
||||
if (dead instanceof Player) {
|
||||
handler.addToPool(new DeathInfo(dead.getUniqueId()));
|
||||
plugin.addToProcessQueue(new DeathInfo(dead.getUniqueId()));
|
||||
}
|
||||
|
||||
EntityDamageEvent entityDamageEvent = dead.getLastDamageCause();
|
||||
@ -69,7 +68,7 @@ public class PlanDeathEventListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
handler.addToPool(new KillInfo(killer.getUniqueId(), time, dead, KillHandling.normalizeMaterialName(itemInHand)));
|
||||
plugin.addToProcessQueue(new KillInfo(killer.getUniqueId(), time, dead, KillHandling.normalizeMaterialName(itemInHand)));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -86,7 +85,7 @@ public class PlanDeathEventListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
handler.addToPool(new KillInfo(owner.getUniqueId(), time, dead, "Wolf"));
|
||||
plugin.addToProcessQueue(new KillInfo(owner.getUniqueId(), time, dead, "Wolf"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package main.java.com.djrapitops.plan.data.listeners;
|
||||
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.InfoType;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.PlaytimeDependentInfo;
|
||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||
@ -20,7 +19,7 @@ import java.util.UUID;
|
||||
*/
|
||||
public class PlanGamemodeChangeListener implements Listener {
|
||||
|
||||
private final DataCacheHandler handler;
|
||||
private final Plan plugin;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
@ -28,7 +27,7 @@ public class PlanGamemodeChangeListener implements Listener {
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public PlanGamemodeChangeListener(Plan plugin) {
|
||||
handler = plugin.getHandler();
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -48,6 +47,6 @@ public class PlanGamemodeChangeListener implements Listener {
|
||||
String gameMode = event.getNewGameMode().name();
|
||||
String worldName = p.getWorld().getName();
|
||||
|
||||
handler.addToPool(new PlaytimeDependentInfo(uuid, InfoType.GM, time, gameMode, worldName));
|
||||
plugin.addToProcessQueue(new PlaytimeDependentInfo(uuid, InfoType.GM, time, gameMode, worldName));
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import com.djrapitops.plugin.utilities.player.Gamemode;
|
||||
import com.djrapitops.plugin.utilities.player.IPlayer;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.data.UserData;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCache;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.KickInfo;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.LoginInfo;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.LogoutInfo;
|
||||
@ -32,7 +32,7 @@ import java.util.UUID;
|
||||
public class PlanPlayerListener implements Listener {
|
||||
|
||||
private final Plan plugin;
|
||||
private final DataCacheHandler handler;
|
||||
private final DataCache handler;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
@ -80,9 +80,9 @@ public class PlanPlayerListener implements Listener {
|
||||
if (isNewPlayer) {
|
||||
UserData newUserData = NewPlayerCreator.createNewPlayer(iPlayer);
|
||||
loginInfo.process(newUserData);
|
||||
handler.newPlayer(newUserData);
|
||||
// TODO Rewrite Register & Login system handler.newPlayer(newUserData);
|
||||
} else {
|
||||
handler.addToPool(loginInfo);
|
||||
// handler.addToPool(loginInfo);
|
||||
}
|
||||
this.cancel();
|
||||
}
|
||||
@ -98,6 +98,7 @@ public class PlanPlayerListener implements Listener {
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
// TODO Rewrite Logout system
|
||||
Player player = event.getPlayer();
|
||||
UUID uuid = player.getUniqueId();
|
||||
handler.endSession(uuid);
|
||||
@ -107,8 +108,7 @@ public class PlanPlayerListener implements Listener {
|
||||
Gamemode gm = Gamemode.wrap(player.getGameMode());
|
||||
String worldName = player.getWorld().getName();
|
||||
|
||||
handler.addToPool(new LogoutInfo(uuid, time, banned, gm.name(), handler.getSession(uuid), worldName));
|
||||
handler.saveCachedData(uuid);
|
||||
plugin.addToProcessQueue(new LogoutInfo(uuid, time, banned, gm.name(), handler.getSession(uuid), worldName));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,8 +134,7 @@ public class PlanPlayerListener implements Listener {
|
||||
Gamemode gm = Gamemode.wrap(player.getGameMode());
|
||||
String worldName = player.getWorld().getName();
|
||||
|
||||
handler.addToPool(new LogoutInfo(uuid, time, banned, gm.name(), handler.getSession(uuid), worldName));
|
||||
handler.addToPool(new KickInfo(uuid));
|
||||
handler.saveCachedData(uuid);
|
||||
plugin.addToProcessQueue(new LogoutInfo(uuid, time, banned, gm.name(), handler.getSession(uuid), worldName));
|
||||
plugin.addToProcessQueue(new KickInfo(uuid));
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package main.java.com.djrapitops.plan.data.listeners;
|
||||
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.InfoType;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.PlaytimeDependentInfo;
|
||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||
@ -14,10 +13,10 @@ import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlanWorldChangeListener implements Listener {
|
||||
private final DataCacheHandler handler;
|
||||
private final Plan plugin;
|
||||
|
||||
public PlanWorldChangeListener(Plan plugin) {
|
||||
this.handler = plugin.getHandler();
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
@ -34,6 +33,6 @@ public class PlanWorldChangeListener implements Listener {
|
||||
String gameMode = p.getGameMode().name();
|
||||
long time = MiscUtils.getTime();
|
||||
|
||||
handler.addToPool(new PlaytimeDependentInfo(uuid, InfoType.WORLD, time, gameMode, worldName));
|
||||
plugin.addToProcessQueue(new PlaytimeDependentInfo(uuid, InfoType.WORLD, time, gameMode, worldName));
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import com.djrapitops.plugin.task.AbsRunnable;
|
||||
import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.data.TPS;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCache;
|
||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||
import main.java.com.djrapitops.plan.utilities.analysis.MathUtils;
|
||||
import org.bukkit.World;
|
||||
@ -23,7 +23,7 @@ import java.util.List;
|
||||
public class TPSCountTimer extends AbsRunnable {
|
||||
|
||||
private final Plan plugin;
|
||||
private final DataCacheHandler handler;
|
||||
private final DataCache handler;
|
||||
private final List<TPS> history;
|
||||
private long lastCheckNano;
|
||||
|
||||
|
@ -43,11 +43,21 @@ public class WorldTimes {
|
||||
worldTimes.put(worldName, new GMTimes(gameMode, changeTime));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the state at the end of the session.
|
||||
* Does not change world or GameMode.
|
||||
*
|
||||
* @param changeTime epoch ms session ended.
|
||||
*/
|
||||
public void updateState(long changeTime) {
|
||||
updateState(currentWorld, currentGamemode, changeTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the time status to match the new state.
|
||||
*
|
||||
* @param worldName World name of the world swapped to.
|
||||
* @param gameMode GameMode name of the gm swapped to.
|
||||
* @param worldName World name of the world swapped to.
|
||||
* @param gameMode GameMode name of the gm swapped to.
|
||||
* @param changeTime Epoch ms the change occurred.
|
||||
*/
|
||||
public void updateState(String worldName, String gameMode, long changeTime) {
|
||||
|
@ -75,7 +75,7 @@ public class SessionsTable extends UserIDTable {
|
||||
set = statement.executeQuery();
|
||||
List<SessionData> sessions = new ArrayList<>();
|
||||
while (set.next()) {
|
||||
sessions.add(new SessionData(set.getLong(columnSessionStart), set.getLong(columnSessionEnd)));
|
||||
// sessions.add(new SessionData(set.getLong(columnSessionStart), set.getLong(columnSessionEnd)));
|
||||
}
|
||||
set.close();
|
||||
statement.close();
|
||||
@ -169,7 +169,7 @@ public class SessionsTable extends UserIDTable {
|
||||
long sessionStart = set.getLong(columnSessionStart);
|
||||
long sessionEnd = set.getLong(columnSessionEnd);
|
||||
|
||||
sessions.get(id).add(new SessionData(sessionStart, sessionEnd));
|
||||
// sessions.get(id).add(new SessionData(sessionStart, sessionEnd));
|
||||
}
|
||||
|
||||
return sessions;
|
||||
|
@ -1,102 +0,0 @@
|
||||
package main.java.com.djrapitops.plan.queue;
|
||||
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
|
||||
import main.java.com.djrapitops.plan.locale.Locale;
|
||||
import main.java.com.djrapitops.plan.locale.Msg;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* This Class contains the Clear Queue Thread, which is clearing data from the DataCache.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class DataCacheClearQueue extends Queue<UUID> {
|
||||
|
||||
/**
|
||||
* Class constructor, starts the new Thread for clearing.
|
||||
*
|
||||
* @param handler current instance of DataCacheHandler.
|
||||
*/
|
||||
public DataCacheClearQueue(DataCacheHandler handler) {
|
||||
super(new ArrayBlockingQueue<>(20000));
|
||||
setup = new ClearSetup(queue, handler);
|
||||
setup.go();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to schedule UserData to be cleared from the cache.
|
||||
*
|
||||
* @param uuid UUID of the UserData object (Player's UUID)
|
||||
*/
|
||||
public void scheduleForClear(UUID uuid) {
|
||||
queue.add(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to schedule multiple UserData objects to be cleared from the cache.
|
||||
*
|
||||
* @param uuids UUIDs of the UserData object (Players' UUIDs)
|
||||
*/
|
||||
public void scheduleForClear(Collection<UUID> uuids) {
|
||||
if (Verify.isEmpty(uuids)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
queue.addAll(uuids.stream().filter(Objects::nonNull).collect(Collectors.toList()));
|
||||
} catch (IllegalStateException e) {
|
||||
Log.error(Locale.get(Msg.RUN_WARN_QUEUE_SIZE).parse("Clear Queue", 20000));
|
||||
}
|
||||
}
|
||||
}
|
||||
@Deprecated
|
||||
class ClearConsumer extends Consumer<UUID> implements Runnable {
|
||||
|
||||
private DataCacheHandler handler;
|
||||
|
||||
ClearConsumer(BlockingQueue<UUID> q, DataCacheHandler handler) {
|
||||
super(q, "ClearQueueConsumer");
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void consume(UUID uuid) {
|
||||
if (!Verify.notNull(handler, uuid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (handler.isDataAccessed(uuid)) {
|
||||
queue.add(uuid);
|
||||
} else {
|
||||
handler.clearFromCache(uuid);
|
||||
}
|
||||
// if online remove from clear list
|
||||
} catch (Exception ex) {
|
||||
Log.toLog(this.getClass().getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void clearVariables() {
|
||||
if (handler != null) {
|
||||
handler = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@Deprecated
|
||||
class ClearSetup extends Setup<UUID> {
|
||||
|
||||
ClearSetup(BlockingQueue<UUID> q, DataCacheHandler handler) {
|
||||
super(new ClearConsumer(q, handler));
|
||||
}
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
package main.java.com.djrapitops.plan.queue;
|
||||
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
|
||||
import main.java.com.djrapitops.plan.database.Database;
|
||||
import main.java.com.djrapitops.plan.locale.Locale;
|
||||
import main.java.com.djrapitops.plan.locale.Msg;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
/**
|
||||
* This Class is starts the Get Queue Thread, that fetches data from DataCache.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class DataCacheGetQueue extends Queue<Map<UUID, List<DBCallableProcessor>>> {
|
||||
|
||||
/**
|
||||
* Class constructor, starts the new Thread for fetching.
|
||||
*
|
||||
* @param plugin current instance of Plan
|
||||
*/
|
||||
public DataCacheGetQueue(Plan plugin) {
|
||||
super(new ArrayBlockingQueue<>(20000));
|
||||
setup = new GetSetup(queue, plugin.getDB());
|
||||
setup.go();
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules UserData objects to be get for the given processors.
|
||||
*
|
||||
* @param uuid UUID of the player whose UserData object is fetched.
|
||||
* @param processors Processors which process-method will be called after
|
||||
* fetch is complete, with the UserData object.
|
||||
*/
|
||||
public void scheduleForGet(UUID uuid, DBCallableProcessor... processors) {
|
||||
try {
|
||||
Map<UUID, List<DBCallableProcessor>> map = new HashMap<>();
|
||||
map.put(uuid, Arrays.asList(processors));
|
||||
queue.add(map);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.error(Locale.get(Msg.RUN_WARN_QUEUE_SIZE).parse("Get Queue", 20000));
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
class GetConsumer extends Consumer<Map<UUID, List<DBCallableProcessor>>> {
|
||||
|
||||
private Database db;
|
||||
|
||||
GetConsumer(BlockingQueue<Map<UUID, List<DBCallableProcessor>>> q, Database db) {
|
||||
super(q, "GetQueueConsumer");
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void consume(Map<UUID, List<DBCallableProcessor>> processors) {
|
||||
if (!Verify.notNull(processors, db)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
for (Map.Entry<UUID, List<DBCallableProcessor>> entrySet : processors.entrySet()) {
|
||||
UUID uuid = entrySet.getKey();
|
||||
List<DBCallableProcessor> processorsList = entrySet.getValue();
|
||||
if (uuid == null || Verify.isEmpty(processorsList)) {
|
||||
continue;
|
||||
}
|
||||
Log.debug("Database", uuid + ": Get, For:" + processorsList.size());
|
||||
db.giveUserDataToProcessors(uuid, processorsList);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Log.toLog(this.getClass().getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void clearVariables() {
|
||||
if (db != null) {
|
||||
db = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
class GetSetup extends Setup<Map<UUID, List<DBCallableProcessor>>> {
|
||||
|
||||
GetSetup(BlockingQueue<Map<UUID, List<DBCallableProcessor>>> q, Database db) {
|
||||
super(new GetConsumer(q, db), new GetConsumer(q, db));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,124 +0,0 @@
|
||||
package main.java.com.djrapitops.plan.queue;
|
||||
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.data.UserData;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
|
||||
import main.java.com.djrapitops.plan.database.Database;
|
||||
import main.java.com.djrapitops.plan.locale.Locale;
|
||||
import main.java.com.djrapitops.plan.locale.Msg;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
/**
|
||||
* This Class is starts the Save Queue Thread, that saves data to the Database.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class DataCacheSaveQueue extends Queue<UserData> {
|
||||
|
||||
/**
|
||||
* Class constructor, starts the new Thread for saving.
|
||||
*
|
||||
* @param plugin current instance of Plan
|
||||
* @param handler DataCacheHandler
|
||||
*/
|
||||
public DataCacheSaveQueue(Plan plugin, DataCacheHandler handler) {
|
||||
super(new ArrayBlockingQueue<>(20000));
|
||||
setup = new SaveSetup(queue, handler, plugin.getDB());
|
||||
setup.go();
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule UserData object to be saved to the database.
|
||||
*
|
||||
* @param data UserData object.
|
||||
*/
|
||||
public void scheduleForSave(UserData data) {
|
||||
try {
|
||||
queue.add(data);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.error(Locale.get(Msg.RUN_WARN_QUEUE_SIZE).parse("Save Queue", 20000));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule UserData object for a new player to be saved to the database.
|
||||
*
|
||||
* @param data UserData object.
|
||||
*/
|
||||
public void scheduleNewPlayer(UserData data) {
|
||||
Log.debug(data.getUuid() + ": Scheduling new Player");
|
||||
scheduleForSave(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether or not the queue contains a UserData object with the uuid.
|
||||
*
|
||||
* @param uuid UUID of the player.
|
||||
* @return true/false
|
||||
*/
|
||||
public boolean containsUUID(UUID uuid) {
|
||||
return uuid != null && queue.stream().anyMatch(d -> d.getUuid().equals(uuid));
|
||||
}
|
||||
}
|
||||
@Deprecated
|
||||
class SaveConsumer extends Consumer<UserData> {
|
||||
|
||||
private Database db;
|
||||
private DataCacheHandler handler;
|
||||
|
||||
SaveConsumer(BlockingQueue<UserData> q, DataCacheHandler handler, Database db) {
|
||||
super(q, "SaveQueueConsumer");
|
||||
this.db = db;
|
||||
this.handler = handler;
|
||||
run = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void consume(UserData data) {
|
||||
if (!Verify.notNull(handler, db, data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
UUID uuid = data.getUuid();
|
||||
/*TODO if (handler.getProcessTask().containsUUID(uuid)) { // Wait for process queue.
|
||||
queue.add(data);
|
||||
return;
|
||||
}*/
|
||||
|
||||
try {
|
||||
db.saveUserData(data);
|
||||
data.stopAccessing();
|
||||
if (data.shouldClearAfterSave()) {
|
||||
handler.getClearTask().scheduleForClear(uuid);
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
Log.toLog(this.getClass().getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void clearVariables() {
|
||||
if (db != null) {
|
||||
db = null;
|
||||
}
|
||||
|
||||
if (handler != null) {
|
||||
handler = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@Deprecated
|
||||
class SaveSetup extends Setup<UserData> {
|
||||
|
||||
SaveSetup(BlockingQueue<UserData> q, DataCacheHandler handler, Database db) {
|
||||
super(new SaveConsumer(q, handler, db), new SaveConsumer(q, handler, db));
|
||||
}
|
||||
}
|
@ -22,13 +22,13 @@ public abstract class Setup<T> {
|
||||
this.consumers = consumers;
|
||||
}
|
||||
|
||||
void go() {
|
||||
public void go() {
|
||||
for (Consumer<T> consumer : consumers) {
|
||||
Plan.getInstance().getRunnableFactory().createNew(consumer).runTaskAsynchronously();
|
||||
}
|
||||
}
|
||||
|
||||
void stop() {
|
||||
public void stop() {
|
||||
for (Consumer<T> consumer : consumers) {
|
||||
consumer.stop();
|
||||
}
|
||||
|
@ -1,40 +1,37 @@
|
||||
package main.java.com.djrapitops.plan.queue;
|
||||
package main.java.com.djrapitops.plan.queue.processing;
|
||||
|
||||
import main.java.com.djrapitops.plan.Log;
|
||||
import main.java.com.djrapitops.plan.queue.processing.Processor;
|
||||
import main.java.com.djrapitops.plan.queue.Consumer;
|
||||
import main.java.com.djrapitops.plan.queue.Queue;
|
||||
import main.java.com.djrapitops.plan.queue.Setup;
|
||||
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
/**
|
||||
* This Class is starts the Process Queue Thread, that processes HandlingInfo
|
||||
* This Class is starts the Process Queue Thread, that processes Processor
|
||||
* objects.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public class DataCacheProcessQueue extends Queue<Processor> {
|
||||
public class ProcessingQueue extends Queue<Processor> {
|
||||
|
||||
/**
|
||||
* Class constructor, starts the new Thread for processing.
|
||||
*/
|
||||
public DataCacheProcessQueue() {
|
||||
public ProcessingQueue() {
|
||||
super(new ArrayBlockingQueue<>(20000));
|
||||
setup = new ProcessSetup(queue);
|
||||
setup.go();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to add HandlingInfo object to be processed.
|
||||
* Used to add Processor object to be processed.
|
||||
*
|
||||
* @param processor object that extends HandlingInfo.
|
||||
* @param processor processing object.
|
||||
*/
|
||||
public void addToQueue(Processor processor) {
|
||||
try {
|
||||
queue.add(processor);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
queue.offer(processor);
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import main.java.com.djrapitops.plan.data.additional.HookHandler;
|
||||
import main.java.com.djrapitops.plan.data.additional.PluginData;
|
||||
import main.java.com.djrapitops.plan.data.analysis.*;
|
||||
import main.java.com.djrapitops.plan.data.cache.AnalysisCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCache;
|
||||
import main.java.com.djrapitops.plan.data.cache.InspectCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.cache.PageCacheHandler;
|
||||
import main.java.com.djrapitops.plan.database.Database;
|
||||
@ -126,7 +126,7 @@ public class Analysis {
|
||||
rawData.sort(new UserDataLastPlayedComparator());
|
||||
List<UUID> uuids = rawData.stream().map(UserData::getUuid).collect(Collectors.toList());
|
||||
Benchmark.start("Create Empty dataset");
|
||||
DataCacheHandler handler = plugin.getHandler();
|
||||
DataCache handler = plugin.getHandler();
|
||||
Map<String, Integer> commandUse = handler.getCommandUse();
|
||||
|
||||
AnalysisData analysisData = new AnalysisData(commandUse, tpsData);
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
package test.java.main.java.com.djrapitops.plan.data.cache;
|
||||
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCache;
|
||||
import main.java.com.djrapitops.plan.database.Database;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.junit.After;
|
||||
@ -18,10 +18,10 @@ import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest(JavaPlugin.class)
|
||||
public class DataCacheHandlerTest {
|
||||
public class DataCacheTest {
|
||||
|
||||
private Database db;
|
||||
private DataCacheHandler handler;
|
||||
private DataCache handler;
|
||||
|
||||
private int callsToSaveCommandUse;
|
||||
private int callsToSaveUserData;
|
||||
@ -30,7 +30,7 @@ public class DataCacheHandlerTest {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public DataCacheHandlerTest() {
|
||||
public DataCacheTest() {
|
||||
}
|
||||
|
||||
/**
|
@ -8,9 +8,7 @@ package test.java.main.java.com.djrapitops.plan.data.cache.queue;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.data.UserData;
|
||||
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.HandlingInfo;
|
||||
import main.java.com.djrapitops.plan.data.handling.info.InfoType;
|
||||
import main.java.com.djrapitops.plan.data.cache.DataCache;
|
||||
import main.java.com.djrapitops.plan.database.Database;
|
||||
import main.java.com.djrapitops.plan.database.databases.SQLiteDB;
|
||||
import main.java.com.djrapitops.plan.utilities.MiscUtils;
|
||||
@ -30,12 +28,14 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.powermock.api.mockito.PowerMockito.when;
|
||||
|
||||
// TODO Rewrite
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({JavaPlugin.class})
|
||||
public class DataCacheQueueTest {
|
||||
public class QueueTest {
|
||||
|
||||
private final UUID uuid1 = MockUtils.getPlayerUUID();
|
||||
private final UserData data1 = MockUtils.mockUserWithMoreData();
|
||||
@ -44,10 +44,10 @@ public class DataCacheQueueTest {
|
||||
private int callsToSaveUserData;
|
||||
private int callsToGetUserData;
|
||||
|
||||
private DataCacheHandler handler;
|
||||
private DataCache handler;
|
||||
private Database db;
|
||||
|
||||
public DataCacheQueueTest() {
|
||||
public QueueTest() {
|
||||
}
|
||||
|
||||
@Before
|
||||
@ -89,7 +89,7 @@ public class DataCacheQueueTest {
|
||||
};
|
||||
db.init();
|
||||
when(plan.getDB()).thenReturn(db);
|
||||
handler = new DataCacheHandler(plan) {
|
||||
handler = new DataCache(plan) {
|
||||
@Override
|
||||
public void startAsyncPeriodicSaveTask() {
|
||||
}
|
||||
@ -102,65 +102,21 @@ public class DataCacheQueueTest {
|
||||
db.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetQueue_cache() {
|
||||
List<Integer> calls = new ArrayList<>();
|
||||
List<Integer> errors = new ArrayList<>();
|
||||
handler.getUserDataForProcessing(data -> {
|
||||
if (data.equals(data1)) {
|
||||
calls.add(1);
|
||||
} else {
|
||||
errors.add(1);
|
||||
}
|
||||
}, uuid1);
|
||||
while (calls.size() < 1) {
|
||||
if (errors.size() > 0) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
assertEquals(1, calls.size());
|
||||
assertEquals(0, errors.size());
|
||||
assertEquals(1, callsToGetUserData);
|
||||
assertTrue(handler.getDataCache().containsKey(uuid1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetQueue_dontCache() {
|
||||
List<Integer> getCalls = new ArrayList<>();
|
||||
List<Integer> errors = new ArrayList<>();
|
||||
handler.getUserDataForProcessing(data -> {
|
||||
if (data.equals(data1)) {
|
||||
getCalls.add(1);
|
||||
} else {
|
||||
errors.add(1);
|
||||
}
|
||||
}, uuid1, false);
|
||||
while (getCalls.size() < 1) {
|
||||
if (errors.size() > 0) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
assertEquals(1, getCalls.size());
|
||||
assertEquals(0, errors.size());
|
||||
assertEquals(1, callsToGetUserData);
|
||||
assertTrue(!handler.getDataCache().containsKey(uuid1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessQueue() {
|
||||
List<Integer> processCalls = new ArrayList<>();
|
||||
List<Integer> errors = new ArrayList<>();
|
||||
handler.addToPool(new HandlingInfo(uuid1, InfoType.OTHER, 0) {
|
||||
@Override
|
||||
public void process(UserData uData) {
|
||||
if (uData.equals(data1)) {
|
||||
uData.setName("TestSuccessful");
|
||||
processCalls.add(1);
|
||||
} else {
|
||||
errors.add(1);
|
||||
}
|
||||
}
|
||||
});
|
||||
// handler.addToPool(new HandlingInfo(uuid1, InfoType.OTHER, 0) {
|
||||
// @Override
|
||||
// public void process(UserData uData) {
|
||||
// if (uData.equals(data1)) {
|
||||
// uData.setName("TestSuccessful");
|
||||
// processCalls.add(1);
|
||||
// } else {
|
||||
// errors.add(1);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
while (processCalls.size() < 1) {
|
||||
if (errors.size() > 0) {
|
||||
fail();
|
||||
@ -169,9 +125,5 @@ public class DataCacheQueueTest {
|
||||
assertEquals(1, processCalls.size());
|
||||
assertEquals(0, errors.size());
|
||||
assertEquals(1, callsToGetUserData);
|
||||
assertTrue(handler.getDataCache().containsKey(uuid1));
|
||||
assertEquals("TestSuccessful", handler.getDataCache().get(uuid1).getName());
|
||||
}
|
||||
|
||||
// TODO Save & Clear Queue tests
|
||||
}
|
Loading…
Reference in New Issue
Block a user