Split TPSCountTimer into multiple subclasses.

This commit is contained in:
Rsl1122 2018-01-13 14:15:35 +02:00
parent 8f6b196b60
commit fb09f327ef
16 changed files with 241 additions and 251 deletions

View File

@ -7,7 +7,9 @@ package com.djrapitops.plan.system;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.system.database.BukkitDBSystem;
import com.djrapitops.plan.system.file.FileSystem;
import com.djrapitops.plan.system.listeners.BukkitListenerSystem;
import com.djrapitops.plan.system.settings.config.BukkitConfigSystem;
import com.djrapitops.plan.system.tasks.BukkitTaskSystem;
import com.djrapitops.plan.system.update.VersionCheckSystem;
/**
@ -22,6 +24,8 @@ public class BukkitSystem extends PlanSystem {
fileSystem = new FileSystem(plugin);
configSystem = new BukkitConfigSystem();
databaseSystem = new BukkitDBSystem();
listenerSystem = new BukkitListenerSystem(plugin);
taskSystem = new BukkitTaskSystem(plugin);
}
public static BukkitSystem getInstance() {

View File

@ -7,7 +7,9 @@ package com.djrapitops.plan.system;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plan.system.database.BungeeDBSystem;
import com.djrapitops.plan.system.file.FileSystem;
import com.djrapitops.plan.system.listeners.BungeeListenerSystem;
import com.djrapitops.plan.system.settings.config.BungeeConfigSystem;
import com.djrapitops.plan.system.tasks.BungeeTaskSystem;
import com.djrapitops.plan.system.update.VersionCheckSystem;
/**
@ -22,6 +24,8 @@ public class BungeeSystem extends PlanSystem {
fileSystem = new FileSystem(plugin);
configSystem = new BungeeConfigSystem();
databaseSystem = new BungeeDBSystem();
listenerSystem = new BungeeListenerSystem(plugin);
taskSystem = new BungeeTaskSystem(plugin);
}
public static BungeeSystem getInstance() {

View File

@ -44,28 +44,36 @@ public abstract class PlanSystem implements SubSystem {
public void enable() throws EnableException {
checkSubSystemInitialization();
versionCheckSystem.enable();
fileSystem.enable();
configSystem.enable();
databaseSystem.enable();
processingQueue.enable();
listenerSystem.enable();
taskSystem.enable();
SubSystem[] systems = new SubSystem[]{
versionCheckSystem,
fileSystem,
configSystem,
databaseSystem,
processingQueue,
listenerSystem,
taskSystem
};
for (SubSystem system : systems) {
system.enable();
}
}
@Override
public void disable() {
processingQueue.disable();
databaseSystem.disable();
taskSystem.disable();
configSystem.disable();
fileSystem.disable();
versionCheckSystem.disable();
}
public void reload() throws EnableException {
checkSubSystemInitialization();
configSystem.reload();
SubSystem[] systems = new SubSystem[]{
listenerSystem,
processingQueue,
databaseSystem,
taskSystem,
configSystem,
fileSystem,
versionCheckSystem
};
for (SubSystem system : systems) {
if (system != null) {
system.disable();
}
}
}
private void checkSubSystemInitialization() throws EnableException {
@ -75,6 +83,7 @@ public abstract class PlanSystem implements SubSystem {
NullCheck.check(configSystem, new IllegalStateException("Config system was not initialized."));
NullCheck.check(databaseSystem, new IllegalStateException("Database system was not initialized."));
NullCheck.check(listenerSystem, new IllegalStateException("Listener system was not initialized."));
NullCheck.check(taskSystem, new IllegalStateException("Task system was not initialized."));
} catch (Exception e) {
throw new EnableException("One of the subsystems is not initialized on enable for " + this.getClass().getSimpleName() + ".", e);
}

View File

@ -7,9 +7,9 @@ package com.djrapitops.plan.system.settings.config;
import com.djrapitops.plan.api.exceptions.EnableException;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.system.PlanSystem;
import com.djrapitops.plan.system.SubSystem;
import com.djrapitops.plan.system.file.FileSystem;
import com.djrapitops.plan.systems.Systems;
import com.djrapitops.plan.utilities.NullCheck;
import com.djrapitops.plugin.api.config.Config;
import com.djrapitops.plugin.api.utility.log.Log;
@ -34,7 +34,7 @@ public abstract class ConfigSystem implements SubSystem {
}
public static ConfigSystem getInstance() {
ConfigSystem configSystem = Systems.getInstance().getConfigSystem();
ConfigSystem configSystem = PlanSystem.getInstance().getConfigSystem();
NullCheck.check(configSystem, new IllegalStateException("Config System has not been initialized."));
return configSystem;
}

View File

@ -8,8 +8,11 @@ import com.djrapitops.plan.Plan;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.tasks.bukkit.BukkitTPSCountTimer;
import com.djrapitops.plan.system.tasks.bukkit.PaperTPSCountTimer;
import com.djrapitops.plan.systems.info.InformationManager;
import com.djrapitops.plugin.api.Benchmark;
import com.djrapitops.plugin.api.Check;
import com.djrapitops.plugin.api.TimeAmount;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.task.AbsRunnable;
@ -23,7 +26,11 @@ import com.djrapitops.plugin.task.RunnableFactory;
*/
public class BukkitTaskSystem extends TaskSystem {
// TODO Remove Plan.getInstance requirement.
private final Plan plugin;
public BukkitTaskSystem(Plan plugin) {
this.plugin = plugin;
}
private ITask bootAnalysisTask;
@ -38,7 +45,9 @@ public class BukkitTaskSystem extends TaskSystem {
String bootAnalysisRunMsg = Locale.get(Msg.ENABLE_BOOT_ANALYSIS_RUN_INFO).toString();
Benchmark.start("Task Registration");
tpsCountTimer = new TPSCountTimer(Plan.getInstance());
tpsCountTimer = Check.isPaperAvailable()
? new PaperTPSCountTimer(plugin)
: new BukkitTPSCountTimer(plugin);
registerTask(tpsCountTimer).runTaskTimer(1000, TimeAmount.SECOND.ticks());
// Analysis refresh settings
@ -48,7 +57,7 @@ public class BukkitTaskSystem extends TaskSystem {
Log.info(bootAnalysisMsg);
InformationManager infoManager = Plan.getInstance().getInfoManager();
InformationManager infoManager = plugin.getInfoManager();
bootAnalysisTask = RunnableFactory.createNew("BootAnalysisTask", new AbsRunnable() {
@Override

View File

@ -5,6 +5,7 @@
package com.djrapitops.plan.system.tasks;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plan.system.tasks.bungee.BungeeTPSCountTimer;
import com.djrapitops.plan.systems.info.BungeeInformationManager;
import com.djrapitops.plugin.api.TimeAmount;
import com.djrapitops.plugin.task.AbsRunnable;
@ -16,6 +17,12 @@ import com.djrapitops.plugin.task.AbsRunnable;
*/
public class BungeeTaskSystem extends TaskSystem {
private final PlanBungee plugin;
public BungeeTaskSystem(PlanBungee plugin) {
this.plugin = plugin;
}
@Override
public void enable() {
registerTasks();
@ -31,7 +38,7 @@ public class BungeeTaskSystem extends TaskSystem {
infoManager.sendConfigSettings();
}
}).runTaskAsynchronously();
registerTask("Player Count task", new TPSCountTimer(PlanBungee.getInstance()))
registerTask("Player Count task", new BungeeTPSCountTimer(plugin))
.runTaskTimerAsynchronously(1000, TimeAmount.SECOND.ticks());
registerTask("NetworkPageContentUpdateTask", new AbsRunnable("NetworkPageContentUpdateTask") {
@Override

View File

@ -1,20 +1,11 @@
package com.djrapitops.plan.system.tasks;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.data.container.TPS;
import com.djrapitops.plan.system.processing.processors.TPSInsertProcessor;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plan.utilities.analysis.MathUtils;
import com.djrapitops.plugin.api.Check;
import com.djrapitops.plugin.api.TimeAmount;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.task.AbsRunnable;
import org.bukkit.World;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.util.ArrayList;
import java.util.List;
@ -23,22 +14,18 @@ import java.util.List;
*
* @author Rsl1122
*/
public class TPSCountTimer extends AbsRunnable {
public abstract class TPSCountTimer<T extends PlanPlugin> extends AbsRunnable {
private final PlanPlugin plugin;
private final List<TPS> history;
private long lastCheckNano;
protected final T plugin;
protected final List<TPS> history;
private final boolean usingBungee;
private int latestPlayersOnline = 0;
protected int latestPlayersOnline = 0;
public TPSCountTimer(PlanPlugin plugin) {
public TPSCountTimer(T plugin) {
super("TPSCountTimer");
lastCheckNano = -1;
this.plugin = plugin;
history = new ArrayList<>();
usingBungee = Check.isBungeeAvailable();
}
@Override
@ -46,141 +33,15 @@ public class TPSCountTimer extends AbsRunnable {
long nanoTime = System.nanoTime();
long now = MiscUtils.getTime();
if (usingBungee) {
history.add(new TPS(now, -1, ((PlanBungee) plugin).getProxy().getOnlineCount(), -1, -1, -1, -1));
} else {
long diff = nanoTime - lastCheckNano;
lastCheckNano = nanoTime;
if (diff > nanoTime) { // First run's diff = nanoTime + 1, no calc possible.
Log.debug("First run of TPSCountTimer Task.");
return;
}
history.add(calculateTPS(diff, now));
}
addNewTPSEntry(nanoTime, now);
if (history.size() >= 60) {
plugin.addToProcessQueue(new TPSInsertProcessor(new ArrayList<>(history)));
history.clear();
}
}
/**
* Calculates the TPS
*
* @param diff The time difference between the last run and the new run
* @param now The time right now
* @return the TPS
*/
private TPS calculateTPS(long diff, long now) {
OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
int availableProcessors = operatingSystemMXBean.getAvailableProcessors();
double averageCPUUsage = MathUtils.round(operatingSystemMXBean.getSystemLoadAverage() / availableProcessors * 100.0);
if (averageCPUUsage < 0) { // If unavailable, getSystemLoadAverage() returns -1
averageCPUUsage = -1;
}
Runtime runtime = Runtime.getRuntime();
long totalMemory = runtime.totalMemory();
long usedMemory = (totalMemory - runtime.freeMemory()) / 1000000;
int playersOnline = ((Plan) plugin).getServer().getOnlinePlayers().size();
latestPlayersOnline = playersOnline;
int loadedChunks = getLoadedChunks();
int entityCount;
if (plugin.getVariable().isUsingPaper()) {
entityCount = getEntityCountPaper();
return getTPSPaper(now, averageCPUUsage, usedMemory, entityCount, loadedChunks, playersOnline);
} else {
entityCount = getEntityCount();
// 40ms removed because the run appears to take 40-50ms, screwing the tps.
long fortyMsAsNs = TimeAmount.MILLISECOND.ns() * 40L;
return getTPS(diff - fortyMsAsNs, now, averageCPUUsage, usedMemory, entityCount, loadedChunks, playersOnline);
}
}
/**
* Gets the TPS for Spigot / Bukkit
*
* @param diff The difference between the last run and this run
* @param now The time right now
* @param cpuUsage The usage of the CPU
* @param playersOnline The amount of players that are online
* @return the TPS
*/
private TPS getTPS(long diff, long now, double cpuUsage, long usedMemory, int entityCount, int chunksLoaded, int playersOnline) {
long difference = diff;
if (difference < TimeAmount.SECOND.ns()) { // No tick count above 20
difference = TimeAmount.SECOND.ns();
}
long twentySeconds = 20L * TimeAmount.SECOND.ns();
while (difference > twentySeconds) {
history.add(new TPS(now, 0, playersOnline, cpuUsage, usedMemory, entityCount, chunksLoaded));
difference -= twentySeconds;
}
double tpsN = twentySeconds * 1.0 / difference;
return new TPS(now, tpsN, playersOnline, cpuUsage, usedMemory, entityCount, chunksLoaded);
}
/**
* Gets the TPS for Paper
*
* @param now The time right now
* @param cpuUsage The usage of the CPU
* @param playersOnline The amount of players that are online
* @return the TPS
*/
private TPS getTPSPaper(long now, double cpuUsage, long usedMemory, int entityCount, int chunksLoaded, int playersOnline) {
double tps = ((Plan) plugin).getServer().getTPS()[0];
if (tps > 20) {
tps = 20;
}
tps = MathUtils.round(tps);
return new TPS(now, tps, playersOnline, cpuUsage, usedMemory, entityCount, chunksLoaded);
}
/**
* Gets the amount of loaded chunks
*
* @return amount of loaded chunks
*/
private int getLoadedChunks() {
return ((Plan) plugin).getServer().getWorlds().stream().mapToInt(world -> world.getLoadedChunks().length).sum();
}
/**
* Gets the amount of entities on the server for Bukkit / Spigot
*
* @return amount of entities
*/
private int getEntityCount() {
return ((Plan) plugin).getServer().getWorlds().stream().mapToInt(world -> world.getEntities().size()).sum();
}
/**
* Gets the amount of entities on the server for Paper
*
* @return amount of entities
*/
private int getEntityCountPaper() {
try {
return ((Plan) plugin).getServer().getWorlds().stream().mapToInt(World::getEntityCount).sum();
} catch (BootstrapMethodError | NoSuchMethodError e) {
return getEntityCount();
}
}
public abstract void addNewTPSEntry(long nanoTime, long now);
public int getLatestPlayersOnline() {
return latestPlayersOnline;

View File

@ -0,0 +1,112 @@
package com.djrapitops.plan.system.tasks.bukkit;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.data.container.TPS;
import com.djrapitops.plan.system.tasks.TPSCountTimer;
import com.djrapitops.plan.utilities.analysis.MathUtils;
import com.djrapitops.plugin.api.TimeAmount;
import com.djrapitops.plugin.api.utility.log.Log;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
public class BukkitTPSCountTimer extends TPSCountTimer<Plan> {
private long lastCheckNano;
public BukkitTPSCountTimer(Plan plugin) {
super(plugin);
lastCheckNano = -1;
}
@Override
public void addNewTPSEntry(long nanoTime, long now) {
long diff = nanoTime - lastCheckNano;
lastCheckNano = nanoTime;
if (diff > nanoTime) { // First run's diff = nanoTime + 1, no calc possible.
Log.debug("First run of TPSCountTimer Task.");
return;
}
history.add(calculateTPS(diff, now));
}
/**
* Calculates the TPS
*
* @param diff The time difference between the last run and the new run
* @param now The time right now
* @return the TPS
*/
private TPS calculateTPS(long diff, long now) {
OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
int availableProcessors = operatingSystemMXBean.getAvailableProcessors();
double averageCPUUsage = MathUtils.round(operatingSystemMXBean.getSystemLoadAverage() / availableProcessors * 100.0);
if (averageCPUUsage < 0) { // If unavailable, getSystemLoadAverage() returns -1
averageCPUUsage = -1;
}
Runtime runtime = Runtime.getRuntime();
long totalMemory = runtime.totalMemory();
long usedMemory = (totalMemory - runtime.freeMemory()) / 1000000;
int playersOnline = plugin.getServer().getOnlinePlayers().size();
latestPlayersOnline = playersOnline;
int loadedChunks = getLoadedChunks();
int entityCount;
entityCount = getEntityCount();
// 40ms removed because the run appears to take 40-50ms, screwing the tps.
long fortyMsAsNs = TimeAmount.MILLISECOND.ns() * 40L;
return getTPS(diff - fortyMsAsNs, now, averageCPUUsage, usedMemory, entityCount, loadedChunks, playersOnline);
}
/**
* Gets the TPS for Spigot / Bukkit
*
* @param diff The difference between the last run and this run
* @param now The time right now
* @param cpuUsage The usage of the CPU
* @param playersOnline The amount of players that are online
* @return the TPS
*/
protected TPS getTPS(long diff, long now, double cpuUsage, long usedMemory, int entityCount, int chunksLoaded, int playersOnline) {
long difference = diff;
if (difference < TimeAmount.SECOND.ns()) { // No tick count above 20
difference = TimeAmount.SECOND.ns();
}
long twentySeconds = 20L * TimeAmount.SECOND.ns();
while (difference > twentySeconds) {
history.add(new TPS(now, 0, playersOnline, cpuUsage, usedMemory, entityCount, chunksLoaded));
difference -= twentySeconds;
}
double tpsN = twentySeconds * 1.0 / difference;
return new TPS(now, tpsN, playersOnline, cpuUsage, usedMemory, entityCount, chunksLoaded);
}
/**
* Gets the amount of loaded chunks
*
* @return amount of loaded chunks
*/
private int getLoadedChunks() {
return plugin.getServer().getWorlds().stream().mapToInt(world -> world.getLoadedChunks().length).sum();
}
/**
* Gets the amount of entities on the server for Bukkit / Spigot
*
* @return amount of entities
*/
protected int getEntityCount() {
return plugin.getServer().getWorlds().stream().mapToInt(world -> world.getEntities().size()).sum();
}
}

View File

@ -0,0 +1,35 @@
package com.djrapitops.plan.system.tasks.bukkit;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.data.container.TPS;
import com.djrapitops.plan.utilities.analysis.MathUtils;
import org.bukkit.World;
public class PaperTPSCountTimer extends BukkitTPSCountTimer {
public PaperTPSCountTimer(Plan plugin) {
super(plugin);
}
@Override
protected TPS getTPS(long diff, long now, double cpuUsage, long usedMemory, int entityCount, int chunksLoaded, int playersOnline) {
double tps = plugin.getServer().getTPS()[0];
if (tps > 20) {
tps = 20;
}
tps = MathUtils.round(tps);
return new TPS(now, tps, playersOnline, cpuUsage, usedMemory, entityCount, chunksLoaded);
}
@Override
protected int getEntityCount() {
try {
return plugin.getServer().getWorlds().stream().mapToInt(World::getEntityCount).sum();
} catch (BootstrapMethodError | NoSuchMethodError e) {
return super.getEntityCount();
}
}
}

View File

@ -0,0 +1,19 @@
package com.djrapitops.plan.system.tasks.bungee;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plan.data.container.TPS;
import com.djrapitops.plan.system.tasks.TPSCountTimer;
public class BungeeTPSCountTimer extends TPSCountTimer<PlanBungee> {
public BungeeTPSCountTimer(PlanBungee plugin) {
super(plugin);
}
@Override
public void addNewTPSEntry(long nanoTime, long now) {
int onlineCount = plugin.getProxy().getOnlineCount();
history.add(new TPS(now, -1, onlineCount, -1, -1, -1, -1));
latestPlayersOnline = onlineCount;
}
}

View File

@ -6,6 +6,7 @@ package com.djrapitops.plan.systems;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.system.SubSystem;
import com.djrapitops.plan.system.database.BukkitDBSystem;
@ -15,11 +16,11 @@ import com.djrapitops.plan.system.file.FileSystem;
import com.djrapitops.plan.system.settings.config.BukkitConfigSystem;
import com.djrapitops.plan.system.settings.config.BungeeConfigSystem;
import com.djrapitops.plan.system.settings.config.ConfigSystem;
import com.djrapitops.plan.system.tasks.BukkitTaskSystem;
import com.djrapitops.plan.system.tasks.BungeeTaskSystem;
import com.djrapitops.plan.system.tasks.TaskSystem;
import com.djrapitops.plan.system.update.VersionCheckSystem;
import com.djrapitops.plan.system.webserver.WebServerSystem;
import com.djrapitops.plan.system.tasks.BungeeTaskSystem;
import com.djrapitops.plan.system.tasks.BukkitTaskSystem;
import com.djrapitops.plan.system.tasks.TaskSystem;
import com.djrapitops.plugin.api.utility.log.Log;
import org.apache.commons.lang3.ArrayUtils;
@ -28,6 +29,7 @@ import org.apache.commons.lang3.ArrayUtils;
*
* @author Rsl1122
*/
@Deprecated
public class Systems {
private FileSystem fileSystem;

View File

@ -52,6 +52,7 @@ import java.util.*;
*
* @author Rsl1122
*/
@Deprecated
public class BukkitInformationManager extends InformationManager {
private final Plan plugin;

View File

@ -5,6 +5,7 @@
package com.djrapitops.plan.systems.info;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.api.exceptions.ParseException;
import com.djrapitops.plan.api.exceptions.WebAPIConnectionFailException;
import com.djrapitops.plan.api.exceptions.WebAPIException;
@ -43,6 +44,7 @@ import java.util.stream.Collectors;
*
* @author Rsl1122
*/
@Deprecated
public class BungeeInformationManager extends InformationManager {
private final PlanBungee plugin;

View File

@ -1,77 +0,0 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.systems.info.parsing;
/**
* Used for parsing URL strings.
*
* @author Rsl1122
*/
public class UrlParser {
private final String webServerAddress;
private StringBuilder url;
public UrlParser(String address) {
webServerAddress = address;
url = new StringBuilder();
}
public UrlParser relativeProtocol() {
url.append("//");
return this;
}
public UrlParser httpProtocol() {
if (url.length() == 0) {
url.append("http://");
} else {
String current = url.toString();
url = new StringBuilder("./");
url.append(current.substring(current.indexOf("/")));
}
return this;
}
public UrlParser httpsProtocol() {
if (url.length() == 0) {
url.append("https://");
} else {
String current = url.toString();
url = new StringBuilder("./");
url.append(current.substring(current.indexOf("/")));
}
return this;
}
public UrlParser relative() {
if (url.length() == 0) {
url.append("./");
} else {
String current = url.toString();
url = new StringBuilder("./");
url.append(current.substring(current.indexOf("/")));
}
return this;
}
public UrlParser webAddress() {
url.append(webServerAddress);
return this;
}
public UrlParser target(String target) {
if (!target.startsWith("/") && url.charAt(url.length() - 1) != '/') {
url.append("/");
}
url.append(target);
return this;
}
@Override
public String toString() {
return url.toString();
}
}

View File

@ -25,6 +25,7 @@ import java.util.UUID;
*
* @author Rsl1122
*/
@Deprecated
public class BukkitServerInfoManager {
private final Plan plugin;

View File

@ -26,6 +26,7 @@ import java.util.stream.Collectors;
*
* @author Rsl1122
*/
@Deprecated
public class BungeeServerInfoManager {
private final PlanBungee plugin;