Periodically remove extension observers (every minute at the moment)

This commit is contained in:
jglrxavpok 2021-02-17 17:37:54 +01:00
parent 6addd63396
commit e40186a2aa
2 changed files with 37 additions and 14 deletions

View File

@ -1,14 +1,13 @@
package net.minestom.server.extensions;
import net.minestom.server.event.handler.EventHandler;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;
public abstract class Extension {
@ -26,6 +25,7 @@ public abstract class Extension {
* from being cleaned up.
*/
private Set<WeakReference<IExtensionObserver>> observers = Collections.newSetFromMap(new ConcurrentHashMap<>());
private ReferenceQueue<IExtensionObserver> observerReferenceQueue = new ReferenceQueue<>();
protected Extension() {
@ -74,7 +74,7 @@ public abstract class Extension {
* @param observer
*/
public void observe(IExtensionObserver observer) {
observers.add(new WeakReference<>(observer));
observers.add(new WeakReference<>(observer, observerReferenceQueue));
}
/**
@ -97,6 +97,18 @@ public abstract class Extension {
return !getDescription().failedToLoadMixin && getDescription().getMissingCodeModifiers().isEmpty();
}
/**
* Removes all expired reference to observers
*
* @see #observers
*/
public void cleanupObservers() {
Reference<? extends IExtensionObserver> ref;
while((ref = observerReferenceQueue.poll()) != null) {
observers.remove(ref);
}
}
public static class ExtensionDescription {
private final String name;
private final String version;

View File

@ -8,6 +8,7 @@ import net.minestom.server.MinecraftServer;
import net.minestom.server.extras.selfmodification.MinestomExtensionClassLoader;
import net.minestom.server.extras.selfmodification.MinestomRootClassLoader;
import net.minestom.server.ping.ResponseDataConsumer;
import net.minestom.server.utils.time.TimeUnit;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -124,6 +125,13 @@ public class ExtensionManager {
MinecraftServer.getExceptionManager().handleException(e);
}
}
// periodically cleanup observers
MinecraftServer.getSchedulerManager().buildTask(() -> {
for(Extension ext : extensionList) {
ext.cleanupObservers();
}
}).repeat(1L, TimeUnit.MINUTE).schedule();
}
private void setupClassLoader(@NotNull DiscoveredExtension discoveredExtension) {
@ -241,16 +249,19 @@ public class ExtensionManager {
@NotNull
private List<DiscoveredExtension> discoverExtensions() {
List<DiscoveredExtension> extensions = new LinkedList<>();
for (File file : extensionFolder.listFiles()) {
if (file.isDirectory()) {
continue;
}
if (!file.getName().endsWith(".jar")) {
continue;
}
DiscoveredExtension extension = discoverFromJar(file);
if (extension != null && extension.loadStatus == DiscoveredExtension.LoadStatus.LOAD_SUCCESS) {
extensions.add(extension);
File[] fileList = extensionFolder.listFiles();
if(fileList != null) {
for (File file : fileList) {
if (file.isDirectory()) {
continue;
}
if (!file.getName().endsWith(".jar")) {
continue;
}
DiscoveredExtension extension = discoverFromJar(file);
if (extension != null && extension.loadStatus == DiscoveredExtension.LoadStatus.LOAD_SUCCESS) {
extensions.add(extension);
}
}
}