aboutsummaryrefslogtreecommitdiff
path: root/spark-common/src/main/java/me
diff options
context:
space:
mode:
Diffstat (limited to 'spark-common/src/main/java/me')
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/command/modules/TickMonitoringModule.java22
-rw-r--r--spark-common/src/main/java/me/lucko/spark/common/monitor/tick/TickMonitor.java95
2 files changed, 93 insertions, 24 deletions
diff --git a/spark-common/src/main/java/me/lucko/spark/common/command/modules/TickMonitoringModule.java b/spark-common/src/main/java/me/lucko/spark/common/command/modules/TickMonitoringModule.java
index 245a55b..7014770 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/command/modules/TickMonitoringModule.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/command/modules/TickMonitoringModule.java
@@ -26,6 +26,7 @@ import me.lucko.spark.common.command.CommandModule;
import me.lucko.spark.common.command.CommandResponseHandler;
import me.lucko.spark.common.command.tabcomplete.TabCompleter;
import me.lucko.spark.common.monitor.tick.TickMonitor;
+import me.lucko.spark.common.monitor.tick.TickMonitor.ReportPredicate;
import me.lucko.spark.common.sampler.tick.TickHook;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
@@ -53,6 +54,7 @@ public class TickMonitoringModule implements CommandModule {
consumer.accept(Command.builder()
.aliases("tickmonitoring")
.argumentUsage("threshold", "percentage increase")
+ .argumentUsage("threshold-tick", "tick duration")
.argumentUsage("without-gc", null)
.executor((platform, sender, resp, arguments) -> {
if (this.tickHook == null) {
@@ -64,19 +66,25 @@ public class TickMonitoringModule implements CommandModule {
}
if (this.activeTickMonitor == null) {
- int threshold = arguments.intFlag("threshold");
- if (threshold == -1) {
- threshold = 100;
+ ReportPredicate reportPredicate;
+
+ int threshold;
+ if ((threshold = arguments.intFlag("threshold")) != -1) {
+ reportPredicate = new ReportPredicate.PercentageChangeGt(threshold);
+ } else if ((threshold = arguments.intFlag("threshold-tick")) != -1) {
+ reportPredicate = new ReportPredicate.DurationGt(threshold);
+ } else {
+ reportPredicate = new ReportPredicate.PercentageChangeGt(100);
}
- this.activeTickMonitor = new ReportingTickMonitor(platform, resp, this.tickHook, threshold, !arguments.boolFlag("without-gc"));
+ this.activeTickMonitor = new ReportingTickMonitor(platform, resp, this.tickHook, reportPredicate, !arguments.boolFlag("without-gc"));
this.tickHook.addCallback(this.activeTickMonitor);
} else {
close();
resp.broadcastPrefixed(TextComponent.of("Tick monitor disabled."));
}
})
- .tabCompleter((platform, sender, arguments) -> TabCompleter.completeForOpts(arguments, "--threshold", "--without-gc"))
+ .tabCompleter((platform, sender, arguments) -> TabCompleter.completeForOpts(arguments, "--threshold", "--threshold-tick", "--without-gc"))
.build()
);
}
@@ -84,8 +92,8 @@ public class TickMonitoringModule implements CommandModule {
private static class ReportingTickMonitor extends TickMonitor {
private final CommandResponseHandler resp;
- ReportingTickMonitor(SparkPlatform platform, CommandResponseHandler resp, TickHook tickHook, int percentageChangeThreshold, boolean monitorGc) {
- super(platform, tickHook, percentageChangeThreshold, monitorGc);
+ ReportingTickMonitor(SparkPlatform platform, CommandResponseHandler resp, TickHook tickHook, ReportPredicate reportPredicate, boolean monitorGc) {
+ super(platform, tickHook, reportPredicate, monitorGc);
this.resp = resp;
}
diff --git a/spark-common/src/main/java/me/lucko/spark/common/monitor/tick/TickMonitor.java b/spark-common/src/main/java/me/lucko/spark/common/monitor/tick/TickMonitor.java
index 8b0befe..4a755d1 100644
--- a/spark-common/src/main/java/me/lucko/spark/common/monitor/tick/TickMonitor.java
+++ b/spark-common/src/main/java/me/lucko/spark/common/monitor/tick/TickMonitor.java
@@ -38,7 +38,7 @@ public abstract class TickMonitor implements TickHook.Callback, GarbageCollectio
private final TickHook tickHook;
private final int zeroTick;
private final GarbageCollectionMonitor garbageCollectionMonitor;
- private final int percentageChangeThreshold;
+ private final ReportPredicate reportPredicate;
// data
private volatile double lastTickTime = 0;
@@ -46,11 +46,11 @@ public abstract class TickMonitor implements TickHook.Callback, GarbageCollectio
private final DoubleSummaryStatistics averageTickTime = new DoubleSummaryStatistics();
private double avg;
- public TickMonitor(SparkPlatform platform, TickHook tickHook, int percentageChangeThreshold, boolean monitorGc) {
+ public TickMonitor(SparkPlatform platform, TickHook tickHook, ReportPredicate reportPredicate, boolean monitorGc) {
this.platform = platform;
this.tickHook = tickHook;
this.zeroTick = tickHook.getCurrentTick();
- this.percentageChangeThreshold = percentageChangeThreshold;
+ this.reportPredicate = reportPredicate;
if (monitorGc) {
this.garbageCollectionMonitor = new GarbageCollectionMonitor();
@@ -88,17 +88,16 @@ public abstract class TickMonitor implements TickHook.Callback, GarbageCollectio
// find the diff
double last = this.lastTickTime;
- double diff = now - last;
- boolean ignore = last == 0;
+ double tickDuration = now - last;
this.lastTickTime = now;
- if (ignore) {
+ if (last == 0) {
return;
}
// form averages
if (this.state == State.SETUP) {
- this.averageTickTime.accept(diff);
+ this.averageTickTime.accept(tickDuration);
// move onto the next state
if (this.averageTickTime.getCount() >= 120) {
@@ -123,13 +122,12 @@ public abstract class TickMonitor implements TickHook.Callback, GarbageCollectio
sendMessage(TextComponent.builder("").color(TextColor.GRAY)
.append(TextComponent.of(">", TextColor.WHITE))
.append(TextComponent.space())
- .append(TextComponent.of("Avg: "))
+ .append(TextComponent.of("Average: "))
.append(TextComponent.of(df.format(this.averageTickTime.getAverage())))
.append(TextComponent.of("ms"))
.build()
);
- sendMessage(TextComponent.of("Starting now, any ticks with >" + this.percentageChangeThreshold + "% increase in " +
- "duration compared to the average will be reported."));
+ sendMessage(this.reportPredicate.monitoringStartMessage());
});
this.avg = this.averageTickTime.getAverage();
@@ -138,19 +136,15 @@ public abstract class TickMonitor implements TickHook.Callback, GarbageCollectio
}
if (this.state == State.MONITORING) {
- double increase = diff - this.avg;
- if (increase <= 0) {
- return;
- }
-
+ double increase = tickDuration - this.avg;
double percentageChange = (increase * 100d) / this.avg;
- if (percentageChange > this.percentageChangeThreshold) {
+ if (this.reportPredicate.shouldReport(tickDuration, increase, percentageChange)) {
this.platform.getPlugin().executeAsync(() -> {
sendMessage(TextComponent.builder("").color(TextColor.GRAY)
.append(TextComponent.of("Tick "))
.append(TextComponent.of("#" + getCurrentTick(), TextColor.DARK_GRAY))
.append(TextComponent.of(" lasted "))
- .append(TextComponent.of(df.format(diff), TextColor.GOLD))
+ .append(TextComponent.of(df.format(tickDuration), TextColor.GOLD))
.append(TextComponent.of(" ms. "))
.append(TextComponent.of("("))
.append(TextComponent.of(df.format(percentageChange) + "%", TextColor.GOLD))
@@ -193,6 +187,73 @@ public abstract class TickMonitor implements TickHook.Callback, GarbageCollectio
});
}
+ /**
+ * A predicate to test whether a tick should be reported.
+ */
+ public interface ReportPredicate {
+
+ /**
+ * Tests whether a tick should be reported.
+ *
+ * @param duration the tick duration
+ * @param increaseFromAvg the difference between the ticks duration and the average
+ * @param percentageChange the percentage change between the ticks duration and the average
+ * @return true if the tick should be reported, false otherwise
+ */
+ boolean shouldReport(double duration, double increaseFromAvg, double percentageChange);
+
+ /**
+ * Gets a component to describe how the predicate will select ticks to report.
+ *
+ * @return the component
+ */
+ Component monitoringStartMessage();
+
+ final class PercentageChangeGt implements ReportPredicate {
+ private final double threshold;
+
+ public PercentageChangeGt(double threshold) {
+ this.threshold = threshold;
+ }
+
+ @Override
+ public boolean shouldReport(double duration, double increaseFromAvg, double percentageChange) {
+ if (increaseFromAvg <= 0) {
+ return false;
+ }
+ return percentageChange > this.threshold;
+ }
+
+ @Override
+ public Component monitoringStartMessage() {
+ return TextComponent.of("Starting now, any ticks with >" + this.threshold + "% increase in " +
+ "duration compared to the average will be reported.");
+ }
+ }
+
+ final class DurationGt implements ReportPredicate {
+ private final double threshold;
+
+ public DurationGt(double threshold) {
+ this.threshold = threshold;
+ }
+
+ @Override
+ public boolean shouldReport(double duration, double increaseFromAvg, double percentageChange) {
+ if (increaseFromAvg <= 0) {
+ return false;
+ }
+ return duration > this.threshold;
+ }
+
+ @Override
+ public Component monitoringStartMessage() {
+ return TextComponent.of("Starting now, any ticks with duration >" + this.threshold + " will be reported.");
+ }
+ }
+
+ }
+
private enum State {
SETUP,
MONITORING