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
This commit is contained in:
Klaus Basan
2015-12-02 01:01:36 +01:00
parent a863f99c9d
commit 51d4301899
5 changed files with 57 additions and 8 deletions

View File

@@ -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

View File

@@ -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<QMetaObject::Connection> CWebDataServices::connectDataReadSignal(QObject *receiver, std::function<void(CEntityFlags::Entity, CEntityFlags::ReadState, int)> 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(), [ = ]()

View File

@@ -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<BlackCore::Data::GlobalSetup> m_setup {this, &CWebDataServices::ps_setupChanged}; //!< setup cache
// for reading XML and VATSIM data files

View File

@@ -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)

View File

@@ -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