Cache placeholder result on non-server thread

Affects issues:
- Fixed #1756
This commit is contained in:
Risto Lahtela 2021-02-14 18:24:42 +02:00
parent a7e4b7df42
commit 2f48f17a4e
2 changed files with 37 additions and 7 deletions

View File

@ -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<String> currentlyProcessing;
private final Processing processing;
private final Cache<String, String> 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;
}
}

View File

@ -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<Placeholders> placeholderRegistries
) {
this.dbSystem = dbSystem;