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
2525
2626 #include "ScriptEngines.h"
2727 #include "ScriptEngineLogging.h"
28+#include <QtCore/QTimer>
2829
2930 ScriptCache::ScriptCache(QObject* parent) {
3031 // nothing to do here...
@@ -133,8 +134,11 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable · 102 unmodified lines
133134 qCDebug(scriptengine) << "Found script in cache:" << url.toString();
134135 contentAvailable(url.toString(), scriptContent, true, true);
135136 } else {
136− bool alreadyWaiting = _contentCallbacks.contains(url);
137− _contentCallbacks.insert(url, contentAvailable);
137+ auto& scriptRequest = _activeScriptRequests[url];
138+
139+ bool alreadyWaiting = scriptRequest.scriptUsers.size() > 0;
140+ scriptRequest.scriptUsers.push_back(contentAvailable);
141+
138142 lock.unlock();
139143
140144 if (alreadyWaiting) {
@@ -152,6 +156,9 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable · 11 unmodified lines
152156 }
153157 }
154158
159+static const int MAX_RETRIES = 5;
160+static int START_DELAY_BETWEEN_RETRIES = 200;
161+
155162 void ScriptCache::scriptContentAvailable() {
156163 #ifdef THREAD_DEBUGGING
157164 qCDebug(scriptengine) << "ScriptCache::scriptContentAvailable() on thread [" << QThread::currentThread() << "] expected thread [" << thread() << "]";
@@ -160,29 +167,60 @@ void ScriptCache::scriptContentAvailable() { · 2 unmodified lines
160167 QUrl url = req->getUrl();
161168
162169 QString scriptContent;
163− QList<contentAvailableCallback> allCallbacks;
170+ std::vector<contentAvailableCallback> allCallbacks;
171+ bool finished { false };
164172 bool success { false };
165173
166174 {
167− Lock lock(_containerLock);
168− allCallbacks = _contentCallbacks.values(url);
169− _contentCallbacks.remove(url);
170175 Q_ASSERT(req->getState() == ResourceRequest::Finished);
171176 success = req->getResult() == ResourceRequest::Success;
172177
173− if (success) {
174− _scriptCache[url] = scriptContent = req->getData();
175− qCDebug(scriptengine) << "Done downloading script at:" << url.toString();
176− } else {
177− // Dubious, but retained here because it matches the behavior before fixing the threading
178− scriptContent = _scriptCache[url];
179− qCWarning(scriptengine) << "Error loading script from URL " << url;
178+ Lock lock(_containerLock);
179+
180+ if (_activeScriptRequests.contains(url)) {
181+ auto& scriptRequest = _activeScriptRequests[url];
182+
183+ if (success) {
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+ }
180218 }
181219 }
182220
183221 req->deleteLater();
184222
185− if (!DependencyManager::get<ScriptEngines>()->isStopped()) {
223+ if (finished && !DependencyManager::get<ScriptEngines>()->isStopped()) {
186224 foreach(contentAvailableCallback thisCallback, allCallbacks) {
187225 thisCallback(url.toString(), scriptContent, true, success);
188226 }