Added AcquirableCollection + waiting time monitor

This commit is contained in:
TheMode 2021-04-15 09:51:37 +02:00
parent 56cc33fcfa
commit b5add32ad6
6 changed files with 219 additions and 11 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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;
}
} }

View File

@ -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);
}
}
}

View File

@ -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);