mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-11-07 19:31:45 +01:00
Added a 10s caching layer between database and network page creation
This commit is contained in:
parent
efa4b36b6c
commit
a8f57c8edd
@ -16,15 +16,22 @@ public class CachingSupplier<T> implements Supplier<T> {
|
|||||||
private final Supplier<T> original;
|
private final Supplier<T> original;
|
||||||
private T cachedValue;
|
private T cachedValue;
|
||||||
private long cacheTime;
|
private long cacheTime;
|
||||||
|
private long timeToLive;
|
||||||
|
|
||||||
public CachingSupplier(Supplier<T> original) {
|
public CachingSupplier(Supplier<T> original) {
|
||||||
|
this(original, TimeAmount.SECOND.ms() * 30L);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CachingSupplier(Supplier<T> original, long timeToLive) {
|
||||||
this.original = original;
|
this.original = original;
|
||||||
|
this.timeToLive = timeToLive;
|
||||||
|
|
||||||
cacheTime = 0L;
|
cacheTime = 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T get() {
|
public T get() {
|
||||||
if (cachedValue == null || System.currentTimeMillis() - cacheTime > TimeAmount.SECOND.ms() * 30L) {
|
if (cachedValue == null || System.currentTimeMillis() - cacheTime > timeToLive) {
|
||||||
cachedValue = original.get();
|
cachedValue = original.get();
|
||||||
cacheTime = System.currentTimeMillis();
|
cacheTime = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package com.djrapitops.plan.data.store.containers;
|
|||||||
import com.djrapitops.plan.data.store.CachingSupplier;
|
import com.djrapitops.plan.data.store.CachingSupplier;
|
||||||
import com.djrapitops.plan.data.store.Key;
|
import com.djrapitops.plan.data.store.Key;
|
||||||
import com.djrapitops.plan.data.store.mutators.formatting.Formatter;
|
import com.djrapitops.plan.data.store.mutators.formatting.Formatter;
|
||||||
|
import com.djrapitops.plugin.api.TimeAmount;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -18,6 +19,16 @@ import java.util.function.Supplier;
|
|||||||
*/
|
*/
|
||||||
public class DataContainer extends HashMap<Key, Supplier> {
|
public class DataContainer extends HashMap<Key, Supplier> {
|
||||||
|
|
||||||
|
private long timeToLive;
|
||||||
|
|
||||||
|
public DataContainer() {
|
||||||
|
timeToLive = TimeAmount.SECOND.ms() * 30L;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataContainer(long timeToLive) {
|
||||||
|
this.timeToLive = timeToLive;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Place your data inside the container.
|
* Place your data inside the container.
|
||||||
*
|
*
|
||||||
@ -33,7 +44,7 @@ public class DataContainer extends HashMap<Key, Supplier> {
|
|||||||
if (supplier == null) {
|
if (supplier == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
super.put(key, new CachingSupplier<>(supplier));
|
super.put(key, new CachingSupplier<>(supplier, timeToLive));
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> Supplier<T> getSupplier(Key<T> key) {
|
public <T> Supplier<T> getSupplier(Key<T> key) {
|
||||||
|
@ -18,6 +18,7 @@ public class CacheSystem implements SubSystem {
|
|||||||
|
|
||||||
private final DataCache dataCache;
|
private final DataCache dataCache;
|
||||||
private final GeolocationCache geolocationCache;
|
private final GeolocationCache geolocationCache;
|
||||||
|
private final DataContainerCache dataContainerCache;
|
||||||
|
|
||||||
public CacheSystem(PlanSystem system) {
|
public CacheSystem(PlanSystem system) {
|
||||||
this(new DataCache(system), system);
|
this(new DataCache(system), system);
|
||||||
@ -26,6 +27,7 @@ public class CacheSystem implements SubSystem {
|
|||||||
protected CacheSystem(DataCache dataCache, PlanSystem system) {
|
protected CacheSystem(DataCache dataCache, PlanSystem system) {
|
||||||
this.dataCache = dataCache;
|
this.dataCache = dataCache;
|
||||||
geolocationCache = new GeolocationCache(() -> system.getLocaleSystem().getLocale());
|
geolocationCache = new GeolocationCache(() -> system.getLocaleSystem().getLocale());
|
||||||
|
dataContainerCache = new DataContainerCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CacheSystem getInstance() {
|
public static CacheSystem getInstance() {
|
||||||
@ -43,6 +45,7 @@ public class CacheSystem implements SubSystem {
|
|||||||
@Override
|
@Override
|
||||||
public void disable() {
|
public void disable() {
|
||||||
geolocationCache.clearCache();
|
geolocationCache.clearCache();
|
||||||
|
dataContainerCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataCache getDataCache() {
|
public DataCache getDataCache() {
|
||||||
@ -52,4 +55,8 @@ public class CacheSystem implements SubSystem {
|
|||||||
public GeolocationCache getGeolocationCache() {
|
public GeolocationCache getGeolocationCache() {
|
||||||
return geolocationCache;
|
return geolocationCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DataContainerCache getDataContainerCache() {
|
||||||
|
return dataContainerCache;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
71
Plan/src/main/java/com/djrapitops/plan/system/cache/DataContainerCache.java
vendored
Normal file
71
Plan/src/main/java/com/djrapitops/plan/system/cache/DataContainerCache.java
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package com.djrapitops.plan.system.cache;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.data.store.Key;
|
||||||
|
import com.djrapitops.plan.data.store.containers.AnalysisContainer;
|
||||||
|
import com.djrapitops.plan.data.store.containers.DataContainer;
|
||||||
|
import com.djrapitops.plan.data.store.containers.NetworkContainer;
|
||||||
|
import com.djrapitops.plan.data.store.containers.PlayerContainer;
|
||||||
|
import com.djrapitops.plan.system.database.databases.Database;
|
||||||
|
import com.djrapitops.plugin.api.TimeAmount;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache to aid Bungee in case SQL is causing cpu thread starvation, leading to mysql connection drops.
|
||||||
|
*
|
||||||
|
* @author Rsl1122
|
||||||
|
*/
|
||||||
|
public class DataContainerCache extends DataContainer {
|
||||||
|
|
||||||
|
public DataContainerCache() {
|
||||||
|
super(TimeAmount.SECOND.ms() * 10L);
|
||||||
|
|
||||||
|
putSupplier(Keys.NETWORK_CONTAINER, Suppliers.NETWORK_CONTAINER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerContainer getPlayerContainer(UUID uuid) {
|
||||||
|
return getAndCacheSupplier(Keys.playerContainer(uuid), Suppliers.playerContainer(uuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnalysisContainer getAnalysisContainer(UUID serverUUID) {
|
||||||
|
return getAndCacheSupplier(Keys.analysisContainer(serverUUID), Suppliers.analysisContainer(serverUUID));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T getAndCacheSupplier(Key<T> key, Supplier<T> ifNotPresent) {
|
||||||
|
if (!supports(key)) {
|
||||||
|
putSupplier(key, ifNotPresent);
|
||||||
|
}
|
||||||
|
return getUnsafe(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NetworkContainer getNetworkContainer() {
|
||||||
|
return getAndCacheSupplier(Keys.NETWORK_CONTAINER, Suppliers.NETWORK_CONTAINER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Keys {
|
||||||
|
static final Key<NetworkContainer> NETWORK_CONTAINER = new Key<>(NetworkContainer.class, "NETWORK_CONTAINER");
|
||||||
|
|
||||||
|
static Key<AnalysisContainer> analysisContainer(UUID serverUUID) {
|
||||||
|
return new Key<>(AnalysisContainer.class, "ANALYSIS_CONTAINER:" + serverUUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Key<PlayerContainer> playerContainer(UUID uuid) {
|
||||||
|
return new Key<>(PlayerContainer.class, "PLAYER_CONTAINER:" + uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Suppliers {
|
||||||
|
static final Supplier<NetworkContainer> NETWORK_CONTAINER = () -> Database.getActive().fetch().getNetworkContainer();
|
||||||
|
|
||||||
|
static Supplier<AnalysisContainer> analysisContainer(UUID serverUUID) {
|
||||||
|
return () -> new AnalysisContainer(Database.getActive().fetch().getServerContainer(serverUUID));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Supplier<PlayerContainer> playerContainer(UUID uuid) {
|
||||||
|
return () -> Database.getActive().fetch().getPlayerContainer(uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -66,12 +66,12 @@ public class MySQLDB extends SQLDB {
|
|||||||
config.setPassword(password);
|
config.setPassword(password);
|
||||||
|
|
||||||
config.setPoolName("Plan Connection Pool-" + increment);
|
config.setPoolName("Plan Connection Pool-" + increment);
|
||||||
config.setDriverClassName("com.mysql.jdbc.Driver");
|
|
||||||
increment();
|
increment();
|
||||||
|
|
||||||
config.setAutoCommit(true);
|
config.setAutoCommit(true);
|
||||||
config.setMaximumPoolSize(8);
|
config.setMaximumPoolSize(8);
|
||||||
config.setLeakDetectionThreshold(TimeAmount.MINUTE.ms() * 10L);
|
config.setMaxLifetime(25L * TimeAmount.MINUTE.ms());
|
||||||
|
config.setLeakDetectionThreshold(10L * TimeAmount.MINUTE.ms());
|
||||||
|
|
||||||
this.dataSource = new HikariDataSource(config);
|
this.dataSource = new HikariDataSource(config);
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ import com.djrapitops.plan.api.exceptions.ParseException;
|
|||||||
import com.djrapitops.plan.api.exceptions.connection.NoServersException;
|
import com.djrapitops.plan.api.exceptions.connection.NoServersException;
|
||||||
import com.djrapitops.plan.api.exceptions.connection.WebException;
|
import com.djrapitops.plan.api.exceptions.connection.WebException;
|
||||||
import com.djrapitops.plan.api.exceptions.connection.WebFailException;
|
import com.djrapitops.plan.api.exceptions.connection.WebFailException;
|
||||||
|
import com.djrapitops.plan.data.store.containers.NetworkContainer;
|
||||||
|
import com.djrapitops.plan.system.cache.CacheSystem;
|
||||||
import com.djrapitops.plan.system.info.connection.BungeeConnectionSystem;
|
import com.djrapitops.plan.system.info.connection.BungeeConnectionSystem;
|
||||||
import com.djrapitops.plan.system.info.request.CacheRequest;
|
import com.djrapitops.plan.system.info.request.CacheRequest;
|
||||||
import com.djrapitops.plan.system.info.request.GenerateInspectPageRequest;
|
import com.djrapitops.plan.system.info.request.GenerateInspectPageRequest;
|
||||||
@ -43,7 +45,8 @@ public class BungeeInfoSystem extends InfoSystem {
|
|||||||
@Override
|
@Override
|
||||||
public void updateNetworkPage() throws WebException {
|
public void updateNetworkPage() throws WebException {
|
||||||
try {
|
try {
|
||||||
String html = new NetworkPage().toHtml();
|
NetworkContainer networkContainer = CacheSystem.getInstance().getDataContainerCache().getNetworkContainer();
|
||||||
|
String html = new NetworkPage(networkContainer).toHtml();
|
||||||
ResponseCache.cacheResponse(PageId.SERVER.of(ServerInfo.getServerUUID()), () -> new AnalysisPageResponse(html));
|
ResponseCache.cacheResponse(PageId.SERVER.of(ServerInfo.getServerUUID()), () -> new AnalysisPageResponse(html));
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
throw new WebFailException("Exception during Network Page Parsing", e);
|
throw new WebFailException("Exception during Network Page Parsing", e);
|
||||||
|
@ -7,7 +7,6 @@ package com.djrapitops.plan.system.webserver.pages.parsing;
|
|||||||
import com.djrapitops.plan.api.exceptions.ParseException;
|
import com.djrapitops.plan.api.exceptions.ParseException;
|
||||||
import com.djrapitops.plan.data.store.containers.NetworkContainer;
|
import com.djrapitops.plan.data.store.containers.NetworkContainer;
|
||||||
import com.djrapitops.plan.data.store.mutators.formatting.PlaceholderReplacer;
|
import com.djrapitops.plan.data.store.mutators.formatting.PlaceholderReplacer;
|
||||||
import com.djrapitops.plan.system.database.databases.Database;
|
|
||||||
import com.djrapitops.plan.system.webserver.response.cache.PageId;
|
import com.djrapitops.plan.system.webserver.response.cache.PageId;
|
||||||
import com.djrapitops.plan.system.webserver.response.cache.ResponseCache;
|
import com.djrapitops.plan.system.webserver.response.cache.ResponseCache;
|
||||||
import com.djrapitops.plan.system.webserver.response.pages.parts.NetworkPageContent;
|
import com.djrapitops.plan.system.webserver.response.pages.parts.NetworkPageContent;
|
||||||
@ -22,12 +21,15 @@ import static com.djrapitops.plan.data.store.keys.NetworkKeys.*;
|
|||||||
*/
|
*/
|
||||||
public class NetworkPage implements Page {
|
public class NetworkPage implements Page {
|
||||||
|
|
||||||
|
private final NetworkContainer networkContainer;
|
||||||
|
|
||||||
|
public NetworkPage(NetworkContainer networkContainer) {
|
||||||
|
this.networkContainer = networkContainer;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toHtml() throws ParseException {
|
public String toHtml() throws ParseException {
|
||||||
try {
|
try {
|
||||||
Database database = Database.getActive();
|
|
||||||
NetworkContainer networkContainer = database.fetch().getNetworkContainer();
|
|
||||||
|
|
||||||
PlaceholderReplacer placeholderReplacer = new PlaceholderReplacer();
|
PlaceholderReplacer placeholderReplacer = new PlaceholderReplacer();
|
||||||
placeholderReplacer.addAllPlaceholdersFrom(networkContainer,
|
placeholderReplacer.addAllPlaceholdersFrom(networkContainer,
|
||||||
VERSION, NETWORK_NAME, TIME_ZONE,
|
VERSION, NETWORK_NAME, TIME_ZONE,
|
||||||
|
Loading…
Reference in New Issue
Block a user