Limit island/player saves per tick (#1578)

* limit island/player saves per tick

* Whoops

* 20 players/islands per tick should be enough

20 players/islands * 20 tick * 60 seconds * 5 minutes (default interval) = 120000 saved entries :)
This commit is contained in:
Gabriele C 2020-11-27 19:12:10 +01:00 committed by GitHub
parent 2e00602371
commit 232d9097cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 120 additions and 29 deletions

View File

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

View File

@ -95,6 +95,18 @@ public class Settings implements ConfigObject {
@ConfigEntry(path = "general.database.backup-period")
private int databaseBackupPeriod = 5;
@ConfigComment("How many players will be saved in one tick. Default is 200")
@ConfigComment("Reduce if you experience lag while saving.")
@ConfigComment("Do not set this too low or data might get lost!")
@ConfigEntry(path = "general.database.max-saved-players-per-tick")
private int maxSavedPlayersPerTick = 20;
@ConfigComment("How many islands will be saved in one tick. Default is 200")
@ConfigComment("Reduce if you experience lag while saving.")
@ConfigComment("Do not set this too low or data might get lost!")
@ConfigEntry(path = "general.database.max-saved-islands-per-tick")
private int maxSavedIslandsPerTick = 20;
@ConfigComment("Enable SSL connection to MongoDB, MariaDB, MySQL and PostgreSQL databases.")
@ConfigEntry(path = "general.database.use-ssl", since = "1.12.0")
private boolean useSSL = false;
@ -379,6 +391,34 @@ public class Settings implements ConfigObject {
this.databaseBackupPeriod = databaseBackupPeriod;
}
/**
* @since 1.15.3
*/
public int getMaxSavedPlayersPerTick() {
return maxSavedPlayersPerTick;
}
/**
* @since 1.15.3
*/
public void setMaxSavedPlayersPerTick(int maxSavedPlayersPerTick) {
this.maxSavedPlayersPerTick = maxSavedPlayersPerTick;
}
/**
* @since 1.15.3
*/
public int getMaxSavedIslandsPerTick() {
return maxSavedIslandsPerTick;
}
/**
* @since 1.15.3
*/
public void setMaxSavedIslandsPerTick(int maxSavedIslandsPerTick) {
this.maxSavedIslandsPerTick = maxSavedIslandsPerTick;
}
public Set<String> getFakePlayers() {
return fakePlayers;
}

View File

@ -1,17 +1,7 @@
package world.bentobox.bentobox.managers;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@ -29,6 +19,7 @@ import org.bukkit.entity.Player;
import org.bukkit.entity.PufferFish;
import org.bukkit.inventory.ItemStack;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
@ -1221,15 +1212,44 @@ public class IslandsManager {
/**
* Save the all the islands to the database
*/
public void saveAll(){
Collection<Island> collection = islandCache.getIslands();
for(Island island : collection){
try {
handler.saveObjectAsync(island);
} catch (Exception e) {
plugin.logError("Could not save island to database when running sync! " + e.getMessage());
public void saveAll() {
saveAll(false);
}
/**
* Save the all the islands to the database
* @param schedule true if we should let the task run over multiple ticks to reduce lag spikes
*/
public void saveAll(boolean schedule){
if (!schedule) {
for(Island island : islandCache.getIslands()){
try {
handler.saveObjectAsync(island);
} catch (Exception e) {
plugin.logError("Could not save island to database when running sync! " + e.getMessage());
}
}
return;
}
Queue<Island> queue = new LinkedList<>(islandCache.getIslands());
new BukkitRunnable() {
@Override
public void run() {
for (int i = 0; i < plugin.getSettings().getMaxSavedIslandsPerTick(); i++) {
Island island = queue.poll();
if (island == null) {
cancel();
return;
}
try {
handler.saveObjectAsync(island);
} catch (Exception e) {
plugin.logError("Could not save island to database when running sync! " + e.getMessage());
}
}
}
}.runTaskTimer(plugin, 0, 1);
}
/**

View File

@ -1,16 +1,11 @@
package world.bentobox.bentobox.managers;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.*;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
@ -67,8 +62,44 @@ public class PlayersManager {
/**
* Save all players
*/
public void saveAll(){
Collections.unmodifiableCollection(playerCache.values()).forEach(handler::saveObjectAsync);
public void saveAll() {
saveAll(false);
}
/**
* Save all players
* @param schedule true if we should let the task run over multiple ticks to reduce lag spikes
*/
public void saveAll(boolean schedule){
if (!schedule) {
for (Players player : playerCache.values()) {
try {
handler.saveObjectAsync(player);
} catch (Exception e) {
plugin.logError("Could not save player to database when running sync! " + e.getMessage());
}
}
return;
}
Queue<Players> queue = new LinkedList<>(playerCache.values());
new BukkitRunnable() {
@Override
public void run() {
for (int i = 0; i < plugin.getSettings().getMaxSavedPlayersPerTick(); i++) {
Players player = queue.poll();
if (player == null) {
cancel();
return;
}
try {
handler.saveObjectAsync(player);
} catch (Exception e) {
plugin.logError("Could not save player to database when running sync! " + e.getMessage());
}
}
}
}.runTaskTimer(plugin, 0, 1);
}
public void shutdown(){