Add pacing option for large region sets: limits updates per tick to avoid lag spikes

recommended 0.60
Mike Primm 11 years ago
parent f9c8a6c892
commit 434afd5862
  1. 74
      src/main/java/org/dynmap/worldguard/DynmapWorldGuardPlugin.java
  2. 2
      src/main/resources/config.yml

@ -1,6 +1,7 @@
package org.dynmap.worldguard;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -44,6 +45,7 @@ public class DynmapWorldGuardPlugin extends JavaPlugin {
MarkerAPI markerapi;
WorldGuardPlugin wg;
BooleanFlag boost_flag;
int updatesPerTick = 20;
FileConfiguration cfg;
MarkerSet set;
@ -100,13 +102,6 @@ public class DynmapWorldGuardPlugin extends JavaPlugin {
log.log(Level.SEVERE, msg);
}
private class WorldGuardUpdate implements Runnable {
public void run() {
if(!stop)
updateRegions();
}
}
private Map<String, AreaMarker> resareas = new HashMap<String, AreaMarker>();
private String formatInfoWindow(ProtectedRegion region, AreaMarker m) {
@ -269,17 +264,50 @@ public class DynmapWorldGuardPlugin extends JavaPlugin {
}
}
/* Update worldguard region information */
private void updateRegions() {
private class UpdateJob implements Runnable {
Map<String,AreaMarker> newmap = new HashMap<String,AreaMarker>(); /* Build new map */
List<World> worldsToDo = null;
List<ProtectedRegion> regionsToDo = null;
World curworld = null;
/* Loop through worlds */
for(World w : getServer().getWorlds()) {
RegionManager rm = wg.getRegionManager(w); /* Get region manager for world */
if(rm == null) continue;
public void run() {
if (stop) {
return;
}
// If worlds list isn't primed, prime it
if (worldsToDo == null) {
worldsToDo = new ArrayList<World>(getServer().getWorlds());
}
while (regionsToDo == null) { // No pending regions for world
if (worldsToDo.isEmpty()) { // No more worlds?
/* Now, review old map - anything left is gone */
for(AreaMarker oldm : resareas.values()) {
oldm.deleteMarker();
}
/* And replace with new map */
resareas = newmap;
// Set up for next update (new job)
getServer().getScheduler().scheduleSyncDelayedTask(DynmapWorldGuardPlugin.this, new UpdateJob(), updperiod);
return;
}
else {
curworld = worldsToDo.remove(0);
RegionManager rm = wg.getRegionManager(curworld); /* Get region manager for world */
if(rm != null) {
Map<String,ProtectedRegion> regions = rm.getRegions(); /* Get all the regions */
for(ProtectedRegion pr : regions.values()) {
if ((regions != null) && (regions.isEmpty() == false)) {
regionsToDo = new ArrayList<ProtectedRegion>(regions.values());
}
}
}
}
/* Now, process up to limit regions */
for (int i = 0; i < updatesPerTick; i++) {
if (regionsToDo.isEmpty()) {
regionsToDo = null;
break;
}
ProtectedRegion pr = regionsToDo.remove(regionsToDo.size()-1);
int depth = 1;
ProtectedRegion p = pr;
while(p.getParent() != null) {
@ -288,18 +316,11 @@ public class DynmapWorldGuardPlugin extends JavaPlugin {
}
if(depth > maxdepth)
continue;
handleRegion(w, pr, newmap);
handleRegion(curworld, pr, newmap);
}
// Tick next step in the job
getServer().getScheduler().scheduleSyncDelayedTask(DynmapWorldGuardPlugin.this, this, 1);
}
/* Now, review old map - anything left is gone */
for(AreaMarker oldm : resareas.values()) {
oldm.deleteMarker();
}
/* And replace with new map */
resareas = newmap;
getServer().getScheduler().scheduleSyncDelayedTask(this, new WorldGuardUpdate(), updperiod);
}
private class OurServerListener implements Listener {
@ -413,6 +434,7 @@ public class DynmapWorldGuardPlugin extends JavaPlugin {
use3d = cfg.getBoolean("use3dregions", false);
infowindow = cfg.getString("infowindow", DEF_INFOWINDOW);
maxdepth = cfg.getInt("maxdepth", 16);
updatesPerTick = cfg.getInt("updates-per-tick", 20);
/* Get style information */
defstyle = new AreaStyle(cfg, "regionstyle");
@ -453,7 +475,7 @@ public class DynmapWorldGuardPlugin extends JavaPlugin {
updperiod = (long)(per*20);
stop = false;
getServer().getScheduler().scheduleSyncDelayedTask(this, new WorldGuardUpdate(), 40); /* First time is 2 seconds */
getServer().getScheduler().scheduleSyncDelayedTask(this, new UpdateJob(), 40); /* First time is 2 seconds */
info("version " + this.getDescription().getVersion() + " is activated");
}

@ -50,3 +50,5 @@ ownerstyle:
# Limit depth of child regions (1=just top regions, 2=top plus children of top)
maxdepth: 16
# Limit number of regions processed per tick (avoid lag spikes on servers with lots of regions)
updates-per-tick: 20

Loading…
Cancel
Save