From 3a93ae1af1158f552838375f454c9dff6d3bc95b Mon Sep 17 00:00:00 2001 From: Johaine <32821455+Johaine@users.noreply.github.com> Date: Sat, 6 Apr 2024 15:22:32 +0200 Subject: [PATCH] feat(Core/Optimization): Correctly document sendBuffer size and optimize it. (#18647) * Fix comment documenting WorldSocket The buffer is constructed with 4096 bytes but later resized in WorldSocketThread::SocketAdded() according to the configuration setting Network.OutUBuff (currently 65536 bytes) * Reuse calculated packet size Instead of recalculating the current packet size three times at worst, calculate it once and reuse it when required. * Reduce reserved buffer size per WorldSocket Don't reserve 64kB of memory for every WorldSocket's output buffer. Instead, start with a 4kB baseline for every WorldSocket and grow the buffer size dynamically when we have single packets that do not fit the current buffer. --- .../apps/worldserver/worldserver.conf.dist | 8 +++---- src/server/game/Server/WorldSocket.cpp | 23 ++++++++++++------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/server/apps/worldserver/worldserver.conf.dist b/src/server/apps/worldserver/worldserver.conf.dist index 05ffeb6fd..34a734331 100644 --- a/src/server/apps/worldserver/worldserver.conf.dist +++ b/src/server/apps/worldserver/worldserver.conf.dist @@ -364,11 +364,11 @@ Network.OutKBuff = -1 # # Network.OutUBuff -# Description: Amount of memory (in bytes) reserved in the user space per connection for -# output buffering. -# Default: 65536 +# Description: Amount of memory (in bytes) reserved initially in the user space per +# connection for output buffering. +# Default: 4096 -Network.OutUBuff = 65536 +Network.OutUBuff = 4096 # # Network.TcpNoDelay: diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 2b44a26ee..a2e8e5dcd 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -165,6 +165,7 @@ bool WorldSocket::Update() { // Allocate buffer only when it's needed but not on every Update() call. MessageBuffer buffer(_sendBufferSize); + std::size_t currentPacketSize; do { queued->CompressIfNeeded(); @@ -172,26 +173,32 @@ bool WorldSocket::Update() if (queued->NeedsEncryption()) _authCrypt.EncryptSend(header.header, header.getHeaderLength()); - if (buffer.GetRemainingSpace() < queued->size() + header.getHeaderLength()) + currentPacketSize = queued->size() + header.getHeaderLength(); + + if (buffer.GetRemainingSpace() < currentPacketSize) { QueuePacket(std::move(buffer)); buffer.Resize(_sendBufferSize); } - if (buffer.GetRemainingSpace() >= queued->size() + header.getHeaderLength()) + if (buffer.GetRemainingSpace() >= currentPacketSize) { buffer.Write(header.header, header.getHeaderLength()); if (!queued->empty()) buffer.Write(queued->contents(), queued->size()); } - else // single packet larger than 4096 bytes + else // Single packet larger than current buffer size { - MessageBuffer packetBuffer(queued->size() + header.getHeaderLength()); - packetBuffer.Write(header.header, header.getHeaderLength()); - if (!queued->empty()) - packetBuffer.Write(queued->contents(), queued->size()); + // Resize buffer to fit current packet + buffer.Resize(currentPacketSize); - QueuePacket(std::move(packetBuffer)); + // Grow future buffers to current packet size if still below limit + if (currentPacketSize <= 65536) + _sendBufferSize = currentPacketSize; + + buffer.Write(header.header, header.getHeaderLength()); + if (!queued->empty()) + buffer.Write(queued->contents(), queued->size()); } delete queued;