Skip to content

Commit 7b9fa02

Browse files
committed
fix(scans): limits not persisting across restarts
1 parent 4f805c0 commit 7b9fa02

6 files changed

Lines changed: 48 additions & 20 deletions

File tree

Insights-API/src/main/java/dev/frankheijden/insights/api/concurrent/ChunkContainerExecutor.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public CompletableFuture<Storage> submit(ChunkContainer container, ScanOptions o
8686
scanTracker.set(worldUid, chunkKey, true);
8787
}
8888

89-
return submit(container).thenApply(storage -> {
89+
return container.scan(containerExecutor).thenApply(storage -> {
9090
if (options.save()) worldStorage.getWorld(worldUid).put(chunkKey, storage);
9191
if (options.track()) scanTracker.set(worldUid, chunkKey, false);
9292

@@ -108,6 +108,11 @@ public CompletableFuture<Void> submit(RunnableContainer container) {
108108
return containerExecutor.submit(container);
109109
}
110110

111+
@Override
112+
public int getTimeout() {
113+
return containerExecutor.getTimeout();
114+
}
115+
111116
@Override
112117
public void shutdown() {
113118
containerExecutor.shutdown();

Insights-API/src/main/java/dev/frankheijden/insights/api/concurrent/ContainerExecutor.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,11 @@ public interface ContainerExecutor {
1010

1111
CompletableFuture<Void> submit(RunnableContainer container);
1212

13+
/**
14+
* Timeout in milliseconds.
15+
* @return Timeout in milliseconds.
16+
*/
17+
int getTimeout();
18+
1319
void shutdown();
1420
}

Insights-API/src/main/java/dev/frankheijden/insights/api/concurrent/containers/ChunkContainer.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.frankheijden.insights.api.concurrent.containers;
22

3+
import dev.frankheijden.insights.api.concurrent.ContainerExecutor;
34
import dev.frankheijden.insights.api.concurrent.ScanOptions;
45
import dev.frankheijden.insights.api.concurrent.storage.DistributionStorage;
56
import dev.frankheijden.insights.api.exceptions.ChunkIOException;
@@ -16,6 +17,7 @@
1617
import java.io.IOException;
1718
import java.util.EnumMap;
1819
import java.util.Map;
20+
import java.util.concurrent.CompletableFuture;
1921
import java.util.function.Consumer;
2022

2123
public abstract class ChunkContainer implements SupplierContainer<DistributionStorage> {
@@ -74,6 +76,16 @@ public ChunkCuboid getChunkCuboid() {
7476

7577
public abstract void getChunkEntities(Consumer<@NotNull ChunkEntity> entityConsumer) throws IOException;
7678

79+
/**
80+
* Implementations may vary what thread this method performs operations on.
81+
*
82+
* @see LoadedChunkContainer#scan(ContainerExecutor)
83+
* @see UnloadedChunkContainer#scan(ContainerExecutor)
84+
* @param executor The executor to run the scan on.
85+
* @return A CompletableFuture of the DistributionStorage.
86+
*/
87+
public abstract CompletableFuture<DistributionStorage> scan(ContainerExecutor executor);
88+
7789
@Override
7890
public DistributionStorage get() {
7991
ChunkVector min = cuboid.getMin();
Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package dev.frankheijden.insights.api.concurrent.containers;
22

33
import dev.frankheijden.insights.api.InsightsPlugin;
4+
import dev.frankheijden.insights.api.concurrent.ContainerExecutor;
45
import dev.frankheijden.insights.api.concurrent.ScanOptions;
6+
import dev.frankheijden.insights.api.concurrent.storage.DistributionStorage;
57
import dev.frankheijden.insights.api.objects.chunk.ChunkCuboid;
68
import dev.frankheijden.insights.nms.core.ChunkEntity;
79
import dev.frankheijden.insights.nms.core.ChunkSection;
@@ -11,6 +13,7 @@
1113
import org.jetbrains.annotations.NotNull;
1214
import org.jetbrains.annotations.Nullable;
1315
import java.util.concurrent.CompletableFuture;
16+
import java.util.concurrent.TimeUnit;
1417
import java.util.function.Consumer;
1518

1619
public class LoadedChunkContainer extends ChunkContainer {
@@ -27,39 +30,28 @@ public LoadedChunkContainer(InsightsNMS nms, Chunk chunk, ChunkCuboid cuboid, Sc
2730

2831
@Override
2932
public void getChunkSections(Consumer<@Nullable ChunkSection> sectionConsumer) {
30-
runOnOwningRegion(() -> nms.getLoadedChunkSections(chunk, sectionConsumer));
33+
nms.getLoadedChunkSections(chunk, sectionConsumer);
3134
}
3235

3336
@Override
3437
public void getChunkEntities(Consumer<@NotNull ChunkEntity> entityConsumer) {
35-
runOnOwningRegion(() -> nms.getLoadedChunkEntities(chunk, entityConsumer));
38+
nms.getLoadedChunkEntities(chunk, entityConsumer);
3639
}
3740

38-
/**
39-
* Runs the given chunk-reading task on the region thread which owns this chunk, blocking the
40-
* calling (worker) thread until it has completed.
41-
*
42-
* <p>This synchronization is required: {@link ChunkContainer#get()} reads the populated
43-
* material/entity maps immediately after invoking these methods. If the read were merely
44-
* scheduled on the region thread (fire-and-forget), {@code get()} would observe still-empty
45-
* maps and return a distribution counting 0, causing limits to be bypassed on every chunk
46-
* that is rescanned after being (re)loaded.
47-
*/
48-
private void runOnOwningRegion(Runnable task) {
41+
@Override
42+
public CompletableFuture<DistributionStorage> scan(ContainerExecutor executor) {
4943
if (Bukkit.isOwnedByCurrentRegion(chunk.getWorld(), chunkX, chunkZ)) {
50-
task.run();
51-
return;
44+
return CompletableFuture.completedFuture(this.get());
5245
}
5346

54-
CompletableFuture<Void> future = new CompletableFuture<>();
47+
CompletableFuture<DistributionStorage> future = new CompletableFuture<>();
5548
Bukkit.getRegionScheduler().execute(InsightsPlugin.getInstance(), chunk.getWorld(), chunkX, chunkZ, () -> {
5649
try {
57-
task.run();
58-
future.complete(null);
50+
future.complete(this.get());
5951
} catch (Throwable th) {
6052
future.completeExceptionally(th);
6153
}
6254
});
63-
future.join();
55+
return future.orTimeout(executor.getTimeout(), TimeUnit.MILLISECONDS);
6456
}
6557
}

Insights-API/src/main/java/dev/frankheijden/insights/api/concurrent/containers/UnloadedChunkContainer.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package dev.frankheijden.insights.api.concurrent.containers;
22

3+
import dev.frankheijden.insights.api.concurrent.ContainerExecutor;
34
import dev.frankheijden.insights.api.concurrent.ScanOptions;
5+
import dev.frankheijden.insights.api.concurrent.storage.DistributionStorage;
46
import dev.frankheijden.insights.api.objects.chunk.ChunkCuboid;
57
import dev.frankheijden.insights.nms.core.ChunkEntity;
68
import dev.frankheijden.insights.nms.core.ChunkSection;
@@ -9,6 +11,7 @@
911
import org.jetbrains.annotations.NotNull;
1012
import org.jetbrains.annotations.Nullable;
1113
import java.io.IOException;
14+
import java.util.concurrent.CompletableFuture;
1215
import java.util.function.Consumer;
1316

1417
public class UnloadedChunkContainer extends ChunkContainer {
@@ -36,4 +39,9 @@ public void getChunkSections(Consumer<@Nullable ChunkSection> sectionConsumer) {
3639
public void getChunkEntities(Consumer<@NotNull ChunkEntity> entityConsumer) throws IOException {
3740
nms.getUnloadedChunkEntities(world, chunkX, chunkZ, entityConsumer);
3841
}
42+
43+
@Override
44+
public CompletableFuture<DistributionStorage> scan(ContainerExecutor executor) {
45+
return executor.submit(this);
46+
}
3947
}

Insights-Core/src/main/java/dev/frankheijden/insights/concurrent/ContainerExecutorService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ public CompletableFuture<Void> submit(RunnableContainer container) {
5454
return CompletableFuture.runAsync(container, executor).orTimeout(timeoutMs, TimeUnit.MILLISECONDS);
5555
}
5656

57+
@Override
58+
public int getTimeout() {
59+
return timeoutMs;
60+
}
61+
5762
public int getQueueSize() {
5863
return executor.getQueue().size();
5964
}

0 commit comments

Comments
 (0)