Network watchdog improvements

- QPointer checks
- renamings
- count failed pings
This commit is contained in:
Klaus Basan
2018-07-05 00:26:33 +02:00
parent a21a510d82
commit f252729fdd
2 changed files with 81 additions and 25 deletions

View File

@@ -9,9 +9,12 @@
#include "networkwatchdog.h" #include "networkwatchdog.h"
#include "application.h" #include "application.h"
#include "blackmisc/logmessage.h"
#include "blackcore/data/globalsetup.h" #include "blackcore/data/globalsetup.h"
#include "blackmisc/network/networkutils.h" #include "blackmisc/network/networkutils.h"
#include <QNetworkReply> #include <QNetworkReply>
#include <QPointer>
using namespace BlackMisc; using namespace BlackMisc;
using namespace BlackMisc::Network; using namespace BlackMisc::Network;
@@ -21,6 +24,15 @@ namespace BlackCore
{ {
namespace Db namespace Db
{ {
const CLogCategoryList &CNetworkWatchdog::getLogCategories()
{
static const BlackMisc::CLogCategoryList cats
(
CContinuousWorker::getLogCategories().join({ CLogCategory::swiftDbWebservice(), CLogCategory::webservice(), CLogCategory::network() })
);
return cats;
}
CNetworkWatchdog::CNetworkWatchdog(QObject *parent) : CContinuousWorker(parent, "swift DB watchdog") CNetworkWatchdog::CNetworkWatchdog(QObject *parent) : CContinuousWorker(parent, "swift DB watchdog")
{ {
Q_ASSERT_X(sApp, Q_FUNC_INFO, "Need sApp"); Q_ASSERT_X(sApp, Q_FUNC_INFO, "Need sApp");
@@ -42,6 +54,8 @@ namespace BlackCore
{ {
m_dbAccessible = accessible; m_dbAccessible = accessible;
m_internetAccessible = m_internetAccessible && m_networkAccessible; m_internetAccessible = m_internetAccessible && m_networkAccessible;
QTimer::singleShot(0, &m_updateTimer, [this] { m_updateTimer.start(); }); // restart timer QTimer::singleShot(0, &m_updateTimer, [this] { m_updateTimer.start(); }); // restart timer
} }
@@ -64,7 +78,12 @@ namespace BlackCore
if (m_checkInProgress) { return -1; } if (m_checkInProgress) { return -1; }
const int n = this->getCheckCount(); const int n = this->getCheckCount();
QTimer::singleShot(0, this, &CNetworkWatchdog::doWork); const QPointer<CNetworkWatchdog> myself(this);
QTimer::singleShot(0, this, [ = ]
{
if (!myself) { return; }
this->doWork();
});
return n; // triggered return n; // triggered
} }
@@ -80,8 +99,8 @@ namespace BlackCore
const QString pUrl(this->getLastPingDbUrl()); const QString pUrl(this->getLastPingDbUrl());
static const QString cct(QString::number(CanConnectTimeMs)); static const QString cct(QString::number(CanConnectTimeMs));
return info. return info.
arg(boolToYesNo(this->isInternetAccessible())).arg(m_goodCountInternet).arg(m_badCountInternet). arg(boolToYesNo(this->isInternetAccessible())).arg(m_totalGoodCountInternet).arg(m_totalBadCountInternet).
arg(boolToYesNo(this->isSwiftDbAccessible())).arg(m_goodCountDb).arg(m_badCountDb). arg(boolToYesNo(this->isSwiftDbAccessible())).arg(m_totalGoodCountDb).arg(m_totalBadCountDb).
arg(pUrl, cct); // cct has to be string, otherwise the % in the URL will be replaced arg(pUrl, cct); // cct has to be string, otherwise the % in the URL will be replaced
} }
@@ -114,16 +133,16 @@ namespace BlackCore
if (m_checkDbAccessibility && m_doDetailedCheck && canConnectDb) if (m_checkDbAccessibility && m_doDetailedCheck && canConnectDb)
{ {
// test against real HTTP response // test against real HTTP response
const bool lastHttpSuccess = m_lastClientPingSuccess; const bool lastHttpSuccess = m_lastClientPingSuccess; // ping result received in meantime
if (lastHttpSuccess && m_checkCount % 10 == 0) if (lastHttpSuccess && m_totalCheckCount % 10 == 0)
{ {
// seems to be OK, from time to time ping // seems to be OK, from time to time ping
this->pingDbClientService(PingStarted); this->pingDbClientService(PingStarted);
} }
else if (!lastHttpSuccess && m_checkCount % 3 == 0) else if (!lastHttpSuccess && m_totalCheckCount % 3 == 0)
{ {
// not OK, retry more frequently // not OK, retry more frequently
this->pingDbClientService(PingStarted, true); this->pingDbClientService(PingStarted, true); // force
} }
canConnectDb = lastHttpSuccess; canConnectDb = lastHttpSuccess;
} }
@@ -171,8 +190,8 @@ namespace BlackCore
static const QString testHost2("www.microsoft.com"); // secondary test static const QString testHost2("www.microsoft.com"); // secondary test
canConnectInternet = CNetworkUtils::canConnect(testHost2, 80, message, CanConnectTimeMs); // running in background worker canConnectInternet = CNetworkUtils::canConnect(testHost2, 80, message, CanConnectTimeMs); // running in background worker
} }
if (canConnectInternet) { m_goodCountInternet++; } if (canConnectInternet) { m_totalGoodCountInternet++; }
else { m_badCountInternet++; } else { m_totalBadCountInternet++; }
} }
m_internetAccessible = networkAccess && canConnectInternet; m_internetAccessible = networkAccess && canConnectInternet;
@@ -182,14 +201,13 @@ namespace BlackCore
while (false); while (false);
m_updateTimer.start(); // restart m_updateTimer.start(); // restart
m_checkCount++; m_totalCheckCount++;
m_checkInProgress = false; m_checkInProgress = false;
} }
bool CNetworkWatchdog::doWorkCheck() const bool CNetworkWatchdog::doWorkCheck() const
{ {
if (!sApp) { return false; } if (!sApp || sApp->isShuttingDown()) { return false; }
if (sApp->isShuttingDown()) { return false; }
if (!this->isEnabled()) { return false; } if (!this->isEnabled()) { return false; }
return true; return true;
} }
@@ -210,7 +228,12 @@ namespace BlackCore
else else
{ {
m_networkAccessible = true; m_networkAccessible = true;
QTimer::singleShot(0, this, &CNetworkWatchdog::doWork); const QPointer<CNetworkWatchdog> myself(this);
QTimer::singleShot(0, this, [ = ]
{
if (!myself) { return; }
this->doWork();
});
} }
} }
@@ -223,7 +246,7 @@ namespace BlackCore
void CNetworkWatchdog::pingDbClientService(CNetworkWatchdog::PingType type, bool force) void CNetworkWatchdog::pingDbClientService(CNetworkWatchdog::PingType type, bool force)
{ {
if (!force && !this->isSwiftDbAccessible()) { return; } if (!force && !this->isSwiftDbAccessible()) { return; }
if (!sApp) { return; } if (!sApp || sApp->isShuttingDown()) { return; }
const CGlobalSetup gs = sApp->getGlobalSetup(); const CGlobalSetup gs = sApp->getGlobalSetup();
if (!gs.wasLoaded()) { return; } if (!gs.wasLoaded()) { return; }
CUrl pingUrl = gs.getDbClientPingServiceUrl(); CUrl pingUrl = gs.getDbClientPingServiceUrl();
@@ -242,6 +265,7 @@ namespace BlackCore
{ {
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nw(nwReply); // delete reply QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nw(nwReply); // delete reply
const bool ok = (nw->error() == QNetworkReply::NoError); const bool ok = (nw->error() == QNetworkReply::NoError);
const QString errorString = nw->errorString();
nw->close(); nw->close();
if (!sApp || sApp->isShuttingDown()) { return; } if (!sApp || sApp->isShuttingDown()) { return; }
m_lastClientPingSuccess = ok; m_lastClientPingSuccess = ok;
@@ -251,8 +275,20 @@ namespace BlackCore
m_lastPingUrl = url; m_lastPingUrl = url;
} }
if (ok) { m_goodCountDb++; } if (ok)
else { m_badCountDb++; } {
m_totalGoodCountDb++;
m_consecutivePingBadCount = 0;
}
else
{
m_totalBadCountDb++;
m_consecutivePingBadCount++;
if (m_logOwnMessages)
{
CStatusMessage(this).warning("Watchdog ping failed, error: '%1', total good/bad DB counts: %2/%3") << errorString << m_totalGoodCountDb << m_totalBadCountDb;
}
}
this->setDbAccessibility(ok); this->setDbAccessibility(ok);
} }
@@ -261,14 +297,23 @@ namespace BlackCore
if (!this->doWorkCheck()) { return; } if (!this->doWorkCheck()) { return; }
// trigger really queued // trigger really queued
const QPointer<CNetworkWatchdog> myself(this);
if (oldDbAccessible != m_dbAccessible) if (oldDbAccessible != m_dbAccessible)
{ {
const CUrl testUrl(this->dbTestUrl()); const CUrl testUrl(this->dbTestUrl());
QTimer::singleShot(0, this, [ = ] { emit this->changedSwiftDbAccessibility(m_dbAccessible, testUrl); }); QTimer::singleShot(0, this, [ = ]
{
if (!myself) { return; }
emit this->changedSwiftDbAccessibility(m_dbAccessible, testUrl);
});
} }
if (oldInternetAccessible != m_internetAccessible) if (oldInternetAccessible != m_internetAccessible)
{ {
QTimer::singleShot(0, this, [this] { emit this->changedInternetAccessibility(m_internetAccessible); }); QTimer::singleShot(0, this, [ = ]
{
if (!myself) { return; }
emit this->changedInternetAccessibility(m_internetAccessible);
});
} }
} }

