refs #719, avoid infinite loop when info object read succeeds, but has incorrect authorizations

* marker for info reader that it failed
* distinguish between "server cannot be connected" and other errors
This commit is contained in:
Klaus Basan
2016-08-04 00:04:34 +02:00
parent a0c20baf53
commit 3aee6174ac
5 changed files with 50 additions and 14 deletions

View File

@@ -103,7 +103,7 @@ namespace BlackCore
//! \threadsafe
bool hasReceivedOkReply() const;
//! Has received Ok response from server at least once?
//! Has received Ok response from server?
//! A message why connect failed can be obtained.
//! \threadsafe
bool hasReceivedOkReply(QString &message) const;
@@ -151,7 +151,7 @@ namespace BlackCore
protected:
CDatabaseReaderConfigList m_config; //!< DB reder configuration
QString m_statusMessage; //!< Returned status message from watchdog
bool m_1stReplyReceived = false; //!< Successful connection?
bool m_1stReplyReceived = false; //!< Successful connection? Does not mean data / authorizations are correct
QNetworkReply::NetworkError m_1stReplyStatus = QNetworkReply::UnknownServerError; //!< Successful connection?
mutable QReadWriteLock m_statusLock; //!< Lock

View File

@@ -48,7 +48,7 @@ namespace BlackCore
bool CInfoDataReader::areAllDataRead() const
{
return getDbInfoObjectCount() > 0;
return getDbInfoObjectCount() > 4;
}
void CInfoDataReader::syncronizeCaches(CEntityFlags::Entity entities)

View File

@@ -147,6 +147,16 @@ namespace BlackCore
return this->m_updateTimer->isActive();
}
bool CThreadedReader::isMarkedAsFailed() const
{
return this->m_markedAsFailed;
}
void CThreadedReader::setMarkedAsFailed(bool failed)
{
this->m_markedAsFailed = failed;
}
void CThreadedReader::setIntervalFromSettingsAndStart()
{
this->setInitialTime();

View File

@@ -22,6 +22,7 @@
#include <QReadWriteLock>
#include <QString>
#include <QtGlobal>
#include <atomic>
class QNetworkReply;
class QTimer;
@@ -66,6 +67,14 @@ namespace BlackCore
//! \threadsafe
bool isTimerActive() const;
//! Is marked as read failed
//! \threadsafe
bool isMarkedAsFailed() const;
//! Set marker for read failed
//! \threadsafe
void setMarkedAsFailed(bool failed);
//! Set inverval from settings and start
void setIntervalFromSettingsAndStart();
@@ -112,6 +121,7 @@ namespace BlackCore
private:
QDateTime m_updateTimestamp; //!< when file/resource was read
uint m_contentHash = 0; //!< has of the content given
std::atomic<bool> m_markedAsFailed { false }; //!< marker if reading failed
QMetaObject::Connection m_toggleConnection; //!< connection to switch interval from initial to periodic
private slots:

View File

@@ -727,12 +727,13 @@ namespace BlackCore
// with info objects wait until info objects are loaded
Q_ASSERT_X(!entities.testFlag(CEntityFlags::InfoObjectEntity), Q_FUNC_INFO, "Info object must be read upfront");
if (this->m_infoDataReader && CEntityFlags::anySwiftDbEntity(entities))
const bool readFromInfoReader = this->m_infoDataReader && !this->m_infoDataReader->areAllDataRead() && !this->m_infoDataReader->isMarkedAsFailed();
if (readFromInfoReader && CEntityFlags::anySwiftDbEntity(entities))
{
// try to read
if (this->m_infoObjectTrials > maxWaitCycles)
{
CLogMessage(this).error("Cannot read info objects for %1 from %2")
CLogMessage(this).warning("Cannot read info objects for %1 from %2")
<< CEntityFlags::flagToString(entities)
<< this->m_infoDataReader->getInfoObjectsUrl().toQString();
// continue here and read data without info objects
@@ -741,6 +742,7 @@ namespace BlackCore
{
if (this->m_infoDataReader->areAllDataRead())
{
// we have all data and carry on
CLogMessage(this).info("Info objects for %1 loaded (trial %2) from %3")
<< CEntityFlags::flagToString(entities)
<< this->m_infoObjectTrials
@@ -749,12 +751,26 @@ namespace BlackCore
}
else
{
// we have received a response, but not all data yet
if (this->m_infoDataReader->hasReceivedOkReply())
{
// ok, this means we are parsing
this->m_infoObjectTrials++;
this->readDeferredInBackground(entities, waitForInfoObjects);
return;
}
else
{
// we have a response, but a failure
// means server is alive, but responded with error
// such an error (access, ...) normally will not go away
CLogMessage(this).error("Info objects loading for %1 failed from %2, '%3'")
<< CEntityFlags::flagToString(entities)
<< this->m_infoDataReader->getInfoObjectsUrl().toQString()
<< this->m_infoDataReader->getStatusMessage();
this->readDeferredInBackground(entities, waitForInfoObjects);
return;
this->m_infoDataReader->setMarkedAsFailed(true);
// continue here and read data
}
}
}
else