History

Add retry logic to ScriptCache

Ryan Huffman committed 10 years ago

Commit 3c374e81 parent 1fff4802 files · +61 −16Browse files

Showing the changes to libraries/script-engine/src/ScriptCache.cpp (1 of 2 files). Show all

Unified · Split

libraries/script-engine/src/ScriptCache.cpp+52−14
@@ -25,6 +25,7 @@ · 24 unmodified lines
25 25
26#include "ScriptEngines.h"26#include "ScriptEngines.h"
27#include "ScriptEngineLogging.h"27#include "ScriptEngineLogging.h"
28#include <QtCore/QTimer>
28 29
29ScriptCache::ScriptCache(QObject* parent) {30ScriptCache::ScriptCache(QObject* parent) {
30 // nothing to do here...31 // nothing to do here...
@@ -133,8 +134,11 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable · 102 unmodified lines
133 qCDebug(scriptengine) << "Found script in cache:" << url.toString();134 qCDebug(scriptengine) << "Found script in cache:" << url.toString();
134 contentAvailable(url.toString(), scriptContent, true, true);135 contentAvailable(url.toString(), scriptContent, true, true);
135 } else {136 } else {
136 bool alreadyWaiting = _contentCallbacks.contains(url);137 auto& scriptRequest = _activeScriptRequests[url];
137 _contentCallbacks.insert(url, contentAvailable);138
139 bool alreadyWaiting = scriptRequest.scriptUsers.size() > 0;
140 scriptRequest.scriptUsers.push_back(contentAvailable);
141
138 lock.unlock();142 lock.unlock();
139 143
140 if (alreadyWaiting) {144 if (alreadyWaiting) {
@@ -152,6 +156,9 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable · 11 unmodified lines
152 }156 }
153}157}
154 158
159static const int MAX_RETRIES = 5;
160static int START_DELAY_BETWEEN_RETRIES = 200;
161
155void ScriptCache::scriptContentAvailable() {162void ScriptCache::scriptContentAvailable() {
156 #ifdef THREAD_DEBUGGING163 #ifdef THREAD_DEBUGGING
157 qCDebug(scriptengine) << "ScriptCache::scriptContentAvailable() on thread [" << QThread::currentThread() << "] expected thread [" << thread() << "]";164 qCDebug(scriptengine) << "ScriptCache::scriptContentAvailable() on thread [" << QThread::currentThread() << "] expected thread [" << thread() << "]";
@@ -160,29 +167,60 @@ void ScriptCache::scriptContentAvailable() { · 2 unmodified lines
160 QUrl url = req->getUrl();167 QUrl url = req->getUrl();
161 168
162 QString scriptContent;169 QString scriptContent;
163 QList<contentAvailableCallback> allCallbacks;170 std::vector<contentAvailableCallback> allCallbacks;
171 bool finished { false };
164 bool success { false };172 bool success { false };
165 173
166 {174 {
167 Lock lock(_containerLock);
168 allCallbacks = _contentCallbacks.values(url);
169 _contentCallbacks.remove(url);
170 Q_ASSERT(req->getState() == ResourceRequest::Finished);175 Q_ASSERT(req->getState() == ResourceRequest::Finished);
171 success = req->getResult() == ResourceRequest::Success;176 success = req->getResult() == ResourceRequest::Success;
172 177
173 if (success) {178 Lock lock(_containerLock);
174 _scriptCache[url] = scriptContent = req->getData();179
175 qCDebug(scriptengine) << "Done downloading script at:" << url.toString();180 if (_activeScriptRequests.contains(url)) {
176 } else {181 auto& scriptRequest = _activeScriptRequests[url];
177 // Dubious, but retained here because it matches the behavior before fixing the threading182
178 scriptContent = _scriptCache[url];183 if (success) {
179 qCWarning(scriptengine) << "Error loading script from URL " << url;184 allCallbacks = scriptRequest.scriptUsers;
185 auto scriptContent = _scriptCache[url];
186
187 _activeScriptRequests.remove(url);
188
189 _scriptCache[url] = scriptContent = req->getData();
190 finished = true;
191 qCDebug(scriptengine) << "Done downloading script at:" << url.toString();
192 } else {
193 if (scriptRequest.numRetries < MAX_RETRIES) {
194 ++scriptRequest.numRetries;
195
196 qDebug() << "Script request failed: " << url;
197
198 int timeout = exp(scriptRequest.numRetries) * START_DELAY_BETWEEN_RETRIES;
199 QTimer::singleShot(timeout, this, [this, url]() {
200 qDebug() << "Retrying script request: " << url;
201
202 auto request = ResourceManager::createResourceRequest(nullptr, url);
203 Q_ASSERT(request);
204
205 // We've already made a request, so the cache must be disabled or it wasn't there, so enabling
206 // it will do nothing.
207 request->setCacheEnabled(false);
208 connect(request, &ResourceRequest::finished, this, &ScriptCache::scriptContentAvailable);
209 request->send();
210 });
211 } else {
212 // Dubious, but retained here because it matches the behavior before fixing the threading
213 scriptContent = _scriptCache[url];
214 finished = true;
215 qCWarning(scriptengine) << "Error loading script from URL " << url;
216 }
217 }
180 }218 }
181 }219 }
182 220
183 req->deleteLater();221 req->deleteLater();
184 222
185 if (!DependencyManager::get<ScriptEngines>()->isStopped()) {223 if (finished && !DependencyManager::get<ScriptEngines>()->isStopped()) {
186 foreach(contentAvailableCallback thisCallback, allCallbacks) {224 foreach(contentAvailableCallback thisCallback, allCallbacks) {
187 thisCallback(url.toString(), scriptContent, true, success);225 thisCallback(url.toString(), scriptContent, true, success);
188 }226 }