View File

@@ -13,8 +13,10 @@
#define BLACKCORE_DB_NETWORKWATCHDOG_H #define BLACKCORE_DB_NETWORKWATCHDOG_H
#include "blackcore/blackcoreexport.h" #include "blackcore/blackcoreexport.h"
#include "blackmisc/worker.h"
#include "blackmisc/network/url.h" #include "blackmisc/network/url.h"
#include "blackmisc/worker.h"
#include "blackmisc/logcategorylist.h"
#include <atomic> #include <atomic>
#include <QReadWriteLock> #include <QReadWriteLock>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
@@ -29,6 +31,9 @@ namespace BlackCore
Q_OBJECT Q_OBJECT
public: public:
//! Log categories
static const BlackMisc::CLogCategoryList &getLogCategories();
//! Ctor //! Ctor
explicit CNetworkWatchdog(QObject *parent = nullptr); explicit CNetworkWatchdog(QObject *parent = nullptr);
@@ -73,12 +78,16 @@ namespace BlackCore
//! \threadsafe //! \threadsafe
BlackMisc::Network::CUrl getWorkingSharedUrl() const; BlackMisc::Network::CUrl getWorkingSharedUrl() const;
//! Log.own status messages
//! \threadsafe
void setLogOwnMessages(bool log) { m_logOwnMessages = log; }
//! Run a check //! Run a check
int triggerCheck(); int triggerCheck();
//! Number of completed checks //! Number of completed checks
//! \threadsafe //! \threadsafe
int getCheckCount() const { return m_checkCount; } int getCheckCount() const { return m_totalCheckCount; }
//! Last URL used for ping /DB ping service) //! Last URL used for ping /DB ping service)
QString getLastPingDbUrl() const; QString getLastPingDbUrl() const;
@@ -153,6 +162,7 @@ namespace BlackCore
//! \remark depends on BlackCore::Application::getGlobalSetup() //! \remark depends on BlackCore::Application::getGlobalSetup()
static BlackMisc::Network::CUrl workingSharedUrlFromSetup(); static BlackMisc::Network::CUrl workingSharedUrlFromSetup();
std::atomic_bool m_logOwnMessages { true };
std::atomic_bool m_doDetailedCheck { true }; std::atomic_bool m_doDetailedCheck { true };
std::atomic_bool m_networkAccessible { true }; std::atomic_bool m_networkAccessible { true };
std::atomic_bool m_internetAccessible { true }; std::atomic_bool m_internetAccessible { true };
@@ -161,11 +171,12 @@ namespace BlackCore
std::atomic_bool m_checkDbAccessibility { true }; std::atomic_bool m_checkDbAccessibility { true };
std::atomic_bool m_checkSharedUrl { true }; std::atomic_bool m_checkSharedUrl { true };
std::atomic_bool m_checkInProgress { false }; //!< a check is currently in progress std::atomic_bool m_checkInProgress { false }; //!< a check is currently in progress
std::atomic_int m_checkCount { 0 }; //!< counting number of checks std::atomic_int m_totalCheckCount { 0 }; //!< counting number of checks
std::atomic_int m_badCountDb { 0 }; //! Total number of DB failing counts (only real responses when tried) std::atomic_int m_totalBadCountDb { 0 }; //! Total number of DB failing counts (only real responses when tried)
std::atomic_int m_badCountInternet { 0 }; //! Total number of Internet failing count (only when network is accessible) std::atomic_int m_totalBadCountInternet { 0 }; //! Total number of Internet failing count (only when network is accessible)
std::atomic_int m_goodCountDb { 0 }; std::atomic_int m_totalGoodCountDb { 0 };
std::atomic_int m_goodCountInternet { 0 }; std::atomic_int m_totalGoodCountInternet { 0 };
std::atomic_int m_consecutivePingBadCount { 0 }; //! Bad count of ping until a godd state is received
QString m_lastPingUrl; QString m_lastPingUrl;
BlackMisc::Network::CUrl m_workingSharedUrl; BlackMisc::Network::CUrl m_workingSharedUrl;
mutable QReadWriteLock m_lockUrl; mutable QReadWriteLock m_lockUrl;