Enforce LOD request concurrency limit.
This commit is contained in:
1 parent
bda0d067ee
commit
9feff5efa5
7 files changed
+73
-14
No files matched your search
@@ -18,6 +18,7 @@
|
||||
|
||||
package no.jckf.dhsupport.core;
|
||||
|
||||
import no.jckf.dhsupport.core.configuration.Configuration;
|
||||
import no.jckf.dhsupport.core.configuration.DhsConfig;
|
||||
import no.jckf.dhsupport.core.database.models.LodModel;
|
||||
import no.jckf.dhsupport.core.dataobject.SectionPosition;
|
||||
@@ -68,7 +69,12 @@ public class PreGenerator implements Runnable
|
||||
|
||||
public void run()
|
||||
{
|
||||
int rateLimit = this.world.getConfig().getInt(DhsConfig.FULL_DATA_REQUEST_CONCURRENCY_LIMIT);
|
||||
Configuration worldConfig = this.world.getConfig();
|
||||
|
||||
// Fall back to the old key in case the server's config file is for an older plugin version.
|
||||
int rateLimit = worldConfig.has(DhsConfig.CLIENT_LOD_REQUEST_CONCURRENCY_LIMIT)
|
||||
? worldConfig.getInt(DhsConfig.CLIENT_LOD_REQUEST_CONCURRENCY_LIMIT)
|
||||
: worldConfig.getInt(DhsConfig.FULL_DATA_REQUEST_CONCURRENCY_LIMIT);
|
||||
|
||||
int currentX = this.centerX;
|
||||
int currentZ = this.centerZ;
|
||||
|
||||
@@ -118,4 +118,9 @@ public class Configuration
|
||||
{
|
||||
return (int) this.variables.compute(key, (k, v) -> v == null ? 1 : (int) v + 1);
|
||||
}
|
||||
|
||||
public int decrement(String key)
|
||||
{
|
||||
return (int) this.variables.compute(key, (k, v) -> v == null ? -1 : (int) v - 1);
|
||||
}
|
||||
}
|
||||
@@ -32,8 +32,15 @@ public abstract class DhsConfig
|
||||
|
||||
public static String DISTANT_GENERATION_ENABLED = "distant_generation_enabled";
|
||||
|
||||
/**
|
||||
* @deprecated Replaced by CLIENT_LOD_REQUEST_CONCURRENCY_LIMIT.
|
||||
*/
|
||||
public static String FULL_DATA_REQUEST_CONCURRENCY_LIMIT = "full_data_request_concurrency_limit";
|
||||
|
||||
public static String CLIENT_LOD_REQUEST_CONCURRENCY_LIMIT = "client_lod_request_concurrency_limit";
|
||||
|
||||
public static String SERVER_LOD_REQUEST_CONCURRENCY_LIMIT = "server_lod_request_concurrency_limit";
|
||||
|
||||
public static String REAL_TIME_UPDATES_ENABLED = "real_time_updates_enabled";
|
||||
|
||||
public static String REAL_TIME_UPDATE_RADIUS = "real_time_update_radius";
|
||||
|
||||
@@ -30,6 +30,7 @@ import no.jckf.dhsupport.core.world.WorldInterface;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class LodHandler
|
||||
{
|
||||
@@ -39,6 +40,8 @@ public class LodHandler
|
||||
|
||||
protected PluginMessageHandler pluginMessageHandler;
|
||||
|
||||
protected AtomicInteger requestsInFlight = new AtomicInteger(0);
|
||||
|
||||
public LodHandler(DhSupport dhSupport, PluginMessageHandler pluginMessageHandler)
|
||||
{
|
||||
this.dhSupport = dhSupport;
|
||||
@@ -100,7 +103,35 @@ public class LodHandler
|
||||
return;
|
||||
}
|
||||
|
||||
int clientRateLimit = playerConfig.getInt(DhsConfig.CLIENT_LOD_REQUEST_CONCURRENCY_LIMIT, 0);
|
||||
int serverRateLimit = dhsConfig.getInt(DhsConfig.SERVER_LOD_REQUEST_CONCURRENCY_LIMIT, 0);
|
||||
|
||||
boolean exceedsClientRateLimit = playerConfig.increment("active-requests") > clientRateLimit;
|
||||
boolean exceedsServerRateLimit = serverRateLimit > 0 && this.requestsInFlight.incrementAndGet() > serverRateLimit;
|
||||
|
||||
if (exceedsClientRateLimit || exceedsServerRateLimit) {
|
||||
if (serverRateLimit > 0) {
|
||||
this.requestsInFlight.decrementAndGet();
|
||||
}
|
||||
|
||||
playerConfig.decrement("active-requests");
|
||||
|
||||
ExceptionMessage exceptionMessage = new ExceptionMessage();
|
||||
exceptionMessage.isResponseTo(requestMessage);
|
||||
exceptionMessage.setTypeId(ExceptionMessage.TYPE_RATE_LIMITED);
|
||||
exceptionMessage.setMessage("Rate limited by the server");
|
||||
this.pluginMessageHandler.sendPluginMessage(requestMessage.getSender(), exceptionMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
this.dhSupport.getLod(worldUuid, position)
|
||||
.whenComplete((lodModel, exception) -> {
|
||||
if (serverRateLimit > 0) {
|
||||
this.requestsInFlight.decrementAndGet();
|
||||
}
|
||||
|
||||
playerConfig.decrement("active-requests");
|
||||
})
|
||||
.thenAccept((lodModel) -> {
|
||||
if (lodModel == null) {
|
||||
ExceptionMessage exceptionMessage = new ExceptionMessage();
|
||||
|
||||
@@ -129,6 +129,11 @@ public class PlayerConfigHandler
|
||||
keepValue = false;
|
||||
}
|
||||
|
||||
// If no value was found under the new key, read the old key to see if the server's config file is for an older plugin version.
|
||||
if (key.equals(DhsConfig.CLIENT_LOD_REQUEST_CONCURRENCY_LIMIT) && dhsValue == null) {
|
||||
dhsValue = dhsConfig.get(DhsConfig.FULL_DATA_REQUEST_CONCURRENCY_LIMIT);
|
||||
}
|
||||
|
||||
// TODO: This is ugly. Move to comparator closures like in DH.
|
||||
if (key.equals(DhsConfig.BORDER_CENTER_X)) {
|
||||
keepValue = world.getWorldBorderX();
|
||||
|
||||
+10
-10
@@ -31,7 +31,7 @@ public class RemotePlayerConfigMessage extends PluginMessage
|
||||
DhsConfig.BORDER_CENTER_X,
|
||||
DhsConfig.BORDER_CENTER_Z,
|
||||
DhsConfig.BORDER_RADIUS,
|
||||
DhsConfig.FULL_DATA_REQUEST_CONCURRENCY_LIMIT,
|
||||
DhsConfig.CLIENT_LOD_REQUEST_CONCURRENCY_LIMIT,
|
||||
DhsConfig.REAL_TIME_UPDATES_ENABLED,
|
||||
DhsConfig.REAL_TIME_UPDATE_RADIUS,
|
||||
DhsConfig.LOGIN_DATA_SYNC_ENABLED,
|
||||
@@ -44,7 +44,7 @@ public class RemotePlayerConfigMessage extends PluginMessage
|
||||
|
||||
protected boolean distantGenerationEnabled;
|
||||
|
||||
protected int fullDataRequestConcurrencyLimit;
|
||||
protected int clientLodRequestConcurrencyLimit;
|
||||
|
||||
protected boolean realTimeUpdatesEnabled;
|
||||
|
||||
@@ -84,14 +84,14 @@ public class RemotePlayerConfigMessage extends PluginMessage
|
||||
return this.distantGenerationEnabled;
|
||||
}
|
||||
|
||||
public void setFullDataRequestConcurrencyLimit(int limit)
|
||||
public void setClientLodRequestConcurrencyLimit(int limit)
|
||||
{
|
||||
this.fullDataRequestConcurrencyLimit = limit;
|
||||
this.clientLodRequestConcurrencyLimit = limit;
|
||||
}
|
||||
|
||||
public int getFullDataRequestConcurrencyLimit()
|
||||
public int getClientLodRequestConcurrencyLimit()
|
||||
{
|
||||
return this.fullDataRequestConcurrencyLimit;
|
||||
return this.clientLodRequestConcurrencyLimit;
|
||||
}
|
||||
|
||||
public void setRealTimeUpdatesEnabled(boolean enabled)
|
||||
@@ -194,7 +194,7 @@ public class RemotePlayerConfigMessage extends PluginMessage
|
||||
encoder.writeInt(this.borderCenterZ);
|
||||
encoder.writeInt(this.borderRadius);
|
||||
|
||||
encoder.writeInt(this.fullDataRequestConcurrencyLimit);
|
||||
encoder.writeInt(this.clientLodRequestConcurrencyLimit);
|
||||
|
||||
encoder.writeBoolean(this.realTimeUpdatesEnabled);
|
||||
encoder.writeInt(this.realTimeUpdateRadius);
|
||||
@@ -216,7 +216,7 @@ public class RemotePlayerConfigMessage extends PluginMessage
|
||||
this.borderCenterZ = decoder.readInt();
|
||||
this.borderRadius = decoder.readInt();
|
||||
|
||||
this.fullDataRequestConcurrencyLimit = decoder.readInt();
|
||||
this.clientLodRequestConcurrencyLimit = decoder.readInt();
|
||||
|
||||
this.realTimeUpdatesEnabled = decoder.readBoolean();
|
||||
this.realTimeUpdateRadius = decoder.readInt();
|
||||
@@ -241,7 +241,7 @@ public class RemotePlayerConfigMessage extends PluginMessage
|
||||
this.borderCenterZ = borderCenterZ == null ? 0 : borderCenterZ;
|
||||
this.borderRadius = borderRadius == null ? 0 : borderRadius;
|
||||
|
||||
this.fullDataRequestConcurrencyLimit = config.getInt(DhsConfig.FULL_DATA_REQUEST_CONCURRENCY_LIMIT);
|
||||
this.clientLodRequestConcurrencyLimit = config.getInt(DhsConfig.CLIENT_LOD_REQUEST_CONCURRENCY_LIMIT);
|
||||
|
||||
this.realTimeUpdatesEnabled = config.getBool(DhsConfig.REAL_TIME_UPDATES_ENABLED);
|
||||
this.realTimeUpdateRadius = config.getInt(DhsConfig.REAL_TIME_UPDATE_RADIUS);
|
||||
@@ -264,7 +264,7 @@ public class RemotePlayerConfigMessage extends PluginMessage
|
||||
config.set(DhsConfig.BORDER_CENTER_Z, this.borderCenterZ);
|
||||
config.set(DhsConfig.BORDER_RADIUS, this.borderRadius);
|
||||
|
||||
config.set(DhsConfig.FULL_DATA_REQUEST_CONCURRENCY_LIMIT, this.fullDataRequestConcurrencyLimit);
|
||||
config.set(DhsConfig.CLIENT_LOD_REQUEST_CONCURRENCY_LIMIT, this.clientLodRequestConcurrencyLimit);
|
||||
|
||||
config.set(DhsConfig.REAL_TIME_UPDATES_ENABLED, this.realTimeUpdatesEnabled);
|
||||
config.set(DhsConfig.REAL_TIME_UPDATE_RADIUS, this.realTimeUpdateRadius);
|
||||
|
||||
@@ -14,10 +14,15 @@ render_distance: 1024
|
||||
# Default: true
|
||||
distant_generation_enabled: true
|
||||
|
||||
# Number of parallel LOD requests per client.
|
||||
# Maximum number of concurrent LOD requests per client.
|
||||
# Required.
|
||||
# Default: 20
|
||||
full_data_request_concurrency_limit: 20
|
||||
client_lod_request_concurrency_limit: 20
|
||||
|
||||
# Maximum concurrent LOD requests server-wide, across all players. 0 = unlimited.
|
||||
# Optional.
|
||||
# Default: 0
|
||||
#server_lod_request_concurrency_limit: 100
|
||||
|
||||
# Send LOD updates to players in real-time?
|
||||
# Required.
|
||||
@@ -235,4 +240,4 @@ scheduler_threads: 4
|
||||
#debug: true
|
||||
|
||||
# Don't touch :)
|
||||
config_version: 10
|
||||
config_version: 11
|
||||
Reference in new issue
Block a user