Better monitoring of the resource loading in flights

This commit is contained in:
Sam Gateau 2019-09-19 16:56:55 -07:00
parent 6154611b05
commit ee5de175eb
5 changed files with 252 additions and 88 deletions

View file

@ -325,7 +325,11 @@ QVariantList ResourceCache::getResourceList() {
BLOCKING_INVOKE_METHOD(this, "getResourceList", BLOCKING_INVOKE_METHOD(this, "getResourceList",
Q_RETURN_ARG(QVariantList, list)); Q_RETURN_ARG(QVariantList, list));
} else { } else {
auto resources = _resources.uniqueKeys(); QList<QUrl> resources;
{
QReadLocker locker(&_resourcesLock);
resources = _resources.uniqueKeys();
}
list.reserve(resources.size()); list.reserve(resources.size());
for (auto& resource : resources) { for (auto& resource : resources) {
list << resource; list << resource;
@ -379,6 +383,7 @@ QSharedPointer<Resource> ResourceCache::getResource(const QUrl& url, const QUrl&
} }
if (!resource) { if (!resource) {
_numLoadingResources++;
resource = createResource(url); resource = createResource(url);
resource->setExtra(extra); resource->setExtra(extra);
resource->setExtraHash(extraHash); resource->setExtraHash(extraHash);
@ -386,6 +391,7 @@ QSharedPointer<Resource> ResourceCache::getResource(const QUrl& url, const QUrl&
resource->setCache(this); resource->setCache(this);
resource->moveToThread(qApp->thread()); resource->moveToThread(qApp->thread());
connect(resource.data(), &Resource::updateSize, this, &ResourceCache::updateTotalSize); connect(resource.data(), &Resource::updateSize, this, &ResourceCache::updateTotalSize);
connect(resource.data(), &Resource::finished, this, &ResourceCache::decreaseNumLoading);
{ {
QWriteLocker locker(&_resourcesLock); QWriteLocker locker(&_resourcesLock);
_resources[url].insert(extraHash, resource); _resources[url].insert(extraHash, resource);
@ -513,6 +519,11 @@ void ResourceCache::updateTotalSize(const qint64& deltaSize) {
emit dirty(); emit dirty();
} }
void ResourceCache::decreaseNumLoading() {
_numLoadingResources--;
emit dirty();
}
QList<QSharedPointer<Resource>> ResourceCache::getLoadingRequests() { QList<QSharedPointer<Resource>> ResourceCache::getLoadingRequests() {
return DependencyManager::get<ResourceCacheSharedItems>()->getLoadingRequests(); return DependencyManager::get<ResourceCacheSharedItems>()->getLoadingRequests();
} }
@ -530,7 +541,7 @@ bool ResourceCache::attemptRequest(QSharedPointer<Resource> resource) {
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>(); auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
if (sharedItems->appendRequest(resource)) { if (sharedItems->appendRequest(resource)) {
resource->makeRequest(); resource->makeRequest();
return true; return true;
} }
return false; return false;

View file

@ -201,6 +201,7 @@ class ResourceCache : public QObject {
Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty) Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty)
Q_PROPERTY(size_t numLoading READ getNumLoadingResources NOTIFY dirty) Q_PROPERTY(size_t numLoading READ getNumLoadingResources NOTIFY dirty)
Q_PROPERTY(size_t numPending READ getNumPendingResources NOTIFY dirty)
public: public:
@ -208,10 +209,13 @@ public:
size_t getSizeTotalResources() const { return _totalResourcesSize; } size_t getSizeTotalResources() const { return _totalResourcesSize; }
size_t getNumCachedResources() const { return _numUnusedResources; } size_t getNumCachedResources() const { return _numUnusedResources; }
size_t getSizeCachedResources() const { return _unusedResourcesSize; } 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 QVariantList getResourceList();
Q_INVOKABLE void decreaseNumLoading();
static void setRequestLimit(uint32_t limit); static void setRequestLimit(uint32_t limit);
static uint32_t getRequestLimit() { return DependencyManager::get<ResourceCacheSharedItems>()->getRequestLimit(); } static uint32_t getRequestLimit() { return DependencyManager::get<ResourceCacheSharedItems>()->getRequestLimit(); }
@ -292,6 +296,8 @@ private:
std::atomic<size_t> _numTotalResources { 0 }; std::atomic<size_t> _numTotalResources { 0 };
std::atomic<qint64> _totalResourcesSize { 0 }; std::atomic<qint64> _totalResourcesSize { 0 };
std::atomic<size_t> _numPendingResources{ 0 };
std::atomic<size_t> _numLoadingResources{ 0 };
// Cached resources // Cached resources
QMap<int, QSharedPointer<Resource>> _unusedResources; QMap<int, QSharedPointer<Resource>> _unusedResources;
@ -320,6 +326,12 @@ class ScriptableResourceCache : public QObject {
Q_PROPERTY(size_t sizeTotal READ getSizeTotalResources NOTIFY dirty) Q_PROPERTY(size_t sizeTotal READ getSizeTotalResources NOTIFY dirty)
Q_PROPERTY(size_t sizeCached READ getSizeCachedResources 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: public:
ScriptableResourceCache(QSharedPointer<ResourceCache> resourceCache); ScriptableResourceCache(QSharedPointer<ResourceCache> resourceCache);
@ -393,6 +405,11 @@ private:
size_t getSizeTotalResources() const { return _resourceCache->getSizeTotalResources(); } size_t getSizeTotalResources() const { return _resourceCache->getSizeTotalResources(); }
size_t getNumCachedResources() const { return _resourceCache->getNumCachedResources(); } size_t getNumCachedResources() const { return _resourceCache->getNumCachedResources(); }
size_t getSizeCachedResources() const { return _resourceCache->getSizeCachedResources(); } 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. /// Base class for resources.

View file

@ -34,6 +34,99 @@ Rectangle {
id: column id: column
width: parent.width 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 { Prop.PropFolderPanel {
label: "Stats" label: "Stats"
isUnfold: true isUnfold: true
@ -81,51 +174,7 @@ Rectangle {
color: "#FFB4EF" 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
}
}
} }
} }
} }

View file

@ -7,7 +7,7 @@
// Distributed under the Apache License, Version 2.0. // Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html // 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.Controls 2.5
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
@ -36,18 +36,39 @@ Item {
if (cache !== undefined) { if (cache !== undefined) {
theList = cache.getResourceList(); theList = cache.getResourceList();
} else { } 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() { function resetItemListFromCache() {
resourceItemsModel.resetItemList(fetchItemsList()) resetItemList(fetchItemsList())
} }
property var needFreshList : false
function updateItemListFromCache() { function updateItemListFromCache() {
resourceItemsModel.updateItemList(fetchItemsList()) 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 { Column {
id: header id: header
@ -77,7 +98,7 @@ Item {
property: "numTotal" property: "numTotal"
integral: true integral: true
readOnly: true readOnly: true
onSourceValueVarChanged: { console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;updateItemListFromCache() } onSourceValueVarChanged: { /*console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;*/updateItemListFromCache() }
} }
Prop.PropScalar { Prop.PropScalar {
id: cachedCount id: cachedCount
@ -88,7 +109,7 @@ Item {
property: "numCached" property: "numCached"
integral: true integral: true
readOnly: true readOnly: true
onSourceValueVarChanged: { console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;updateItemListFromCache() } onSourceValueVarChanged: { /*console.log( root.cacheResourceName + " NumCached Value Changed!!!!");*/updateItemListFromCache() }
} }
height: totalCount.height height: totalCount.height
} }
@ -97,26 +118,81 @@ Item {
ListModel { ListModel {
id: resourceItemsModel id: resourceItemsModel
}
property var currentItemsList: new Array();
function packItemEntry(item) { function packItemEntry(item) {
var some_uri = Qt.resolvedUrl(item) var entry = { "name": "", "root": "", "path": "", "base": "", "url": item}
if (item.length > 0) {
return { "name": item, "url": some_uri} 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]
} }
return entry
}
function resetItemList(itemList) { function resetItemList(itemList) {
resourceItemsModel.clear() currentItemsList = []
for (var i in itemList) { resourceItemsModel.clear()
resourceItemsModel.append(packItemEntry(itemList[i])) 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) { for (var i in newItemList) {
resourceItemsModel.clear() var item = newItemList[i]
for (var i in itemList) { if (item != 0) {
resourceItemsModel.append(packItemEntry(itemList[i])) 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 { Component {
@ -131,24 +207,35 @@ Item {
size:8 size:8
} }
Prop.PropLabel { Prop.PropLabel {
text: JSON.stringify(model.url) text: model.root
width: 30
} }
/* Prop.PropLabel { Prop.PropSplitter {
text: model.url 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.top: header.bottom
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
clip: true clip: true
ListView {
id: listView id: listView
model: resourceItemsModel model: resourceItemsModel
delegate: resouceItemDelegate delegate: resouceItemDelegate
}
} }
} }

View file

@ -91,12 +91,12 @@ Rectangle {
} }
} }
Original.ScrollView { ListView {
anchors.fill: parent anchors.fill: parent
ListView {
id: theView id: theView
model: jobsModel model: jobsModel
delegate: objRecursiveDelegate delegate: objRecursiveDelegate
}
} }
} }