From 1b7fdf5d16b76581ee5e29f688c8b4a8e57a5e6d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 5 Mar 2015 18:49:52 +0100 Subject: [PATCH] Improve disk cache usage Now we always load from the disk cache if the file is in there. Then we check the last modidied date from the network file against the one in the cache. If needed, we redownload. --- libraries/networking/src/ResourceCache.cpp | 43 +++++++++++++++++++++- libraries/networking/src/ResourceCache.h | 6 ++- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index 7eadb0a3dd..658f32aba1 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -12,9 +12,10 @@ #include #include +#include +#include #include #include -#include #include @@ -314,13 +315,51 @@ void Resource::handleReplyTimeout() { "received" << _bytesReceived << "total" << _bytesTotal); } +void Resource::maybeRefresh() { + if (Q_LIKELY(NetworkAccessManager::getInstance().cache())) { + QNetworkReply* reply = qobject_cast(sender()); + QVariant variant = reply->header(QNetworkRequest::LastModifiedHeader); + QNetworkCacheMetaData metaData = NetworkAccessManager::getInstance().cache()->metaData(_url); + if (variant.isValid() && variant.canConvert() && metaData.isValid()) { + QDateTime lastModified = variant.value(); + QDateTime lastModifiedOld = metaData.lastModified(); + if (lastModified.isValid() && lastModifiedOld.isValid() && + lastModifiedOld == lastModified) { + // We don't need to update, return + return; + } + } + qDebug() << "Loaded" << _url.fileName() << "from the disk cache but the network version is newer, refreshing."; + refresh(); + } +} + void Resource::makeRequest() { _reply = NetworkAccessManager::getInstance().get(_request); connect(_reply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(handleDownloadProgress(qint64,qint64))); connect(_reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(handleReplyError())); connect(_reply, SIGNAL(finished()), SLOT(handleReplyFinished())); - + + if (_reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool()) { + // If the file as been updated since it was cached, refresh it + QNetworkRequest request(_request); + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork); + request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false); + QNetworkReply* reply = NetworkAccessManager::getInstance().head(request); + connect(reply, &QNetworkReply::finished, this, &Resource::maybeRefresh); + } else { + if (Q_LIKELY(NetworkAccessManager::getInstance().cache())) { + QNetworkCacheMetaData metaData = NetworkAccessManager::getInstance().cache()->metaData(_url); + if (metaData.expirationDate().isNull() || metaData.expirationDate() <= QDateTime::currentDateTime()) { + // If the expiration date is NULL or in the past, + // put one far enough away that it won't be an issue. + metaData.setExpirationDate(QDateTime::currentDateTime().addYears(100)); + NetworkAccessManager::getInstance().cache()->updateMetaData(metaData); + } + } + } + _replyTimer = new QTimer(this); connect(_replyTimer, SIGNAL(timeout()), SLOT(handleReplyTimeout())); _replyTimer->setSingleShot(true); diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index 62fca71ea5..11b091a9e3 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -149,7 +149,7 @@ public: /// For loading resources, returns the load progress. float getProgress() const { return (_bytesTotal <= 0) ? 0.0f : (float)_bytesReceived / _bytesTotal; } - + /// Refreshes the resource. void refresh(); @@ -169,6 +169,10 @@ signals: protected slots: void attemptRequest(); + + /// Refreshes the resource if the last modified date on the network + /// is greater than the last modified date in the cache. + void maybeRefresh(); protected: