From af932c5bc9800a26fb86e0f88fb8fba1580d2988 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 2 Dec 2024 07:51:07 -0600 Subject: [PATCH] Add visited position removal timer in RemoteFullDataSourceProvider This is done to hopefully prevent memory leaks --- .../RemoteFullDataSourceProvider.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/RemoteFullDataSourceProvider.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/RemoteFullDataSourceProvider.java index cb84c8a3e..f35cff1b5 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/RemoteFullDataSourceProvider.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/RemoteFullDataSourceProvider.java @@ -24,15 +24,20 @@ import com.seibel.distanthorizons.core.file.structure.ISaveStructure; import com.seibel.distanthorizons.core.generation.RemoteWorldRetrievalQueue; import com.seibel.distanthorizons.core.level.IDhClientLevel; import com.seibel.distanthorizons.core.level.WorldGenModule; +import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.multiplayer.client.SyncOnLoadRequestQueue; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; +import com.seibel.distanthorizons.core.util.TimerUtil; import com.seibel.distanthorizons.coreapi.util.BitShiftUtil; +import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.Map; import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; import java.util.concurrent.ConcurrentHashMap; /** @@ -41,6 +46,11 @@ import java.util.concurrent.ConcurrentHashMap; */ public class RemoteFullDataSourceProvider extends GeneratedFullDataSourceProvider { + private static final Logger LOGGER = DhLoggerBuilder.getLogger(); + private static final Timer DELAY_UPDATE_TIMER = TimerUtil.CreateTimer("Remote DataSource Visited Pos Removal Timer"); + /** auto remove visited positions from the set after a given amount of time to prevent the set from growing infinitely */ + private static final int VISITED_POSITION_REMOVAL_TIME_IN_MS = 20 * 60 * 1_000; // 20 minutes + @Nullable private final SyncOnLoadRequestQueue syncOnLoadRequestQueue; private final Set visitedPositions = ConcurrentHashMap.newKeySet(); @@ -128,6 +138,7 @@ public class RemoteFullDataSourceProvider extends GeneratedFullDataSourceProvide { return; } + this.queueVisitedPositionForRemoval(childPos); // check if the server has newer versions of these LODs Long subTimestamp = timestamps.get(childPos); @@ -139,6 +150,23 @@ public class RemoteFullDataSourceProvider extends GeneratedFullDataSourceProvide return super.get(pos); } + /** this is done to prevent infinite set growth */ + private void queueVisitedPositionForRemoval(long pos) + { + TimerTask timerTask = new TimerTask() + { + @Override + public void run() + { + RemoteFullDataSourceProvider.this.visitedPositions.remove(pos); + } + }; + try + { + DELAY_UPDATE_TIMER.schedule(timerTask, VISITED_POSITION_REMOVAL_TIME_IN_MS); + } + catch (IllegalStateException ignore) { /* shouldn't happen, but there have been issues like this in the past */ } + }