Skip to content

Commit d34dc24

Browse files
committed
Async Saving on World Unload
1 parent 48367ac commit d34dc24

File tree

5 files changed

+81
-39
lines changed

5 files changed

+81
-39
lines changed

src/com/dre/brewery/BCauldron.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -507,14 +507,22 @@ public static boolean remove(Block block) {
507507
/**
508508
* Are any Cauldrons in that World
509509
*/
510-
public static boolean hasDataInWorld(String name) {
511-
return bcauldrons.keySet().stream().anyMatch(block -> block.getWorld().getName().equals(name));
510+
public static boolean hasDataInWorld(World world) {
511+
return bcauldrons.keySet().stream().anyMatch(block -> block.getWorld().equals(world));
512512
}
513513

514514
// unloads cauldrons that are in a unloading world
515515
// as they were written to file just before, this is safe to do
516-
public static void onUnload(String name) {
517-
bcauldrons.keySet().removeIf(block -> block.getWorld().getName().equals(name));
516+
public static void onUnload(World world) {
517+
bcauldrons.keySet().removeIf(block -> block.getWorld().equals(world));
518+
}
519+
520+
/**
521+
* Unload all Cauldrons that have are in a unloaded World
522+
*/
523+
public static void unloadWorlds() {
524+
List<World> worlds = P.p.getServer().getWorlds();
525+
bcauldrons.keySet().removeIf(block -> !worlds.contains(block.getWorld()));
518526
}
519527

520528
public static void save(ConfigurationSection config, ConfigurationSection oldData) {

src/com/dre/brewery/Barrel.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.bukkit.Material;
1515
import org.bukkit.Sound;
1616
import org.bukkit.SoundCategory;
17+
import org.bukkit.World;
1718
import org.bukkit.block.Block;
1819
import org.bukkit.configuration.ConfigurationSection;
1920
import org.bukkit.entity.HumanEntity;
@@ -125,13 +126,9 @@ public boolean hasPermsOpen(Player player, PlayerInteractEvent event) {
125126

126127
// Call event
127128
BarrelAccessEvent accessEvent = new BarrelAccessEvent(this, player, event.getClickedBlock(), event.getBlockFace());
128-
// Listened to by WGBarrel7, WGBarrelNew, WGBarrelOld, GriefPreventionBarrel (IntegrationListener)
129+
// Listened to by IntegrationListener
129130
P.p.getServer().getPluginManager().callEvent(accessEvent);
130-
if (accessEvent.isCancelled()) {
131-
return false;
132-
}
133-
134-
return true;
131+
return !accessEvent.isCancelled();
135132
}
136133

137134
/**
@@ -475,15 +472,23 @@ public Block getBrokenBlock(boolean force) {
475472
/**
476473
* Are any Barrels in that World
477474
*/
478-
public static boolean hasDataInWorld(String name) {
479-
return barrels.stream().anyMatch(barrel -> barrel.spigot.getWorld().getName().equals(name));
475+
public static boolean hasDataInWorld(World world) {
476+
return barrels.stream().anyMatch(barrel -> barrel.spigot.getWorld().equals(world));
480477
}
481478

482479
/**
483480
* unloads barrels that are in a unloading world
484481
*/
485-
public static void onUnload(String name) {
486-
barrels.removeIf(barrel -> barrel.spigot.getWorld().getName().equals(name));
482+
public static void onUnload(World world) {
483+
barrels.removeIf(barrel -> barrel.spigot.getWorld().equals(world));
484+
}
485+
486+
/**
487+
* Unload all Barrels that have a Block in a unloaded World
488+
*/
489+
public static void unloadWorlds() {
490+
List<World> worlds = P.p.getServer().getWorlds();
491+
barrels.removeIf(barrel -> !worlds.contains(barrel.spigot.getWorld()));
487492
}
488493

489494
/**

src/com/dre/brewery/Wakeup.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.dre.brewery.utility.BUtil;
44
import org.bukkit.Location;
5+
import org.bukkit.World;
56
import org.bukkit.command.CommandSender;
67
import org.bukkit.configuration.ConfigurationSection;
78
import org.bukkit.entity.Player;
@@ -266,8 +267,13 @@ public static void save(ConfigurationSection section, ConfigurationSection oldDa
266267
}
267268
}
268269

269-
public static void onUnload(String worldName) {
270-
wakeups.removeIf(wakeup -> wakeup.loc.getWorld().getName().equals(worldName));
270+
public static void onUnload(World world) {
271+
wakeups.removeIf(wakeup -> wakeup.loc.getWorld().equals(world));
272+
}
273+
274+
public static void unloadWorlds() {
275+
List<World> worlds = P.p.getServer().getWorlds();
276+
wakeups.removeIf(wakeup -> !worlds.contains(wakeup.loc.getWorld()));
271277
}
272278

273279
}

src/com/dre/brewery/filedata/DataSave.java

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import java.util.ArrayList;
1313
import java.util.List;
14+
import java.util.concurrent.CopyOnWriteArrayList;
1415

1516
public class DataSave extends BukkitRunnable {
1617

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

2325
public ReadOldData read;
24-
private long time;
26+
private final long time;
27+
private final List<World> loadedWorlds;
2528
public boolean collected = false;
2629

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

3337

38+
// Running in Main Thread
3439
@Override
3540
public void run() {
3641
try {
@@ -107,6 +112,20 @@ public void run() {
107112

108113
collected = true;
109114

115+
if (!unloadingWorlds.isEmpty()) {
116+
try {
117+
for (World world : unloadingWorlds) {
118+
// In the very most cases, it is just one world, so just looping like this is fine
119+
Barrel.onUnload(world);
120+
BCauldron.onUnload(world);
121+
Wakeup.onUnload(world);
122+
}
123+
} catch (Exception e) {
124+
e.printStackTrace();
125+
}
126+
unloadingWorlds.clear();
127+
}
128+
110129
P.p.debugLog("saving: " + ((System.nanoTime() - saveTime) / 1000000.0) + "ms");
111130

112131
if (P.p.isEnabled()) {
@@ -121,6 +140,22 @@ public void run() {
121140
}
122141
}
123142

143+
public void saveWorldNames(FileConfiguration root, ConfigurationSection old) {
144+
if (old != null) {
145+
root.set("Worlds", old);
146+
}
147+
for (World world : loadedWorlds) {
148+
String worldName = world.getName();
149+
if (worldName.startsWith("DXL_")) {
150+
worldName = BUtil.getDxlName(worldName);
151+
root.set("Worlds." + worldName, 0);
152+
} else {
153+
worldName = world.getUID().toString();
154+
root.set("Worlds." + worldName, world.getName());
155+
}
156+
}
157+
}
158+
124159
// Finish the collection of data immediately
125160
public void now() {
126161
if (!read.done) {
@@ -164,20 +199,4 @@ public static void autoSave() {
164199
lastSave++;
165200
}
166201
}
167-
168-
public static void saveWorldNames(FileConfiguration root, ConfigurationSection old) {
169-
if (old != null) {
170-
root.set("Worlds", old);
171-
}
172-
for (World world : P.p.getServer().getWorlds()) {
173-
String worldName = world.getName();
174-
if (worldName.startsWith("DXL_")) {
175-
worldName = BUtil.getDxlName(worldName);
176-
root.set("Worlds." + worldName, 0);
177-
} else {
178-
worldName = world.getUID().toString();
179-
root.set("Worlds." + worldName, world.getName());
180-
}
181-
}
182-
}
183202
}

src/com/dre/brewery/listeners/WorldListener.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,17 @@ private void lwDataTask(World world) {
4545

4646
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
4747
public void onWorldUnload(WorldUnloadEvent event) {
48-
String worldName = event.getWorld().getName();
49-
if (Barrel.hasDataInWorld(worldName) || BCauldron.hasDataInWorld(worldName)) {
50-
DataSave.save(true);
51-
Barrel.onUnload(worldName);
52-
BCauldron.onUnload(worldName);
48+
World world = event.getWorld();
49+
if (DataSave.running == null) {
50+
// No datasave running, save data if we have any in that world
51+
if (Barrel.hasDataInWorld(world) || BCauldron.hasDataInWorld(world)) {
52+
DataSave.unloadingWorlds.add(world);
53+
DataSave.save(false);
54+
}
55+
} else {
56+
// already running, tell it to unload world
57+
DataSave.unloadingWorlds.add(world);
5358
}
54-
Wakeup.onUnload(worldName);
5559
}
5660

5761
}

0 commit comments

Comments
 (0)