[BUG] Lag caused by SyncStaminaMessage
Summary The number of SyncStaminaMessage data packets will grow exponentially with the number of players, which causes lag in server.
Running Environment
- Minecraft Version: 1.20.1 (may also be in other versions)
- ParCool Version: lastest (may also be in other versions)
- Forge Version (optional):
Detail Detail about the bug
Additional Data If there are 50 players on the server, and their stamina changes (which is not a rare event), the server will send 50^2 = 2,500 packets per tick. Writing data to the buffer still blocks the server thread, which caused unnecessary performance overhead. Besides, Forge does not optimize for tiny packets in custom payloads, so the TCP header and custom packet data header also contribute to bandwidth overhead. The server should send just one update packet to the player every tick, which include stamina message the client SHOULD know. Of course, it would be better to give up frequent synchronization from the client.
// SyncStaminaMessage.java
@OnlyIn(Dist.DEDICATED_SERVER)
public void handleServer(Supplier<NetworkEvent.Context> contextSupplier) {
contextSupplier.get().enqueueWork(() -> {
ServerPlayerEntity player;
player = contextSupplier.get().getSender();
ParCool.CHANNEL_INSTANCE.send(PacketDistributor.ALL.noArg(), this); // Send to all players, which causes the problem
if (player == null) return;
IStamina stamina = IStamina.get(player);
if (stamina == null) return;
if (stamina instanceof OtherStamina) {
((OtherStamina) stamina).setMax(this.max);
((OtherStamina) stamina).setImposingPenalty(imposingPenalty);
}
if (staminaType != -1 && consumeOnServer > 0) {
IStamina.Type.values()[staminaType].handleConsumeOnServer(player, consumeOnServer);
}
stamina.set(this.stamina);
stamina.setExhaustion(exhausted);
});
contextSupplier.get().setPacketHandled(true);
}
Thankyou. I think it's good idea. I'll work on next patch in few weeks so I'll try this for it.