From 2f48f17a4e0f14fa160bb503eff5c0e0d9a0cdec Mon Sep 17 00:00:00 2001 From: Risto Lahtela <24460436+AuroraLS3@users.noreply.github.com> Date: Sun, 14 Feb 2021 18:24:42 +0200 Subject: [PATCH] Cache placeholder result on non-server thread Affects issues: - Fixed #1756 --- .../PlanPlaceholderExtension.java | 38 ++++++++++++++++++- .../plan/placeholder/PlanPlaceholders.java | 6 --- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/addons/placeholderapi/PlanPlaceholderExtension.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/addons/placeholderapi/PlanPlaceholderExtension.java index 927c2dcf9..a793fa4cd 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/addons/placeholderapi/PlanPlaceholderExtension.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/addons/placeholderapi/PlanPlaceholderExtension.java @@ -18,16 +18,23 @@ package com.djrapitops.plan.addons.placeholderapi; import com.djrapitops.plan.PlanSystem; import com.djrapitops.plan.placeholder.PlanPlaceholders; +import com.djrapitops.plan.processing.Processing; import com.djrapitops.plan.utilities.logging.ErrorContext; import com.djrapitops.plan.utilities.logging.ErrorLogger; import com.djrapitops.plan.version.VersionChecker; import com.djrapitops.plugin.logging.L; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import org.bukkit.entity.Player; import java.util.Collections; +import java.util.Objects; +import java.util.Set; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; /** * Placeholder expansion used to provide data from Plan on Bukkit. @@ -40,14 +47,24 @@ public class PlanPlaceholderExtension extends PlaceholderExpansion { private final VersionChecker versionChecker; private final PlanPlaceholders placeholders; + private final Set currentlyProcessing; + private final Processing processing; + private final Cache cache; + public PlanPlaceholderExtension( PlanPlaceholders placeholders, PlanSystem system, ErrorLogger errorLogger ) { this.placeholders = placeholders; + processing = system.getProcessing(); this.versionChecker = system.getVersionChecker(); this.errorLogger = errorLogger; + + currentlyProcessing = Collections.newSetFromMap(new ConcurrentHashMap<>()); + cache = Caffeine.newBuilder() + .expireAfterWrite(60, TimeUnit.SECONDS) + .build(); } @Override @@ -79,8 +96,12 @@ public class PlanPlaceholderExtension extends PlaceholderExpansion { public String onPlaceholderRequest(Player player, String params) { UUID uuid = player != null ? player.getUniqueId() : null; if ("Server thread".equalsIgnoreCase(Thread.currentThread().getName())) { - return "[placeholder replacement on server thread is not supported by Plan because it can crash the server!]"; + return getCached(params, uuid); } + return getPlaceholderValue(params, uuid); + } + + private String getPlaceholderValue(String params, UUID uuid) { try { String value = placeholders.onPlaceholderRequest(uuid, params, Collections.emptyList()); @@ -96,4 +117,19 @@ public class PlanPlaceholderExtension extends PlaceholderExpansion { return null; } } + + private String getCached(String params, UUID uuid) { + String key = params + "-" + uuid; + String found = cache.getIfPresent(key); + if (found != null) return found; + + if (!currentlyProcessing.contains(key)) { + currentlyProcessing.add(key); + processing.submitNonCritical(() -> { + cache.put(key, Objects.requireNonNull(getPlaceholderValue(params, uuid))); + currentlyProcessing.remove(key); + }); + } + return null; + } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/placeholder/PlanPlaceholders.java b/Plan/common/src/main/java/com/djrapitops/plan/placeholder/PlanPlaceholders.java index be6d596de..33ebe6975 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/placeholder/PlanPlaceholders.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/placeholder/PlanPlaceholders.java @@ -18,10 +18,7 @@ package com.djrapitops.plan.placeholder; import com.djrapitops.plan.delivery.domain.container.PlayerContainer; import com.djrapitops.plan.delivery.domain.keys.PlayerKeys; -import com.djrapitops.plan.delivery.formatting.Formatters; import com.djrapitops.plan.gathering.cache.SessionCache; -import com.djrapitops.plan.identification.ServerInfo; -import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.queries.containers.ContainerFetchQueries; @@ -55,10 +52,7 @@ public final class PlanPlaceholders { @Inject public PlanPlaceholders( - PlanConfig config, DBSystem dbSystem, - ServerInfo serverInfo, - Formatters formatters, Set placeholderRegistries ) { this.dbSystem = dbSystem;