mirror of
https://github.com/Minestom/Minestom.git
synced 2024-11-15 15:16:46 +01:00
Added AcquirableCollection + waiting time monitor
This commit is contained in:
parent
56cc33fcfa
commit
b5add32ad6
@ -136,7 +136,7 @@ public final class MinecraftServer {
|
|||||||
private static int compressionThreshold = 256;
|
private static int compressionThreshold = 256;
|
||||||
private static boolean packetCaching = true;
|
private static boolean packetCaching = true;
|
||||||
private static boolean groupedPacket = true;
|
private static boolean groupedPacket = true;
|
||||||
private static boolean waitMonitoring = false;
|
private static boolean waitMonitoring = true;
|
||||||
private static ResponseDataConsumer responseDataConsumer;
|
private static ResponseDataConsumer responseDataConsumer;
|
||||||
private static String brandName = "Minestom";
|
private static String brandName = "Minestom";
|
||||||
private static Difficulty difficulty = Difficulty.NORMAL;
|
private static Difficulty difficulty = Difficulty.NORMAL;
|
||||||
|
@ -86,10 +86,9 @@ public final class UpdateManager {
|
|||||||
|
|
||||||
// Monitoring
|
// Monitoring
|
||||||
if (!tickMonitors.isEmpty()) {
|
if (!tickMonitors.isEmpty()) {
|
||||||
// TODO use value
|
|
||||||
final double acquisitionTimeMs = Acquisition.getCurrentWaitMonitoring() / 1e6D;
|
final double acquisitionTimeMs = Acquisition.getCurrentWaitMonitoring() / 1e6D;
|
||||||
final double tickTimeMs = tickTime / 1e6D;
|
final double tickTimeMs = tickTime / 1e6D;
|
||||||
final TickMonitor tickMonitor = new TickMonitor(tickTimeMs);
|
final TickMonitor tickMonitor = new TickMonitor(tickTimeMs, acquisitionTimeMs);
|
||||||
this.tickMonitors.forEach(consumer -> consumer.accept(tickMonitor));
|
this.tickMonitors.forEach(consumer -> consumer.accept(tickMonitor));
|
||||||
|
|
||||||
Acquisition.resetWaitMonitoring();
|
Acquisition.resetWaitMonitoring();
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package net.minestom.server.lock;
|
||||||
|
|
||||||
|
import net.minestom.server.utils.collection.CollectionView;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class AcquirableCollection<E extends LockedElement> extends CollectionView<E, Acquirable<E>> {
|
||||||
|
|
||||||
|
private final Collection<Acquirable<E>> acquirableCollection;
|
||||||
|
|
||||||
|
public AcquirableCollection(@NotNull Collection<Acquirable<E>> acquirableCollection) {
|
||||||
|
super(acquirableCollection,
|
||||||
|
LockedElement::getAcquiredElement,
|
||||||
|
Acquirable::unwrap);
|
||||||
|
this.acquirableCollection = acquirableCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void forEachAcquire(@NotNull Consumer<@NotNull E> action) {
|
||||||
|
Acquisition.acquireForEach(acquirableCollection, action);
|
||||||
|
}
|
||||||
|
}
|
@ -3,12 +3,18 @@ package net.minestom.server.monitoring;
|
|||||||
public class TickMonitor {
|
public class TickMonitor {
|
||||||
|
|
||||||
private final double tickTime;
|
private final double tickTime;
|
||||||
|
private final double acquisitionTime;
|
||||||
|
|
||||||
public TickMonitor(double tickTime) {
|
public TickMonitor(double tickTime, double acquisitionTime) {
|
||||||
this.tickTime = tickTime;
|
this.tickTime = tickTime;
|
||||||
|
this.acquisitionTime = acquisitionTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getTickTime() {
|
public double getTickTime() {
|
||||||
return tickTime;
|
return tickTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getAcquisitionTime() {
|
||||||
|
return acquisitionTime;
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,178 @@
|
|||||||
|
package net.minestom.server.utils.collection;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A CollectionView is a class which is mapped to another collection
|
||||||
|
* and convert every result using a given function. It is more efficient
|
||||||
|
* than filling a new collection every time, as long as the two types are interchangeable.
|
||||||
|
* <p>
|
||||||
|
* The view is not thread-safe.
|
||||||
|
*
|
||||||
|
* @param <E> the type that the collection should return
|
||||||
|
* @param <V> the type of the viewed collection
|
||||||
|
*/
|
||||||
|
public class CollectionView<E, V> implements Collection<E> {
|
||||||
|
|
||||||
|
private final Collection<V> collectionView;
|
||||||
|
private final Function<E, V> toViewFunction;
|
||||||
|
private final Function<V, E> toTypeFunction;
|
||||||
|
|
||||||
|
public CollectionView(@NotNull Collection<V> collectionView,
|
||||||
|
@NotNull Function<E, V> toViewFunction,
|
||||||
|
@NotNull Function<V, E> toTypeFunction) {
|
||||||
|
this.collectionView = collectionView;
|
||||||
|
this.toViewFunction = toViewFunction;
|
||||||
|
this.toTypeFunction = toTypeFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return collectionView.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return collectionView.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Object o) {
|
||||||
|
try {
|
||||||
|
return collectionView.contains(toViewFunction.apply((E) o));
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Iterator<E> iterator() {
|
||||||
|
return new IteratorView<>(collectionView.iterator(), toTypeFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Object[] toArray() {
|
||||||
|
Object[] array = new Object[size()];
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (E e : this) {
|
||||||
|
array[i++] = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public <T1> T1[] toArray(@NotNull T1[] a) {
|
||||||
|
int i = 0;
|
||||||
|
for (E e : this) {
|
||||||
|
a[i++] = (T1) e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(E e) {
|
||||||
|
return collectionView.add(toViewFunction.apply(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Object o) {
|
||||||
|
try {
|
||||||
|
return collectionView.remove(toViewFunction.apply((E) o));
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAll(@NotNull Collection<?> c) {
|
||||||
|
for (Object e : c) {
|
||||||
|
if (!contains(e))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addAll(@NotNull Collection<? extends E> c) {
|
||||||
|
boolean changed = false;
|
||||||
|
try {
|
||||||
|
for (Object e : c) {
|
||||||
|
if (add((E) e))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
} catch (ClassCastException ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeAll(@NotNull Collection<?> c) {
|
||||||
|
boolean changed = false;
|
||||||
|
try {
|
||||||
|
for (Object e : c) {
|
||||||
|
if (remove(e))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
} catch (ClassCastException ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean retainAll(@NotNull Collection<?> c) {
|
||||||
|
boolean changed = false;
|
||||||
|
try {
|
||||||
|
for (Object e : c) {
|
||||||
|
if (!contains(e)) {
|
||||||
|
remove(e);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ClassCastException ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
this.collectionView.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class IteratorView<T, V> implements Iterator<T> {
|
||||||
|
|
||||||
|
private final Iterator<V> iteratorView;
|
||||||
|
private final Function<V, T> toTypeFunction;
|
||||||
|
|
||||||
|
public IteratorView(Iterator<V> iteratorView,
|
||||||
|
Function<V, T> toTypeFunction) {
|
||||||
|
this.iteratorView = iteratorView;
|
||||||
|
this.toTypeFunction = toTypeFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return iteratorView.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T next() {
|
||||||
|
final V viewElement = iteratorView.next();
|
||||||
|
return toTypeFunction.apply(viewElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,10 +1,8 @@
|
|||||||
package demo;
|
package demo;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.AtomicDouble;
|
|
||||||
import demo.generator.ChunkGeneratorDemo;
|
import demo.generator.ChunkGeneratorDemo;
|
||||||
import demo.generator.NoiseTestGenerator;
|
import demo.generator.NoiseTestGenerator;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.TextColor;
|
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.adventure.audience.Audiences;
|
import net.minestom.server.adventure.audience.Audiences;
|
||||||
import net.minestom.server.chat.ColoredText;
|
import net.minestom.server.chat.ColoredText;
|
||||||
@ -32,8 +30,8 @@ import net.minestom.server.item.ItemTag;
|
|||||||
import net.minestom.server.item.Material;
|
import net.minestom.server.item.Material;
|
||||||
import net.minestom.server.item.metadata.CompassMeta;
|
import net.minestom.server.item.metadata.CompassMeta;
|
||||||
import net.minestom.server.monitoring.BenchmarkManager;
|
import net.minestom.server.monitoring.BenchmarkManager;
|
||||||
|
import net.minestom.server.monitoring.TickMonitor;
|
||||||
import net.minestom.server.network.ConnectionManager;
|
import net.minestom.server.network.ConnectionManager;
|
||||||
import net.minestom.server.ping.ResponseDataConsumer;
|
|
||||||
import net.minestom.server.utils.MathUtils;
|
import net.minestom.server.utils.MathUtils;
|
||||||
import net.minestom.server.utils.Position;
|
import net.minestom.server.utils.Position;
|
||||||
import net.minestom.server.utils.Vector;
|
import net.minestom.server.utils.Vector;
|
||||||
@ -43,8 +41,8 @@ import net.minestom.server.world.DimensionType;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
public class PlayerInit {
|
public class PlayerInit {
|
||||||
|
|
||||||
@ -91,14 +89,14 @@ public class PlayerInit {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AtomicDouble LAST_TICK_TIME = new AtomicDouble();
|
private static AtomicReference<TickMonitor> LAST_TICK = new AtomicReference<>();
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
ConnectionManager connectionManager = MinecraftServer.getConnectionManager();
|
ConnectionManager connectionManager = MinecraftServer.getConnectionManager();
|
||||||
BenchmarkManager benchmarkManager = MinecraftServer.getBenchmarkManager();
|
BenchmarkManager benchmarkManager = MinecraftServer.getBenchmarkManager();
|
||||||
|
|
||||||
MinecraftServer.getUpdateManager().addTickMonitor(tickMonitor ->
|
MinecraftServer.getUpdateManager().addTickMonitor(tickMonitor ->
|
||||||
LAST_TICK_TIME.set(tickMonitor.getTickTime()));
|
LAST_TICK.set(tickMonitor));
|
||||||
|
|
||||||
MinecraftServer.getSchedulerManager().buildTask(() -> {
|
MinecraftServer.getSchedulerManager().buildTask(() -> {
|
||||||
|
|
||||||
@ -110,9 +108,13 @@ public class PlayerInit {
|
|||||||
long ramUsage = benchmarkManager.getUsedMemory();
|
long ramUsage = benchmarkManager.getUsedMemory();
|
||||||
ramUsage /= 1e6; // bytes to MB
|
ramUsage /= 1e6; // bytes to MB
|
||||||
|
|
||||||
|
TickMonitor tickMonitor = LAST_TICK.get();
|
||||||
|
|
||||||
final Component header = Component.text("RAM USAGE: " + ramUsage + " MB")
|
final Component header = Component.text("RAM USAGE: " + ramUsage + " MB")
|
||||||
.append(Component.newline())
|
.append(Component.newline())
|
||||||
.append(Component.text("TICK TIME: " + MathUtils.round(LAST_TICK_TIME.get(), 2) + "ms"));
|
.append(Component.text("TICK TIME: " + MathUtils.round(tickMonitor.getTickTime(), 2) + "ms"))
|
||||||
|
.append(Component.newline())
|
||||||
|
.append(Component.text("ACQ TIME: " + MathUtils.round(tickMonitor.getAcquisitionTime(), 2) + "ms"));
|
||||||
final Component footer = benchmarkManager.getCpuMonitoringMessage();
|
final Component footer = benchmarkManager.getCpuMonitoringMessage();
|
||||||
Audiences.players().sendPlayerListHeaderAndFooter(header, footer);
|
Audiences.players().sendPlayerListHeaderAndFooter(header, footer);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user