summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2023-09-14 18:42:42 +0300
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2023-09-14 18:51:33 +0300
commitfa47e4402b7925a45c5fec9fb9d92fb5e34a589e (patch)
tree6056c5c4b0ad333464fd664751d9ea1ce5255fa6
parentb5c745185f4e3d2d215b5a171dc96a57d01eb079 (diff)
SL-20285 Sturdier cof and fixed link fetching
-rw-r--r--indra/newview/llaisapi.cpp62
-rw-r--r--indra/newview/llaisapi.h2
-rw-r--r--indra/newview/llappearancemgr.cpp58
-rw-r--r--indra/newview/llattachmentsmgr.cpp1
-rw-r--r--indra/newview/llinventoryobserver.cpp19
5 files changed, 70 insertions, 72 deletions
diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp
index d8d30037c8..087cfb8d48 100644
--- a/indra/newview/llaisapi.cpp
+++ b/indra/newview/llaisapi.cpp
@@ -741,8 +741,10 @@ void AISAPI::FetchCategoryLinks(const LLUUID &catId, completion_t callback)
(&LLCoreHttpUtil::HttpCoroutineAdapter::getAndSuspend),
_1, _2, _3, _5, _6);
+ LLSD body;
+ body["depth"] = 0;
LLCoprocedureManager::CoProcedure_t proc(
- boost::bind(&AISAPI::InvokeAISCommandCoro, _1, getFn, url, LLUUID::null, LLSD(), callback, FETCHCATEGORYLINKS));
+ boost::bind(&AISAPI::InvokeAISCommandCoro, _1, getFn, url, LLUUID::null, body, callback, FETCHCATEGORYLINKS));
EnqueueAISCommand("FetchCategoryLinks", proc);
}
@@ -1337,13 +1339,6 @@ void AISUpdate::parseCategory(const LLSD& category_map, S32 depth)
return;
}
- // Check descendent count first, as it may be needed
- // to populate newly created categories
- if (category_map.has("_embedded"))
- {
- parseDescendentCount(category_id, category_map["_embedded"]);
- }
-
LLPointer<LLViewerInventoryCategory> new_cat;
if (curr_cat)
{
@@ -1366,6 +1361,13 @@ void AISUpdate::parseCategory(const LLSD& category_map, S32 depth)
// *NOTE: unpackMessage does not unpack version or descendent count.
if (rv)
{
+ // Check descendent count first, as it may be needed
+ // to populate newly created categories
+ if (category_map.has("_embedded"))
+ {
+ parseDescendentCount(category_id, new_cat->getPreferredType(), category_map["_embedded"]);
+ }
+
if (mFetch)
{
uuid_int_map_t::const_iterator lookup_it = mCatDescendentsKnown.find(category_id);
@@ -1379,10 +1381,20 @@ void AISUpdate::parseCategory(const LLSD& category_map, S32 depth)
// set version only if we are sure this update has full data and embeded items
// since viewer uses version to decide if folder and content still need fetching
if (version > LLViewerInventoryCategory::VERSION_UNKNOWN
- && (depth >= 0 || (curr_cat && curr_cat->getVersion() > LLViewerInventoryCategory::VERSION_UNKNOWN)))
+ && depth >= 0)
{
- LL_DEBUGS("Inventory") << "Setting version to " << version
- << " for category " << category_id << LL_ENDL;
+ if (curr_cat && curr_cat->getVersion() > version)
+ {
+ LL_WARNS("Inventory") << "Version was " << curr_cat->getVersion()
+ << ", but fetch returned version " << version
+ << " for category " << category_id << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("Inventory") << "Setting version to " << version
+ << " for category " << category_id << LL_ENDL;
+ }
+
new_cat->setVersion(version);
}
}
@@ -1445,27 +1457,21 @@ void AISUpdate::parseCategory(const LLSD& category_map, S32 depth)
}
}
-void AISUpdate::parseDescendentCount(const LLUUID& category_id, const LLSD& embedded)
+void AISUpdate::parseDescendentCount(const LLUUID& category_id, LLFolderType::EType type, const LLSD& embedded)
{
- if (mType == AISAPI::FETCHCOF)
+ // We can only determine true descendent count if this contains all descendent types.
+ if (embedded.has("categories") &&
+ embedded.has("links") &&
+ embedded.has("items"))
{
- // contains only links
- if (embedded.has("links"))
- {
- mCatDescendentsKnown[category_id] = embedded["links"].size();
- }
+ mCatDescendentsKnown[category_id] = embedded["categories"].size();
+ mCatDescendentsKnown[category_id] += embedded["links"].size();
+ mCatDescendentsKnown[category_id] += embedded["items"].size();
}
- else
+ else if (mFetch && embedded.has("links") && (type == LLFolderType::FT_CURRENT_OUTFIT || type == LLFolderType::FT_OUTFIT))
{
- // We can only determine true descendent count if this contains all descendent types.
- if (embedded.has("categories") &&
- embedded.has("links") &&
- embedded.has("items"))
- {
- mCatDescendentsKnown[category_id] = embedded["categories"].size();
- mCatDescendentsKnown[category_id] += embedded["links"].size();
- mCatDescendentsKnown[category_id] += embedded["items"].size();
- }
+ // COF and outfits contain links only
+ mCatDescendentsKnown[category_id] = embedded["links"].size();
}
}
diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h
index 53c74ae078..0fdf4a0b74 100644
--- a/indra/newview/llaisapi.h
+++ b/indra/newview/llaisapi.h
@@ -118,7 +118,7 @@ public:
void parseLink(const LLSD& link_map, S32 depth);
void parseItem(const LLSD& link_map);
void parseCategory(const LLSD& link_map, S32 depth);
- void parseDescendentCount(const LLUUID& category_id, const LLSD& embedded);
+ void parseDescendentCount(const LLUUID& category_id, LLFolderType::EType type, const LLSD& embedded);
void parseEmbedded(const LLSD& embedded, S32 depth);
void parseEmbeddedLinks(const LLSD& links, S32 depth);
void parseEmbeddedItems(const LLSD& items);
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 80ef5e3bae..876ae23e62 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -4446,7 +4446,7 @@ public:
{
LLViewerInventoryCategory* cat = gInventory.getCategory(*it);
if (!cat) continue;
- if (!isCategoryComplete(cat))
+ if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)
{
// CHECK IT: isCategoryComplete() checks both version and descendant count but
// fetch() only works for Unknown version and doesn't care about descentants,
@@ -4456,6 +4456,12 @@ public:
cat->fetch(); //blindly fetch it without seeing if anything else is fetching it.
mIncomplete.push_back(*it); //Add to list of things being downloaded for this observer.
}
+ else if (!isCategoryComplete(cat))
+ {
+ LL_DEBUGS("Inventory") << "Categoty " << *it << " incomplete despite having version" << LL_ENDL;
+ LLInventoryModelBackgroundFetch::instance().scheduleFolderFetch(*it, true);
+ mIncomplete.push_back(*it);
+ }
else if (ais3)
{
LLInventoryModel::cat_array_t* cats;
@@ -4484,10 +4490,7 @@ public:
if (incomplete_count > MAX_INDIVIDUAL_FETCH
|| (incomplete_count > 1 && complete_count == 0))
{
- // To prevent premature removal from mIncomplete and
- // since we are doing a full refetch anyway, mark unknown
- cat->setVersion(LLViewerInventoryCategory::VERSION_UNKNOWN);
- cat->fetch();
+ LLInventoryModelBackgroundFetch::instance().scheduleFolderFetch(*it, true);
mIncomplete.push_back(*it);
}
else
@@ -4496,6 +4499,7 @@ public:
mComplete.push_back(*it);
}
}
+ // else should have been handled by isCategoryComplete
}
else
{
@@ -4519,13 +4523,11 @@ public:
// What we do here is get the complete information on the
// items in the requested category, and set up an observer
// that will wait for that to happen.
- LLInventoryModel::cat_array_t cat_array;
- LLInventoryModel::item_array_t item_array;
- gInventory.collectDescendents(mComplete.front(),
- cat_array,
- item_array,
- LLInventoryModel::EXCLUDE_TRASH);
- S32 count = item_array.size();
+ LLInventoryModel::cat_array_t* cats;
+ LLInventoryModel::item_array_t* items;
+ gInventory.getDirectDescendentsOf(mComplete.front(), cats, items);
+
+ S32 count = items->size();
if(!count)
{
LL_WARNS() << "Nothing fetched in category " << mComplete.front()
@@ -4537,11 +4539,13 @@ public:
return;
}
- LL_INFOS() << "stage1 got " << item_array.size() << " items, passing to stage2 " << LL_ENDL;
+ LLViewerInventoryCategory* cat = gInventory.getCategory(mComplete.front());
+ S32 version = cat ? cat->getVersion() : -2;
+ LL_INFOS() << "stage1, category " << mComplete.front() << " got " << count << " items, version " << version << " passing to stage2 " << LL_ENDL;
uuid_vec_t ids;
for(S32 i = 0; i < count; ++i)
{
- ids.push_back(item_array.at(i)->getUUID());
+ ids.push_back(items->at(i)->getUUID());
}
gInventory.removeObserver(this);
@@ -4570,14 +4574,14 @@ void callAfterCOFFetch(nullary_func_t cb)
{
LLUUID cat_id = LLAppearanceMgr::instance().getCOF();
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
- if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)
+
+ if (AISAPI::isAvailable())
{
- if (AISAPI::isAvailable())
- {
- // Mark cof (update timer) so that background fetch won't request it
- cat->setFetching(LLViewerInventoryCategory::FETCH_RECURSIVE);
- // Assume that we have no relevant cache. Fetch cof, and items cof's links point to.
- AISAPI::FetchCOF([cb](const LLUUID& id)
+ // Mark cof (update timer) so that background fetch won't request it
+ cat->setFetching(LLViewerInventoryCategory::FETCH_RECURSIVE);
+ // For reliability assume that we have no relevant cache, so
+ // fetch cof along with items cof's links point to.
+ AISAPI::FetchCOF([cb](const LLUUID& id)
{
cb();
LLUUID cat_id = LLAppearanceMgr::instance().getCOF();
@@ -4587,18 +4591,12 @@ void callAfterCOFFetch(nullary_func_t cb)
cat->setFetching(LLViewerInventoryCategory::FETCH_NONE);
}
});
- }
- else
- {
- LL_WARNS() << "AIS API v3 not available, can't use AISAPI::FetchCOF" << LL_ENDL;
- // startup should have marked folder as fetching, remove that
- cat->setFetching(LLViewerInventoryCategory::FETCH_NONE);
- callAfterCategoryFetch(cat_id, cb);
- }
}
else
{
- // Assume that cache is present. Process like a normal folder.
+ LL_INFOS() << "AIS API v3 not available, using callAfterCategoryFetch" << LL_ENDL;
+ // startup should have marked folder as fetching, remove that
+ cat->setFetching(LLViewerInventoryCategory::FETCH_NONE);
callAfterCategoryFetch(cat_id, cb);
}
}
diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp
index bcd89cf8db..d3fce306bc 100644
--- a/indra/newview/llattachmentsmgr.cpp
+++ b/indra/newview/llattachmentsmgr.cpp
@@ -243,6 +243,7 @@ void LLAttachmentsMgr::linkRecentlyArrivedAttachments()
if (LLAppearanceMgr::instance().getCOFVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)
{
// Wait for cof to load
+ LL_DEBUGS_ONCE("Avatar") << "Received atachments, but cof isn't loaded yet, postponing processing" << LL_ENDL;
return;
}
diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp
index 227d4285eb..51be44bef4 100644
--- a/indra/newview/llinventoryobserver.cpp
+++ b/indra/newview/llinventoryobserver.cpp
@@ -334,21 +334,14 @@ void LLInventoryFetchItemsObserver::startFetch()
if (aisv3)
{
- const S32 MAX_INDIVIDUAL_REQUESTS = 10;
+ const S32 MAX_INDIVIDUAL_REQUESTS = 7;
for (requests_by_folders_t::value_type &folder : requests)
{
- LLViewerInventoryCategory* cat = gInventory.getCategory(folder.first);
if (folder.second.size() > MAX_INDIVIDUAL_REQUESTS)
{
// requesting one by one will take a while
// do whole folder
- if (cat)
- {
- // Either drop version or use scheduleFolderFetch to force-fetch
- // otherwise background fetch will ignore folders with set version
- cat->setVersion(LLViewerInventoryCategory::VERSION_UNKNOWN);
- }
- LLInventoryModelBackgroundFetch::getInstance()->start(folder.first);
+ LLInventoryModelBackgroundFetch::getInstance()->scheduleFolderFetch(folder.first, true);
}
else
{
@@ -360,12 +353,11 @@ void LLInventoryFetchItemsObserver::startFetch()
// start fetching whole folder since it's not ready either way
cat->fetch();
}
- else if (cat->getViewerDescendentCount() <= folder.second.size())
+ else if (cat->getViewerDescendentCount() <= folder.second.size()
+ || cat->getDescendentCount() <= folder.second.size())
{
// Start fetching whole folder since we need all items
- // Drop version or use scheduleFolderFetch
- cat->setVersion(LLViewerInventoryCategory::VERSION_UNKNOWN);
- cat->fetch();
+ LLInventoryModelBackgroundFetch::getInstance()->scheduleFolderFetch(folder.first, true);
}
else
@@ -382,6 +374,7 @@ void LLInventoryFetchItemsObserver::startFetch()
// Isn't supposed to happen? We should have all folders
// and if item exists, folder is supposed to exist as well.
llassert(false);
+ LL_WARNS("Inventory") << "Missing folder: " << folder.first << " fetching items individually" << LL_ENDL;
// get items one by one
for (LLUUID &item_id : folder.second)