From ee5de175eb028d3b02e6f2b57997361827d1c7de Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 19 Sep 2019 16:56:55 -0700 Subject: [PATCH] Better monitoring of the resource loading in flights --- libraries/networking/src/ResourceCache.cpp | 15 +- libraries/networking/src/ResourceCache.h | 19 ++- scripts/developer/utilities/cache/cash.qml | 139 +++++++++++----- .../cache/cash/ResourceCacheInspector.qml | 155 ++++++++++++++---- .../utilities/lib/jet/qml/TaskListView.qml | 12 +- 5 files changed, 252 insertions(+), 88 deletions(-) diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index 36daf7709c..d29b4daf2f 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -325,7 +325,11 @@ QVariantList ResourceCache::getResourceList() { BLOCKING_INVOKE_METHOD(this, "getResourceList", Q_RETURN_ARG(QVariantList, list)); } else { - auto resources = _resources.uniqueKeys(); + QList resources; + { + QReadLocker locker(&_resourcesLock); + resources = _resources.uniqueKeys(); + } list.reserve(resources.size()); for (auto& resource : resources) { list << resource; @@ -379,6 +383,7 @@ QSharedPointer ResourceCache::getResource(const QUrl& url, const QUrl& } if (!resource) { + _numLoadingResources++; resource = createResource(url); resource->setExtra(extra); resource->setExtraHash(extraHash); @@ -386,6 +391,7 @@ QSharedPointer ResourceCache::getResource(const QUrl& url, const QUrl& resource->setCache(this); resource->moveToThread(qApp->thread()); connect(resource.data(), &Resource::updateSize, this, &ResourceCache::updateTotalSize); + connect(resource.data(), &Resource::finished, this, &ResourceCache::decreaseNumLoading); { QWriteLocker locker(&_resourcesLock); _resources[url].insert(extraHash, resource); @@ -513,6 +519,11 @@ void ResourceCache::updateTotalSize(const qint64& deltaSize) { emit dirty(); } +void ResourceCache::decreaseNumLoading() { + _numLoadingResources--; + emit dirty(); +} + QList> ResourceCache::getLoadingRequests() { return DependencyManager::get()->getLoadingRequests(); } @@ -530,7 +541,7 @@ bool ResourceCache::attemptRequest(QSharedPointer resource) { auto sharedItems = DependencyManager::get(); if (sharedItems->appendRequest(resource)) { - resource->makeRequest(); + resource->makeRequest(); return true; } return false; diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index 8026acb265..f7af951d44 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -201,6 +201,7 @@ class ResourceCache : public QObject { Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty) Q_PROPERTY(size_t numLoading READ getNumLoadingResources NOTIFY dirty) + Q_PROPERTY(size_t numPending READ getNumPendingResources NOTIFY dirty) public: @@ -208,10 +209,13 @@ public: size_t getSizeTotalResources() const { return _totalResourcesSize; } size_t getNumCachedResources() const { return _numUnusedResources; } size_t getSizeCachedResources() const { return _unusedResourcesSize; } - size_t getSizeCachedResources() const { return _unusedResourcesSize; } + size_t getNumPendingResources() const { return _numPendingResources; } + size_t getNumLoadingResources() const { return _numLoadingResources; } Q_INVOKABLE QVariantList getResourceList(); + Q_INVOKABLE void decreaseNumLoading(); + static void setRequestLimit(uint32_t limit); static uint32_t getRequestLimit() { return DependencyManager::get()->getRequestLimit(); } @@ -292,6 +296,8 @@ private: std::atomic _numTotalResources { 0 }; std::atomic _totalResourcesSize { 0 }; + std::atomic _numPendingResources{ 0 }; + std::atomic _numLoadingResources{ 0 }; // Cached resources QMap> _unusedResources; @@ -320,6 +326,12 @@ class ScriptableResourceCache : public QObject { Q_PROPERTY(size_t sizeTotal READ getSizeTotalResources NOTIFY dirty) Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty) + Q_PROPERTY(size_t numPending READ getNumPendingResources NOTIFY dirty) + Q_PROPERTY(size_t numLoading READ getNumLoadingResources NOTIFY dirty) + + Q_PROPERTY(size_t numGlobalQueriesPending READ getNumGlobalQueriesPending NOTIFY dirty) + Q_PROPERTY(size_t numGlobalQueriesLoading READ getNumGlobalQueriesLoading NOTIFY dirty) + public: ScriptableResourceCache(QSharedPointer resourceCache); @@ -393,6 +405,11 @@ private: size_t getSizeTotalResources() const { return _resourceCache->getSizeTotalResources(); } size_t getNumCachedResources() const { return _resourceCache->getNumCachedResources(); } size_t getSizeCachedResources() const { return _resourceCache->getSizeCachedResources(); } + size_t getNumPendingResources() const { return _resourceCache->getNumPendingResources(); } + size_t getNumLoadingResources() const { return _resourceCache->getNumLoadingResources(); } + + size_t getNumGlobalQueriesPending() const { return ResourceCache::getLoadingRequestCount(); } + size_t getNumGlobalQueriesLoading() const { return ResourceCache::getPendingRequestCount(); } }; /// Base class for resources. diff --git a/scripts/developer/utilities/cache/cash.qml b/scripts/developer/utilities/cache/cash.qml index 572fd481cb..e143a82e62 100644 --- a/scripts/developer/utilities/cache/cash.qml +++ b/scripts/developer/utilities/cache/cash.qml @@ -34,6 +34,99 @@ Rectangle { id: column width: parent.width + Prop.PropFolderPanel { + label: "Resource Queries Inspector" + isUnfold: true + panelFrameData: Component { + Column { + PlotPerf { + title: "Global Queries" + height: 80 + valueScale: 1 + valueUnit: "" + plots: [ + { + object: ModelCache, + prop: "numGlobalQueriesPending", + label: "Pending", + color: "#1AC567" + }, + { + object: ModelCache, + prop: "numGlobalQueriesLoading", + label: "Loading", + color: "#FEC567" + }, + { + object: ModelCache, + prop: "numLoading", + label: "Model Loading", + color: "#C5FE67" + } + ] + } + } + } + } + + Prop.PropFolderPanel { + label: "Cache Inspectors" + isUnfold: true + panelFrameData: Component { + Column { + Prop.PropButton { + text: "Model" + onClicked: { + sendToScript({method: "openModelCacheInspector"}); + } + width:column.width + } + Prop.PropButton { + text: "Material" + onClicked: { + sendToScript({method: "openMaterialCacheInspector"}); + } + width:column.width + } + Prop.PropButton { + text: "Texture" + onClicked: { + sendToScript({method: "openTextureCacheInspector"}); + } + width:column.width + } + Prop.PropButton { + text: "Animation" + onClicked: { + sendToScript({method: "openAnimationCacheInspector"}); + } + width:column.width + } + Prop.PropButton { + text: "Sound" + onClicked: { + sendToScript({method: "openSoundCacheInspector"}); + } + width:column.width + } + + Prop.PropScalar { + label: "Texture Loading" + object: TextureCache + property: "numLoading" + integral: true + readOnly: true + } + Prop.PropScalar { + label: "Model Loading" + object: ModelCache + property: "numLoading" + integral: true + readOnly: true + } + } + } + } Prop.PropFolderPanel { label: "Stats" isUnfold: true @@ -81,51 +174,7 @@ Rectangle { color: "#FFB4EF" } ] - } - }} - } - - Prop.PropFolderPanel { - label: "Cache Inspectors" - isUnfold: true - panelFrameData: Component { - Column { - Prop.PropButton { - text: "Model" - onClicked: { - sendToScript({method: "openModelCacheInspector"}); - } - width:column.width - } - Prop.PropButton { - text: "Material" - onClicked: { - sendToScript({method: "openMaterialCacheInspector"}); - } - width:column.width - } - Prop.PropButton { - text: "Texture" - onClicked: { - sendToScript({method: "openTextureCacheInspector"}); - } - width:column.width - } - Prop.PropButton { - text: "Animation" - onClicked: { - sendToScript({method: "openAnimationCacheInspector"}); - } - width:column.width - } - Prop.PropButton { - text: "Sound" - onClicked: { - sendToScript({method: "openSoundCacheInspector"}); - } - width:column.width - } - } + }} } } } diff --git a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml index a8eeee2d27..159773b06e 100644 --- a/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml +++ b/scripts/developer/utilities/cache/cash/ResourceCacheInspector.qml @@ -7,7 +7,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html // -import QtQuick 2.7 +import QtQuick 2.12 import QtQuick.Controls 2.5 import QtQuick.Layouts 1.3 @@ -36,18 +36,39 @@ Item { if (cache !== undefined) { theList = cache.getResourceList(); } else { - theList = [{"name": "ResourceCacheInspector.cache is undefined"}]; + theList = ["ResourceCacheInspector.cache is undefined"]; } - return theList; + var theListString = new Array(theList.length) + for (var i in theList) { + theListString[i] = (theList[i].toString()) + } + return theListString; } function resetItemListFromCache() { - resourceItemsModel.resetItemList(fetchItemsList()) + resetItemList(fetchItemsList()) } - function updateItemListFromCache() { - resourceItemsModel.updateItemList(fetchItemsList()) + + property var needFreshList : false + + function updateItemListFromCache() { + needFreshList = true } + Timer { + interval: 1000; running: true; repeat: true + onTriggered: pullFreshValues() + } + + function pullFreshValues() { + if (needFreshList) { + console.log("Updating " + cacheResourceName + "cache list") + updateItemList(fetchItemsList()) + needFreshList = false + } + } + + Column { id: header @@ -77,7 +98,7 @@ Item { property: "numTotal" integral: true readOnly: true - onSourceValueVarChanged: { console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;updateItemListFromCache() } + onSourceValueVarChanged: { /*console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;*/updateItemListFromCache() } } Prop.PropScalar { id: cachedCount @@ -88,7 +109,7 @@ Item { property: "numCached" integral: true readOnly: true - onSourceValueVarChanged: { console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;updateItemListFromCache() } + onSourceValueVarChanged: { /*console.log( root.cacheResourceName + " NumCached Value Changed!!!!");*/updateItemListFromCache() } } height: totalCount.height } @@ -97,26 +118,81 @@ Item { ListModel { id: resourceItemsModel - - function packItemEntry(item) { - var some_uri = Qt.resolvedUrl(item) - - return { "name": item, "url": some_uri} + } + property var currentItemsList: new Array(); + + function packItemEntry(item) { + var entry = { "name": "", "root": "", "path": "", "base": "", "url": item} + if (item.length > 0) { + var rootPos = item.search("://") + entry.root = item.substring(0, rootPos) + if (rootPos >= 0) rootPos += 3 + entry.path = item.substring(rootPos, item.length) + var splitted = entry.path.split('/') + entry.name = splitted[splitted.length - 1] + entry.base = splitted[0] } - - function resetItemList(itemList) { - resourceItemsModel.clear() - for (var i in itemList) { - resourceItemsModel.append(packItemEntry(itemList[i])) - } + return entry + } + + function resetItemList(itemList) { + currentItemsList = [] + resourceItemsModel.clear() + for (var i in itemList) { + var item = itemList[i] + currentItemsList.push(item) + resourceItemsModel.append(packItemEntry(item)) + } + } + + function updateItemList(newItemList) { + resetItemList(newItemList) +/* + var nextListLength = (currentItemList.length < newItemList.length ? newItemList.length : currentItemList.length ) + var nextList = new Array(nextListLength) + + var addedList = [] + var removedList = [] + var movedList = [] + + for (var i in currentItemList) { + var item = currentItemList[i] + var foundPos = newItemList.findIndex(item) + if (foundPos == i) { + newList[i] = item + newItemList[i] = 0 + } else if (foundPos == -1) { + removedList.push(i) + } else { + movedList.push([i,foundPos]) + } } - function updateItemList(itemList) { - resourceItemsModel.clear() - for (var i in itemList) { - resourceItemsModel.append(packItemEntry(itemList[i])) - } + for (var i in newItemList) { + var item = newItemList[i] + if (item != 0) { + var foundPos = currentItemList.findIndex(item) + if (foundPos == -1) { + addedList.push(item) + } + } } + + + for (var i in itemList) { + newList[i] = itemList[i] + } + + + + +*/ + /*currentItemsList.clear() + resourceItemsModel.clear() + for (var i in itemList) { + currentItemsList.append(itemList[i].toString()) + resourceItemsModel.append(packItemEntry(currentItemsList[i])) + } */ } Component { @@ -131,24 +207,35 @@ Item { size:8 } Prop.PropLabel { - text: JSON.stringify(model.url) + text: model.root + width: 30 } - /* Prop.PropLabel { - text: model.url - }*/ + Prop.PropSplitter { + size:8 + } + Prop.PropLabel { + text: model.base + width: 60 + } + Prop.PropSplitter { + size:8 + } + Prop.PropLabel { + text: model.name + } + } } - ScrollView { + ListView { anchors.top: header.bottom anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right clip: true - ListView { - id: listView - model: resourceItemsModel - delegate: resouceItemDelegate - } + + id: listView + model: resourceItemsModel + delegate: resouceItemDelegate } } diff --git a/scripts/developer/utilities/lib/jet/qml/TaskListView.qml b/scripts/developer/utilities/lib/jet/qml/TaskListView.qml index e2576fe783..a935163bd9 100644 --- a/scripts/developer/utilities/lib/jet/qml/TaskListView.qml +++ b/scripts/developer/utilities/lib/jet/qml/TaskListView.qml @@ -91,12 +91,12 @@ Rectangle { } } - Original.ScrollView { + ListView { anchors.fill: parent - ListView { - id: theView - model: jobsModel - delegate: objRecursiveDelegate - } + + id: theView + model: jobsModel + delegate: objRecursiveDelegate } + } \ No newline at end of file