From bc52a3892224a6133b829fd83fd388be85cf0a6c Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Tue, 21 Jul 2020 19:21:27 +0100 Subject: [PATCH] Improved network bandwidth data collection --- src/Server.php | 7 +- src/command/defaults/StatusCommand.php | 5 +- src/network/BandwidthStatsTracker.php | 74 +++++++++++++++++++ .../BidirectionalBandwidthStatsTracker.php | 59 +++++++++++++++ src/network/Network.php | 25 +------ src/network/mcpe/raklib/RakLibInterface.php | 10 +-- 6 files changed, 145 insertions(+), 35 deletions(-) create mode 100644 src/network/BandwidthStatsTracker.php create mode 100644 src/network/BidirectionalBandwidthStatsTracker.php diff --git a/src/Server.php b/src/Server.php index 3fad9f6f7..fd7183715 100644 --- a/src/Server.php +++ b/src/Server.php @@ -1587,14 +1587,15 @@ class Server{ $online = count($this->playerList); $connecting = $this->network->getConnectionCount() - $online; + $bandwidthStats = $this->network->getBandwidthTracker(); echo "\x1b]0;" . $this->getName() . " " . $this->getPocketMineVersion() . " | Online $online/" . $this->getMaxPlayers() . ($connecting > 0 ? " (+$connecting connecting)" : "") . " | Memory " . $usage . - " | U " . round($this->network->getUpload() / 1024, 2) . - " D " . round($this->network->getDownload() / 1024, 2) . + " | U " . round($bandwidthStats->getSend()->getAverageBytes() / 1024, 2) . + " D " . round($bandwidthStats->getReceive()->getAverageBytes() / 1024, 2) . " kB/s | TPS " . $this->getTicksPerSecondAverage() . " | Load " . $this->getTickUsageAverage() . "%\x07"; @@ -1640,7 +1641,7 @@ class Server{ $this->queryInfo = $queryRegenerateEvent->getQueryInfo(); $this->network->updateName(); - $this->network->resetStatistics(); + $this->network->getBandwidthTracker()->rotateAverageHistory(); } if($this->sendUsageTicker > 0 and --$this->sendUsageTicker === 0){ diff --git a/src/command/defaults/StatusCommand.php b/src/command/defaults/StatusCommand.php index 8c8d71af8..f0c791192 100644 --- a/src/command/defaults/StatusCommand.php +++ b/src/command/defaults/StatusCommand.php @@ -91,8 +91,9 @@ class StatusCommand extends VanillaCommand{ $sender->sendMessage(TextFormat::GOLD . "Current TPS: {$tpsColor}{$server->getTicksPerSecond()} ({$server->getTickUsage()}%)"); $sender->sendMessage(TextFormat::GOLD . "Average TPS: {$tpsColor}{$server->getTicksPerSecondAverage()} ({$server->getTickUsageAverage()}%)"); - $sender->sendMessage(TextFormat::GOLD . "Network upload: " . TextFormat::RED . round($server->getNetwork()->getUpload() / 1024, 2) . " kB/s"); - $sender->sendMessage(TextFormat::GOLD . "Network download: " . TextFormat::RED . round($server->getNetwork()->getDownload() / 1024, 2) . " kB/s"); + $bandwidth = $server->getNetwork()->getBandwidthTracker(); + $sender->sendMessage(TextFormat::GOLD . "Network upload: " . TextFormat::RED . round($bandwidth->getSend()->getAverageBytes() / 1024, 2) . " kB/s"); + $sender->sendMessage(TextFormat::GOLD . "Network download: " . TextFormat::RED . round($bandwidth->getReceive()->getAverageBytes() / 1024, 2) . " kB/s"); $sender->sendMessage(TextFormat::GOLD . "Thread count: " . TextFormat::RED . Process::getThreadCount()); diff --git a/src/network/BandwidthStatsTracker.php b/src/network/BandwidthStatsTracker.php new file mode 100644 index 000000000..0f0358dd1 --- /dev/null +++ b/src/network/BandwidthStatsTracker.php @@ -0,0 +1,74 @@ +history = array_fill(0, $historySize, 0); + } + + public function add(int $bytes) : void{ + $this->totalBytes += $bytes; + $this->bytesSinceLastRotation += $bytes; + } + + public function getTotalBytes() : int{ return $this->totalBytes; } + + /** + * Adds the bytes tracked since the last rotation to the history array, overwriting an old entry. + * This should be called on a regular interval that you want to collect average measurements over + * (e.g. if you want bytes per second, call this every second). + */ + public function rotateHistory() : void{ + $this->history[$this->nextHistoryIndex] = $this->bytesSinceLastRotation; + $this->bytesSinceLastRotation = 0; + $this->nextHistoryIndex = ($this->nextHistoryIndex + 1) % count($this->history); + } + + /** + * Returns the average of all the tracked history values. + */ + public function getAverageBytes() : float{ + return array_sum($this->history) / count($this->history); + } + + public function resetHistory() : void{ + $this->history = array_fill(0, count($this->history), 0); + } +} diff --git a/src/network/BidirectionalBandwidthStatsTracker.php b/src/network/BidirectionalBandwidthStatsTracker.php new file mode 100644 index 000000000..a4cf3f6a4 --- /dev/null +++ b/src/network/BidirectionalBandwidthStatsTracker.php @@ -0,0 +1,59 @@ +send = new BandwidthStatsTracker($historySize); + $this->receive = new BandwidthStatsTracker($historySize); + } + + public function getSend() : BandwidthStatsTracker{ return $this->send; } + + public function getReceive() : BandwidthStatsTracker{ return $this->receive; } + + public function add(int $sendBytes, int $recvBytes) : void{ + $this->send->add($sendBytes); + $this->receive->add($recvBytes); + } + + /** @see BandwidthStatsTracker::rotateHistory() */ + public function rotateAverageHistory() : void{ + $this->send->rotateHistory(); + $this->receive->rotateHistory(); + } + + /** @see BandwidthStatsTracker::resetHistory() */ + public function resetHistory() : void{ + $this->send->resetHistory(); + $this->receive->resetHistory(); + } +} diff --git a/src/network/Network.php b/src/network/Network.php index 2f671df3c..24944dcd5 100644 --- a/src/network/Network.php +++ b/src/network/Network.php @@ -48,10 +48,8 @@ class Network{ /** @var int[] */ private $bannedIps = []; - /** @var float */ - private $upload = 0; - /** @var float */ - private $download = 0; + /** @var BandwidthStatsTracker */ + private $bandwidthTracker; /** @var string */ private $name; @@ -65,25 +63,10 @@ class Network{ public function __construct(\Logger $logger){ $this->sessionManager = new NetworkSessionManager(); $this->logger = $logger; + $this->bandwidthTracker = new BidirectionalBandwidthStatsTracker(5); } - public function addStatistics(float $upload, float $download) : void{ - $this->upload += $upload; - $this->download += $download; - } - - public function getUpload() : float{ - return $this->upload; - } - - public function getDownload() : float{ - return $this->download; - } - - public function resetStatistics() : void{ - $this->upload = 0; - $this->download = 0; - } + public function getBandwidthTracker() : BidirectionalBandwidthStatsTracker{ return $this->bandwidthTracker; } /** * @return NetworkInterface[] diff --git a/src/network/mcpe/raklib/RakLibInterface.php b/src/network/mcpe/raklib/RakLibInterface.php index 63913b859..459ae94b7 100644 --- a/src/network/mcpe/raklib/RakLibInterface.php +++ b/src/network/mcpe/raklib/RakLibInterface.php @@ -43,7 +43,6 @@ use raklib\utils\InternetAddress; use function addcslashes; use function bin2hex; use function implode; -use function microtime; use function mt_rand; use function random_bytes; use function rtrim; @@ -83,13 +82,9 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ /** @var SleeperNotifier */ private $sleeper; - /** @var float */ - private $lastBandwidthReport; - public function __construct(Server $server){ $this->server = $server; $this->rakServerId = mt_rand(0, PHP_INT_MAX); - $this->lastBandwidthReport = microtime(true); $this->sleeper = new SleeperNotifier(); @@ -250,10 +245,7 @@ class RakLibInterface implements ServerEventListener, AdvancedNetworkInterface{ } public function handleBandwidthStats(int $bytesSentDiff, int $bytesReceivedDiff) : void{ - $now = microtime(true); - $diff = $now - $this->lastBandwidthReport; - $this->lastBandwidthReport = $now; - $this->network->addStatistics($bytesSentDiff / $diff, $bytesReceivedDiff / $diff); + $this->network->getBandwidthTracker()->add($bytesSentDiff, $bytesReceivedDiff); } public function putPacket(int $sessionId, string $payload, bool $immediate = true) : void{