Skip to content

Commit

Permalink
Async Saving on World Unload
Browse files Browse the repository at this point in the history
  • Loading branch information
Sn0wStorm committed Nov 27, 2020
1 parent 48367ac commit d34dc24
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 39 deletions.
16 changes: 12 additions & 4 deletions src/com/dre/brewery/BCauldron.java
Original file line number Diff line number Diff line change
Expand Up @@ -507,14 +507,22 @@ public static boolean remove(Block block) {
/**
* Are any Cauldrons in that World
*/
public static boolean hasDataInWorld(String name) {
return bcauldrons.keySet().stream().anyMatch(block -> block.getWorld().getName().equals(name));
public static boolean hasDataInWorld(World world) {
return bcauldrons.keySet().stream().anyMatch(block -> block.getWorld().equals(world));
}

// unloads cauldrons that are in a unloading world
// as they were written to file just before, this is safe to do
public static void onUnload(String name) {
bcauldrons.keySet().removeIf(block -> block.getWorld().getName().equals(name));
public static void onUnload(World world) {
bcauldrons.keySet().removeIf(block -> block.getWorld().equals(world));
}

/**
* Unload all Cauldrons that have are in a unloaded World
*/
public static void unloadWorlds() {
List<World> worlds = P.p.getServer().getWorlds();
bcauldrons.keySet().removeIf(block -> !worlds.contains(block.getWorld()));
}

public static void save(ConfigurationSection config, ConfigurationSection oldData) {
Expand Down
25 changes: 15 additions & 10 deletions src/com/dre/brewery/Barrel.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.SoundCategory;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.HumanEntity;
Expand Down Expand Up @@ -125,13 +126,9 @@ public boolean hasPermsOpen(Player player, PlayerInteractEvent event) {

// Call event
BarrelAccessEvent accessEvent = new BarrelAccessEvent(this, player, event.getClickedBlock(), event.getBlockFace());
// Listened to by WGBarrel7, WGBarrelNew, WGBarrelOld, GriefPreventionBarrel (IntegrationListener)
// Listened to by IntegrationListener
P.p.getServer().getPluginManager().callEvent(accessEvent);
if (accessEvent.isCancelled()) {
return false;
}

return true;
return !accessEvent.isCancelled();
}

/**
Expand Down Expand Up @@ -475,15 +472,23 @@ public Block getBrokenBlock(boolean force) {
/**
* Are any Barrels in that World
*/
public static boolean hasDataInWorld(String name) {
return barrels.stream().anyMatch(barrel -> barrel.spigot.getWorld().getName().equals(name));
public static boolean hasDataInWorld(World world) {
return barrels.stream().anyMatch(barrel -> barrel.spigot.getWorld().equals(world));
}

/**
* unloads barrels that are in a unloading world
*/
public static void onUnload(String name) {
barrels.removeIf(barrel -> barrel.spigot.getWorld().getName().equals(name));
public static void onUnload(World world) {
barrels.removeIf(barrel -> barrel.spigot.getWorld().equals(world));
}

/**
* Unload all Barrels that have a Block in a unloaded World
*/
public static void unloadWorlds() {
List<World> worlds = P.p.getServer().getWorlds();
barrels.removeIf(barrel -> !worlds.contains(barrel.spigot.getWorld()));
}

/**
Expand Down
10 changes: 8 additions & 2 deletions src/com/dre/brewery/Wakeup.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.dre.brewery.utility.BUtil;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
Expand Down Expand Up @@ -266,8 +267,13 @@ public static void save(ConfigurationSection section, ConfigurationSection oldDa
}
}

public static void onUnload(String worldName) {
wakeups.removeIf(wakeup -> wakeup.loc.getWorld().getName().equals(worldName));
public static void onUnload(World world) {
wakeups.removeIf(wakeup -> wakeup.loc.getWorld().equals(world));
}

public static void unloadWorlds() {
List<World> worlds = P.p.getServer().getWorlds();
wakeups.removeIf(wakeup -> !worlds.contains(wakeup.loc.getWorld()));
}

}
53 changes: 36 additions & 17 deletions src/com/dre/brewery/filedata/DataSave.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class DataSave extends BukkitRunnable {

Expand All @@ -19,18 +20,22 @@ public class DataSave extends BukkitRunnable {
public static int autosave = 3;
final public static String dataVersion = "1.2";
public static DataSave running;
public static List<World> unloadingWorlds = new CopyOnWriteArrayList<>();

public ReadOldData read;
private long time;
private final long time;
private final List<World> loadedWorlds;
public boolean collected = false;

// Not Thread-Safe! Needs to be run in main thread but uses async Read/Write
public DataSave(ReadOldData read) {
this.read = read;
time = System.currentTimeMillis();
loadedWorlds = P.p.getServer().getWorlds();
}


// Running in Main Thread
@Override
public void run() {
try {
Expand Down Expand Up @@ -107,6 +112,20 @@ public void run() {

collected = true;

if (!unloadingWorlds.isEmpty()) {
try {
for (World world : unloadingWorlds) {
// In the very most cases, it is just one world, so just looping like this is fine
Barrel.onUnload(world);
BCauldron.onUnload(world);
Wakeup.onUnload(world);
}
} catch (Exception e) {
e.printStackTrace();
}
unloadingWorlds.clear();
}

P.p.debugLog("saving: " + ((System.nanoTime() - saveTime) / 1000000.0) + "ms");

if (P.p.isEnabled()) {
Expand All @@ -121,6 +140,22 @@ public void run() {
}
}

public void saveWorldNames(FileConfiguration root, ConfigurationSection old) {
if (old != null) {
root.set("Worlds", old);
}
for (World world : loadedWorlds) {
String worldName = world.getName();
if (worldName.startsWith("DXL_")) {
worldName = BUtil.getDxlName(worldName);
root.set("Worlds." + worldName, 0);
} else {
worldName = world.getUID().toString();
root.set("Worlds." + worldName, world.getName());
}
}
}

// Finish the collection of data immediately
public void now() {
if (!read.done) {
Expand Down Expand Up @@ -164,20 +199,4 @@ public static void autoSave() {
lastSave++;
}
}

public static void saveWorldNames(FileConfiguration root, ConfigurationSection old) {
if (old != null) {
root.set("Worlds", old);
}
for (World world : P.p.getServer().getWorlds()) {
String worldName = world.getName();
if (worldName.startsWith("DXL_")) {
worldName = BUtil.getDxlName(worldName);
root.set("Worlds." + worldName, 0);
} else {
worldName = world.getUID().toString();
root.set("Worlds." + worldName, world.getName());
}
}
}
}
16 changes: 10 additions & 6 deletions src/com/dre/brewery/listeners/WorldListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,17 @@ private void lwDataTask(World world) {

@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onWorldUnload(WorldUnloadEvent event) {
String worldName = event.getWorld().getName();
if (Barrel.hasDataInWorld(worldName) || BCauldron.hasDataInWorld(worldName)) {
DataSave.save(true);
Barrel.onUnload(worldName);
BCauldron.onUnload(worldName);
World world = event.getWorld();
if (DataSave.running == null) {
// No datasave running, save data if we have any in that world
if (Barrel.hasDataInWorld(world) || BCauldron.hasDataInWorld(world)) {
DataSave.unloadingWorlds.add(world);
DataSave.save(false);
}
} else {
// already running, tell it to unload world
DataSave.unloadingWorlds.add(world);
}
Wakeup.onUnload(worldName);
}

}

0 comments on commit d34dc24

Please sign in to comment.