From 991bc61b0c140697208a15c0314670a118555282 Mon Sep 17 00:00:00 2001 From: pop4959 Date: Fri, 5 May 2023 15:44:22 -0700 Subject: [PATCH] Expire UserMap cache more aggressively and add cache debugging (#5331) --- .../java/com/earth2me/essentials/ISettings.java | 2 ++ .../java/com/earth2me/essentials/Settings.java | 8 +++++++- .../essentials/userstorage/ModernUserMap.java | 17 +++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/ISettings.java b/Essentials/src/main/java/com/earth2me/essentials/ISettings.java index 4da7f5254..823734ebc 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/ISettings.java +++ b/Essentials/src/main/java/com/earth2me/essentials/ISettings.java @@ -282,6 +282,8 @@ public interface ISettings extends IConf { int getMaxUserCacheCount(); + long getMaxUserCacheValueExpiry(); + boolean allowSilentJoinQuit(); boolean isCustomJoinMessage(); diff --git a/Essentials/src/main/java/com/earth2me/essentials/Settings.java b/Essentials/src/main/java/com/earth2me/essentials/Settings.java index c0b1c6182..43d2109d7 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Settings.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Settings.java @@ -1469,10 +1469,16 @@ public class Settings implements net.ess3.api.ISettings { // #easteregg @Override public int getMaxUserCacheCount() { - final long count = Runtime.getRuntime().maxMemory() / 1024 / 96; + final long count = Runtime.getRuntime().maxMemory() / 1024 / 1024; return config.getInt("max-user-cache-count", (int) count); } + // #easteregg + @Override + public long getMaxUserCacheValueExpiry() { + return config.getLong("max-user-cache-value-expiry", 600); + } + @Override public boolean isLastMessageReplyRecipient() { return config.getBoolean("last-message-reply-recipient", false); diff --git a/Essentials/src/main/java/com/earth2me/essentials/userstorage/ModernUserMap.java b/Essentials/src/main/java/com/earth2me/essentials/userstorage/ModernUserMap.java index eaab42c0f..2fee7e6db 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/userstorage/ModernUserMap.java +++ b/Essentials/src/main/java/com/earth2me/essentials/userstorage/ModernUserMap.java @@ -16,6 +16,7 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; @@ -26,6 +27,7 @@ public class ModernUserMap extends CacheLoader implements IUserMap { private final boolean debugPrintStackWithWarn; private final long debugMaxWarnsPerType; + private final boolean debugLogCache; private final ConcurrentMap debugNonPlayerWarnCounts; public ModernUserMap(final IEssentials ess) { @@ -33,6 +35,7 @@ public class ModernUserMap extends CacheLoader implements IUserMap { this.uuidCache = new ModernUUIDCache(ess); this.userCache = CacheBuilder.newBuilder() .maximumSize(ess.getSettings().getMaxUserCacheCount()) + .expireAfterAccess(ess.getSettings().getMaxUserCacheValueExpiry(), TimeUnit.SECONDS) .softValues() .build(this); @@ -40,9 +43,12 @@ public class ModernUserMap extends CacheLoader implements IUserMap { final String printStackProperty = System.getProperty("net.essentialsx.usermap.print-stack", "false"); // -Dnet.essentialsx.usermap.max-warns=20 final String maxWarnProperty = System.getProperty("net.essentialsx.usermap.max-warns", "100"); + // -Dnet.essentialsx.usermap.log-cache=true + final String logCacheProperty = System.getProperty("net.essentialsx.usermap.log-cache", "false"); this.debugMaxWarnsPerType = NumberUtil.isLong(maxWarnProperty) ? Long.parseLong(maxWarnProperty) : -1; this.debugPrintStackWithWarn = Boolean.parseBoolean(printStackProperty); + this.debugLogCache = Boolean.parseBoolean(logCacheProperty); this.debugNonPlayerWarnCounts = new ConcurrentHashMap<>(); } @@ -81,6 +87,7 @@ public class ModernUserMap extends CacheLoader implements IUserMap { public User getUser(final Player base) { final User user = loadUncachedUser(base); userCache.put(user.getUUID(), user); + debugLogCache(user); return user; } @@ -114,6 +121,7 @@ public class ModernUserMap extends CacheLoader implements IUserMap { public User load(final UUID uuid) throws Exception { final User user = loadUncachedUser(uuid); if (user != null) { + debugLogCache(user); return user; } @@ -168,6 +176,7 @@ public class ModernUserMap extends CacheLoader implements IUserMap { public void addCachedUser(final User user) { userCache.put(user.getUUID(), user); + debugLogCache(user); } @Override @@ -196,6 +205,14 @@ public class ModernUserMap extends CacheLoader implements IUserMap { uuidCache.shutdown(); } + private void debugLogCache(final User user) { + if (!debugLogCache) { + return; + } + final Throwable throwable = new Throwable(); + ess.getLogger().log(Level.INFO, String.format("Caching user %s (%s)", user.getName(), user.getUUID()), throwable); + } + private void debugLogUncachedNonPlayer(final Player base) { final String typeName = base.getClass().getName(); final long count = debugNonPlayerWarnCounts.computeIfAbsent(typeName, name -> new AtomicLong(0)).getAndIncrement();