From 51d43018995d721a03a9f68a7709fe7f3b56334d Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Wed, 2 Dec 2015 01:01:36 +0100 Subject: [PATCH] As a follow up of #533 and also detected during #538 #524 tasks, fixed 2 more issues/bugs * only call this->abandonAndWait() when not in main thread (also slack discussion MS/KB) * make sure web data service start to read even if setup reader signal was missed * add timestamp to setupreader to detect "recently read" in case signal is missed --- src/blackcore/setupreader.cpp | 7 ++++++- src/blackcore/webdataservices.cpp | 24 +++++++++++++++++++++++- src/blackcore/webdataservices.h | 6 +++++- src/blackmisc/threadedreader.cpp | 16 +++++++++++++++- src/blackmisc/threadedreader.h | 12 ++++++++---- 5 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/blackcore/setupreader.cpp b/src/blackcore/setupreader.cpp index eb673d06d..588a8f7f0 100644 --- a/src/blackcore/setupreader.cpp +++ b/src/blackcore/setupreader.cpp @@ -36,7 +36,10 @@ namespace BlackCore // initialized by local file for testing // I do not even need to start in background here CLogMessage(this).info("Using local bootstrap file: %1") << localFileName; - emit this->setupSynchronized(true); + BlackMisc::singleShot(1000, QThread::currentThread(), [ = ]() + { + emit this->setupSynchronized(true); + }); } else { @@ -272,6 +275,7 @@ namespace BlackCore if (sameVersionLoaded) { CLogMessage(this).info("Same update info loaded from %1 as already in data cache %2") << urlString << m_updateInfo.getFilename(); + this->setUpdateTimestamp(); emit versionSynchronized(true); return; // success } @@ -295,6 +299,7 @@ namespace BlackCore else { CLogMessage(this).info("Update info: Updated data cache in %1") << m_updateInfo.getFilename(); + this->setUpdateTimestamp(); emit versionSynchronized(true); return; // success } // cache diff --git a/src/blackcore/webdataservices.cpp b/src/blackcore/webdataservices.cpp index fbac85ae2..a815cabdf 100644 --- a/src/blackcore/webdataservices.cpp +++ b/src/blackcore/webdataservices.cpp @@ -39,9 +39,22 @@ namespace BlackCore QObject(parent), m_readerFlags(readerFlags), m_autoReadAfterSetupMs(autoReadAfterSetupSynchronizedMs) { this->setObjectName("CWebDataReader"); - connect(&CSetupReader::instance(), &CSetupReader::setupSynchronized, this, &CWebDataServices::ps_setupRead); this->initReaders(readerFlags); this->initWriters(); + if (autoReadAfterSetupSynchronizedMs >= 0) + { + // wait for setup read completion + // in case this was already fired or will never be fired set a time out + if (CSetupReader::instance().updatedWithinLastMs(10 * 1000)) + { + QTimer::singleShot(500, this, &CWebDataServices::ps_setupTimedOut); + } + else + { + connect(&CSetupReader::instance(), &CSetupReader::setupSynchronized, this, &CWebDataServices::ps_setupRead); + QTimer::singleShot(10 * 1000, this, &CWebDataServices::ps_setupTimedOut); + } + } } QList CWebDataServices::connectDataReadSignal(QObject *receiver, std::function dataRead) @@ -153,6 +166,7 @@ namespace BlackCore CEntityFlags::Entity CWebDataServices::triggerRead(CEntityFlags::Entity whatToRead) { + m_initialRead = true; CEntityFlags::Entity triggeredRead = CEntityFlags::NoEntity; if (m_vatsimDataFileReader) { @@ -486,6 +500,7 @@ namespace BlackCore { if (m_autoReadAfterSetupMs >= 0) { + if (m_initialRead) { return; } CLogMessage(this).info("Setup synchronized, will trigger read of web service data"); this->readInBackground(CEntityFlags::AllEntities, m_autoReadAfterSetupMs); } @@ -501,8 +516,15 @@ namespace BlackCore CLogMessage(this).debug() << "Setup changed"; } + void CWebDataServices::ps_setupTimedOut() + { + if (this->m_initialRead) { return; } + this->ps_setupRead(true); + } + void CWebDataServices::readInBackground(CEntityFlags::Entity entities, int delayMs) { + m_initialRead = true; if (delayMs > 100) { BlackMisc::singleShot(delayMs, QThread::currentThread(), [ = ]() diff --git a/src/blackcore/webdataservices.h b/src/blackcore/webdataservices.h index b1221ba39..9bdcee413 100644 --- a/src/blackcore/webdataservices.h +++ b/src/blackcore/webdataservices.h @@ -268,6 +268,9 @@ namespace BlackCore //! Setup has been changed void ps_setupChanged(); + //! Setup timed out + void ps_setupTimedOut(); + private: //! Init the readers void initReaders(CWebReaderFlags::WebReader flags); @@ -276,7 +279,8 @@ namespace BlackCore void initWriters(); CWebReaderFlags::WebReader m_readerFlags = CWebReaderFlags::WebReaderFlag::None; //!< which readers are available - int m_autoReadAfterSetupMs = -1; //!< directly read all known readers after setup was syncronized + int m_autoReadAfterSetupMs = -1; //!< directly read all known readers after setup was syncronized + bool m_initialRead = false; //!< Initial read conducted BlackCore::CData m_setup {this, &CWebDataServices::ps_setupChanged}; //!< setup cache // for reading XML and VATSIM data files diff --git a/src/blackmisc/threadedreader.cpp b/src/blackmisc/threadedreader.cpp index f68d48e43..ec0e87134 100644 --- a/src/blackmisc/threadedreader.cpp +++ b/src/blackmisc/threadedreader.cpp @@ -8,6 +8,7 @@ */ #include "threadedreader.h" +#include "blackmisc/threadutils.h" using namespace BlackMisc; using namespace BlackMisc::Network; @@ -48,6 +49,14 @@ namespace BlackMisc this->m_updateTimestamp = updateTimestamp; } + bool CThreadedReader::updatedWithinLastMs(qint64 timeLastMs) + { + QDateTime dt(getUpdateTimestamp()); + if (dt.isNull() || !dt.isValid()) { return false; } + qint64 delta = QDateTime::currentMSecsSinceEpoch() - dt.toMSecsSinceEpoch(); + return delta <= timeLastMs; + } + void CThreadedReader::requestReload() { // default implementation, subclasses shall override as required @@ -56,11 +65,16 @@ namespace BlackMisc void CThreadedReader::gracefulShutdown() { - this->abandonAndWait(); + // if not in main thread stop, otherwise it makes no sense to abandon + if (!CThreadUtils::isCurrentThreadObjectThread(this)) + { + this->abandonAndWait(); + } } CThreadedReader::~CThreadedReader() { + gracefulShutdown(); } void CThreadedReader::setInterval(int updatePeriodMs) diff --git a/src/blackmisc/threadedreader.h b/src/blackmisc/threadedreader.h index 82c345af6..3601c39b3 100644 --- a/src/blackmisc/threadedreader.h +++ b/src/blackmisc/threadedreader.h @@ -30,21 +30,25 @@ namespace BlackMisc class BLACKMISC_EXPORT CThreadedReader : public CContinuousWorker { public: + //! Destructor + virtual ~CThreadedReader(); + //! Thread safe, set update timestamp //! \threadsafe QDateTime getUpdateTimestamp() const; //! Thread safe, set update timestamp //! \threadsafe - void setUpdateTimestamp(const QDateTime &updateTimestamp); + void setUpdateTimestamp(const QDateTime &updateTimestamp = QDateTime::currentDateTimeUtc()); + + //! Was setup read within last xx milliseconds + //! \threadsafe + bool updatedWithinLastMs(qint64 timeLastMs); //! Request new reading //! \note override as required, default is to call initialize() virtual void requestReload(); - //! Destructor - virtual ~CThreadedReader(); - //! Set the update time //! \param updatePeriodMs <=0 stops the timer //! \threadsafe