From 779a0086c4862c46775c26e5d09da376df2e6595 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 2 Feb 2015 11:56:50 -0800 Subject: [PATCH] BandwidthRecorder no longer knows about channel displays. cause overlay pps and Mbps to only update once per second --- interface/src/Application.cpp | 4 +- interface/src/ui/ApplicationOverlay.cpp | 8 +- interface/src/ui/BandwidthDialog.cpp | 38 ++-- interface/src/ui/BandwidthDialog.h | 7 +- interface/src/ui/Stats.cpp | 10 +- .../networking/src/BandwidthRecorder.cpp | 177 ++++++++++++------ libraries/networking/src/BandwidthRecorder.h | 26 ++- libraries/networking/src/LimitedNodeList.cpp | 5 +- libraries/networking/src/LimitedNodeList.h | 3 + .../networking/src/ThreadedAssignment.cpp | 1 + 10 files changed, 188 insertions(+), 91 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 517c229185..acbf3492ea 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -437,9 +437,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : // hook up bandwidth estimator QSharedPointer bandwidthRecorder = DependencyManager::get(); connect(nodeList.data(), SIGNAL(dataSent(const quint8, const int)), - &*bandwidthRecorder, SLOT(updateOutboundData(const quint8, const int))); + bandwidthRecorder.data(), SLOT(updateOutboundData(const quint8, const int))); connect(nodeList.data(), SIGNAL(dataReceived(const quint8, const int)), - &*bandwidthRecorder, SLOT(updateInboundData(const quint8, const int))); + bandwidthRecorder.data(), SLOT(updateInboundData(const quint8, const int))); // check first run... bool firstRun = SettingHandles::firstRun.get(); diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index f63afb5aee..0eeac9a90e 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -920,10 +920,10 @@ void ApplicationOverlay::renderStatsAndLogs() { int voxelPacketsToProcess = octreePacketProcessor.packetsToProcessCount(); // Onscreen text about position, servers, etc Stats::getInstance()->display(WHITE_TEXT, horizontalOffset, application->getFps(), - bandwidthRecorder->totalChannel.getAverageInputPacketsPerSecond(), - bandwidthRecorder->totalChannel.getAverageOutputPacketsPerSecond(), - bandwidthRecorder->totalChannel.getAverageInputKilobitsPerSecond(), - bandwidthRecorder->totalChannel.getAverageOutputKilobitsPerSecond(), + bandwidthRecorder->getCachedTotalAverageInputPacketsPerSecond(), + bandwidthRecorder->getCachedTotalAverageOutputPacketsPerSecond(), + bandwidthRecorder->getCachedTotalAverageInputKilobitsPerSecond(), + bandwidthRecorder->getCachedTotalAverageOutputKilobitsPerSecond(), voxelPacketsToProcess); } diff --git a/interface/src/ui/BandwidthDialog.cpp b/interface/src/ui/BandwidthDialog.cpp index f9ea02d662..8b9fbc2da9 100644 --- a/interface/src/ui/BandwidthDialog.cpp +++ b/interface/src/ui/BandwidthDialog.cpp @@ -22,16 +22,16 @@ #include -BandwidthChannelDisplay::BandwidthChannelDisplay(BandwidthRecorder::Channel *ch, QFormLayout* form, +BandwidthChannelDisplay::BandwidthChannelDisplay(QVector nodeTypesToFollow, + QFormLayout* form, char const* const caption, char const* unitCaption, const float unitScale, unsigned colorRGBA) : + nodeTypesToFollow(nodeTypesToFollow), caption(caption), unitCaption(unitCaption), unitScale(unitScale), colorRGBA(colorRGBA) { - this->ch = ch; - label = new QLabel(); label->setAlignment(Qt::AlignRight); @@ -47,9 +47,19 @@ BandwidthChannelDisplay::BandwidthChannelDisplay(BandwidthRecorder::Channel *ch, void BandwidthChannelDisplay::bandwidthAverageUpdated() { + float inTotal = 0.; + float outTotal = 0.; + + QSharedPointer bandwidthRecorder = DependencyManager::get(); + + for (int i = 0; i < nodeTypesToFollow.size(); ++i) { + inTotal += bandwidthRecorder->getAverageInputKilobitsPerSecond(nodeTypesToFollow.at(i)); + outTotal += bandwidthRecorder->getAverageOutputKilobitsPerSecond(nodeTypesToFollow.at(i)); + } + strBuf = - QString("").setNum((int) (ch->getAverageInputKilobitsPerSecond() * unitScale)) + "/" + - QString("").setNum((int) (ch->getAverageOutputKilobitsPerSecond() * unitScale)) + " " + unitCaption; + QString("").setNum((int) (inTotal * unitScale)) + "/" + + QString("").setNum((int) (outTotal * unitScale)) + " " + unitCaption; } @@ -58,7 +68,6 @@ void BandwidthChannelDisplay::Paint() { } - BandwidthDialog::BandwidthDialog(QWidget* parent) : QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint) { @@ -71,18 +80,21 @@ BandwidthDialog::BandwidthDialog(QWidget* parent) : QSharedPointer bandwidthRecorder = DependencyManager::get(); _allChannelDisplays[0] = _audioChannelDisplay = - new BandwidthChannelDisplay(&bandwidthRecorder->audioChannel, form, "Audio", "Kbps", 1.0, COLOR0); + new BandwidthChannelDisplay({NodeType::AudioMixer}, form, "Audio", "Kbps", 1.0, COLOR0); _allChannelDisplays[1] = _avatarsChannelDisplay = - new BandwidthChannelDisplay(&bandwidthRecorder->avatarsChannel, form, "Avatars", "Kbps", 1.0, COLOR1); + new BandwidthChannelDisplay({NodeType::Agent, NodeType::AvatarMixer}, form, "Avatars", "Kbps", 1.0, COLOR1); _allChannelDisplays[2] = _octreeChannelDisplay = - new BandwidthChannelDisplay(&bandwidthRecorder->octreeChannel, form, "Octree", "Kbps", 1.0, COLOR2); + new BandwidthChannelDisplay({NodeType::DomainServer, NodeType::EntityServer}, form, "Octree", "Kbps", 1.0, COLOR2); _allChannelDisplays[3] = _metavoxelsChannelDisplay = - new BandwidthChannelDisplay(&bandwidthRecorder->metavoxelsChannel, form, "Metavoxels", "Kbps", 1.0, COLOR2); + new BandwidthChannelDisplay({NodeType::MetavoxelServer, NodeType::EnvironmentServer}, form, "Metavoxels", "Kbps", 1.0, COLOR2); _allChannelDisplays[4] = _otherChannelDisplay = - new BandwidthChannelDisplay(&bandwidthRecorder->otherChannel, form, "Other", "Kbps", 1.0, COLOR2); + new BandwidthChannelDisplay({NodeType::Unassigned}, form, "Other", "Kbps", 1.0, COLOR2); _allChannelDisplays[5] = _totalChannelDisplay = - new BandwidthChannelDisplay(&bandwidthRecorder->totalChannel, form, "Total", "Kbps", 1.0, COLOR2); - + new BandwidthChannelDisplay({NodeType::DomainServer, NodeType::EntityServer, NodeType::MetavoxelServer, + NodeType::EnvironmentServer, NodeType::AudioMixer, NodeType::Agent, + NodeType::AvatarMixer, NodeType::Unassigned}, + form, "Total", "Kbps", 1.0, COLOR2); + connect(averageUpdateTimer, SIGNAL(timeout()), this, SLOT(updateTimerTimeout())); averageUpdateTimer->start(1000); } diff --git a/interface/src/ui/BandwidthDialog.h b/interface/src/ui/BandwidthDialog.h index 7209235e18..0ca38b5e4c 100644 --- a/interface/src/ui/BandwidthDialog.h +++ b/interface/src/ui/BandwidthDialog.h @@ -15,7 +15,9 @@ #include #include #include +#include +#include "Node.h" #include "BandwidthRecorder.h" @@ -28,12 +30,13 @@ class BandwidthChannelDisplay : public QObject { Q_OBJECT public: - BandwidthChannelDisplay(BandwidthRecorder::Channel *ch, QFormLayout* form, + BandwidthChannelDisplay(QVector nodeTypesToFollow, + QFormLayout* form, char const* const caption, char const* unitCaption, float unitScale, unsigned colorRGBA); void Paint(); private: - BandwidthRecorder::Channel *ch; + QVector nodeTypesToFollow; QLabel* label; QString strBuf; char const* const caption; diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index a29722825f..b271891ed9 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -443,12 +443,10 @@ void Stats::display( SharedNodePointer avatarMixer = DependencyManager::get()->soloNodeOfType(NodeType::AvatarMixer); if (avatarMixer) { sprintf(avatarMixerStats, "Avatar Mixer: %.f kbps, %.f pps", - // roundf(avatarMixer->getAverageKilobitsPerSecond()), - // roundf(avatarMixer->getAveragePacketsPerSecond()) - roundf(bandwidthRecorder->audioChannel.getAverageInputKilobitsPerSecond() + - bandwidthRecorder->audioChannel.getAverageOutputKilobitsPerSecond()), - roundf(bandwidthRecorder->audioChannel.getAverageInputPacketsPerSecond() + - bandwidthRecorder->audioChannel.getAverageOutputPacketsPerSecond())); + roundf(bandwidthRecorder->getAverageInputKilobitsPerSecond(NodeType::AudioMixer) + + bandwidthRecorder->getAverageOutputKilobitsPerSecond(NodeType::AudioMixer)), + roundf(bandwidthRecorder->getAverageInputPacketsPerSecond(NodeType::AudioMixer) + + bandwidthRecorder->getAverageOutputPacketsPerSecond(NodeType::AudioMixer))); } else { sprintf(avatarMixerStats, "No Avatar Mixer"); } diff --git a/libraries/networking/src/BandwidthRecorder.cpp b/libraries/networking/src/BandwidthRecorder.cpp index 36256755bd..097697a685 100644 --- a/libraries/networking/src/BandwidthRecorder.cpp +++ b/libraries/networking/src/BandwidthRecorder.cpp @@ -11,6 +11,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include +#include #include "BandwidthRecorder.h" @@ -48,69 +50,134 @@ void BandwidthRecorder::Channel::updateOutputAverage(const float sample) { _output.updateAverage(sample); } - - BandwidthRecorder::BandwidthRecorder() { + for (uint i=0; iupdateInputAverage(sample); } void BandwidthRecorder::updateOutboundData(const quint8 channelType, const int sample) { - - totalChannel.updateOutputAverage(sample); - - // see Node.h NodeType - switch (channelType) { - case NodeType::DomainServer: - case NodeType::EntityServer: - octreeChannel.updateOutputAverage(sample); - break; - case NodeType::MetavoxelServer: - case NodeType::EnvironmentServer: - metavoxelsChannel.updateOutputAverage(sample); - break; - case NodeType::AudioMixer: - audioChannel.updateOutputAverage(sample); - break; - case NodeType::Agent: - case NodeType::AvatarMixer: - avatarsChannel.updateOutputAverage(sample); - break; - case NodeType::Unassigned: - default: - otherChannel.updateOutputAverage(sample); - break; - } + Q_ASSERT(channelType < CHANNEL_COUNT); + if (! _channels[channelType]) + _channels[channelType] = new Channel(); + _channels[channelType]->updateOutputAverage(sample); +} + +float BandwidthRecorder::getAverageInputPacketsPerSecond(const quint8 channelType) { + Q_ASSERT(channelType < CHANNEL_COUNT); + if (! _channels[channelType]) + return 0.; + return _channels[channelType]->getAverageInputPacketsPerSecond(); +} + +float BandwidthRecorder::getAverageOutputPacketsPerSecond(const quint8 channelType) { + Q_ASSERT(channelType < CHANNEL_COUNT); + if (! _channels[channelType]) + return 0.; + return _channels[channelType]->getAverageOutputPacketsPerSecond(); +} + +float BandwidthRecorder::getAverageInputKilobitsPerSecond(const quint8 channelType) { + Q_ASSERT(channelType < CHANNEL_COUNT); + if (! _channels[channelType]) + return 0.; + return _channels[channelType]->getAverageInputKilobitsPerSecond(); +} + +float BandwidthRecorder::getAverageOutputKilobitsPerSecond(const quint8 channelType) { + Q_ASSERT(channelType < CHANNEL_COUNT); + if (! _channels[channelType]) + return 0.; + return _channels[channelType]->getAverageOutputKilobitsPerSecond(); +} + +float BandwidthRecorder::getTotalAverageInputPacketsPerSecond() { + float result = 0.; + for (uint i=0; igetAverageInputPacketsPerSecond(); + } + return result; +} + +float BandwidthRecorder::getTotalAverageOutputPacketsPerSecond() { + float result = 0.; + for (uint i=0; igetAverageOutputPacketsPerSecond(); + } + return result; +} + +float BandwidthRecorder::getTotalAverageInputKilobitsPerSecond(){ + float result = 0.; + for (uint i=0; igetAverageInputKilobitsPerSecond(); + } + return result; +} + +float BandwidthRecorder::getTotalAverageOutputKilobitsPerSecond(){ + float result = 0.; + for (uint i=0; igetAverageOutputKilobitsPerSecond(); + } + return result; +} + +float BandwidthRecorder::getCachedTotalAverageInputPacketsPerSecond() { + static qint64 lastCalculated = 0; + static float cachedValue = 0.; + qint64 now = QDateTime::currentMSecsSinceEpoch(); + if (now - lastCalculated > 1000.) { + lastCalculated = now; + cachedValue = getTotalAverageInputPacketsPerSecond(); + } + return cachedValue; +} + +float BandwidthRecorder::getCachedTotalAverageOutputPacketsPerSecond() { + static qint64 lastCalculated = 0; + static float cachedValue = 0.; + qint64 now = QDateTime::currentMSecsSinceEpoch(); + if (now - lastCalculated > 1000.) { + lastCalculated = now; + cachedValue = getTotalAverageOutputPacketsPerSecond(); + } + return cachedValue; +} + +float BandwidthRecorder::getCachedTotalAverageInputKilobitsPerSecond() { + static qint64 lastCalculated = 0; + static float cachedValue = 0.; + qint64 now = QDateTime::currentMSecsSinceEpoch(); + if (now - lastCalculated > 1000.) { + lastCalculated = now; + cachedValue = getTotalAverageInputKilobitsPerSecond(); + } + return cachedValue; +} + +float BandwidthRecorder::getCachedTotalAverageOutputKilobitsPerSecond() { + static qint64 lastCalculated = 0; + static float cachedValue = 0.; + qint64 now = QDateTime::currentMSecsSinceEpoch(); + if (now - lastCalculated > 1000.) { + lastCalculated = now; + cachedValue = getTotalAverageOutputKilobitsPerSecond(); + } + return cachedValue; } diff --git a/libraries/networking/src/BandwidthRecorder.h b/libraries/networking/src/BandwidthRecorder.h index 24e254552d..a7f51fbb45 100644 --- a/libraries/networking/src/BandwidthRecorder.h +++ b/libraries/networking/src/BandwidthRecorder.h @@ -47,15 +47,27 @@ public: SimpleMovingAverage _output = SimpleMovingAverage(); }; + float getAverageInputPacketsPerSecond(const quint8 channelType); + float getAverageOutputPacketsPerSecond(const quint8 channelType); + float getAverageInputKilobitsPerSecond(const quint8 channelType); + float getAverageOutputKilobitsPerSecond(const quint8 channelType); + + float getTotalAverageInputPacketsPerSecond(); + float getTotalAverageOutputPacketsPerSecond(); + float getTotalAverageInputKilobitsPerSecond(); + float getTotalAverageOutputKilobitsPerSecond(); + + float getCachedTotalAverageInputPacketsPerSecond(); + float getCachedTotalAverageOutputPacketsPerSecond(); + float getCachedTotalAverageInputKilobitsPerSecond(); + float getCachedTotalAverageOutputKilobitsPerSecond(); - // create the channels we keep track of - Channel audioChannel = Channel(); - Channel avatarsChannel = Channel(); - Channel octreeChannel = Channel(); - Channel metavoxelsChannel = Channel(); - Channel otherChannel = Channel(); - Channel totalChannel = Channel(); +private: + // one for each possible Node type + static const unsigned int CHANNEL_COUNT = 256; + Channel* _channels[CHANNEL_COUNT]; + public slots: void updateInboundData(const quint8 channelType, const int bytes); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 7d188af6aa..c7948e37aa 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -233,9 +233,10 @@ qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram, const HifiSock replaceHashInPacketGivenConnectionUUID(datagramCopy, connectionSecret); } + // XXX can BandwidthRecorder be used for this? // stat collection for packets - // ++_numCollectedPackets; - // _numCollectedBytes += datagram.size(); + ++_numCollectedPackets; + _numCollectedBytes += datagram.size(); qint64 bytesWritten = _nodeSocket.writeDatagram(datagramCopy, destinationSockAddr.getAddress(), destinationSockAddr.getPort()); diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 233d3c9f0c..f80f0367c7 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -206,8 +206,11 @@ protected: HifiSockAddr _localSockAddr; HifiSockAddr _publicSockAddr; HifiSockAddr _stunSockAddr; + + // XXX can BandwidthRecorder be used for this? int _numCollectedPackets; int _numCollectedBytes; + QElapsedTimer _packetStatTimer; template diff --git a/libraries/networking/src/ThreadedAssignment.cpp b/libraries/networking/src/ThreadedAssignment.cpp index 21f520babb..ea94a8e22c 100644 --- a/libraries/networking/src/ThreadedAssignment.cpp +++ b/libraries/networking/src/ThreadedAssignment.cpp @@ -83,6 +83,7 @@ void ThreadedAssignment::addPacketStatsAndSendStatsPacket(QJsonObject &statsObje auto nodeList = DependencyManager::get(); float packetsPerSecond, bytesPerSecond; + // XXX can BandwidthRecorder be used for this? nodeList->getPacketStats(packetsPerSecond, bytesPerSecond); nodeList->resetPacketStats();