diff --git a/src/blackcore/db/airportdatareader.cpp b/src/blackcore/db/airportdatareader.cpp index 51f6455af..417b034c9 100644 --- a/src/blackcore/db/airportdatareader.cpp +++ b/src/blackcore/db/airportdatareader.cpp @@ -143,9 +143,14 @@ namespace BlackCore return getBaseUrl(mode).withAppendedPath(fileNameForMode(CEntityFlags::AirportEntity, mode)); } - void CAirportDataReader::ps_parseAirportData(QNetworkReply *nwReply) + void CAirportDataReader::ps_parseAirportData(QNetworkReply *nwReplyPtr) { - const CDatabaseReader::JsonDatastoreResponse res = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply); + // wrap pointer, make sure any exit cleans up reply + // required to use delete later as object is created in a different thread + QScopedPointer nwReply(nwReplyPtr); + if (this->isShuttingDown()) { return; } + + const CDatabaseReader::JsonDatastoreResponse res = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReplyPtr); if (res.hasErrorMessage()) { CLogMessage::preformatted(res.lastWarningOrAbove()); @@ -170,12 +175,13 @@ namespace BlackCore if (size > 0 && latestTimestamp < 0) { CLogMessage(this).error("No timestamp in airport list, setting to last modified value"); - latestTimestamp = lastModifiedMsSinceEpoch(nwReply); + latestTimestamp = lastModifiedMsSinceEpoch(nwReply.data()); } this->m_airportCache.set(airports, latestTimestamp); this->updateReaderUrl(getBaseUrl(CDbFlags::DbReading)); - emit this->dataRead(CEntityFlags::AirportEntity, CEntityFlags::ReadFinished, airports.size()); + + this->emitAndLogDataRead(CEntityFlags::AirportEntity, size, res); } void CAirportDataReader::ps_read(CEntityFlags::Entity entity, CDbFlags::DataRetrievalModeFlag mode, const QDateTime &newerThan) diff --git a/src/blackcore/db/airportdatareader.h b/src/blackcore/db/airportdatareader.h index 422b591f0..95bd94f8f 100644 --- a/src/blackcore/db/airportdatareader.h +++ b/src/blackcore/db/airportdatareader.h @@ -64,7 +64,7 @@ namespace BlackCore private slots: //! Parse downloaded JSON file - void ps_parseAirportData(QNetworkReply *nwReply); + void ps_parseAirportData(QNetworkReply *nwReplyPtr); //! Read / re-read data file void ps_read(BlackMisc::Network::CEntityFlags::Entity entity = BlackMisc::Network::CEntityFlags::DistributorLiveryModel, diff --git a/src/blackcore/db/databasereader.cpp b/src/blackcore/db/databasereader.cpp index 672610dd8..f579ca5ad 100644 --- a/src/blackcore/db/databasereader.cpp +++ b/src/blackcore/db/databasereader.cpp @@ -249,7 +249,7 @@ namespace BlackCore const QString url(nwReply->url().toString()); nwReply->abort(); headerResponse.setMessage(CStatusMessage(this, CStatusMessage::SeverityError, - QString("Reading data failed: " + error + " " + url))); + QString("Reading data failed: '" + error + "' " + url))); return false; } } @@ -408,6 +408,13 @@ namespace BlackCore return emitted; } + void CDatabaseReader::emitAndLogDataRead(CEntityFlags::Entity entity, int number, const JsonDatastoreResponse &res) + { + // never emit when lock is held, deadlock + emit dataRead(entity, res.isRestricted() ? CEntityFlags::ReadFinishedRestricted : CEntityFlags::ReadFinished, number); + CLogMessage(this).info("Read %1 entities of '%2' from '%3' (%4)") << number << CEntityFlags::flagToString(entity) << res.getUrlString() << res.getLoadTimeString(); + } + CUrl CDatabaseReader::getBaseUrl(CDbFlags::DataRetrievalModeFlag mode) const { if (this->isShuttingDown()) { return CUrl(); } diff --git a/src/blackcore/db/databasereader.h b/src/blackcore/db/databasereader.h index 793b45cf5..7bd8863ef 100644 --- a/src/blackcore/db/databasereader.h +++ b/src/blackcore/db/databasereader.h @@ -91,6 +91,9 @@ namespace BlackCore //! URL loaded const BlackMisc::Network::CUrl &getUrl() const { return m_url; } + //! URL loaded as string + QString getUrlString() const { return m_url.toQString(); } + //! Set the loaded URL void setUrl(const BlackMisc::Network::CUrl &url) { m_url = url; } @@ -100,11 +103,14 @@ namespace BlackCore //! Load time in ms (from request to response) qint64 getLoadTimeMs() const { return m_loadTimeMs; } + //! Load time as string + QString getLoadTimeString() const { return QString("%1ms").arg(getLoadTimeMs()); } + //! Set the load time (delta start -> response received) void setLoadTimeMs(qint64 deltaTime) { m_loadTimeMs = deltaTime; } }; - //! Response from our database (depneding on JSON DB backend generates) + //! Response from our database (depending on JSON DB backend generates) struct JsonDatastoreResponse : public HeaderResponse { private: @@ -260,6 +266,9 @@ namespace BlackCore //! Split into single entity and send dataRead signal BlackMisc::Network::CEntityFlags::Entity emitReadSignalPerSingleCachedEntity(BlackMisc::Network::CEntityFlags::Entity cachedEntities, bool onlyIfHasData); + //! Emit signal and log when data have been read + void emitAndLogDataRead(BlackMisc::Network::CEntityFlags::Entity entity, int number, const JsonDatastoreResponse &res); + //! Get the service URL, individual for each reader virtual BlackMisc::Network::CUrl getDbServiceBaseUrl() const = 0; diff --git a/src/blackcore/db/icaodatareader.cpp b/src/blackcore/db/icaodatareader.cpp index 023747216..1df4a53df 100644 --- a/src/blackcore/db/icaodatareader.cpp +++ b/src/blackcore/db/icaodatareader.cpp @@ -230,7 +230,6 @@ namespace BlackCore QScopedPointer nwReply(nwReplyPtr); if (this->isShuttingDown()) { return; } - const QString urlString(nwReply->url().toString()); CDatabaseReader::JsonDatastoreResponse res = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data()); if (res.hasErrorMessage()) { @@ -251,8 +250,8 @@ namespace BlackCore this->m_aircraftIcaoCache.set(codes, latestTimestamp); this->updateReaderUrl(getBaseUrl(CDbFlags::DbReading)); - emit dataRead(CEntityFlags::AircraftIcaoEntity, CEntityFlags::ReadFinished, n); - CLogMessage(this).info("Read %1 %2 from %3") << n << CEntityFlags::flagToString(CEntityFlags::AircraftIcaoEntity) << urlString; + + this->emitAndLogDataRead(CEntityFlags::AircraftIcaoEntity, n, res); } void CIcaoDataReader::ps_parseAirlineIcaoData(QNetworkReply *nwReplyPtr) @@ -260,7 +259,6 @@ namespace BlackCore QScopedPointer nwReply(nwReplyPtr); if (this->isShuttingDown()) { return; } - QString urlString(nwReply->url().toString()); CDatabaseReader::JsonDatastoreResponse res = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data()); if (res.hasErrorMessage()) { @@ -279,14 +277,13 @@ namespace BlackCore this->m_airlineIcaoCache.set(codes, latestTimestamp); this->updateReaderUrl(getBaseUrl(CDbFlags::DbReading)); - emit dataRead(CEntityFlags::AirlineIcaoEntity, CEntityFlags::ReadFinished, n); - CLogMessage(this).info("Read %1 %2 from %3") << n << CEntityFlags::flagToString(CEntityFlags::AirlineIcaoEntity) << urlString; + + this->emitAndLogDataRead(CEntityFlags::AirlineIcaoEntity, n, res); } void CIcaoDataReader::ps_parseCountryData(QNetworkReply *nwReplyPtr) { QScopedPointer nwReply(nwReplyPtr); - QString urlString(nwReply->url().toString()); CDatabaseReader::JsonDatastoreResponse res = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data()); if (res.hasErrorMessage()) { @@ -305,8 +302,8 @@ namespace BlackCore this->m_countryCache.set(countries, latestTimestamp); this->updateReaderUrl(getBaseUrl(CDbFlags::DbReading)); - emit dataRead(CEntityFlags::CountryEntity, CEntityFlags::ReadFinished, n); - CLogMessage(this).info("Read %1 %2 from %3") << n << CEntityFlags::flagToString(CEntityFlags::CountryEntity) << urlString; + + this->emitAndLogDataRead(CEntityFlags::CountryEntity, n, res); } CStatusMessageList CIcaoDataReader::readFromJsonFiles(const QString &dir, CEntityFlags::Entity whatToRead) diff --git a/src/blackcore/db/infodatareader.cpp b/src/blackcore/db/infodatareader.cpp index a44ada357..50a5897ab 100644 --- a/src/blackcore/db/infodatareader.cpp +++ b/src/blackcore/db/infodatareader.cpp @@ -132,7 +132,6 @@ namespace BlackCore QScopedPointer nwReply(nwReplyPtr); if (this->isShuttingDown()) { return; } - QString urlString(nwReply->url().toString()); CDatabaseReader::JsonDatastoreResponse res = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data()); if (res.hasErrorMessage()) { @@ -142,19 +141,16 @@ namespace BlackCore } // get all or incremental set - CDbInfoList infoObjects = CDbInfoList::fromDatabaseJson(res.getJsonArray()); + const CDbInfoList infoObjects = CDbInfoList::fromDatabaseJson(res.getJsonArray()); // this part needs to be synchronized - int n = infoObjects.size(); + const int n = infoObjects.size(); { QWriteLocker wl(&this->m_lockInfoObjects); this->m_infoObjects = infoObjects; } - // never emit when lock is held -> deadlock - emit dataRead(CEntityFlags::InfoObjectEntity, - res.isRestricted() ? CEntityFlags::ReadFinishedRestricted : CEntityFlags::ReadFinished, n); - CLogMessage(this).info("Read %1 %2 from %3") << n << CEntityFlags::flagToString(CEntityFlags::InfoObjectEntity) << urlString; + this->emitAndLogDataRead(CEntityFlags::InfoObjectEntity, n, res); } CUrl CInfoDataReader::getInfoObjectsUrl() const diff --git a/src/blackcore/db/modeldatareader.cpp b/src/blackcore/db/modeldatareader.cpp index 1ed21afea..da4c3a1db 100644 --- a/src/blackcore/db/modeldatareader.cpp +++ b/src/blackcore/db/modeldatareader.cpp @@ -261,7 +261,6 @@ namespace BlackCore // required to use delete later as object is created in a different thread QScopedPointer nwReply(nwReplyPtr); if (this->isShuttingDown()) { return; } - QString urlString(nwReply->url().toString()); CDatabaseReader::JsonDatastoreResponse res = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data()); if (res.hasErrorMessage()) { @@ -293,9 +292,7 @@ namespace BlackCore this->m_liveryCache.set(liveries, latestTimestamp); this->updateReaderUrl(getBaseUrl(CDbFlags::DbReading)); - // never emit when lock is held -> deadlock - emit dataRead(CEntityFlags::LiveryEntity, res.isRestricted() ? CEntityFlags::ReadFinishedRestricted : CEntityFlags::ReadFinished, n); - CLogMessage(this).info("Read '%1' '%2' from '%3'") << n << CEntityFlags::flagToString(CEntityFlags::ModelEntity) << urlString; + this->emitAndLogDataRead(CEntityFlags::LiveryEntity, n, res); } void CModelDataReader::ps_parseDistributorData(QNetworkReply *nwReplyPtr) @@ -304,7 +301,6 @@ namespace BlackCore // required to use delete later as object is created in a different thread QScopedPointer nwReply(nwReplyPtr); if (this->isShuttingDown()) { return; } - const QString urlString(nwReply->url().toString()); CDatabaseReader::JsonDatastoreResponse res = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data()); if (res.hasErrorMessage()) { @@ -336,8 +332,7 @@ namespace BlackCore this->m_distributorCache.set(distributors, latestTimestamp); this->updateReaderUrl(getBaseUrl(CDbFlags::DbReading)); - emit dataRead(CEntityFlags::DistributorEntity, res.isRestricted() ? CEntityFlags::ReadFinishedRestricted : CEntityFlags::ReadFinished, n); - CLogMessage(this).info("Read '%1' '%2' from '%3'") << n << CEntityFlags::flagToString(CEntityFlags::ModelEntity) << urlString; + this->emitAndLogDataRead(CEntityFlags::DistributorEntity, n, res); } void CModelDataReader::ps_parseModelData(QNetworkReply *nwReplyPtr) @@ -346,7 +341,6 @@ namespace BlackCore // required to use delete later as object is created in a different thread QScopedPointer nwReply(nwReplyPtr); if (this->isShuttingDown()) { return; } - const QString urlString(nwReply->url().toString()); CDatabaseReader::JsonDatastoreResponse res = this->setStatusAndTransformReplyIntoDatastoreResponse(nwReply.data()); if (res.hasErrorMessage()) { @@ -379,8 +373,7 @@ namespace BlackCore this->m_modelCache.set(models, latestTimestamp); this->updateReaderUrl(getBaseUrl(CDbFlags::DbReading)); - emit dataRead(CEntityFlags::ModelEntity, res.isRestricted() ? CEntityFlags::ReadFinishedRestricted : CEntityFlags::ReadFinished, n); - CLogMessage(this).info("Read '%1' '%2' from '%3'") << n << CEntityFlags::flagToString(CEntityFlags::ModelEntity) << urlString; + this->emitAndLogDataRead(CEntityFlags::ModelEntity, n, res); } CStatusMessageList CModelDataReader::readFromJsonFiles(const QString &dir, CEntityFlags::Entity whatToRead)