Spreads out backup database saving to avoid lag

https://github.com/BentoBoxWorld/BentoBox/issues/976
This commit is contained in:
tastybento 2019-10-07 16:16:26 -07:00
parent 27647da6f4
commit 2db926f640
4 changed files with 62 additions and 2 deletions

View File

@ -184,8 +184,8 @@ public class BentoBox extends JavaPlugin {
// Save islands & players data every X minutes
instance.getServer().getScheduler().runTaskTimer(instance, () -> {
playersManager.saveAll();
islandsManager.saveAll();
playersManager.asyncSaveAll();
islandsManager.asyncSaveAll();
}, getSettings().getDatabaseBackupPeriod() * 20 * 60L, getSettings().getDatabaseBackupPeriod() * 20 * 60L);
// Make sure all flag listeners are registered.

View File

@ -5,6 +5,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -28,6 +29,7 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.PufferFish;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
@ -95,6 +97,12 @@ public class IslandsManager {
@NonNull
private List<String> deletedIslands;
private Set<String> toSave = new HashSet<>();
private Iterator<String> it;
private BukkitTask task;
/**
* Islands Manager
* @param plugin - plugin
@ -970,6 +978,24 @@ public class IslandsManager {
}
}
/**
* Saves all the players at a rate of 1 per tick. Used as a backup.
* @since 1.8.0
*/
public void asyncSaveAll() {
if (!toSave.isEmpty()) return;
// Get a list of ID's to save
toSave = islandCache.getAllIslandIds();
it = toSave.iterator();
task = Bukkit.getScheduler().runTaskTimer(plugin, () -> {
if (plugin.isEnabled() && it.hasNext()) {
getIslandById(it.next()).ifPresent(this::save);
} else {
toSave.clear();
task.cancel();
}
}, 0L, 1L);
}
/**
* Puts a player in a team. Removes them from their old island if required.
* @param teamIsland - team island

View File

@ -4,12 +4,15 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.scheduler.BukkitTask;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
@ -28,6 +31,9 @@ public class PlayersManager {
private Map<UUID, Players> playerCache;
private Set<UUID> inTeleport;
private Set<UUID> toSave = new HashSet<>();
private Iterator<UUID> it;
private BukkitTask task;
/**
* Provides a memory cache of online player information
@ -69,6 +75,25 @@ public class PlayersManager {
public void saveAll(){
Collections.unmodifiableCollection(playerCache.values()).forEach(handler::saveObject);
}
/**
* Saves all the players at a rate of 1 per tick. Used as a backup.
* @since 1.8.0
*/
public void asyncSaveAll() {
if (!toSave.isEmpty()) return;
// Get a list of ID's to save
toSave = playerCache.keySet();
it = toSave.iterator();
task = Bukkit.getScheduler().runTaskTimer(plugin, () -> {
if (plugin.isEnabled() && it.hasNext()) {
this.save(it.next());
} else {
toSave.clear();
task.cancel();
}
}, 0L, 1L);
}
public void shutdown(){
saveAll();

View File

@ -326,4 +326,13 @@ public class IslandCache {
int setting = BentoBox.getInstance().getIWM().getDefaultIslandFlags(w).getOrDefault(flag, flag.getDefaultRank());
islandsById.values().stream().filter(i -> i.getWorld().equals(w)).forEach(i -> i.setFlag(flag, setting));
}
/**
* Get all the island ids
* @return set of ids
* @since 1.8.0
*/
public Set<String> getAllIslandIds() {
return islandsById.keySet();
}
}