Fix ExpiringSet not really working & causing memory leaks (#3027)

This commit is contained in:
Luck 2021-05-19 12:31:48 +01:00
parent 228687b741
commit f5cdb98b01
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
4 changed files with 23 additions and 17 deletions

View File

@ -53,13 +53,12 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class LuckPermsMessagingService implements InternalMessagingService, IncomingMessageConsumer { public class LuckPermsMessagingService implements InternalMessagingService, IncomingMessageConsumer {
private final LuckPermsPlugin plugin; private final LuckPermsPlugin plugin;
private final Set<UUID> receivedMessages; private final ExpiringSet<UUID> receivedMessages;
private final PushUpdateBuffer updateBuffer; private final PushUpdateBuffer updateBuffer;
private final MessengerProvider messengerProvider; private final MessengerProvider messengerProvider;

View File

@ -36,7 +36,6 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -98,7 +97,7 @@ public class FileWatcher extends AbstractFileWatcher {
private final Path path; private final Path path;
/** A set of files which have been modified recently */ /** A set of files which have been modified recently */
private final Set<String> recentlyModifiedFiles = new ExpiringSet<>(4, TimeUnit.SECONDS); private final ExpiringSet<String> recentlyModifiedFiles = new ExpiringSet<>(4, TimeUnit.SECONDS);
/** The listener callback functions */ /** The listener callback functions */
private final List<Consumer<Path>> callbacks = new CopyOnWriteArrayList<>(); private final List<Consumer<Path>> callbacks = new CopyOnWriteArrayList<>();

View File

@ -26,10 +26,7 @@
package me.lucko.luckperms.common.util; package me.lucko.luckperms.common.util;
import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Cache;
import com.google.common.collect.ForwardingSet;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
@ -37,16 +34,27 @@ import java.util.concurrent.TimeUnit;
* *
* @param <E> element type * @param <E> element type
*/ */
public class ExpiringSet<E> extends ForwardingSet<E> { public class ExpiringSet<E> {
private final Set<E> setView; private final Cache<E, Long> cache;
private final long lifetime;
public ExpiringSet(long duration, TimeUnit unit) { public ExpiringSet(long duration, TimeUnit unit) {
Cache<E, Boolean> cache = CaffeineFactory.newBuilder().expireAfterAccess(duration, unit).build(); this.cache = CaffeineFactory.newBuilder().expireAfterWrite(duration, unit).build();
this.setView = Collections.newSetFromMap(cache.asMap()); this.lifetime = unit.toMillis(duration);
} }
@Override public boolean add(E item) {
protected Set<E> delegate() { boolean present = contains(item);
return this.setView; this.cache.put(item, System.currentTimeMillis() + this.lifetime);
return !present;
}
public boolean contains(E item) {
Long timeout = this.cache.getIfPresent(item);
return timeout != null && timeout > System.currentTimeMillis();
}
public void remove(E item) {
this.cache.invalidate(item);
} }
} }

View File

@ -4,14 +4,14 @@ plugins {
} }
repositories { repositories {
maven { url 'https://repo.velocitypowered.com/snapshots/' } maven { url 'https://repo.velocitypowered.com/releases/' }
} }
dependencies { dependencies {
compile project(':common') compile project(':common')
compileOnly 'com.velocitypowered:velocity-api:1.1.0-SNAPSHOT' compileOnly 'com.velocitypowered:velocity-api:1.1.5'
annotationProcessor 'com.velocitypowered:velocity-api:1.1.0-SNAPSHOT' annotationProcessor 'com.velocitypowered:velocity-api:1.1.5'
} }
blossom { blossom {