Showing the changes to libraries/script-engine/src/ScriptCache.cpp (1 of 2 files). Show all
Unified · Split
| @@ -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 | ||
| 29 | ScriptCache::ScriptCache(QObject* parent) { | 30 | ScriptCache::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 | ||
| 159 | static const int MAX_RETRIES = 5; | ||
| 160 | static int START_DELAY_BETWEEN_RETRIES = 200; | ||
| 161 | |||
| 155 | void ScriptCache::scriptContentAvailable() { | 162 | void ScriptCache::scriptContentAvailable() { |
| 156 | #ifdef THREAD_DEBUGGING | 163 | #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 threading | 182 | |
| 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 | } |