Browse Source

Improve session statistics handling

PR #17779.
adaptive-webui-19844
Vladimir Golovnev 2 years ago committed by GitHub
parent
commit
616057a433
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/base/CMakeLists.txt
  2. 2
      src/base/base.pri
  3. 2
      src/base/bittorrent/session.h
  4. 62
      src/base/bittorrent/sessionimpl.cpp
  5. 14
      src/base/bittorrent/sessionimpl.h
  6. 2
      src/base/bittorrent/sessionstatus.h
  7. 114
      src/base/bittorrent/statistics.cpp
  8. 66
      src/base/bittorrent/statistics.h
  9. 4
      src/gui/statsdialog.cpp
  10. 4
      src/webui/api/synccontroller.cpp

2
src/base/CMakeLists.txt

@ -33,7 +33,6 @@ add_library(qbt_base STATIC @@ -33,7 +33,6 @@ add_library(qbt_base STATIC
bittorrent/sessionimpl.h
bittorrent/sessionstatus.h
bittorrent/speedmonitor.h
bittorrent/statistics.h
bittorrent/torrent.h
bittorrent/torrentcontentlayout.h
bittorrent/torrentcreatorthread.h
@ -128,7 +127,6 @@ add_library(qbt_base STATIC @@ -128,7 +127,6 @@ add_library(qbt_base STATIC
bittorrent/resumedatastorage.cpp
bittorrent/sessionimpl.cpp
bittorrent/speedmonitor.cpp
bittorrent/statistics.cpp
bittorrent/torrent.cpp
bittorrent/torrentcreatorthread.cpp
bittorrent/torrentimpl.cpp

2
src/base/base.pri

@ -32,7 +32,6 @@ HEADERS += \ @@ -32,7 +32,6 @@ HEADERS += \
$$PWD/bittorrent/sessionimpl.h \
$$PWD/bittorrent/sessionstatus.h \
$$PWD/bittorrent/speedmonitor.h \
$$PWD/bittorrent/statistics.h \
$$PWD/bittorrent/torrent.h \
$$PWD/bittorrent/torrentcontentlayout.h \
$$PWD/bittorrent/torrentcreatorthread.h \
@ -128,7 +127,6 @@ SOURCES += \ @@ -128,7 +127,6 @@ SOURCES += \
$$PWD/bittorrent/resumedatastorage.cpp \
$$PWD/bittorrent/sessionimpl.cpp \
$$PWD/bittorrent/speedmonitor.cpp \
$$PWD/bittorrent/statistics.cpp \
$$PWD/bittorrent/torrent.cpp \
$$PWD/bittorrent/torrentcreatorthread.cpp \
$$PWD/bittorrent/torrentimpl.cpp \

2
src/base/bittorrent/session.h

@ -404,8 +404,6 @@ namespace BitTorrent @@ -404,8 +404,6 @@ namespace BitTorrent
virtual bool hasRunningSeed() const = 0;
virtual const SessionStatus &status() const = 0;
virtual const CacheStatus &cacheStatus() const = 0;
virtual qint64 getAlltimeDL() const = 0;
virtual qint64 getAlltimeUL() const = 0;
virtual bool isListening() const = 0;
virtual MaxRatioAction maxRatioAction() const = 0;

62
src/base/bittorrent/sessionimpl.cpp

@ -106,7 +106,6 @@ @@ -106,7 +106,6 @@
#include "nativesessionextension.h"
#include "portforwarderimpl.h"
#include "resumedatastorage.h"
#include "statistics.h"
#include "torrentimpl.h"
#include "tracker.h"
@ -115,6 +114,7 @@ using namespace BitTorrent; @@ -115,6 +114,7 @@ using namespace BitTorrent;
const Path CATEGORIES_FILE_NAME {u"categories.json"_qs};
const int MAX_PROCESSING_RESUMEDATA_COUNT = 50;
const int STATISTICS_SAVE_INTERVAL = std::chrono::milliseconds(15min).count();
namespace
{
@ -493,7 +493,6 @@ SessionImpl::SessionImpl(QObject *parent) @@ -493,7 +493,6 @@ SessionImpl::SessionImpl(QObject *parent)
, m_resumeDataStorageType(BITTORRENT_SESSION_KEY(u"ResumeDataStorageType"_qs), ResumeDataStorageType::Legacy)
, m_seedingLimitTimer {new QTimer {this}}
, m_resumeDataTimer {new QTimer {this}}
, m_statistics {new Statistics {this}}
, m_ioThread {new QThread {this}}
, m_recentErroredTorrentsTimer {new QTimer {this}}
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
@ -557,6 +556,7 @@ SessionImpl::SessionImpl(QObject *parent) @@ -557,6 +556,7 @@ SessionImpl::SessionImpl(QObject *parent)
new PortForwarderImpl(m_nativeSession);
initMetrics();
loadStatistics();
prepareStartup();
}
@ -1004,6 +1004,8 @@ void SessionImpl::setGlobalMaxSeedingMinutes(int minutes) @@ -1004,6 +1004,8 @@ void SessionImpl::setGlobalMaxSeedingMinutes(int minutes)
// Main destructor
SessionImpl::~SessionImpl()
{
saveStatistics();
// Do some BT related saving
saveResumeData();
@ -1372,6 +1374,8 @@ void SessionImpl::endStartup(ResumeSessionContext *context) @@ -1372,6 +1374,8 @@ void SessionImpl::endStartup(ResumeSessionContext *context)
else
enqueueRefresh();
m_statisticsLastUpdateTimer.start();
// Regular saving of fastresume data
connect(m_resumeDataTimer, &QTimer::timeout, this, &SessionImpl::generateResumeData);
const int saveInterval = saveResumeDataInterval();
@ -4893,16 +4897,6 @@ const CacheStatus &SessionImpl::cacheStatus() const @@ -4893,16 +4897,6 @@ const CacheStatus &SessionImpl::cacheStatus() const
return m_cacheStatus;
}
qint64 SessionImpl::getAlltimeDL() const
{
return m_statistics->getAlltimeDL();
}
qint64 SessionImpl::getAlltimeUL() const
{
return m_statistics->getAlltimeUL();
}
void SessionImpl::enqueueRefresh()
{
Q_ASSERT(!m_refreshEnqueued);
@ -5456,8 +5450,6 @@ void SessionImpl::handleSessionStatsAlert(const lt::session_stats_alert *p) @@ -5456,8 +5450,6 @@ void SessionImpl::handleSessionStatsAlert(const lt::session_stats_alert *p)
m_status.trackerDownloadRate = calcRate(m_status.trackerDownload, trackerDownload);
m_status.trackerUploadRate = calcRate(m_status.trackerUpload, trackerUpload);
m_status.totalDownload = totalDownload;
m_status.totalUpload = totalUpload;
m_status.totalPayloadDownload = totalPayloadDownload;
m_status.totalPayloadUpload = totalPayloadUpload;
m_status.ipOverheadDownload = ipOverheadDownload;
@ -5473,6 +5465,24 @@ void SessionImpl::handleSessionStatsAlert(const lt::session_stats_alert *p) @@ -5473,6 +5465,24 @@ void SessionImpl::handleSessionStatsAlert(const lt::session_stats_alert *p)
m_status.diskWriteQueue = stats[m_metricIndices.peer.numPeersDownDisk];
m_status.peersCount = stats[m_metricIndices.peer.numPeersConnected];
if (totalDownload > m_status.totalDownload)
{
m_status.totalDownload = totalDownload;
m_isStatisticsDirty = true;
}
if (totalUpload > m_status.totalUpload)
{
m_status.totalUpload = totalUpload;
m_isStatisticsDirty = true;
}
m_status.allTimeDownload = m_previouslyDownloaded + m_status.totalDownload;
m_status.allTimeUpload = m_previouslyUploaded + m_status.totalUpload;
if (m_statisticsLastUpdateTimer.hasExpired(STATISTICS_SAVE_INTERVAL))
saveStatistics();
m_cacheStatus.totalUsedBuffers = stats[m_metricIndices.disk.diskBlocksInUse];
m_cacheStatus.jobQueueLength = stats[m_metricIndices.disk.queuedDiskJobs];
@ -5648,3 +5658,27 @@ void SessionImpl::processTrackerStatuses() @@ -5648,3 +5658,27 @@ void SessionImpl::processTrackerStatuses()
m_updatedTrackerEntries.clear();
}
}
void SessionImpl::saveStatistics() const
{
if (!m_isStatisticsDirty)
return;
const QVariantHash stats {
{u"AlltimeDL"_qs, m_status.allTimeDownload},
{u"AlltimeUL"_qs, m_status.allTimeUpload}};
std::unique_ptr<QSettings> settings = Profile::instance()->applicationSettings(u"qBittorrent-data"_qs);
settings->setValue(u"Stats/AllStats"_qs, stats);
m_statisticsLastUpdateTimer.start();
m_isStatisticsDirty = false;
}
void SessionImpl::loadStatistics()
{
const std::unique_ptr<QSettings> settings = Profile::instance()->applicationSettings(u"qBittorrent-data"_qs);
const QVariantHash value = settings->value(u"Stats/AllStats"_qs).toHash();
m_previouslyDownloaded = value[u"AlltimeDL"_qs].toLongLong();
m_previouslyUploaded = value[u"AlltimeUL"_qs].toLongLong();
}

14
src/base/bittorrent/sessionimpl.h

@ -35,6 +35,7 @@ @@ -35,6 +35,7 @@
#include <libtorrent/fwd.hpp>
#include <libtorrent/torrent_handle.hpp>
#include <QElapsedTimer>
#include <QHash>
#include <QPointer>
#include <QSet>
@ -72,7 +73,6 @@ class QUrl; @@ -72,7 +73,6 @@ class QUrl;
class BandwidthScheduler;
class FileSearcher;
class FilterParserThread;
class Statistics;
namespace Net
{
@ -384,8 +384,6 @@ namespace BitTorrent @@ -384,8 +384,6 @@ namespace BitTorrent
bool hasRunningSeed() const override;
const SessionStatus &status() const override;
const CacheStatus &cacheStatus() const override;
qint64 getAlltimeDL() const override;
qint64 getAlltimeUL() const override;
bool isListening() const override;
MaxRatioAction maxRatioAction() const override;
@ -550,6 +548,9 @@ namespace BitTorrent @@ -550,6 +548,9 @@ namespace BitTorrent
void storeCategories() const;
void upgradeCategories();
void saveStatistics() const;
void loadStatistics();
// BitTorrent
lt::session *m_nativeSession = nullptr;
@ -675,10 +676,15 @@ namespace BitTorrent @@ -675,10 +676,15 @@ namespace BitTorrent
QVector<TrackerEntry> m_additionalTrackerList;
QVector<QRegularExpression> m_excludedFileNamesRegExpList;
// Statistics
mutable QElapsedTimer m_statisticsLastUpdateTimer;
mutable bool m_isStatisticsDirty = false;
qint64 m_previouslyUploaded = 0;
qint64 m_previouslyDownloaded = 0;
bool m_refreshEnqueued = false;
QTimer *m_seedingLimitTimer = nullptr;
QTimer *m_resumeDataTimer = nullptr;
Statistics *m_statistics = nullptr;
// IP filtering
QPointer<FilterParserThread> m_filterParser;
QPointer<BandwidthScheduler> m_bwScheduler;

2
src/base/bittorrent/sessionstatus.h

@ -56,6 +56,8 @@ namespace BitTorrent @@ -56,6 +56,8 @@ namespace BitTorrent
qint64 trackerUploadRate = 0;
qint64 trackerDownloadRate = 0;
qint64 allTimeDownload = 0;
qint64 allTimeUpload = 0;
qint64 totalDownload = 0;
qint64 totalUpload = 0;
qint64 totalPayloadDownload = 0;

114
src/base/bittorrent/statistics.cpp

@ -1,114 +0,0 @@ @@ -1,114 +0,0 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*/
#include "statistics.h"
#include <chrono>
#include <QTimer>
#include "base/global.h"
#include "base/bittorrent/sessionimpl.h"
#include "base/bittorrent/sessionstatus.h"
#include "base/profile.h"
using namespace std::chrono_literals;
using namespace BitTorrent;
const int SAVE_INTERVAL = std::chrono::milliseconds(15min).count();
Statistics::Statistics(BitTorrent::SessionImpl *session)
: QObject(session)
, m_session(session)
{
load();
m_lastUpdateTimer.start();
auto *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &Statistics::gather);
timer->start(60s);
}
Statistics::~Statistics()
{
save();
}
qint64 Statistics::getAlltimeDL() const
{
return m_alltimeDL + m_sessionDL;
}
qint64 Statistics::getAlltimeUL() const
{
return m_alltimeUL + m_sessionUL;
}
void Statistics::gather()
{
const SessionStatus &ss = m_session->status();
if (ss.totalDownload > m_sessionDL)
{
m_sessionDL = ss.totalDownload;
m_dirty = true;
}
if (ss.totalUpload > m_sessionUL)
{
m_sessionUL = ss.totalUpload;
m_dirty = true;
}
if (m_lastUpdateTimer.hasExpired(SAVE_INTERVAL))
save();
}
void Statistics::save() const
{
if (!m_dirty)
return;
const QVariantHash stats =
{
{u"AlltimeDL"_qs, (m_alltimeDL + m_sessionDL)},
{u"AlltimeUL"_qs, (m_alltimeUL + m_sessionUL)}
};
std::unique_ptr<QSettings> settings = Profile::instance()->applicationSettings(u"qBittorrent-data"_qs);
settings->setValue(u"Stats/AllStats"_qs, stats);
m_lastUpdateTimer.start();
m_dirty = false;
}
void Statistics::load()
{
const std::unique_ptr<QSettings> s = Profile::instance()->applicationSettings(u"qBittorrent-data"_qs);
const QVariantHash v = s->value(u"Stats/AllStats"_qs).toHash();
m_alltimeDL = v[u"AlltimeDL"_qs].toLongLong();
m_alltimeUL = v[u"AlltimeUL"_qs].toLongLong();
}

66
src/base/bittorrent/statistics.h

@ -1,66 +0,0 @@ @@ -1,66 +0,0 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2015 Vladimir Golovnev <glassez@yandex.ru>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If you
* modify file(s), you may extend this exception to your version of the file(s),
* but you are not obligated to do so. If you do not wish to do so, delete this
* exception statement from your version.
*/
#pragma once
#include <QElapsedTimer>
#include <QObject>
namespace BitTorrent
{
class SessionImpl;
}
class Statistics : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(Statistics)
public:
explicit Statistics(BitTorrent::SessionImpl *session);
~Statistics();
qint64 getAlltimeDL() const;
qint64 getAlltimeUL() const;
private slots:
void gather();
private:
void save() const;
void load();
BitTorrent::SessionImpl *m_session = nullptr;
mutable QElapsedTimer m_lastUpdateTimer;
mutable bool m_dirty = false;
qint64 m_alltimeUL = 0;
qint64 m_alltimeDL = 0;
qint64 m_sessionUL = 0;
qint64 m_sessionDL = 0;
};

4
src/gui/statsdialog.cpp

@ -76,8 +76,8 @@ void StatsDialog::update() @@ -76,8 +76,8 @@ void StatsDialog::update()
const BitTorrent::CacheStatus &cs = BitTorrent::Session::instance()->cacheStatus();
// All-time DL/UL
const qint64 atd = BitTorrent::Session::instance()->getAlltimeDL();
const qint64 atu = BitTorrent::Session::instance()->getAlltimeUL();
const qint64 atd = ss.allTimeDownload;
const qint64 atu = ss.allTimeUpload;
m_ui->labelAlltimeDL->setText(Utils::Misc::friendlyUnit(atd));
m_ui->labelAlltimeUL->setText(Utils::Misc::friendlyUnit(atu));
// Total waste (this session)

4
src/webui/api/synccontroller.cpp

@ -129,8 +129,8 @@ namespace @@ -129,8 +129,8 @@ namespace
map[KEY_TRANSFER_DLRATELIMIT] = session->downloadSpeedLimit();
map[KEY_TRANSFER_UPRATELIMIT] = session->uploadSpeedLimit();
const qint64 atd = session->getAlltimeDL();
const qint64 atu = session->getAlltimeUL();
const qint64 atd = sessionStatus.allTimeDownload;
const qint64 atu = sessionStatus.allTimeUpload;
map[KEY_TRANSFER_ALLTIME_DL] = atd;
map[KEY_TRANSFER_ALLTIME_UL] = atu;
map[KEY_TRANSFER_TOTAL_WASTE_SESSION] = sessionStatus.totalWasted;

Loading…
Cancel
Save