mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-23 07:15:35 +08:00
Ref T150, network watchdog check accessibility in background
* no need to check elsewhere with canConnect -> processEventsFor * many checks were redundant (when I can connect the DB, no need to check internet) * watchdog can also be connected to other read signals, if models are read elsewhere, it means DB is up Summary: less checks, less calls of canConnect in main thread
This commit is contained in:
committed by
Mathew Sutcliffe
parent
afbf3f05c8
commit
a6855f1891
212
src/blackcore/db/networkwatchdog.cpp
Normal file
212
src/blackcore/db/networkwatchdog.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
/* Copyright (C) 2017
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "networkwatchdog.h"
|
||||
#include "application.h"
|
||||
#include "blackmisc/network/networkutils.h"
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::Network;
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
namespace Db
|
||||
{
|
||||
CNetworkWatchdog::CNetworkWatchdog(QObject *parent) : CContinuousWorker(parent, "swift DB watchdog")
|
||||
{
|
||||
Q_ASSERT_X(sApp, Q_FUNC_INFO, "Need sApp");
|
||||
const bool network = sApp->isNetworkAccessible(); // default
|
||||
m_networkAccessible = network;
|
||||
m_dbAccessible = network && m_checkDbAccessibility;
|
||||
m_internetAccessible = network;
|
||||
|
||||
if (network)
|
||||
{
|
||||
this->initWorkingSharedUrlFromSetup();
|
||||
}
|
||||
|
||||
m_updateTimer.setInterval(10 * 1000);
|
||||
connect(&m_updateTimer, &QTimer::timeout, this, &CNetworkWatchdog::doWork);
|
||||
}
|
||||
|
||||
void CNetworkWatchdog::setDbAccessibility(bool available)
|
||||
{
|
||||
m_dbAccessible = available;
|
||||
m_internetAccessible = m_internetAccessible && m_networkAccessible;
|
||||
QTimer::singleShot(0, &m_updateTimer, [this] { this->m_updateTimer.start(); }); // restart
|
||||
}
|
||||
|
||||
CUrl CNetworkWatchdog::getWorkingSharedUrl() const
|
||||
{
|
||||
if (!m_networkAccessible) return CUrl();
|
||||
QReadLocker l(&m_lockSharedUrl);
|
||||
return m_workingSharedUrl;
|
||||
}
|
||||
|
||||
int CNetworkWatchdog::triggerCheck()
|
||||
{
|
||||
if (!this->doWorkCheck()) return false; // senseless
|
||||
if (m_checkInProgress) return -1;
|
||||
|
||||
const int n = this->getCheckCount();
|
||||
QTimer::singleShot(0, this, &CNetworkWatchdog::doWork);
|
||||
return n; // triggered
|
||||
}
|
||||
|
||||
void CNetworkWatchdog::setWorkingSharedUrl(const CUrl &workingUrl)
|
||||
{
|
||||
QWriteLocker l(&m_lockSharedUrl);
|
||||
m_workingSharedUrl = workingUrl;
|
||||
}
|
||||
|
||||
bool CNetworkWatchdog::isDbUrl(const CUrl &url)
|
||||
{
|
||||
const QString host(url.getHost());
|
||||
return host == dbHost();
|
||||
}
|
||||
|
||||
void CNetworkWatchdog::doWork()
|
||||
{
|
||||
if (!this->doWorkCheck()) { return; }
|
||||
if (m_checkInProgress) { return; }
|
||||
m_checkInProgress = true;
|
||||
|
||||
do
|
||||
{
|
||||
const bool wasDbAvailable = m_dbAccessible;
|
||||
const bool wasInternetAvailable = m_internetAccessible;
|
||||
const bool networkAccess = m_networkAccessible;
|
||||
const bool canConnectDb = m_checkDbAccessibility && networkAccess &&
|
||||
CNetworkUtils::canConnect(dbTestUrl()); // running in background worker
|
||||
bool canConnectInternet = canConnectDb;
|
||||
bool checkInternetAccess = !canConnectDb;
|
||||
|
||||
m_dbAccessible = canConnectDb;
|
||||
if (canConnectDb)
|
||||
{
|
||||
// DB available means internet available
|
||||
m_internetAccessible = canConnectDb;
|
||||
}
|
||||
|
||||
// check shared URL
|
||||
if (!this->doWorkCheck()) { break; }
|
||||
if (m_checkSharedUrl && networkAccess)
|
||||
{
|
||||
if (CNetworkUtils::canConnect(this->getWorkingSharedUrl()))
|
||||
{
|
||||
canConnectInternet = true;
|
||||
checkInternetAccess = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
const CUrl sharedUrl = this->getWorkingSharedUrl();
|
||||
if (!sharedUrl.isEmpty())
|
||||
{
|
||||
canConnectInternet = true;
|
||||
checkInternetAccess = false;
|
||||
this->setWorkingSharedUrl(sharedUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check internet access
|
||||
if (!this->doWorkCheck()) { break; }
|
||||
if (checkInternetAccess)
|
||||
{
|
||||
QString message;
|
||||
static const QString testHost1("www.google.com"); // what else?
|
||||
canConnectInternet = CNetworkUtils::canConnect(testHost1, 443, message); // running in background worker
|
||||
if (!canConnectInternet)
|
||||
{
|
||||
static const QString testHost2("www.microsoft.com"); // secondary test
|
||||
canConnectInternet = CNetworkUtils::canConnect(testHost2, 80, message); // running in background worker
|
||||
}
|
||||
}
|
||||
m_internetAccessible = networkAccess && canConnectInternet;
|
||||
|
||||
// signals
|
||||
m_checkCount++;
|
||||
this->triggerChangedSignals(wasDbAvailable, wasInternetAvailable);
|
||||
}
|
||||
while (false);
|
||||
|
||||
m_updateTimer.start(); // restart
|
||||
m_checkInProgress = false;
|
||||
}
|
||||
|
||||
bool CNetworkWatchdog::doWorkCheck() const
|
||||
{
|
||||
if (!sApp) { return false; }
|
||||
if (sApp->isShuttingDown()) { return false; }
|
||||
if (!this->isEnabled()) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
void CNetworkWatchdog::onChangedNetworkAccessibility(QNetworkAccessManager::NetworkAccessibility accessible)
|
||||
{
|
||||
const bool db = m_dbAccessible;
|
||||
const bool internet = m_internetAccessible;
|
||||
|
||||
// Intentionally rating unknown as "accessible"
|
||||
if (accessible == QNetworkAccessManager::NotAccessible)
|
||||
{
|
||||
m_networkAccessible = false;
|
||||
m_dbAccessible = false;
|
||||
m_internetAccessible = false;
|
||||
this->triggerChangedSignals(db, internet);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_networkAccessible = true;
|
||||
QTimer::singleShot(0, this, &CNetworkWatchdog::doWork);
|
||||
}
|
||||
}
|
||||
|
||||
void CNetworkWatchdog::triggerChangedSignals(bool oldDbAccessible, bool oldInternetAccessible)
|
||||
{
|
||||
if (!this->doWorkCheck()) { return; }
|
||||
|
||||
// trigger really queued
|
||||
if (oldDbAccessible != m_dbAccessible)
|
||||
{
|
||||
QTimer::singleShot(0, this, [this] { emit this->changedSwiftDbAccessibility(m_dbAccessible);});
|
||||
}
|
||||
if (oldInternetAccessible != m_internetAccessible)
|
||||
{
|
||||
QTimer::singleShot(0, this, [this] { emit this->changedInternetAccessibility(m_internetAccessible);});
|
||||
}
|
||||
}
|
||||
|
||||
void CNetworkWatchdog::initWorkingSharedUrlFromSetup()
|
||||
{
|
||||
const CUrl workingUrl(CNetworkWatchdog::workingSharedUrlFromSetup()); // takes long
|
||||
this->setWorkingSharedUrl(workingUrl);
|
||||
}
|
||||
|
||||
BlackMisc::Network::CUrl CNetworkWatchdog::dbTestUrl()
|
||||
{
|
||||
// requires global setup to be read
|
||||
const CUrl testUrl(sApp->getGlobalSetup().getDbHomePageUrl());
|
||||
return testUrl;
|
||||
}
|
||||
|
||||
QString CNetworkWatchdog::dbHost()
|
||||
{
|
||||
const QString host = dbTestUrl().getHost();
|
||||
return host;
|
||||
}
|
||||
|
||||
CUrl CNetworkWatchdog::workingSharedUrlFromSetup()
|
||||
{
|
||||
const CUrlList urls(sApp->getGlobalSetup().getSwiftSharedUrls());
|
||||
CFailoverUrlList failoverUrls(urls);
|
||||
return failoverUrls.getRandomWorkingUrl(); // use CNetworkUtils::canConnect
|
||||
}
|
||||
} // ns
|
||||
} // ns
|
||||
130
src/blackcore/db/networkwatchdog.h
Normal file
130
src/blackcore/db/networkwatchdog.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/* Copyright (C) 2017
|
||||
* swift project Community / Contributors
|
||||
*
|
||||
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
||||
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
||||
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef BLACKCORE_DB_NETWORKWATCHDOG_H
|
||||
#define BLACKCORE_DB_NETWORKWATCHDOG_H
|
||||
|
||||
#include "blackmisc/worker.h"
|
||||
#include "blackmisc/network/url.h"
|
||||
#include <atomic>
|
||||
#include <QReadWriteLock>
|
||||
#include <QNetworkAccessManager>
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
namespace Db
|
||||
{
|
||||
/**
|
||||
* Monitoring the swift DB, internet access, shared URL
|
||||
*/
|
||||
class CNetworkWatchdog : public BlackMisc::CContinuousWorker
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Ctor
|
||||
explicit CNetworkWatchdog(QObject *parent = nullptr);
|
||||
|
||||
//! DB available?
|
||||
//! \threadsafe
|
||||
bool isSwiftDbAccessible() const { return m_dbAccessible; }
|
||||
|
||||
//! Set DB as avialable (from external)
|
||||
//! \remark if data was read from DB, this can save another check
|
||||
//! \threadsafe
|
||||
void setDbAccessibility(bool available);
|
||||
|
||||
//! DB is accessible
|
||||
//! \threadsafe
|
||||
void setDbIsAccessible() { this->setDbAccessibility(true); }
|
||||
|
||||
//! DB is NOT accessible
|
||||
//! \threadsafe
|
||||
void setDbIsNotAccessible() { this->setDbAccessibility(false); }
|
||||
|
||||
//! Check the DB availability, can disable the check
|
||||
//! \threadsafe
|
||||
void setCheckDbAccessibility(bool check) { m_checkDbAccessibility = check; }
|
||||
|
||||
//! Check the shared URL, can disable the check
|
||||
//! \threadsafe
|
||||
void setCheckSharedUrl(bool check) { m_checkSharedUrl = check; }
|
||||
|
||||
//! Internet available?
|
||||
//! \threadsafe
|
||||
bool isInternetAccessible() const { return m_internetAccessible; }
|
||||
|
||||
//! A working shared URL
|
||||
//! \threadsafe
|
||||
BlackMisc::Network::CUrl getWorkingSharedUrl() const;
|
||||
|
||||
//! Run a check
|
||||
int triggerCheck();
|
||||
|
||||
//! Number of completed checks
|
||||
int getCheckCount() const { return m_checkCount; }
|
||||
|
||||
//! Set working URL from external
|
||||
//! \threadsafe
|
||||
void setWorkingSharedUrl(const BlackMisc::Network::CUrl &workingUrl);
|
||||
|
||||
//! Network status changed, use this function to inform the watchdog
|
||||
void onChangedNetworkAccessibility(QNetworkAccessManager::NetworkAccessibility accessible);
|
||||
|
||||
//! URL referring to the DB
|
||||
//! \remark depends on BlackCore::Application::getGlobalSetup()
|
||||
static bool isDbUrl(const BlackMisc::Network::CUrl &url);
|
||||
|
||||
signals:
|
||||
//! DB was available, but not longer is and vice versa
|
||||
void changedSwiftDbAccessibility(bool available);
|
||||
|
||||
//! Internet was available, but not longer is and vice versa
|
||||
void changedInternetAccessibility(bool available);
|
||||
|
||||
private:
|
||||
//! Do work, i.e. check connectivity
|
||||
void doWork();
|
||||
|
||||
//! Do check
|
||||
bool doWorkCheck() const;
|
||||
|
||||
//! Trigger the changed signals
|
||||
void triggerChangedSignals(bool oldDbAccessible, bool oldInternetAccessible);
|
||||
|
||||
//! Init a working shared URL
|
||||
void initWorkingSharedUrlFromSetup();
|
||||
|
||||
//! The URL being tested
|
||||
//! \remark depends on BlackCore::Application::getGlobalSetup()
|
||||
static BlackMisc::Network::CUrl dbTestUrl();
|
||||
|
||||
//! The DB server
|
||||
//! \remark depends on BlackCore::Application::getGlobalSetup()
|
||||
static QString dbHost();
|
||||
|
||||
//! Obtain working DB data file location URL
|
||||
//! \remark depends on BlackCore::Application::getGlobalSetup()
|
||||
static BlackMisc::Network::CUrl workingSharedUrlFromSetup();
|
||||
|
||||
std::atomic_bool m_networkAccessible { true };
|
||||
std::atomic_bool m_internetAccessible { true };
|
||||
std::atomic_bool m_dbAccessible { true };
|
||||
std::atomic_bool m_checkDbAccessibility { true };
|
||||
std::atomic_bool m_checkSharedUrl { true };
|
||||
std::atomic_bool m_checkInProgress { false }; //!< a check is currently in progress
|
||||
std::atomic_int m_checkCount { 0 }; //!< counting number of checks
|
||||
BlackMisc::Network::CUrl m_workingSharedUrl;
|
||||
mutable QReadWriteLock m_lockSharedUrl;
|
||||
};
|
||||
} // ns
|
||||
} // ns
|
||||
#endif // guard
|
||||
Reference in New Issue
Block a user