History

* refactor ScriptCache per FIXMEs * include error details in BatchLoader results * update EntityServerScript properties in edtior to reflect more granular statuses * ScriptEngine plumbing in prep for require/module integration

humbletim committed 9 years ago

Commit 831bf931 parent e6142d914 files · +286 −257Browse files

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

Unified · Split

libraries/script-engine/src/ScriptCache.cpp+34−83
@@ -19,6 +19,7 @@ · 18 unmodified lines
1919 #include <QObject>
2020 #include <QThread>
2121 #include <QRegularExpression>
22+#include <QMetaEnum>
2223
2324 #include <assert.h>
2425 #include <SharedUtil.h>
@@ -27,12 +28,18 @@ · 2 unmodified lines
2728 #include "ScriptEngineLogging.h"
2829 #include <QtCore/QTimer>
2930
31+const QString ScriptCache::STATUS_INLINE { "Inline" };
32+const QString ScriptCache::STATUS_CACHED { "Cached" };
33+
3034 ScriptCache::ScriptCache(QObject* parent) {
3135 // nothing to do here...
3236 }
3337
3438 void ScriptCache::clearCache() {
3539 Lock lock(_containerLock);
40+ foreach(auto& url, _scriptCache.keys()) {
41+ qCDebug(scriptengine) << "clearing cache: " << url;
42+ }
3643 _scriptCache.clear();
3744 }
3845
@@ -49,35 +56,6 @@ void ScriptCache::clearATPScriptsFromCache() { · 10 unmodified lines
4956 }
5057 }
5158
52−QString ScriptCache::getScript(const QUrl& unnormalizedURL, ScriptUser* scriptUser, bool& isPending, bool reload) {
53− QUrl url = ResourceManager::normalizeURL(unnormalizedURL);
54− QString scriptContents;
55−
56− Lock lock(_containerLock);
57− if (_scriptCache.contains(url) && !reload) {
58− qCDebug(scriptengine) << "Found script in cache:" << url.toString();
59− scriptContents = _scriptCache[url];
60− lock.unlock();
61− scriptUser->scriptContentsAvailable(url, scriptContents);
62− isPending = false;
63− } else {
64− isPending = true;
65− bool alreadyWaiting = _scriptUsers.contains(url);
66− _scriptUsers.insert(url, scriptUser);
67− lock.unlock();
68−
69− if (alreadyWaiting) {
70− qCDebug(scriptengine) << "Already downloading script at:" << url.toString();
71− } else {
72− auto request = ResourceManager::createResourceRequest(nullptr, url);
73− request->setCacheEnabled(!reload);
74− connect(request, &ResourceRequest::finished, this, &ScriptCache::scriptDownloaded);
75− request->send();
76− }
77− }
78− return scriptContents;
79−}
80−
8159 void ScriptCache::deleteScript(const QUrl& unnormalizedURL) {
8260 QUrl url = ResourceManager::normalizeURL(unnormalizedURL);
8361 Lock lock(_containerLock);
@@ -87,37 +65,7 @@ void ScriptCache::deleteScript(const QUrl& unnormalizedURL) { · 3 unmodified lines
8765 }
8866 }
8967
90−void ScriptCache::scriptDownloaded() {
91− ResourceRequest* req = qobject_cast<ResourceRequest*>(sender());
92− QUrl url = req->getUrl();
93−
94− Lock lock(_containerLock);
95− QList<ScriptUser*> scriptUsers = _scriptUsers.values(url);
96− _scriptUsers.remove(url);
97−
98− if (!DependencyManager::get<ScriptEngines>()->isStopped()) {
99− if (req->getResult() == ResourceRequest::Success) {
100− auto scriptContents = req->getData();
101− _scriptCache[url] = scriptContents;
102− lock.unlock();
103− qCDebug(scriptengine) << "Done downloading script at:" << url.toString();
104−
105− foreach(ScriptUser* user, scriptUsers) {
106− user->scriptContentsAvailable(url, scriptContents);
107− }
108− } else {
109− lock.unlock();
110− qCWarning(scriptengine) << "Error loading script from URL " << url;
111− foreach(ScriptUser* user, scriptUsers) {
112− user->errorInLoadingScript(url);
113− }
114− }
115− }
116−
117− req->deleteLater();
118−}
119−
120−void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailableCallback contentAvailable, bool forceDownload) {
68+void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailableCallback contentAvailable, bool forceDownload, int maxRetries) {
12169 #ifdef THREAD_DEBUGGING
12270 qCDebug(scriptengine) << "ScriptCache::getScriptContents() on thread [" << QThread::currentThread() << "] expected thread [" << thread() << "]";
12371 #endif
@@ -128,7 +76,7 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable · 4 unmodified lines
12876 // entityScript use case)
12977 if (unnormalizedURL.scheme().isEmpty() &&
13078 scriptOrURL.simplified().replace(" ", "").contains(QRegularExpression(R"(\(function\([a-z]?[\w,]*\){)"))) {
131− contentAvailable(scriptOrURL, scriptOrURL, false, true);
79+ contentAvailable(scriptOrURL, scriptOrURL, false, true, STATUS_INLINE);
13280 return;
13381 }
13482
@@ -136,7 +84,7 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable · 1 unmodified line
13684 if (unnormalizedURL.scheme() == "javascript") {
13785 QString contents { scriptOrURL };
13886 contents.replace(QRegularExpression("^javascript:"), "");
139− contentAvailable(scriptOrURL, contents, false, true);
87+ contentAvailable(scriptOrURL, contents, false, true, STATUS_INLINE);
14088 return;
14189 }
14290
@@ -145,34 +93,32 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable · 2 unmodified lines
14593 auto scriptContent = _scriptCache[url];
14694 lock.unlock();
14795 qCDebug(scriptengine) << "Found script in cache:" << url.toString();
148− contentAvailable(url.toString(), scriptContent, true, true);
96+ contentAvailable(url.toString(), scriptContent, true, true, STATUS_CACHED);
14997 } else {
15098 auto& scriptRequest = _activeScriptRequests[url];
151−
15299 bool alreadyWaiting = scriptRequest.scriptUsers.size() > 0;
153100 scriptRequest.scriptUsers.push_back(contentAvailable);
154101
155102 lock.unlock();
156103
157104 if (alreadyWaiting) {
158− qCDebug(scriptengine) << "Already downloading script at:" << url.toString();
105+ qCDebug(scriptengine) << QString("Already downloading script at: %1 (retry: %2; scriptusers: %3)")
106+ .arg(url.toString()).arg(scriptRequest.numRetries).arg(scriptRequest.scriptUsers.size());
159107 } else {
108+ scriptRequest.maxRetries = maxRetries;
160109 #ifdef THREAD_DEBUGGING
161110 qCDebug(scriptengine) << "about to call: ResourceManager::createResourceRequest(this, url); on thread [" << QThread::currentThread() << "] expected thread [" << thread() << "]";
162111 #endif
163112 auto request = ResourceManager::createResourceRequest(nullptr, url);
164113 Q_ASSERT(request);
165114 request->setCacheEnabled(!forceDownload);
166− connect(request, &ResourceRequest::finished, this, &ScriptCache::scriptContentAvailable);
115+ connect(request, &ResourceRequest::finished, this, [=]{ scriptContentAvailable(maxRetries); });
167116 request->send();
168117 }
169118 }
170119 }
171120
172−static const int MAX_RETRIES = 5;
173−static int START_DELAY_BETWEEN_RETRIES = 200;
174−
175−void ScriptCache::scriptContentAvailable() {
121+void ScriptCache::scriptContentAvailable(int maxRetries) {
176122 #ifdef THREAD_DEBUGGING
177123 qCDebug(scriptengine) << "ScriptCache::scriptContentAvailable() on thread [" << QThread::currentThread() << "] expected thread [" << thread() << "]";
178124 #endif
@@ -181,7 +127,7 @@ void ScriptCache::scriptContentAvailable() { · 2 unmodified lines
181127
182128 QString scriptContent;
183129 std::vector<contentAvailableCallback> allCallbacks;
184− bool finished { false };
130+ QString status = QMetaEnum::fromType<ResourceRequest::Result>().valueToKey(req->getResult());
185131 bool success { false };
186132
187133 {
@@ -199,7 +145,6 @@ void ScriptCache::scriptContentAvailable() { · 11 unmodified lines
199145 _activeScriptRequests.remove(url);
200146
201147 _scriptCache[url] = scriptContent = req->getData();
202− finished = true;
203148 qCDebug(scriptengine) << "Done downloading script at:" << url.toString();
204149 } else {
205150 auto result = req->getResult();
@@ -207,16 +152,19 @@ void ScriptCache::scriptContentAvailable() { · 1 unmodified line
207152 result == ResourceRequest::AccessDenied ||
208153 result == ResourceRequest::InvalidURL ||
209154 result == ResourceRequest::NotFound ||
210− scriptRequest.numRetries >= MAX_RETRIES;
155+ scriptRequest.numRetries >= maxRetries;
211156
212157 if (!irrecoverable) {
213158 ++scriptRequest.numRetries;
214159
215− qCDebug(scriptengine) << "Script request failed: " << url;
160+ int timeout = exp(scriptRequest.numRetries) * ScriptRequest::START_DELAY_BETWEEN_RETRIES;
161+ int attempt = scriptRequest.numRetries;
162+ qCDebug(scriptengine) << QString("Script request failed [%1]: %2 (will retry %3 more times; attempt #%4 in %5ms...)")
163+ .arg(status).arg(url.toString()).arg(maxRetries - attempt + 1).arg(attempt).arg(timeout);
216164
217− int timeout = exp(scriptRequest.numRetries) * START_DELAY_BETWEEN_RETRIES;
218− QTimer::singleShot(timeout, this, [this, url]() {
219− qCDebug(scriptengine) << "Retrying script request: " << url;
165+ QTimer::singleShot(timeout, this, [this, url, attempt, maxRetries]() {
166+ qCDebug(scriptengine) << QString("Retrying script request [%1 / %2]: %3")
167+ .arg(attempt).arg(maxRetries).arg(url.toString());
220168
221169 auto request = ResourceManager::createResourceRequest(nullptr, url);
222170 Q_ASSERT(request);
@@ -224,7 +172,7 @@ void ScriptCache::scriptContentAvailable() { · 1 unmodified line
224172 // We've already made a request, so the cache must be disabled or it wasn't there, so enabling
225173 // it will do nothing.
226174 request->setCacheEnabled(false);
227− connect(request, &ResourceRequest::finished, this, &ScriptCache::scriptContentAvailable);
175+ connect(request, &ResourceRequest::finished, this, [=]{ scriptContentAvailable(maxRetries); });
228176 request->send();
229177 });
230178 } else {
@@ -232,9 +180,12 @@ void ScriptCache::scriptContentAvailable() { · 1 unmodified line
232180
233181 allCallbacks = scriptRequest.scriptUsers;
234182
235− scriptContent = _scriptCache[url];
236− finished = true;
237− qCWarning(scriptengine) << "Error loading script from URL " << url;
183+ if (_scriptCache.contains(url)) {
184+ scriptContent = _scriptCache[url];
185+ }
186+ _activeScriptRequests.remove(url);
187+ qCWarning(scriptengine) << "Error loading script from URL " << url << "(" << status <<")";
188+
238189 }
239190 }
240191 }
@@ -242,9 +193,9 @@ void ScriptCache::scriptContentAvailable() { · 1 unmodified line
242193
243194 req->deleteLater();
244195
245− if (finished && !DependencyManager::get<ScriptEngines>()->isStopped()) {
196+ if (allCallbacks.size() > 0 && !DependencyManager::get<ScriptEngines>()->isStopped()) {
246197 foreach(contentAvailableCallback thisCallback, allCallbacks) {
247− thisCallback(url.toString(), scriptContent, true, success);
198+ thisCallback(url.toString(), scriptContent, true, success, status);
248199 }
249200 }
250201 }