121 lines
4.6 KiB
Diff
121 lines
4.6 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: MrHua269 <novau233@163.com>
|
|
Date: Fri, 12 Apr 2024 13:48:09 +0000
|
|
Subject: [PATCH] Rewrite linear region flush task dispatching
|
|
|
|
|
|
diff --git a/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFile.java b/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFile.java
|
|
index e40989889f3821bb7484fc0bae5d94b033013904..dc5a5f42c9ca7a50295c18424722568a3ad33fa5 100644
|
|
--- a/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFile.java
|
|
+++ b/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFile.java
|
|
@@ -126,7 +126,7 @@ public class LinearRegionFile implements AbstractRegionFile, AutoCloseable {
|
|
}
|
|
|
|
public void flush() throws IOException {
|
|
- if (isMarkedToSave()) flushWrapper(); // sync
|
|
+ if (getAndResetSaveMarker()) flushWrapper(); // sync
|
|
}
|
|
|
|
private void markToSave() {
|
|
@@ -134,10 +134,18 @@ public class LinearRegionFile implements AbstractRegionFile, AutoCloseable {
|
|
markedToSave.set(true);
|
|
}
|
|
|
|
- public boolean isMarkedToSave() {
|
|
+ public boolean getAndResetSaveMarker() {
|
|
return markedToSave.getAndSet(false);
|
|
}
|
|
|
|
+ public boolean isMarkedToSave(){
|
|
+ return this.markedToSave.get();
|
|
+ }
|
|
+
|
|
+ public void resetSaveMarker(){
|
|
+ this.markedToSave.set(false);
|
|
+ }
|
|
+
|
|
public void flushWrapper() {
|
|
try {
|
|
save();
|
|
diff --git a/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFileFlusher.java b/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFileFlusher.java
|
|
index f06d7767c79e465f999b2032086cc224de95152a..65435eb666b2e1cabffc145e016faa5e3b373464 100644
|
|
--- a/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFileFlusher.java
|
|
+++ b/src/main/java/dev/kaiijumc/kaiiju/region/LinearRegionFileFlusher.java
|
|
@@ -1,17 +1,14 @@
|
|
package dev.kaiijumc.kaiiju.region;
|
|
|
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
|
-import java.util.Queue;
|
|
+
|
|
+import java.util.Set;
|
|
import java.util.concurrent.*;
|
|
import org.bukkit.Bukkit;
|
|
|
|
public class LinearRegionFileFlusher {
|
|
- private final Queue<LinearRegionFile> savingQueue = new LinkedBlockingQueue<>();
|
|
- private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(
|
|
- new ThreadFactoryBuilder()
|
|
- .setNameFormat("linear-flush-scheduler")
|
|
- .build()
|
|
- );
|
|
+ private final Set<LinearRegionFile> pendingSaving = ConcurrentHashMap.newKeySet();
|
|
+
|
|
private final ExecutorService executor = Executors.newFixedThreadPool(
|
|
me.earthme.luminol.config.modules.misc.RegionFormatConfig.linearFlushThreads,
|
|
new ThreadFactoryBuilder()
|
|
@@ -19,26 +16,42 @@ public class LinearRegionFileFlusher {
|
|
.build()
|
|
);
|
|
|
|
+ private final Executor delayedFlusher = CompletableFuture.delayedExecutor(
|
|
+ me.earthme.luminol.config.modules.misc.RegionFormatConfig.linearFlushFrequency,
|
|
+ TimeUnit.SECONDS,
|
|
+ executor
|
|
+ );
|
|
+
|
|
public LinearRegionFileFlusher() {
|
|
Bukkit.getLogger().info("Using " + me.earthme.luminol.config.modules.misc.RegionFormatConfig.linearFlushThreads + " threads for linear region flushing.");
|
|
- scheduler.scheduleAtFixedRate(this::pollAndFlush, 0L, me.earthme.luminol.config.modules.misc.RegionFormatConfig.linearFlushFrequency, TimeUnit.SECONDS);
|
|
}
|
|
|
|
public void scheduleSave(LinearRegionFile regionFile) {
|
|
- if (savingQueue.contains(regionFile)) return;
|
|
- savingQueue.add(regionFile);
|
|
- }
|
|
-
|
|
- private void pollAndFlush() {
|
|
- while (!savingQueue.isEmpty()) {
|
|
- LinearRegionFile regionFile = savingQueue.poll();
|
|
- if (!regionFile.closed && regionFile.isMarkedToSave())
|
|
- executor.execute(regionFile::flushWrapper);
|
|
+ if (this.pendingSaving.contains(regionFile) || !regionFile.isMarkedToSave()){
|
|
+ return;
|
|
}
|
|
+
|
|
+ this.pendingSaving.add(regionFile);
|
|
+ this.delayedFlusher.execute(()->{
|
|
+ try {
|
|
+ if (!regionFile.closed && regionFile.isMarkedToSave()){
|
|
+ regionFile.flushWrapper();
|
|
+ }
|
|
+ }finally {
|
|
+ regionFile.resetSaveMarker();
|
|
+ this.pendingSaving.remove(regionFile);
|
|
+ }
|
|
+ });
|
|
}
|
|
|
|
public void shutdown() {
|
|
- executor.shutdown();
|
|
- scheduler.shutdown();
|
|
+ this.executor.shutdown();
|
|
+ for (;;) {
|
|
+ try {
|
|
+ if (this.executor.awaitTermination(5_00,TimeUnit.MILLISECONDS)) break;
|
|
+ } catch (InterruptedException e) {
|
|
+ e.printStackTrace();
|
|
+ }
|
|
+ }
|
|
}
|
|
}
|