feat: synchronise disk clipboard loading and deletion to clipboardLock (#2342)

- another possible help towards the OverlappingFileLockException
This commit is contained in:
Jordan 2023-07-15 16:40:52 +01:00 committed by GitHub
parent f4da4b0287
commit e6b1308590
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 34 deletions

View File

@ -449,7 +449,6 @@ public class Fawe {
* @return Executor used for clipboard IO if clipboard on disk is enabled or null * @return Executor used for clipboard IO if clipboard on disk is enabled or null
* @since 2.6.2 * @since 2.6.2
*/ */
@Nullable
public KeyQueuedExecutorService<UUID> getClipboardExecutor() { public KeyQueuedExecutorService<UUID> getClipboardExecutor() {
return this.clipboardExecutor; return this.clipboardExecutor;
} }

View File

@ -23,8 +23,10 @@ import com.fastasyncworldedit.core.Fawe;
import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.configuration.Settings;
import com.fastasyncworldedit.core.extent.ResettableExtent; import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.fastasyncworldedit.core.extent.clipboard.DiskOptimizedClipboard;
import com.fastasyncworldedit.core.extent.clipboard.MultiClipboardHolder; import com.fastasyncworldedit.core.extent.clipboard.MultiClipboardHolder;
import com.fastasyncworldedit.core.history.DiskStorageHistory; import com.fastasyncworldedit.core.history.DiskStorageHistory;
import com.fastasyncworldedit.core.internal.exception.FaweClipboardVersionMismatchException;
import com.fastasyncworldedit.core.internal.io.FaweInputStream; import com.fastasyncworldedit.core.internal.io.FaweInputStream;
import com.fastasyncworldedit.core.internal.io.FaweOutputStream; import com.fastasyncworldedit.core.internal.io.FaweOutputStream;
import com.fastasyncworldedit.core.limit.FaweLimit; import com.fastasyncworldedit.core.limit.FaweLimit;
@ -50,6 +52,8 @@ import com.sk89q.worldedit.command.tool.Tool;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Locatable; import com.sk89q.worldedit.extension.platform.Locatable;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.ChangeSetExecutor; import com.sk89q.worldedit.function.operation.ChangeSetExecutor;
@ -93,6 +97,7 @@ import java.util.ListIterator;
import java.util.Objects; import java.util.Objects;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
@ -877,6 +882,58 @@ public class LocalSession implements TextureHolder {
} }
} }
} }
/**
* Load a clipboard from disk and into this localsession. Synchronises with other clipboard setting/getting to and from
* this session
*
* @param file Clipboard file to load
* @throws FaweClipboardVersionMismatchException in clipboard version mismatch (between saved and internal, expected, version)
* @throws ExecutionException if the computation threw an exception
* @throws InterruptedException if the current thread was interrupted while waiting
*/
public void loadClipboardFromDisk(File file) throws FaweClipboardVersionMismatchException, ExecutionException,
InterruptedException {
synchronized (clipboardLock) {
if (file.exists() && file.length() > 5) {
try {
if (getClipboard() != null) {
return;
}
} catch (EmptyClipboardException ignored) {
}
DiskOptimizedClipboard doc = Fawe.instance().getClipboardExecutor().submit(
uuid,
() -> DiskOptimizedClipboard.loadFromFile(file)
).get();
Clipboard clip = doc.toClipboard();
ClipboardHolder holder = new ClipboardHolder(clip);
setClipboard(holder);
}
}
}
public void deleteClipboardOnDisk() {
synchronized (clipboardLock) {
ClipboardHolder holder = getExistingClipboard();
if (holder != null) {
for (Clipboard clipboard : holder.getClipboards()) {
DiskOptimizedClipboard doc;
if (clipboard instanceof DiskOptimizedClipboard) {
doc = (DiskOptimizedClipboard) clipboard;
} else if (clipboard instanceof BlockArrayClipboard && ((BlockArrayClipboard) clipboard).getParent() instanceof DiskOptimizedClipboard) {
doc = (DiskOptimizedClipboard) ((BlockArrayClipboard) clipboard).getParent();
} else {
continue;
}
Fawe.instance().getClipboardExecutor().submit(uuid, () -> {
doc.close(); // Ensure closed before deletion
doc.getFile().delete();
});
}
}
}
}
//FAWE end //FAWE end
/** /**

View File

@ -426,23 +426,7 @@ public interface Player extends Entity, Actor {
cancel(true); cancel(true);
LocalSession session = getSession(); LocalSession session = getSession();
if (Settings.settings().CLIPBOARD.USE_DISK && Settings.settings().CLIPBOARD.DELETE_ON_LOGOUT) { if (Settings.settings().CLIPBOARD.USE_DISK && Settings.settings().CLIPBOARD.DELETE_ON_LOGOUT) {
ClipboardHolder holder = session.getExistingClipboard(); session.deleteClipboardOnDisk();
if (holder != null) {
for (Clipboard clipboard : holder.getClipboards()) {
DiskOptimizedClipboard doc;
if (clipboard instanceof DiskOptimizedClipboard) {
doc = (DiskOptimizedClipboard) clipboard;
} else if (clipboard instanceof BlockArrayClipboard && ((BlockArrayClipboard) clipboard).getParent() instanceof DiskOptimizedClipboard) {
doc = (DiskOptimizedClipboard) ((BlockArrayClipboard) clipboard).getParent();
} else {
continue;
}
Fawe.instance().getClipboardExecutor().submit(getUniqueId(), () -> {
doc.close(); // Ensure closed before deletion
doc.getFile().delete();
});
}
}
} else if (Settings.settings().CLIPBOARD.USE_DISK) { } else if (Settings.settings().CLIPBOARD.USE_DISK) {
Fawe.instance().getClipboardExecutor().submit(getUniqueId(), () -> session.setClipboard(null)); Fawe.instance().getClipboardExecutor().submit(getUniqueId(), () -> session.setClipboard(null));
} else if (Settings.settings().CLIPBOARD.DELETE_ON_LOGOUT) { } else if (Settings.settings().CLIPBOARD.DELETE_ON_LOGOUT) {
@ -464,22 +448,7 @@ public interface Player extends Entity, Actor {
Settings.settings().PATHS.CLIPBOARD + File.separator + getUniqueId() + ".bd" Settings.settings().PATHS.CLIPBOARD + File.separator + getUniqueId() + ".bd"
); );
try { try {
if (file.exists() && file.length() > 5) { getSession().loadClipboardFromDisk(file);
LocalSession session = getSession();
try {
if (session.getClipboard() != null) {
return;
}
} catch (EmptyClipboardException ignored) {
}
DiskOptimizedClipboard doc = Fawe.instance().getClipboardExecutor().submit(
getUniqueId(),
() -> DiskOptimizedClipboard.loadFromFile(file)
).get();
Clipboard clip = doc.toClipboard();
ClipboardHolder holder = new ClipboardHolder(clip);
session.setClipboard(holder);
}
} catch (FaweClipboardVersionMismatchException e) { } catch (FaweClipboardVersionMismatchException e) {
print(e.getComponent()); print(e.getComponent());
} catch (RuntimeException e) { } catch (RuntimeException e) {