failed attmpt to fix leaks
Breaks split world gen requests
This commit is contained in:
+1
-1
@@ -78,7 +78,7 @@ public class FullDataSourceV2
|
||||
/** how many chunks wide this datasource is at detail level 0. */
|
||||
public static final int NUMB_OF_CHUNKS_WIDE = WIDTH / LodUtil.CHUNK_WIDTH;
|
||||
|
||||
public static final PhantomArrayListPool ARRAY_LIST_POOL = new PhantomArrayListPool("FullDataV2");
|
||||
public static final PhantomArrayListPool ARRAY_LIST_POOL = new PhantomArrayListPool("FullDataV2", true);
|
||||
|
||||
|
||||
|
||||
|
||||
+12
-13
@@ -29,6 +29,7 @@ import com.seibel.distanthorizons.core.file.structure.ISaveStructure;
|
||||
import com.seibel.distanthorizons.core.generation.DhLightingEngine;
|
||||
import com.seibel.distanthorizons.core.generation.IFullDataSourceRetrievalQueue;
|
||||
import com.seibel.distanthorizons.core.generation.tasks.DataSourceRetrievalResult;
|
||||
import com.seibel.distanthorizons.core.generation.tasks.ERetrievalResultState;
|
||||
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
@@ -117,35 +118,33 @@ public class GeneratedFullDataSourceProvider extends FullDataSourceProviderV2 im
|
||||
|
||||
private void onWorldGenTaskComplete(DataSourceRetrievalResult genTaskResult, Throwable exception)
|
||||
{
|
||||
if (exception != null)
|
||||
if (genTaskResult.state == ERetrievalResultState.FAIL)
|
||||
{
|
||||
LodUtil.assertTrue(genTaskResult.dataSource == null, "Errored retrieval object should not have a datasource.");
|
||||
|
||||
// don't log shutdown exceptions
|
||||
if (!ExceptionUtil.isInterruptOrReject(exception))
|
||||
{
|
||||
LOGGER.error("Uncaught Gen Task Exception at ["+genTaskResult.pos+"], error: ["+exception.getMessage()+"].", exception);
|
||||
}
|
||||
}
|
||||
else if (genTaskResult.generatedDataSource != null)
|
||||
else if (genTaskResult.state == ERetrievalResultState.SUCCESS)
|
||||
{
|
||||
this.dataUpdater.updateDataSource(genTaskResult.generatedDataSource);
|
||||
LodUtil.assertTrue(genTaskResult.dataSource != null, "Successful retrieval object should have a datasource.");
|
||||
|
||||
this.dataUpdater.updateDataSource(genTaskResult.dataSource);
|
||||
this.fireOnGenPosSuccessListeners(genTaskResult.pos);
|
||||
genTaskResult.dataSource.close();
|
||||
}
|
||||
else if (exception == null && !genTaskResult.success) // TODO use enum to check type
|
||||
else if (genTaskResult.state == ERetrievalResultState.REQUIRES_SPLITTING)
|
||||
{
|
||||
// task was split
|
||||
LodUtil.assertTrue(genTaskResult.dataSource == null, "Split retrieval object should not have a datasource.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// shouldn't happen, but just in case
|
||||
// TODO is definitely happening
|
||||
LOGGER.warn("Unexpected gen Task state at: [" + DhSectionPos.toString(genTaskResult.pos) + "], success: ["+genTaskResult.success+"], datasource: NULL, exception: NULL.");
|
||||
}
|
||||
|
||||
|
||||
// if the generation task was split up into smaller positions, add the on-complete event to them
|
||||
for (CompletableFuture<DataSourceRetrievalResult> siblingFuture : genTaskResult.childFutures)
|
||||
{
|
||||
siblingFuture.whenComplete((siblingGenTaskResult, siblingEx) -> this.onWorldGenTaskComplete(siblingGenTaskResult, siblingEx));
|
||||
LOGGER.warn("Unexpected gen Task state at: [" + DhSectionPos.toString(genTaskResult.pos) + "], state: ["+genTaskResult.state+"], datasource: NULL, exception: NULL.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+33
-19
@@ -23,11 +23,11 @@ import com.google.common.cache.CacheBuilder;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||
import com.seibel.distanthorizons.core.file.structure.ISaveStructure;
|
||||
import com.seibel.distanthorizons.core.generation.RemoteWorldRetrievalQueue;
|
||||
import com.seibel.distanthorizons.core.generation.tasks.DataSourceRetrievalResult;
|
||||
import com.seibel.distanthorizons.core.level.IDhLevel;
|
||||
import com.seibel.distanthorizons.core.level.LodRequestModule;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.multiplayer.client.ENetRequestState;
|
||||
import com.seibel.distanthorizons.core.multiplayer.client.NetRequestResult;
|
||||
import com.seibel.distanthorizons.core.generation.tasks.ERetrievalResultState;
|
||||
import com.seibel.distanthorizons.core.multiplayer.client.SyncOnLoadRequestQueue;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -104,23 +104,37 @@ public class RemoteFullDataSourceProvider extends GeneratedFullDataSourceProvide
|
||||
Long timestamp = this.getTimestampForPos(pos);
|
||||
if (timestamp != null)
|
||||
{
|
||||
this.syncOnLoadRequestQueue.submitRequest(pos, timestamp)
|
||||
.thenAccept((NetRequestResult netRequestResult) ->
|
||||
{
|
||||
if (netRequestResult.state == ENetRequestState.SUCCESS)
|
||||
{
|
||||
FullDataSourceV2 fullDataSource = netRequestResult.receivedDataSource;
|
||||
if (fullDataSource != null)
|
||||
{
|
||||
this.updateDataSourceAsync(fullDataSource)
|
||||
.handle((voidObj, throwable) ->
|
||||
{
|
||||
fullDataSource.close();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
//this.syncOnLoadRequestQueue.submitRequest(pos, timestamp)
|
||||
// .thenAccept((DataSourceRetrievalResult result) ->
|
||||
// {
|
||||
// //if (result.receivedDataSource != null)
|
||||
// //{
|
||||
// // result.receivedDataSource.close();
|
||||
// //}
|
||||
//
|
||||
// if (result.state == ERetrievalResultState.SUCCESS)
|
||||
// {
|
||||
// FullDataSourceV2 dataSource = result.dataSource;
|
||||
// if (dataSource != null)
|
||||
// {
|
||||
// this.updateDataSourceAsync(dataSource)
|
||||
// .handle((voidObj, throwable) ->
|
||||
// {
|
||||
// dataSource.close();
|
||||
// return null;
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (result.dataSource != null)
|
||||
// {
|
||||
// int k = 0;
|
||||
// //result.receivedDataSource.close();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// });
|
||||
}
|
||||
|
||||
return super.get(pos);
|
||||
|
||||
@@ -7,7 +7,9 @@ import com.seibel.distanthorizons.core.api.internal.SharedApi;
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.file.fullDatafile.GeneratedFullDataSourceProvider;
|
||||
import com.seibel.distanthorizons.core.generation.tasks.DataSourceRetrievalResult;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.generation.tasks.ERetrievalResultState;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D;
|
||||
import com.seibel.distanthorizons.core.util.FormatUtil;
|
||||
@@ -154,14 +156,16 @@ public class PregenManager
|
||||
}
|
||||
else
|
||||
{
|
||||
this.fullDataSourceProvider.queuePositionForRetrieval(fullDataSource.getPos()).thenAccept(result -> {
|
||||
if (!result.success)
|
||||
this.fullDataSourceProvider.queuePositionForRetrieval(fullDataSource.getPos())
|
||||
.thenAccept((DataSourceRetrievalResult result) ->
|
||||
{
|
||||
LOGGER.warn("Failed to generate section " + DhSectionPos.toString(result.pos));
|
||||
}
|
||||
|
||||
this.pendingGenerations.invalidate(result.pos);
|
||||
});
|
||||
if (result.state == ERetrievalResultState.FAIL)
|
||||
{
|
||||
LOGGER.warn("Failed to generate section " + DhSectionPos.toString(result.pos));
|
||||
}
|
||||
|
||||
this.pendingGenerations.invalidate(result.pos);
|
||||
});
|
||||
}
|
||||
|
||||
fullDataSource.close();
|
||||
|
||||
+13
-82
@@ -1,13 +1,12 @@
|
||||
package com.seibel.distanthorizons.core.generation;
|
||||
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||
import com.seibel.distanthorizons.core.generation.tasks.DataSourceRetrievalResult;
|
||||
import com.seibel.distanthorizons.core.generation.tasks.ERetrievalResultState;
|
||||
import com.seibel.distanthorizons.core.level.DhClientLevel;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.multiplayer.client.AbstractFullDataNetworkRequestQueue;
|
||||
import com.seibel.distanthorizons.core.multiplayer.client.ClientNetworkState;
|
||||
import com.seibel.distanthorizons.core.multiplayer.client.NetRequestResult;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D;
|
||||
import com.seibel.distanthorizons.core.render.renderer.IDebugRenderable;
|
||||
@@ -17,7 +16,6 @@ import com.seibel.distanthorizons.core.util.objects.RollingAverage;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
public class RemoteWorldRetrievalQueue extends AbstractFullDataNetworkRequestQueue implements IFullDataSourceRetrievalQueue, IDebugRenderable
|
||||
@@ -59,90 +57,23 @@ public class RemoteWorldRetrievalQueue extends AbstractFullDataNetworkRequestQue
|
||||
long generationStartMsTime = System.currentTimeMillis();
|
||||
|
||||
|
||||
CompletableFuture<DataSourceRetrievalResult> returnFuture = new CompletableFuture<>();
|
||||
|
||||
Executor worldGenExecutor = ThreadPoolUtil.getWorldGenExecutor();
|
||||
if (worldGenExecutor == null)
|
||||
CompletableFuture<DataSourceRetrievalResult> future = super.submitRequest(sectionPos, /* client timestamp */null);
|
||||
future.thenAccept((DataSourceRetrievalResult result) ->
|
||||
{
|
||||
return CompletableFuture.completedFuture(DataSourceRetrievalResult.CreateFail());
|
||||
}
|
||||
|
||||
CompletableFuture<NetRequestResult> netFuture = super.submitRequest(sectionPos, /* client timestamp */null);
|
||||
netFuture.handle((NetRequestResult netResult, Throwable throwable) ->
|
||||
{
|
||||
try
|
||||
if (result.state == ERetrievalResultState.SUCCESS)
|
||||
{
|
||||
if (throwable != null)
|
||||
{
|
||||
return DataSourceRetrievalResult.CreateFail();
|
||||
}
|
||||
|
||||
long totalGenTimeInMs = System.currentTimeMillis() - generationStartMsTime;
|
||||
|
||||
|
||||
int chunkWidth = DhSectionPos.getChunkWidth(sectionPos);
|
||||
int chunkCount = chunkWidth * chunkWidth;
|
||||
double timePerChunk = (double) totalGenTimeInMs / (double) chunkCount;
|
||||
|
||||
switch (netResult.state)
|
||||
{
|
||||
case SUCCESS:
|
||||
// only add the time on successes
|
||||
// it won't be a perfect estimate but fails will often come back faster, skewing the time faster
|
||||
this.rollingAverageChunkGenTimeInMs.add(timePerChunk);
|
||||
|
||||
return DataSourceRetrievalResult.CreateSuccess(sectionPos, netResult.receivedDataSource);
|
||||
case FAIL:
|
||||
return DataSourceRetrievalResult.CreateFail();
|
||||
case REQUIRES_SPLITTING:
|
||||
ArrayList<CompletableFuture<DataSourceRetrievalResult>> childFutures = new ArrayList<>(4);
|
||||
DhSectionPos.forEachChild(sectionPos, (long childPos) ->
|
||||
{
|
||||
boolean shouldGenerate;
|
||||
try (FullDataSourceV2 fullDataSource = this.level.remoteDataSourceProvider.get(childPos))
|
||||
{
|
||||
if (fullDataSource != null)
|
||||
{
|
||||
shouldGenerate = !this.level.remoteDataSourceProvider.generationStepsAreFullyGenerated(fullDataSource.columnGenerationSteps);
|
||||
}
|
||||
else
|
||||
{
|
||||
shouldGenerate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldGenerate)
|
||||
{
|
||||
childFutures.add(this.submitRetrievalTask(childPos, requiredDataDetail));
|
||||
}
|
||||
});
|
||||
return DataSourceRetrievalResult.CreateSplit(childFutures);
|
||||
}
|
||||
|
||||
LodUtil.assertNotReach("Unexpected and unhandled request response result: [" + netResult.state + "]");
|
||||
return DataSourceRetrievalResult.CreateFail();
|
||||
|
||||
// only add the time on successes
|
||||
// it won't be a perfect estimate but fails will often come back faster, skewing the time faster
|
||||
this.rollingAverageChunkGenTimeInMs.add(timePerChunk);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.error("Unexpected issue in submitRetrievalTask returned future, error: ["+e.getMessage()+"]", e);
|
||||
return DataSourceRetrievalResult.CreateFail();
|
||||
}
|
||||
})
|
||||
// convert the net result
|
||||
.handleAsync((DataSourceRetrievalResult retrievalResult, Throwable throwable) ->
|
||||
{
|
||||
if (throwable != null)
|
||||
{
|
||||
returnFuture.completeExceptionally(throwable);
|
||||
}
|
||||
else
|
||||
{
|
||||
returnFuture.complete(retrievalResult);
|
||||
}
|
||||
|
||||
return null;
|
||||
}, worldGenExecutor);
|
||||
|
||||
return returnFuture;
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -176,13 +107,13 @@ public class RemoteWorldRetrievalQueue extends AbstractFullDataNetworkRequestQue
|
||||
return DhSectionPos.getChebyshevSignedBlockDistance(sectionPos, targetPos) <= this.networkState.sessionConfig.getMaxGenerationRequestDistance() * 16;
|
||||
}
|
||||
@Override
|
||||
protected boolean onBeforeRequest(long sectionPos, CompletableFuture<NetRequestResult> future)
|
||||
protected boolean onBeforeRequest(long sectionPos, CompletableFuture<DataSourceRetrievalResult> future)
|
||||
{
|
||||
// split up large requests if N-sized gen isn't enabled
|
||||
if (!Config.Server.Experimental.enableNSizedGeneration.get()
|
||||
&& DhSectionPos.getDetailLevel(sectionPos) > DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL)
|
||||
{
|
||||
future.complete(NetRequestResult.CreateSplit());
|
||||
future.complete(DataSourceRetrievalResult.CreateSplit());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+12
-19
@@ -316,18 +316,7 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
|
||||
// detail level is too high (if the detail level was too low, the generator would've ignored the request),
|
||||
// split up the task
|
||||
|
||||
|
||||
// split up the task and add each to the queue
|
||||
ArrayList<CompletableFuture<DataSourceRetrievalResult>> childFutures = new ArrayList<>(4);
|
||||
DhSectionPos.forEachChild(closestTask.pos, (childDhSectionPos) ->
|
||||
{
|
||||
DataSourceRetrievalTask newGenTask = new DataSourceRetrievalTask(childDhSectionPos, DhSectionPos.getDetailLevel(childDhSectionPos));
|
||||
childFutures.add(newGenTask.future);
|
||||
this.waitingTasks.put(newGenTask.pos, newGenTask);
|
||||
});
|
||||
|
||||
// send the child futures to the future recipient, to notify them of the new tasks
|
||||
closestTask.future.complete(DataSourceRetrievalResult.CreateSplit(childFutures));
|
||||
closestTask.future.complete(DataSourceRetrievalResult.CreateSplit());
|
||||
}
|
||||
|
||||
|
||||
@@ -372,13 +361,16 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
|
||||
LOGGER.error("Error generating data for pos: " + DhSectionPos.toString(taskPos), exception);
|
||||
}
|
||||
|
||||
LodUtil.assertTrue(fullDataSource == null);
|
||||
worldGenTask.future.complete(DataSourceRetrievalResult.CreateFail());
|
||||
}
|
||||
|
||||
boolean worked = this.inProgressGenTasksByLodPos.remove(taskPos, worldGenTask);
|
||||
LodUtil.assertTrue(worked, "Unable to find in progress generator task with position ["+DhSectionPos.toString(taskPos)+"]");
|
||||
|
||||
worldGenTask.future.complete(DataSourceRetrievalResult.CreateSuccess(taskPos, fullDataSourceV2));
|
||||
else
|
||||
{
|
||||
boolean taskRemoved = this.inProgressGenTasksByLodPos.remove(taskPos, worldGenTask);
|
||||
LodUtil.assertTrue(taskRemoved, "Unable to find in progress generator task with position ["+DhSectionPos.toString(taskPos)+"]");
|
||||
|
||||
worldGenTask.future.complete(DataSourceRetrievalResult.CreateSuccess(taskPos, fullDataSource));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -692,9 +684,10 @@ public class WorldGenerationQueue implements IFullDataSourceRetrievalQueue, IDeb
|
||||
LOGGER.error("Error when terminating data generation for pos: ["+DhSectionPos.toString(genTask.pos)+"], error: ["+throwable.getMessage()+"].", throwable);
|
||||
}
|
||||
|
||||
if (result.generatedDataSource != null)
|
||||
if (result != null
|
||||
&& result.dataSource != null)
|
||||
{
|
||||
result.generatedDataSource.close();
|
||||
result.dataSource.close();
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
+8
-20
@@ -22,23 +22,16 @@ package com.seibel.distanthorizons.core.generation.tasks;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* @see DataSourceRetrievalTask
|
||||
*/
|
||||
public class DataSourceRetrievalResult
|
||||
{
|
||||
/** true if terrain was generated */
|
||||
public final boolean success; // TODO reponse enum?
|
||||
public final ERetrievalResultState state;
|
||||
/** the position that was generated, will be null if nothing was generated */
|
||||
public final long pos;
|
||||
@Nullable
|
||||
public final FullDataSourceV2 generatedDataSource;
|
||||
|
||||
/** if a position is too high detail for world generator to handle it, these futures are for its 4 children positions after being split up. */
|
||||
public final ArrayList<CompletableFuture<DataSourceRetrievalResult>> childFutures = new ArrayList<>(4);
|
||||
public final FullDataSourceV2 dataSource;
|
||||
|
||||
|
||||
|
||||
@@ -46,19 +39,14 @@ public class DataSourceRetrievalResult
|
||||
// constructors //
|
||||
//==============//
|
||||
|
||||
public static DataSourceRetrievalResult CreateSplit(ArrayList<CompletableFuture<DataSourceRetrievalResult>> siblingFutures) { return new DataSourceRetrievalResult(false, 0, null, siblingFutures); }
|
||||
public static DataSourceRetrievalResult CreateFail() { return new DataSourceRetrievalResult(false, 0, null,null); }
|
||||
public static DataSourceRetrievalResult CreateSuccess(long pos, FullDataSourceV2 generatedDataSource) { return new DataSourceRetrievalResult(true, pos, generatedDataSource, null); }
|
||||
private DataSourceRetrievalResult(boolean success, long pos, @Nullable FullDataSourceV2 generatedDataSource, ArrayList<CompletableFuture<DataSourceRetrievalResult>> childFutures)
|
||||
public static DataSourceRetrievalResult CreateSplit() { return new DataSourceRetrievalResult(ERetrievalResultState.REQUIRES_SPLITTING, 0, null); }
|
||||
public static DataSourceRetrievalResult CreateFail() { return new DataSourceRetrievalResult(ERetrievalResultState.FAIL, 0, null); }
|
||||
public static DataSourceRetrievalResult CreateSuccess(long pos, FullDataSourceV2 generatedDataSource) { return new DataSourceRetrievalResult(ERetrievalResultState.SUCCESS, pos, generatedDataSource); }
|
||||
private DataSourceRetrievalResult(ERetrievalResultState state, long pos, @Nullable FullDataSourceV2 dataSource)
|
||||
{
|
||||
this.success = success;
|
||||
this.state = state;
|
||||
this.pos = pos;
|
||||
this.generatedDataSource = generatedDataSource;
|
||||
|
||||
if (childFutures != null)
|
||||
{
|
||||
this.childFutures.addAll(childFutures);
|
||||
}
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.seibel.distanthorizons.core.generation.tasks;
|
||||
|
||||
/**
|
||||
* SUCCESS <br>
|
||||
* REQUIRES_SPLITTING <br>
|
||||
* FAIL <br>
|
||||
*
|
||||
* @see DataSourceRetrievalResult
|
||||
*/
|
||||
public enum ERetrievalResultState
|
||||
{
|
||||
SUCCESS,
|
||||
REQUIRES_SPLITTING,
|
||||
FAIL,
|
||||
}
|
||||
+9
-30
@@ -6,6 +6,7 @@ import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.config.types.ConfigEntry;
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.generation.tasks.DataSourceRetrievalResult;
|
||||
import com.seibel.distanthorizons.core.level.DhClientLevel;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
@@ -71,16 +72,6 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
|
||||
|
||||
private final SupplierBasedRateLimiter<Void> rateLimiter = new SupplierBasedRateLimiter<>(this::getRequestRateLimit);
|
||||
|
||||
private final Set<Long> succeededPositions = Collections.newSetFromMap(CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(20, TimeUnit.MINUTES)
|
||||
.<Long, Boolean>build()
|
||||
.asMap());
|
||||
|
||||
private final Set<Long> requiresSplittingPositions = Collections.newSetFromMap(CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(20, TimeUnit.MINUTES)
|
||||
.<Long, Boolean>build()
|
||||
.asMap());
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
@@ -106,7 +97,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
|
||||
|
||||
protected abstract int getRequestRateLimit();
|
||||
protected abstract boolean sectionInAllowedGenerationRadius(long sectionPos, DhBlockPos2D targetPos);
|
||||
protected abstract boolean onBeforeRequest(long sectionPos, CompletableFuture<NetRequestResult> future);
|
||||
protected abstract boolean onBeforeRequest(long sectionPos, CompletableFuture<DataSourceRetrievalResult> future);
|
||||
|
||||
protected abstract String getQueueName();
|
||||
|
||||
@@ -116,18 +107,8 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
|
||||
// request submitting //
|
||||
//====================//
|
||||
|
||||
public CompletableFuture<NetRequestResult> submitRequest(long sectionPos, @Nullable Long clientTimestamp)
|
||||
public CompletableFuture<DataSourceRetrievalResult> submitRequest(long sectionPos, @Nullable Long clientTimestamp)
|
||||
{
|
||||
if (this.succeededPositions.contains(sectionPos))
|
||||
{
|
||||
return CompletableFuture.completedFuture(NetRequestResult.CreateFail());
|
||||
}
|
||||
|
||||
if (this.requiresSplittingPositions.contains(sectionPos))
|
||||
{
|
||||
return CompletableFuture.completedFuture(NetRequestResult.CreateSplit());
|
||||
}
|
||||
|
||||
NetRequestTask requestEntry = this.waitingTasksBySectionPos.compute(sectionPos, (pos, existingNetTask) ->
|
||||
{
|
||||
// ignore already queued tasks
|
||||
@@ -138,7 +119,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
|
||||
|
||||
|
||||
NetRequestTask newRequestEntry = new NetRequestTask(pos, clientTimestamp);
|
||||
newRequestEntry.future.whenComplete((requestResult, throwable) ->
|
||||
newRequestEntry.future.whenComplete((DataSourceRetrievalResult requestResult, Throwable throwable) ->
|
||||
{
|
||||
this.waitingTasksBySectionPos.remove(pos);
|
||||
|
||||
@@ -146,10 +127,8 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
|
||||
{
|
||||
case SUCCESS:
|
||||
this.finishedRequests.incrementAndGet();
|
||||
this.succeededPositions.add(pos);
|
||||
break;
|
||||
case REQUIRES_SPLITTING:
|
||||
this.requiresSplittingPositions.add(pos);
|
||||
break;
|
||||
case FAIL:
|
||||
this.failedRequests.incrementAndGet();
|
||||
@@ -274,12 +253,12 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
|
||||
this.level.updateBeaconBeamsForSectionPos(dataSourceDto.pos, response.payload.beaconBeams);
|
||||
|
||||
FullDataSourceV2 fullDataSource = dataSourceDto.createDataSource(this.level.getLevelWrapper(), null);
|
||||
requestTask.future.complete(NetRequestResult.CreateSuccess(fullDataSource));
|
||||
requestTask.future.complete(DataSourceRetrievalResult.CreateSuccess(dataSourceDto.pos, fullDataSource));
|
||||
}
|
||||
}
|
||||
catch (SectionRequiresSplittingException ignored)
|
||||
{
|
||||
requestTask.future.complete(NetRequestResult.CreateSplit());
|
||||
requestTask.future.complete(DataSourceRetrievalResult.CreateSplit());
|
||||
}
|
||||
catch (SessionClosedException | CancellationException ignored)
|
||||
{
|
||||
@@ -288,7 +267,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
|
||||
catch (RequestRejectedException e)
|
||||
{
|
||||
LOGGER.info("Request rejected by the server, message: [" + e.getMessage() + "].");
|
||||
requestTask.future.complete(NetRequestResult.CreateFail());
|
||||
requestTask.future.complete(DataSourceRetrievalResult.CreateFail());
|
||||
}
|
||||
catch (RateLimitedException e)
|
||||
{
|
||||
@@ -317,7 +296,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
|
||||
}
|
||||
else
|
||||
{
|
||||
requestTask.future.complete(NetRequestResult.CreateFail());
|
||||
requestTask.future.complete(DataSourceRetrievalResult.CreateFail());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -458,7 +437,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
|
||||
public final long pos;
|
||||
|
||||
/** encapsulates the entire request, including client side queuing and the actual server request */
|
||||
public final CompletableFuture<NetRequestResult> future = new CompletableFuture<>();
|
||||
public final CompletableFuture<DataSourceRetrievalResult> future = new CompletableFuture<>();
|
||||
/** will be null if we want to retrieve the LOD regardless of when it was last updated */
|
||||
@Nullable
|
||||
public final Long updateTimestamp;
|
||||
|
||||
+2
-2
@@ -129,8 +129,8 @@ public class ClientNetworkState implements Closeable
|
||||
{
|
||||
this.serverSupportStatus = EServerSupportStatus.FULL;
|
||||
|
||||
// TODO only log changes
|
||||
LOGGER.info("Connection config has been changed: [" + message.config + "].");
|
||||
/// TODO only log changes
|
||||
//LOGGER.info("Connection config has been changed: [" + message.config + "].");
|
||||
this.sessionConfig = message.config;
|
||||
this.configReceived = true;
|
||||
});
|
||||
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
package com.seibel.distanthorizons.core.multiplayer.client;
|
||||
|
||||
/**
|
||||
* SUCCESS <br>
|
||||
* REQUIRES_SPLITTING <br>
|
||||
* FAIL <br>
|
||||
*
|
||||
* @see NetRequestResult
|
||||
*/
|
||||
public enum ENetRequestState
|
||||
{
|
||||
SUCCESS,
|
||||
REQUIRES_SPLITTING,
|
||||
FAIL,
|
||||
}
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Distant Horizons mod
|
||||
* licensed under the GNU LGPL v3 License.
|
||||
*
|
||||
* Copyright (C) 2020 James Seibel
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.seibel.distanthorizons.core.multiplayer.client;
|
||||
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class NetRequestResult
|
||||
{
|
||||
public final ENetRequestState state;
|
||||
@Nullable
|
||||
public final FullDataSourceV2 receivedDataSource;
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// constructors //
|
||||
//==============//
|
||||
|
||||
public static NetRequestResult CreateFail() { return new NetRequestResult(ENetRequestState.FAIL, null); }
|
||||
public static NetRequestResult CreateSuccess(FullDataSourceV2 receivedDataSource) { return new NetRequestResult(ENetRequestState.SUCCESS, receivedDataSource); }
|
||||
public static NetRequestResult CreateSplit() { return new NetRequestResult(ENetRequestState.REQUIRES_SPLITTING, null); }
|
||||
private NetRequestResult(ENetRequestState state, @Nullable FullDataSourceV2 receivedDataSource)
|
||||
{
|
||||
this.state = state;
|
||||
this.receivedDataSource = receivedDataSource;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+2
-1
@@ -2,6 +2,7 @@ package com.seibel.distanthorizons.core.multiplayer.client;
|
||||
|
||||
import com.seibel.distanthorizons.core.config.Config;
|
||||
import com.seibel.distanthorizons.core.generation.RemoteWorldRetrievalQueue;
|
||||
import com.seibel.distanthorizons.core.generation.tasks.DataSourceRetrievalResult;
|
||||
import com.seibel.distanthorizons.core.level.DhClientLevel;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D;
|
||||
@@ -40,7 +41,7 @@ public class SyncOnLoadRequestQueue extends AbstractFullDataNetworkRequestQueue
|
||||
return DhSectionPos.getChebyshevSignedBlockDistance(sectionPos, targetPos) <= this.networkState.sessionConfig.getMaxSyncOnLoadDistance() * 16;
|
||||
}
|
||||
@Override
|
||||
protected boolean onBeforeRequest(long sectionPos, CompletableFuture<NetRequestResult> future) { return true; }
|
||||
protected boolean onBeforeRequest(long sectionPos, CompletableFuture<DataSourceRetrievalResult> future) { return true; }
|
||||
|
||||
@Override
|
||||
protected String getQueueName() { return "Sync On Login Queue"; }
|
||||
|
||||
+1
-1
@@ -265,7 +265,7 @@ public class FullDataSourceRequestHandler implements AutoCloseable
|
||||
else
|
||||
{
|
||||
//LOGGER.info("sending - queueing [" + DhSectionPos.toString(pos) + "]");
|
||||
this.fullDataSourceProvider().queuePositionForRetrieval(pos);
|
||||
//this.fullDataSourceProvider().queuePositionForRetrieval(pos);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -23,7 +23,9 @@ import com.seibel.distanthorizons.coreapi.util.MathUtil;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
/** immutable */
|
||||
@Deprecated // TODO why does this exist vs blockpos2d?
|
||||
public class Pos2D
|
||||
{
|
||||
public static final Pos2D ZERO = new Pos2D(0, 0);
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodBuff
|
||||
import com.seibel.distanthorizons.core.enums.EDhDirection;
|
||||
import com.seibel.distanthorizons.core.file.fullDatafile.V2.FullDataSourceProviderV2;
|
||||
import com.seibel.distanthorizons.core.generation.tasks.DataSourceRetrievalResult;
|
||||
import com.seibel.distanthorizons.core.generation.tasks.ERetrievalResultState;
|
||||
import com.seibel.distanthorizons.core.level.IDhClientLevel;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
@@ -776,7 +777,7 @@ public class LodQuadTree extends QuadTree<LodRenderSection> implements IDebugRen
|
||||
this.queuedGenerationPosSet.remove(missingPos);
|
||||
|
||||
// if the task failed re-queue so we can try again
|
||||
if (!result.success)
|
||||
if (result.state == ERetrievalResultState.FAIL)
|
||||
{
|
||||
this.missingGenerationPosSet.add(missingPos);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user