From 1468bd1b497d0e9df2d7696ef95301a2b66ac1d9 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Mar 2014 14:31:13 -0800 Subject: [PATCH 1/2] Add a five second download timeout timer: if that much time passes without any progress, consider it an error. --- libraries/shared/src/ResourceCache.cpp | 40 +++++++++++++++++++------- libraries/shared/src/ResourceCache.h | 6 ++++ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/libraries/shared/src/ResourceCache.cpp b/libraries/shared/src/ResourceCache.cpp index bd08b240c5..869f503175 100644 --- a/libraries/shared/src/ResourceCache.cpp +++ b/libraries/shared/src/ResourceCache.cpp @@ -9,7 +9,6 @@ #include #include -#include #include #include @@ -156,25 +155,51 @@ void Resource::finishedLoading(bool success) { _loadPriorities.clear(); } +const int REPLY_TIMEOUT_MS = 5000; + void Resource::handleDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) { if (!_reply->isFinished()) { + _replyTimer->start(REPLY_TIMEOUT_MS); return; } _reply->disconnect(this); QNetworkReply* reply = _reply; _reply = NULL; + _replyTimer->disconnect(this); + _replyTimer->deleteLater(); + _replyTimer = NULL; ResourceCache::requestCompleted(); downloadFinished(reply); } void Resource::handleReplyError() { - QDebug debug = qDebug() << _reply->errorString(); + handleReplyError(_reply->error(), qDebug() << _reply->errorString()); +} + +void Resource::handleReplyTimeout() { + handleReplyError(QNetworkReply::TimeoutError, qDebug() << "Timed out loading" << _reply->url()); +} + +void Resource::makeRequest() { + _reply = ResourceCache::getNetworkAccessManager()->get(_request); - QNetworkReply::NetworkError error = _reply->error(); + connect(_reply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(handleDownloadProgress(qint64,qint64))); + connect(_reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(handleReplyError())); + + _replyTimer = new QTimer(this); + connect(_replyTimer, SIGNAL(timeout()), SLOT(handleReplyTimeout())); + _replyTimer->setSingleShot(true); + _replyTimer->start(REPLY_TIMEOUT_MS); +} + +void Resource::handleReplyError(QNetworkReply::NetworkError error, QDebug debug) { _reply->disconnect(this); _reply->deleteLater(); _reply = NULL; + _replyTimer->disconnect(this); + _replyTimer->deleteLater(); + _replyTimer = NULL; ResourceCache::requestCompleted(); // retry for certain types of failures @@ -193,7 +218,7 @@ void Resource::handleReplyError() { const int BASE_DELAY_MS = 1000; if (++_attempts < MAX_ATTEMPTS) { QTimer::singleShot(BASE_DELAY_MS * (int)pow(2.0, _attempts), this, SLOT(attemptRequest())); - debug << " -- retrying..."; + debug << "-- retrying..."; return; } // fall through to final failure @@ -204,13 +229,6 @@ void Resource::handleReplyError() { } } -void Resource::makeRequest() { - _reply = ResourceCache::getNetworkAccessManager()->get(_request); - - connect(_reply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(handleDownloadProgress(qint64,qint64))); - connect(_reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(handleReplyError())); -} - uint qHash(const QPointer& value, uint seed) { return qHash(value.data(), seed); } diff --git a/libraries/shared/src/ResourceCache.h b/libraries/shared/src/ResourceCache.h index c77318aac2..398f4afb29 100644 --- a/libraries/shared/src/ResourceCache.h +++ b/libraries/shared/src/ResourceCache.h @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -20,6 +21,7 @@ class QNetworkAccessManager; class QNetworkReply; +class QTimer; class Resource; @@ -116,14 +118,18 @@ private slots: void handleDownloadProgress(qint64 bytesReceived, qint64 bytesTotal); void handleReplyError(); + void handleReplyTimeout(); private: void makeRequest(); + void handleReplyError(QNetworkReply::NetworkError error, QDebug debug); + friend class ResourceCache; QNetworkReply* _reply; + QTimer* _replyTimer; int _attempts; }; From 8ec7a5e60078b233bd084a23a49c6a84112b11fd Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 6 Mar 2014 15:08:34 -0800 Subject: [PATCH 2/2] When we time out, report the last received/total counts. --- libraries/shared/src/ResourceCache.cpp | 6 +++++- libraries/shared/src/ResourceCache.h | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/ResourceCache.cpp b/libraries/shared/src/ResourceCache.cpp index 869f503175..a7c0302a9c 100644 --- a/libraries/shared/src/ResourceCache.cpp +++ b/libraries/shared/src/ResourceCache.cpp @@ -159,6 +159,8 @@ const int REPLY_TIMEOUT_MS = 5000; void Resource::handleDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) { if (!_reply->isFinished()) { + _bytesReceived = bytesReceived; + _bytesTotal = bytesTotal; _replyTimer->start(REPLY_TIMEOUT_MS); return; } @@ -178,7 +180,8 @@ void Resource::handleReplyError() { } void Resource::handleReplyTimeout() { - handleReplyError(QNetworkReply::TimeoutError, qDebug() << "Timed out loading" << _reply->url()); + handleReplyError(QNetworkReply::TimeoutError, qDebug() << "Timed out loading" << _reply->url() << + "received" << _bytesReceived << "total" << _bytesTotal); } void Resource::makeRequest() { @@ -191,6 +194,7 @@ void Resource::makeRequest() { connect(_replyTimer, SIGNAL(timeout()), SLOT(handleReplyTimeout())); _replyTimer->setSingleShot(true); _replyTimer->start(REPLY_TIMEOUT_MS); + _bytesReceived = _bytesTotal = 0; } void Resource::handleReplyError(QNetworkReply::NetworkError error, QDebug debug) { diff --git a/libraries/shared/src/ResourceCache.h b/libraries/shared/src/ResourceCache.h index 398f4afb29..8aed2bfcb0 100644 --- a/libraries/shared/src/ResourceCache.h +++ b/libraries/shared/src/ResourceCache.h @@ -130,6 +130,8 @@ private: QNetworkReply* _reply; QTimer* _replyTimer; + qint64 _bytesReceived; + qint64 _bytesTotal; int _attempts; };