From e02d52ce8d45550a4d77f11971e31cf0732e5f0c Mon Sep 17 00:00:00 2001 From: Luck Date: Tue, 4 Feb 2020 00:49:40 +0000 Subject: Monitor average tick durations & report them in /spark tps --- .../spark/common/sampler/AbstractTickCounter.java | 53 ------------------ .../me/lucko/spark/common/sampler/Sampler.java | 5 +- .../lucko/spark/common/sampler/SamplerBuilder.java | 12 ++-- .../me/lucko/spark/common/sampler/TickCounter.java | 64 ---------------------- .../sampler/aggregator/TickedDataAggregator.java | 10 ++-- .../common/sampler/tick/AbstractTickHook.java | 53 ++++++++++++++++++ .../common/sampler/tick/AbstractTickReporter.java | 45 +++++++++++++++ .../lucko/spark/common/sampler/tick/TickHook.java | 64 ++++++++++++++++++++++ .../spark/common/sampler/tick/TickReporter.java | 57 +++++++++++++++++++ 9 files changed, 234 insertions(+), 129 deletions(-) delete mode 100644 spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractTickCounter.java delete mode 100644 spark-common/src/main/java/me/lucko/spark/common/sampler/TickCounter.java create mode 100644 spark-common/src/main/java/me/lucko/spark/common/sampler/tick/AbstractTickHook.java create mode 100644 spark-common/src/main/java/me/lucko/spark/common/sampler/tick/AbstractTickReporter.java create mode 100644 spark-common/src/main/java/me/lucko/spark/common/sampler/tick/TickHook.java create mode 100644 spark-common/src/main/java/me/lucko/spark/common/sampler/tick/TickReporter.java (limited to 'spark-common/src/main/java/me/lucko/spark/common/sampler') diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractTickCounter.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractTickCounter.java deleted file mode 100644 index 4633024..0000000 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/AbstractTickCounter.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of spark. - * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package me.lucko.spark.common.sampler; - -import java.util.HashSet; -import java.util.Set; - -public abstract class AbstractTickCounter implements TickCounter { - - private final Set tasks = new HashSet<>(); - private int tick = 0; - - protected void onTick() { - for (TickTask r : this.tasks) { - r.onTick(this); - } - this.tick++; - } - - @Override - public int getCurrentTick() { - return this.tick; - } - - @Override - public void addTickTask(TickTask runnable) { - this.tasks.add(runnable); - } - - @Override - public void removeTickTask(TickTask runnable) { - this.tasks.remove(runnable); - } - -} diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/Sampler.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/Sampler.java index 81a757a..56093c0 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/Sampler.java +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/Sampler.java @@ -27,6 +27,7 @@ import me.lucko.spark.common.sampler.aggregator.DataAggregator; import me.lucko.spark.common.sampler.aggregator.SimpleDataAggregator; import me.lucko.spark.common.sampler.aggregator.TickedDataAggregator; import me.lucko.spark.common.sampler.node.ThreadNode; +import me.lucko.spark.common.sampler.tick.TickHook; import me.lucko.spark.proto.SparkProtos.SamplerData; import me.lucko.spark.proto.SparkProtos.SamplerMetadata; @@ -86,9 +87,9 @@ public class Sampler implements Runnable { this.endTime = endTime; } - public Sampler(int interval, ThreadDumper threadDumper, ThreadGrouper threadGrouper, long endTime, boolean includeLineNumbers, boolean ignoreSleeping, TickCounter tickCounter, int tickLengthThreshold) { + public Sampler(int interval, ThreadDumper threadDumper, ThreadGrouper threadGrouper, long endTime, boolean includeLineNumbers, boolean ignoreSleeping, TickHook tickHook, int tickLengthThreshold) { this.threadDumper = threadDumper; - this.dataAggregator = new TickedDataAggregator(this.workerPool, threadGrouper, interval, includeLineNumbers, ignoreSleeping, tickCounter, tickLengthThreshold); + this.dataAggregator = new TickedDataAggregator(this.workerPool, threadGrouper, interval, includeLineNumbers, ignoreSleeping, tickHook, tickLengthThreshold); this.interval = interval; this.endTime = endTime; } diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/SamplerBuilder.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/SamplerBuilder.java index 4808214..ae7fb89 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/SamplerBuilder.java +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/SamplerBuilder.java @@ -20,6 +20,8 @@ package me.lucko.spark.common.sampler; +import me.lucko.spark.common.sampler.tick.TickHook; + import java.util.concurrent.TimeUnit; /** @@ -35,7 +37,7 @@ public class SamplerBuilder { private ThreadGrouper threadGrouper = ThreadGrouper.BY_NAME; private int ticksOver = -1; - private TickCounter tickCounter = null; + private TickHook tickHook = null; public SamplerBuilder() { } @@ -63,9 +65,9 @@ public class SamplerBuilder { return this; } - public SamplerBuilder ticksOver(int ticksOver, TickCounter tickCounter) { + public SamplerBuilder ticksOver(int ticksOver, TickHook tickHook) { this.ticksOver = ticksOver; - this.tickCounter = tickCounter; + this.tickHook = tickHook; return this; } @@ -83,10 +85,10 @@ public class SamplerBuilder { Sampler sampler; int intervalMicros = (int) (this.samplingInterval * 1000d); - if (this.ticksOver == -1 || this.tickCounter == null) { + if (this.ticksOver == -1 || this.tickHook == null) { sampler = new Sampler(intervalMicros, this.threadDumper, this.threadGrouper, this.timeout, this.includeLineNumbers, this.ignoreSleeping); } else { - sampler = new Sampler(intervalMicros, this.threadDumper, this.threadGrouper, this.timeout, this.includeLineNumbers, this.ignoreSleeping, this.tickCounter, this.ticksOver); + sampler = new Sampler(intervalMicros, this.threadDumper, this.threadGrouper, this.timeout, this.includeLineNumbers, this.ignoreSleeping, this.tickHook, this.ticksOver); } sampler.start(); diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/TickCounter.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/TickCounter.java deleted file mode 100644 index aa839ba..0000000 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/TickCounter.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of spark. - * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package me.lucko.spark.common.sampler; - -/** - * A hook with the game's "tick loop". - */ -public interface TickCounter extends AutoCloseable { - - /** - * Starts the counter - */ - void start(); - - /** - * Stops the counter - */ - @Override - void close(); - - /** - * Gets the current tick number - * - * @return the current tick - */ - int getCurrentTick(); - - /** - * Adds a task to be called each time the tick increments - * - * @param runnable the task - */ - void addTickTask(TickTask runnable); - - /** - * Removes a tick task - * - * @param runnable the task - */ - void removeTickTask(TickTask runnable); - - interface TickTask { - void onTick(TickCounter counter); - } - -} diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/TickedDataAggregator.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/TickedDataAggregator.java index a4dfdb8..d8fda73 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/TickedDataAggregator.java +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/aggregator/TickedDataAggregator.java @@ -21,8 +21,8 @@ package me.lucko.spark.common.sampler.aggregator; import me.lucko.spark.common.sampler.ThreadGrouper; -import me.lucko.spark.common.sampler.TickCounter; import me.lucko.spark.common.sampler.node.ThreadNode; +import me.lucko.spark.common.sampler.tick.TickHook; import me.lucko.spark.proto.SparkProtos.SamplerMetadata; import java.lang.management.ThreadInfo; @@ -39,7 +39,7 @@ import java.util.concurrent.TimeUnit; public class TickedDataAggregator extends AbstractDataAggregator { /** Used to monitor the current "tick" of the server */ - private final TickCounter tickCounter; + private final TickHook tickHook; /** Tick durations under this threshold will not be inserted, measured in microseconds */ private final long tickLengthThreshold; @@ -53,9 +53,9 @@ public class TickedDataAggregator extends AbstractDataAggregator { private int currentTick = -1; private TickList currentData = new TickList(0); - public TickedDataAggregator(ExecutorService workerPool, ThreadGrouper threadGrouper, int interval, boolean includeLineNumbers, boolean ignoreSleeping, TickCounter tickCounter, int tickLengthThreshold) { + public TickedDataAggregator(ExecutorService workerPool, ThreadGrouper threadGrouper, int interval, boolean includeLineNumbers, boolean ignoreSleeping, TickHook tickHook, int tickLengthThreshold) { super(workerPool, threadGrouper, interval, includeLineNumbers, ignoreSleeping); - this.tickCounter = tickCounter; + this.tickHook = tickHook; this.tickLengthThreshold = TimeUnit.MILLISECONDS.toMicros(tickLengthThreshold); // 50 millis in a tick, plus 10 so we have a bit of room to go over double intervalMilliseconds = interval / 1000d; @@ -74,7 +74,7 @@ public class TickedDataAggregator extends AbstractDataAggregator { @Override public void insertData(ThreadInfo threadInfo) { synchronized (this.mutex) { - int tick = this.tickCounter.getCurrentTick(); + int tick = this.tickHook.getCurrentTick(); if (this.currentTick != tick) { pushCurrentTick(); this.currentTick = tick; diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/tick/AbstractTickHook.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/tick/AbstractTickHook.java new file mode 100644 index 0000000..b4e5054 --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/tick/AbstractTickHook.java @@ -0,0 +1,53 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.common.sampler.tick; + +import java.util.HashSet; +import java.util.Set; + +public abstract class AbstractTickHook implements TickHook { + + private final Set tasks = new HashSet<>(); + private int tick = 0; + + protected void onTick() { + for (Callback r : this.tasks) { + r.onTick(this); + } + this.tick++; + } + + @Override + public int getCurrentTick() { + return this.tick; + } + + @Override + public void addCallback(Callback runnable) { + this.tasks.add(runnable); + } + + @Override + public void removeCallback(Callback runnable) { + this.tasks.remove(runnable); + } + +} diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/tick/AbstractTickReporter.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/tick/AbstractTickReporter.java new file mode 100644 index 0000000..4005f87 --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/tick/AbstractTickReporter.java @@ -0,0 +1,45 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.common.sampler.tick; + +import java.util.HashSet; +import java.util.Set; + +public abstract class AbstractTickReporter implements TickReporter { + private final Set tasks = new HashSet<>(); + + protected void onTick(double duration) { + for (Callback r : this.tasks) { + r.onTick(duration); + } + } + + @Override + public void addCallback(Callback runnable) { + this.tasks.add(runnable); + } + + @Override + public void removeCallback(Callback runnable) { + this.tasks.remove(runnable); + } + +} diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/tick/TickHook.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/tick/TickHook.java new file mode 100644 index 0000000..a0dd425 --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/tick/TickHook.java @@ -0,0 +1,64 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.common.sampler.tick; + +/** + * A hook with the game's "tick loop". + */ +public interface TickHook extends AutoCloseable { + + /** + * Starts the hook + */ + void start(); + + /** + * Stops the hook + */ + @Override + void close(); + + /** + * Gets the current tick number + * + * @return the current tick + */ + int getCurrentTick(); + + /** + * Adds a callback to be called each time the tick increments + * + * @param runnable the task + */ + void addCallback(Callback runnable); + + /** + * Removes a callback + * + * @param runnable the callback + */ + void removeCallback(Callback runnable); + + interface Callback { + void onTick(TickHook hook); + } + +} diff --git a/spark-common/src/main/java/me/lucko/spark/common/sampler/tick/TickReporter.java b/spark-common/src/main/java/me/lucko/spark/common/sampler/tick/TickReporter.java new file mode 100644 index 0000000..e922e72 --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/sampler/tick/TickReporter.java @@ -0,0 +1,57 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package me.lucko.spark.common.sampler.tick; + +/** + * A reporting callback for the game's "tick loop". + */ +public interface TickReporter extends AutoCloseable { + + /** + * Starts the reporter + */ + void start(); + + /** + * Stops the reporter + */ + @Override + void close(); + + /** + * Adds a callback to be called each time the tick increments + * + * @param runnable the callback + */ + void addCallback(Callback runnable); + + /** + * Removes a callback + * + * @param runnable callback + */ + void removeCallback(Callback runnable); + + interface Callback { + void onTick(double duration); + } + +} -- cgit