The first bug in #548 (and the only issue in #547) was a typo. The second bug was fixed by tracking "friends" of the event types, so we can invalidate everything as needed.
This commit is contained in:
Andrew Steinborn
2021-07-19 13:26:37 -04:00
parent f79736b8b7
commit e017949abf
3 changed files with 245 additions and 10 deletions

View File

@@ -0,0 +1,41 @@
package com.velocitypowered.proxy.event;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.reflect.TypeToken;
import java.util.List;
import java.util.stream.Collectors;
class EventTypeTracker {
private final ListMultimap<Class<?>, Class<?>> friends;
public EventTypeTracker() {
this.friends = ArrayListMultimap.create();
}
public List<Class<?>> getFriendsOf(final Class<?> eventType) {
if (friends.containsKey(eventType)) {
return ImmutableList.copyOf(friends.get(eventType));
}
final List<Class<?>> types = getEventTypes(eventType);
for (Class<?> type : types) {
if (type == eventType) {
continue;
}
friends.put(type, eventType);
}
return types;
}
private static List<Class<?>> getEventTypes(final Class<?> eventType) {
return TypeToken.of(eventType).getTypes().rawTypes().stream()
.filter(type -> type != Object.class)
.collect(Collectors.toList());
}
}

View File

@@ -99,6 +99,7 @@ public class VelocityEventManager implements EventManager {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final List<CustomHandlerAdapter<?>> handlerAdapters = new ArrayList<>();
private final EventTypeTracker eventTypeTracker = new EventTypeTracker();
/**
* Initializes the Velocity event manager.
@@ -172,15 +173,9 @@ public class VelocityEventManager implements EventManager {
}
}
private static List<Class<?>> getEventTypes(final Class<?> eventType) {
return TypeToken.of(eventType).getTypes().rawTypes().stream()
.filter(type -> type != Object.class)
.collect(Collectors.toList());
}
private @Nullable HandlersCache bakeHandlers(final Class<?> eventType) {
final List<HandlerRegistration> baked = new ArrayList<>();
final List<Class<?>> types = getEventTypes(eventType);
final List<Class<?>> types = eventTypeTracker.getFriendsOf(eventType);
lock.readLock().lock();
try {
@@ -336,7 +331,7 @@ public class VelocityEventManager implements EventManager {
}
// Invalidate all the affected event subtypes
handlersCache.invalidateAll(registrations.stream()
.flatMap(registration -> getEventTypes(registration.eventType).stream())
.flatMap(registration -> eventTypeTracker.getFriendsOf(registration.eventType).stream())
.distinct()
.collect(Collectors.toList()));
}
@@ -407,7 +402,7 @@ public class VelocityEventManager implements EventManager {
final PluginContainer pluginContainer = pluginManager.ensurePluginContainer(plugin);
requireNonNull(handler, "handler");
unregisterIf(registration ->
registration.plugin == pluginContainer && registration.handler == handler);
registration.plugin == pluginContainer && registration.instance == handler);
}
@Override
@@ -433,7 +428,7 @@ public class VelocityEventManager implements EventManager {
// Invalidate all the affected event subtypes
handlersCache.invalidateAll(removed.stream()
.flatMap(registration -> getEventTypes(registration.eventType).stream())
.flatMap(registration -> eventTypeTracker.getFriendsOf(registration.eventType).stream())
.distinct()
.collect(Collectors.toList()));
}