From ac145cb21f382b8eab9f770cecfa23ea9d58aac6 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 14 Mar 2023 23:21:26 +0200 Subject: SL-18629 WIP Fetch Inventory using AIS caps --- indra/newview/llinventorymodelbackgroundfetch.cpp | 214 ++++++++++++++++++---- 1 file changed, 178 insertions(+), 36 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 406c8b89d0..1905a9c9a4 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -27,6 +27,7 @@ #include "llviewerprecompiledheaders.h" #include "llinventorymodelbackgroundfetch.h" +#include "llaisapi.h" #include "llagent.h" #include "llappviewer.h" #include "llcallbacklist.h" @@ -184,12 +185,12 @@ const char * const LOG_INV("Inventory"); ///---------------------------------------------------------------------------- LLInventoryModelBackgroundFetch::LLInventoryModelBackgroundFetch(): - mBackgroundFetchActive(FALSE), + mBackgroundFetchActive(false), mFolderFetchActive(false), mFetchCount(0), - mAllFoldersFetched(FALSE), - mRecursiveInventoryFetchStarted(FALSE), - mRecursiveLibraryFetchStarted(FALSE), + mAllFoldersFetched(false), + mRecursiveInventoryFetchStarted(false), + mRecursiveLibraryFetchStarted(false), mMinTimeBetweenFetches(0.3f) {} @@ -241,17 +242,17 @@ BOOL LLInventoryModelBackgroundFetch::folderFetchActive() const return mFolderFetchActive; } -void LLInventoryModelBackgroundFetch::addRequestAtFront(const LLUUID & id, BOOL recursive, bool is_category) +void LLInventoryModelBackgroundFetch::addRequestAtFront(const LLUUID & id, bool recursive, bool is_category) { mFetchQueue.push_front(FetchQueueInfo(id, recursive, is_category)); } -void LLInventoryModelBackgroundFetch::addRequestAtBack(const LLUUID & id, BOOL recursive, bool is_category) +void LLInventoryModelBackgroundFetch::addRequestAtBack(const LLUUID & id, bool recursive, bool is_category) { mFetchQueue.push_back(FetchQueueInfo(id, recursive, is_category)); } -void LLInventoryModelBackgroundFetch::start(const LLUUID& id, BOOL recursive) +void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) { LLViewerInventoryCategory * cat(gInventory.getCategory(id)); @@ -260,31 +261,57 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, BOOL recursive) // it's a folder, do a bulk fetch LL_DEBUGS(LOG_INV) << "Start fetching category: " << id << ", recursive: " << recursive << LL_ENDL; - mBackgroundFetchActive = TRUE; + mBackgroundFetchActive = true; mFolderFetchActive = true; if (id.isNull()) { if (! mRecursiveInventoryFetchStarted) { mRecursiveInventoryFetchStarted |= recursive; - mFetchQueue.push_back(FetchQueueInfo(gInventory.getRootFolderID(), recursive)); + if (recursive && AISAPI::isAvailable()) + { + mRecursiveFetchQueue.push_back(FetchQueueInfo(gInventory.getRootFolderID(), recursive)); + } + else + { + mFetchQueue.push_back(FetchQueueInfo(gInventory.getRootFolderID(), recursive)); + } gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } if (! mRecursiveLibraryFetchStarted) { mRecursiveLibraryFetchStarted |= recursive; - mFetchQueue.push_back(FetchQueueInfo(gInventory.getLibraryRootFolderID(), recursive)); + if (recursive && AISAPI::isAvailable()) + { + mRecursiveFetchQueue.push_back(FetchQueueInfo(gInventory.getLibraryRootFolderID(), recursive)); + } + else + { + mFetchQueue.push_back(FetchQueueInfo(gInventory.getLibraryRootFolderID(), recursive)); + } gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } } else { - // Specific folder requests go to front of queue. - if (mFetchQueue.empty() || mFetchQueue.front().mUUID != id) - { - mFetchQueue.push_front(FetchQueueInfo(id, recursive)); - gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); - } + if (recursive && AISAPI::isAvailable()) + { + // AIS does depth requests, recursive requests will need to be prioritizes + if (mRecursiveFetchQueue.empty() || mRecursiveFetchQueue.back().mUUID != id) + { + mRecursiveFetchQueue.push_back(FetchQueueInfo(id, recursive)); + gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); + } + } + else + { + // Specific folder requests go to front of queue. + if (mFetchQueue.empty() || mFetchQueue.front().mUUID != id) + { + mFetchQueue.push_front(FetchQueueInfo(id, recursive)); + gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); + } + } if (id == gInventory.getLibraryRootFolderID()) { mRecursiveLibraryFetchStarted |= recursive; @@ -299,7 +326,7 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, BOOL recursive) { if (! itemp->mIsComplete && (mFetchQueue.empty() || mFetchQueue.front().mUUID != id)) { - mBackgroundFetchActive = TRUE; + mBackgroundFetchActive = true; mFetchQueue.push_front(FetchQueueInfo(id, false, false)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); @@ -309,9 +336,9 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, BOOL recursive) void LLInventoryModelBackgroundFetch::findLostItems() { - mBackgroundFetchActive = TRUE; + mBackgroundFetchActive = true; mFolderFetchActive = true; - mFetchQueue.push_back(FetchQueueInfo(LLUUID::null, TRUE)); + mFetchQueue.push_back(FetchQueueInfo(LLUUID::null, true)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } @@ -320,7 +347,7 @@ void LLInventoryModelBackgroundFetch::setAllFoldersFetched() if (mRecursiveInventoryFetchStarted && mRecursiveLibraryFetchStarted) { - mAllFoldersFetched = TRUE; + mAllFoldersFetched = true; //LL_INFOS(LOG_INV) << "All folders fetched, validating" << LL_ENDL; //gInventory.validate(); } @@ -338,8 +365,15 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() { if (mBackgroundFetchActive && gAgent.getRegion() && gAgent.getRegion()->capabilitiesReceived()) { - // If we'll be using the capability, we'll be sending batches and the background thing isn't as important. - bulkFetch(); + if (AISAPI::isAvailable()) + { + bulkFetchViaAis(); + } + else + { + // If we'll be using the capability, we'll be sending batches and the background thing isn't as important. + bulkFetch(); + } } } @@ -352,9 +386,118 @@ void LLInventoryModelBackgroundFetch::incrFetchCount(S32 fetching) mFetchCount = 0; } } +void ais_callback(const LLUUID& inv_id) +{ + LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); +} static LLTrace::BlockTimerStatHandle FTM_BULK_FETCH("Bulk Fetch"); +void LLInventoryModelBackgroundFetch::bulkFetchViaAis() +{ + LL_RECORD_BLOCK_TIME(FTM_BULK_FETCH); + //Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped. + if (gDisconnected) + { + return; + } + + static const S32 max_concurrent_fetches(12); + + if (mFetchCount >= max_concurrent_fetches) + { + return; + } + + // Start with recursive queue since it can get multiple categories + // in a single request and might contain what other requests want + while (!mRecursiveFetchQueue.empty() && mFetchCount < max_concurrent_fetches) + { + const FetchQueueInfo & fetch_info(mRecursiveFetchQueue.front()); + bulkFetchViaAis(fetch_info); + mRecursiveFetchQueue.pop_front(); + } + + while (!mFetchQueue.empty() && mFetchCount < max_concurrent_fetches) + { + const FetchQueueInfo & fetch_info(mFetchQueue.front()); + bulkFetchViaAis(fetch_info); + mFetchQueue.pop_front(); + } + + if (isBulkFetchProcessingComplete()) + { + setAllFoldersFetched(); + } +} + +void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetch_info) +{ + if (fetch_info.mIsCategory) + { + const LLUUID & cat_id(fetch_info.mUUID); + if (cat_id.isNull()) // Lost and found + { + AISAPI::FetchCategoryChildren(LLUUID::null, AISAPI::INVENTORY, false, ais_callback); + mFetchCount++; + } + else + { + const LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); + + if (cat) + { + if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) + { + if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) + { + AISAPI::FetchCategoryChildren(cat->getUUID(), AISAPI::LIBRARY, fetch_info.mRecursive, ais_callback); + } + else + { + AISAPI::FetchCategoryChildren(cat->getUUID(), AISAPI::INVENTORY, fetch_info.mRecursive, ais_callback); + } + mFetchCount++; + } + else + { + // Already fetched, check if anything inside needs fetching + if (fetch_info.mRecursive) + { + LLInventoryModel::cat_array_t * categories(NULL); + LLInventoryModel::item_array_t * items(NULL); + gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); + for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); + it != categories->end(); + ++it) + { + mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); + } + } + } + } + // else??? + } + } + else + { + LLViewerInventoryItem * itemp(gInventory.getItem(fetch_info.mUUID)); + + if (itemp) + { + if (itemp->getPermissions().getOwner() == gAgent.getID()) + { + AISAPI::FetchItem(itemp->getUUID(), AISAPI::INVENTORY, ais_callback); + } + else + { + AISAPI::FetchItem(itemp->getUUID(), AISAPI::LIBRARY, ais_callback); + } + mFetchCount++; + } + } +} + // Bundle up a bunch of requests to send all at once. void LLInventoryModelBackgroundFetch::bulkFetch() { @@ -374,13 +517,6 @@ void LLInventoryModelBackgroundFetch::bulkFetch() // inventory more quickly. static const U32 max_batch_size(10); static const S32 max_concurrent_fetches(12); // Outstanding requests, not connections - static const F32 new_min_time(0.05f); // *HACK: Clean this up when old code goes away entirely. - - mMinTimeBetweenFetches = new_min_time; - if (mMinTimeBetweenFetches < new_min_time) - { - mMinTimeBetweenFetches = new_min_time; // *HACK: See above. - } if (mFetchCount) { @@ -394,8 +530,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch() gInventory.notifyObservers(); } - if ((mFetchCount > max_concurrent_fetches) || - (mFetchTimer.getElapsedTimeF32() < mMinTimeBetweenFetches)) + if (mFetchCount > max_concurrent_fetches) { return; } @@ -414,6 +549,13 @@ void LLInventoryModelBackgroundFetch::bulkFetch() LLSD item_request_body; LLSD item_request_body_lib; + if (!mRecursiveFetchQueue.empty()) + { + LL_DEBUGS(LOG_INV) << "Request was sheduled for AIS, using legacy" << LL_ENDL; + mFetchQueue.insert(mFetchQueue.begin(), mRecursiveFetchQueue.begin(), mRecursiveFetchQueue.end()); + mRecursiveFetchQueue.clear(); + } + while (! mFetchQueue.empty() && (item_count + folder_count) < max_batch_size) { @@ -421,14 +563,14 @@ void LLInventoryModelBackgroundFetch::bulkFetch() if (fetch_info.mIsCategory) { const LLUUID & cat_id(fetch_info.mUUID); - if (cat_id.isNull()) //DEV-17797 + if (cat_id.isNull()) //DEV-17797 Lost and found { LLSD folder_sd; folder_sd["folder_id"] = LLUUID::null.asString(); folder_sd["owner_id"] = gAgent.getID(); folder_sd["sort_order"] = LLSD::Integer(sort_order); - folder_sd["fetch_folders"] = LLSD::Boolean(FALSE); - folder_sd["fetch_items"] = LLSD::Boolean(TRUE); + folder_sd["fetch_folders"] = LLSD::Boolean(false); + folder_sd["fetch_items"] = LLSD::Boolean(true); folder_request_body["folders"].append(folder_sd); folder_count++; } @@ -444,8 +586,8 @@ void LLInventoryModelBackgroundFetch::bulkFetch() folder_sd["folder_id"] = cat->getUUID(); folder_sd["owner_id"] = cat->getOwnerID(); folder_sd["sort_order"] = LLSD::Integer(sort_order); - folder_sd["fetch_folders"] = LLSD::Boolean(TRUE); //(LLSD::Boolean)sFullFetchStarted; - folder_sd["fetch_items"] = LLSD::Boolean(TRUE); + folder_sd["fetch_folders"] = LLSD::Boolean(true); //(LLSD::Boolean)sFullFetchStarted; + folder_sd["fetch_items"] = LLSD::Boolean(true); if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) { -- cgit v1.3 From 83811ff846d9c046e694708c209a6d4dc0bb45a3 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 15 Mar 2023 03:29:03 +0200 Subject: SL-18629 WIP Fetch Inventory using AIS caps #2 --- indra/newview/llaisapi.cpp | 113 +++++++-------- indra/newview/llaisapi.h | 1 - indra/newview/llinventorymodelbackgroundfetch.cpp | 164 ++++++++++++++-------- indra/newview/llinventorymodelbackgroundfetch.h | 10 +- 4 files changed, 164 insertions(+), 124 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 87811e9c0b..23bb123dee 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -483,41 +483,6 @@ void AISAPI::FetchCategoryCategories(const LLUUID &catId, ITEM_TYPE type, bool r EnqueueAISCommand("FetchCategoryCategories", proc); } -/*static*/ -void AISAPI::FetchCOF(completion_t callback) -{ - std::string cap; - cap = getInvCap(); - if (cap.empty()) - { - LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; - return; - } - LLUUID cof_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); - - std::string url = cap + std::string("/category/") + cof_id.asString() + "/links"; - - //LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_ROOT_INVENTORY); - //std::string url = cap + std::string("/category/") + root_id.asString() + "/children?depth=*"; - - invokationFn_t patchFn = boost::bind( - // Humans ignore next line. It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload. - static_cast - //---- - // _1 -> httpAdapter - // _2 -> httpRequest - // _3 -> url - // _4 -> body - // _5 -> httpOptions - // _6 -> httpHeaders - (&LLCoreHttpUtil::HttpCoroutineAdapter::getAndSuspend), _1, _2, _3, _5, _6); - - LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, - _1, patchFn, url, cof_id, LLSD(), callback, FETCHCOF)); - - EnqueueAISCommand("FetchCOF", proc); -} - /*static*/ void AISAPI::EnqueueAISCommand(const std::string &procName, LLCoprocedureManager::CoProcedure_t proc) { @@ -578,8 +543,7 @@ void AISAPI::onUpdateReceived(const std::string& context, const LLSD& update, CO } bool is_fetch = (type == FETCHITEM) || (type == FETCHCATEGORYCHILDREN) - || (type == FETCHCATEGORYCATEGORIES) - || (type == FETCHCOF); + || (type == FETCHCATEGORYCATEGORIES); // parse update llsd into stuff to do or parse received items. AISUpdate ais_update(update, is_fetch); ais_update.doUpdate(); // execute the updates in the appropriate order. @@ -648,36 +612,16 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht } } } - /*else if (status.getType() == 403) + else if (status.getType() == 403) { if (type == FETCHCATEGORYCHILDREN) { - if (url.find("?depth=*") != std::string::npos) - { - LL_WARNS() << "too much" << LL_ENDL; - AISAPI::FetchCategoryChildren(gInventory.getRootFolderID(), AISAPI::ITEM_TYPE::INVENTORY, false, boost::bind(&LLInventoryModel::fetchDescendentsDepthOne, &gInventory, targetId)); - - if (result["oversize_inventory"].asBoolean() == true) - { - LL_WARNS("Inventory") << "Can't fetch the oversized inventory folder" << LL_ENDL; - } - } - else - { - if (result["oversize_inventory"].asBoolean() == true) - { - LL_WARNS("Inventory") << "Can't fetch the oversized inventory folder" << LL_ENDL; - } - } + LL_DEBUGS("Inventory") << "Fetch failed, content is over imit" << LL_ENDL; } - }*/ + } LL_WARNS("Inventory") << "Inventory error: " << status.toString() << LL_ENDL; LL_WARNS("Inventory") << ll_pretty_print_sd(result) << LL_ENDL; } - else if (type == FETCHCOF) - { - //LL_WARNS("Inventory") << ll_pretty_print_sd(result) << LL_ENDL; - } LL_DEBUGS("Inventory") << result << LL_ENDL; onUpdateReceived("AISCommand", result, type); @@ -687,7 +631,10 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht bool needs_callback = true; LLUUID id(LLUUID::null); - if (type == COPYLIBRARYCATEGORY && result.has("category_id")) + if ( ( (type == COPYLIBRARYCATEGORY) + || (type == FETCHCATEGORYCATEGORIES) + || (type == FETCHCATEGORYCHILDREN)) + && result.has("category_id")) { id = result["category_id"]; } @@ -871,7 +818,12 @@ void AISUpdate::parseItem(const LLSD& item_map) BOOL rv = new_item->unpackMessage(item_map); if (rv) { - if (!mFetch && curr_item) + if (mFetch) + { + mItemsCreated[item_id] = new_item; + mCatDescendentDeltas[new_item->getParentUUID()]; + } + else if (curr_item) { mItemsUpdated[item_id] = new_item; // This statement is here to cause a new entry with 0 @@ -906,7 +858,19 @@ void AISUpdate::parseLink(const LLSD& link_map) if (rv) { const LLUUID& parent_id = new_link->getParentUUID(); - if (!mFetch && curr_link) + if (mFetch) + { + LLPermissions default_perms; + default_perms.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); + default_perms.initMasks(PERM_NONE, PERM_NONE, PERM_NONE, PERM_NONE, PERM_NONE); + new_link->setPermissions(default_perms); + LLSaleInfo default_sale_info; + new_link->setSaleInfo(default_sale_info); + //LL_DEBUGS("Inventory") << "creating link from llsd: " << ll_pretty_print_sd(link_map) << LL_ENDL; + mItemsCreated[item_id] = new_link; + mCatDescendentDeltas[parent_id]; + } + else if (curr_link) { mItemsUpdated[item_id] = new_link; // This statement is here to cause a new entry with 0 @@ -973,7 +937,28 @@ void AISUpdate::parseCategory(const LLSD& category_map) //} if (rv) { - if (curr_cat && !mFetch) + if (mFetch) + { + // Set version/descendents for newly created categories. + if (category_map.has("version")) + { + S32 version = category_map["version"].asInteger(); + LL_DEBUGS("Inventory") << "Setting version to " << version + << " for new category " << category_id << LL_ENDL; + new_cat->setVersion(version); + } + uuid_int_map_t::const_iterator lookup_it = mCatDescendentsKnown.find(category_id); + if (mCatDescendentsKnown.end() != lookup_it) + { + S32 descendent_count = lookup_it->second; + LL_DEBUGS("Inventory") << "Setting descendents count to " << descendent_count + << " for new category " << category_id << LL_ENDL; + new_cat->setDescendentCount(descendent_count); + } + mCategoriesCreated[category_id] = new_cat; + mCatDescendentDeltas[new_cat->getParentUUID()]; + } + else if (curr_cat) { mCategoriesUpdated[category_id] = new_cat; // This statement is here to cause a new entry with 0 diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h index 3de3366a0e..58f6a17650 100644 --- a/indra/newview/llaisapi.h +++ b/indra/newview/llaisapi.h @@ -75,7 +75,6 @@ private: FETCHITEM, FETCHCATEGORYCHILDREN, FETCHCATEGORYCATEGORIES, - FETCHCOF, } COMMAND_TYPE; static const std::string INVENTORY_CAP_NAME; diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 1905a9c9a4..5ea8fe4cba 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -244,12 +244,14 @@ BOOL LLInventoryModelBackgroundFetch::folderFetchActive() const void LLInventoryModelBackgroundFetch::addRequestAtFront(const LLUUID & id, bool recursive, bool is_category) { - mFetchQueue.push_front(FetchQueueInfo(id, recursive, is_category)); + ERecursionType recursion_type = recursive ? RT_RECURSIVE : RT_NONE; + mFetchQueue.push_front(FetchQueueInfo(id, recursion_type, is_category)); } void LLInventoryModelBackgroundFetch::addRequestAtBack(const LLUUID & id, bool recursive, bool is_category) { - mFetchQueue.push_back(FetchQueueInfo(id, recursive, is_category)); + ERecursionType recursion_type = recursive ? RT_RECURSIVE : RT_NONE; + mFetchQueue.push_back(FetchQueueInfo(id, recursion_type, is_category)); } void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) @@ -263,6 +265,7 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) mBackgroundFetchActive = true; mFolderFetchActive = true; + ERecursionType recursion_type = recursive ? RT_RECURSIVE : RT_NONE; if (id.isNull()) { if (! mRecursiveInventoryFetchStarted) @@ -270,11 +273,14 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) mRecursiveInventoryFetchStarted |= recursive; if (recursive && AISAPI::isAvailable()) { - mRecursiveFetchQueue.push_back(FetchQueueInfo(gInventory.getRootFolderID(), recursive)); + // Not only root folder can be massive, but + // most system folders will be requested independently + // so request root folder and content separately + mRecursiveFetchQueue.push_back(FetchQueueInfo(gInventory.getRootFolderID(), RT_CONTENT)); } else { - mFetchQueue.push_back(FetchQueueInfo(gInventory.getRootFolderID(), recursive)); + mFetchQueue.push_back(FetchQueueInfo(gInventory.getRootFolderID(), recursion_type)); } gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } @@ -283,11 +289,11 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) mRecursiveLibraryFetchStarted |= recursive; if (recursive && AISAPI::isAvailable()) { - mRecursiveFetchQueue.push_back(FetchQueueInfo(gInventory.getLibraryRootFolderID(), recursive)); + mRecursiveFetchQueue.push_back(FetchQueueInfo(gInventory.getLibraryRootFolderID(), recursion_type)); } else { - mFetchQueue.push_back(FetchQueueInfo(gInventory.getLibraryRootFolderID(), recursive)); + mFetchQueue.push_back(FetchQueueInfo(gInventory.getLibraryRootFolderID(), recursion_type)); } gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } @@ -299,7 +305,7 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) // AIS does depth requests, recursive requests will need to be prioritizes if (mRecursiveFetchQueue.empty() || mRecursiveFetchQueue.back().mUUID != id) { - mRecursiveFetchQueue.push_back(FetchQueueInfo(id, recursive)); + mRecursiveFetchQueue.push_back(FetchQueueInfo(id, recursion_type)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } } @@ -308,7 +314,7 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) // Specific folder requests go to front of queue. if (mFetchQueue.empty() || mFetchQueue.front().mUUID != id) { - mFetchQueue.push_front(FetchQueueInfo(id, recursive)); + mFetchQueue.push_front(FetchQueueInfo(id, recursion_type)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } } @@ -328,7 +334,7 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) { mBackgroundFetchActive = true; - mFetchQueue.push_front(FetchQueueInfo(id, false, false)); + mFetchQueue.push_front(FetchQueueInfo(id, RT_NONE, false)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } } @@ -338,7 +344,7 @@ void LLInventoryModelBackgroundFetch::findLostItems() { mBackgroundFetchActive = true; mFolderFetchActive = true; - mFetchQueue.push_back(FetchQueueInfo(LLUUID::null, true)); + mFetchQueue.push_back(FetchQueueInfo(LLUUID::null, RT_RECURSIVE)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } @@ -386,11 +392,45 @@ void LLInventoryModelBackgroundFetch::incrFetchCount(S32 fetching) mFetchCount = 0; } } -void ais_callback(const LLUUID& inv_id) + +void ais_simple_callback(const LLUUID& inv_id) { LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); } +void LLInventoryModelBackgroundFetch::onAISCalback(const LLUUID &request_id, const LLUUID &response_id, ERecursionType recursion) +{ + incrFetchCount(-1); + if (response_id.isNull()) // Failure + { + if (recursion == RT_RECURSIVE) + { + // A full recursive request failed. + // Try requesting folder and nested content separately + mBackgroundFetchActive = true; + mFolderFetchActive = true; + mRecursiveFetchQueue.push_back(FetchQueueInfo(request_id, RT_CONTENT)); + gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); + } + } + else + { + if (recursion == RT_CONTENT) + { + // Got the folder, now recursively request content + LLInventoryModel::cat_array_t * categories(NULL); + LLInventoryModel::item_array_t * items(NULL); + gInventory.getDirectDescendentsOf(request_id, categories, items); + for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); + it != categories->end(); + ++it) + { + mRecursiveFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), RT_RECURSIVE)); + } + } + } +} + static LLTrace::BlockTimerStatHandle FTM_BULK_FETCH("Bulk Fetch"); void LLInventoryModelBackgroundFetch::bulkFetchViaAis() @@ -438,45 +478,54 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc const LLUUID & cat_id(fetch_info.mUUID); if (cat_id.isNull()) // Lost and found { - AISAPI::FetchCategoryChildren(LLUUID::null, AISAPI::INVENTORY, false, ais_callback); + AISAPI::FetchCategoryChildren(LLUUID::null, AISAPI::INVENTORY, false, ais_simple_callback); mFetchCount++; } else { - const LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); - if (cat) + if (!gInventory.isCategoryComplete(cat_id)) { - if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) + const LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); + if (cat) { if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) { - AISAPI::FetchCategoryChildren(cat->getUUID(), AISAPI::LIBRARY, fetch_info.mRecursive, ais_callback); + AISAPI::FetchCategoryChildren(cat->getUUID(), AISAPI::LIBRARY, fetch_info.mRecursive == RT_RECURSIVE, ais_simple_callback); } else { - AISAPI::FetchCategoryChildren(cat->getUUID(), AISAPI::INVENTORY, fetch_info.mRecursive, ais_callback); + LLUUID cat_id = cat->getUUID(); + ERecursionType type = fetch_info.mRecursive; + AISAPI::FetchCategoryChildren( + cat_id, + AISAPI::INVENTORY, + type == RT_RECURSIVE, + [cat_id, type](const LLUUID &response_id) + { + LLInventoryModelBackgroundFetch::instance().onAISCalback(cat_id, response_id, type); + }); } mFetchCount++; } - else + // else? + } + else + { + // Already fetched, check if anything inside needs fetching + if (fetch_info.mRecursive) { - // Already fetched, check if anything inside needs fetching - if (fetch_info.mRecursive) + LLInventoryModel::cat_array_t * categories(NULL); + LLInventoryModel::item_array_t * items(NULL); + gInventory.getDirectDescendentsOf(cat_id, categories, items); + for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); + it != categories->end(); + ++it) { - LLInventoryModel::cat_array_t * categories(NULL); - LLInventoryModel::item_array_t * items(NULL); - gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); - for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); - it != categories->end(); - ++it) - { - mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); - } + mRecursiveFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); } } } - // else??? } } else @@ -487,11 +536,11 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc { if (itemp->getPermissions().getOwner() == gAgent.getID()) { - AISAPI::FetchItem(itemp->getUUID(), AISAPI::INVENTORY, ais_callback); + AISAPI::FetchItem(itemp->getUUID(), AISAPI::INVENTORY, ais_simple_callback); } else { - AISAPI::FetchItem(itemp->getUUID(), AISAPI::LIBRARY, ais_callback); + AISAPI::FetchItem(itemp->getUUID(), AISAPI::LIBRARY, ais_simple_callback); } mFetchCount++; } @@ -576,36 +625,37 @@ void LLInventoryModelBackgroundFetch::bulkFetch() } else { - const LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); - - if (cat) - { - if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) - { - LLSD folder_sd; - folder_sd["folder_id"] = cat->getUUID(); - folder_sd["owner_id"] = cat->getOwnerID(); - folder_sd["sort_order"] = LLSD::Integer(sort_order); - folder_sd["fetch_folders"] = LLSD::Boolean(true); //(LLSD::Boolean)sFullFetchStarted; - folder_sd["fetch_items"] = LLSD::Boolean(true); - - if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) - { - folder_request_body_lib["folders"].append(folder_sd); - } - else - { - folder_request_body["folders"].append(folder_sd); - } - folder_count++; - } - + if (!gInventory.isCategoryComplete(cat_id)) + { + const LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); + if (cat) + { + LLSD folder_sd; + folder_sd["folder_id"] = cat->getUUID(); + folder_sd["owner_id"] = cat->getOwnerID(); + folder_sd["sort_order"] = LLSD::Integer(sort_order); + folder_sd["fetch_folders"] = LLSD::Boolean(true); //(LLSD::Boolean)sFullFetchStarted; + folder_sd["fetch_items"] = LLSD::Boolean(true); + + if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) + { + folder_request_body_lib["folders"].append(folder_sd); + } + else + { + folder_request_body["folders"].append(folder_sd); + } + folder_count++; + } + } + else + { // May already have this folder, but append child folders to list. if (fetch_info.mRecursive) { LLInventoryModel::cat_array_t * categories(NULL); LLInventoryModel::item_array_t * items(NULL); - gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); + gInventory.getDirectDescendentsOf(cat_id, categories, items); for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); it != categories->end(); ++it) diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index ac1c42e0d7..4c4de6ac7c 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -73,9 +73,14 @@ public: protected: + typedef enum { + RT_NONE = 0, + RT_CONTENT, // request content recursively + RT_RECURSIVE, // request everything recursively + } ERecursionType; struct FetchQueueInfo { - FetchQueueInfo(const LLUUID& id, bool recursive, bool is_category = true) + FetchQueueInfo(const LLUUID& id, ERecursionType recursive, bool is_category = true) : mUUID(id), mIsCategory(is_category), mRecursive(recursive) @@ -83,10 +88,11 @@ protected: LLUUID mUUID; bool mIsCategory; - bool mRecursive; + ERecursionType mRecursive; }; typedef std::deque fetch_queue_t; + void onAISCalback(const LLUUID &request_id, const LLUUID &response_id, ERecursionType recursion); void bulkFetchViaAis(); void bulkFetchViaAis(const FetchQueueInfo& fetch_info); void bulkFetch(); -- cgit v1.3 From 7a70d93c437a7065b0c0be7fa63d36f511a9cef2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 15 Mar 2023 20:03:53 +0200 Subject: SL-18629 Fetch Inventory using AIS caps #3 --- indra/newview/llaisapi.cpp | 28 ++++++++++--- indra/newview/llinventorymodelbackgroundfetch.cpp | 50 ++++++++--------------- indra/newview/llinventorymodelbackgroundfetch.h | 1 - 3 files changed, 39 insertions(+), 40 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 23bb123dee..bb963d77c9 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -901,7 +901,25 @@ void AISUpdate::parseLink(const LLSD& link_map) void AISUpdate::parseCategory(const LLSD& category_map) { - LLUUID category_id = category_map["category_id"].asUUID(); + LLUUID category_id = category_map["category_id"].asUUID(); + S32 version = LLViewerInventoryCategory::VERSION_UNKNOWN; + + if (category_map.has("version")) + { + version = category_map["version"].asInteger(); + } + + LLViewerInventoryCategory *curr_cat = gInventory.getCategory(category_id); + + if (curr_cat + && curr_cat->getVersion() > LLViewerInventoryCategory::VERSION_UNKNOWN + && version > LLViewerInventoryCategory::VERSION_UNKNOWN + && version < curr_cat->getVersion()) + { + LL_WARNS() << "Got stale folder, known: " << curr_cat->getVersion() + << ", received: " << version << LL_ENDL; + return; + } // Check descendent count first, as it may be needed // to populate newly created categories @@ -911,7 +929,6 @@ void AISUpdate::parseCategory(const LLSD& category_map) } LLPointer new_cat; - LLViewerInventoryCategory *curr_cat = gInventory.getCategory(category_id); if (curr_cat) { // Default to current values where not provided. @@ -940,11 +957,10 @@ void AISUpdate::parseCategory(const LLSD& category_map) if (mFetch) { // Set version/descendents for newly created categories. - if (category_map.has("version")) + if (version > LLViewerInventoryCategory::VERSION_UNKNOWN) { - S32 version = category_map["version"].asInteger(); LL_DEBUGS("Inventory") << "Setting version to " << version - << " for new category " << category_id << LL_ENDL; + << " for category " << category_id << LL_ENDL; new_cat->setVersion(version); } uuid_int_map_t::const_iterator lookup_it = mCatDescendentsKnown.find(category_id); @@ -952,7 +968,7 @@ void AISUpdate::parseCategory(const LLSD& category_map) { S32 descendent_count = lookup_it->second; LL_DEBUGS("Inventory") << "Setting descendents count to " << descendent_count - << " for new category " << category_id << LL_ENDL; + << " for category " << category_id << LL_ENDL; new_cat->setDescendentCount(descendent_count); } mCategoriesCreated[category_id] = new_cat; diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 5ea8fe4cba..098ced4ec9 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -276,7 +276,7 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) // Not only root folder can be massive, but // most system folders will be requested independently // so request root folder and content separately - mRecursiveFetchQueue.push_back(FetchQueueInfo(gInventory.getRootFolderID(), RT_CONTENT)); + mFetchQueue.push_front(FetchQueueInfo(gInventory.getRootFolderID(), RT_CONTENT)); } else { @@ -287,25 +287,18 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) if (! mRecursiveLibraryFetchStarted) { mRecursiveLibraryFetchStarted |= recursive; - if (recursive && AISAPI::isAvailable()) - { - mRecursiveFetchQueue.push_back(FetchQueueInfo(gInventory.getLibraryRootFolderID(), recursion_type)); - } - else - { - mFetchQueue.push_back(FetchQueueInfo(gInventory.getLibraryRootFolderID(), recursion_type)); - } + mFetchQueue.push_back(FetchQueueInfo(gInventory.getLibraryRootFolderID(), recursion_type)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } } else { - if (recursive && AISAPI::isAvailable()) + if (AISAPI::isAvailable() && !recursive) { - // AIS does depth requests, recursive requests will need to be prioritizes - if (mRecursiveFetchQueue.empty() || mRecursiveFetchQueue.back().mUUID != id) + // Specific folder requests go to front of queue. + if (mFetchQueue.empty() || mFetchQueue.back().mUUID != id) { - mRecursiveFetchQueue.push_back(FetchQueueInfo(id, recursion_type)); + mFetchQueue.push_back(FetchQueueInfo(id, recursion_type)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } } @@ -318,6 +311,7 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } } + if (id == gInventory.getLibraryRootFolderID()) { mRecursiveLibraryFetchStarted |= recursive; @@ -409,7 +403,7 @@ void LLInventoryModelBackgroundFetch::onAISCalback(const LLUUID &request_id, con // Try requesting folder and nested content separately mBackgroundFetchActive = true; mFolderFetchActive = true; - mRecursiveFetchQueue.push_back(FetchQueueInfo(request_id, RT_CONTENT)); + mFetchQueue.push_front(FetchQueueInfo(request_id, RT_CONTENT)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } } @@ -425,7 +419,13 @@ void LLInventoryModelBackgroundFetch::onAISCalback(const LLUUID &request_id, con it != categories->end(); ++it) { - mRecursiveFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), RT_RECURSIVE)); + mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), RT_RECURSIVE)); + } + if (!mFetchQueue.empty()) + { + mBackgroundFetchActive = true; + mFolderFetchActive = true; + gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } } } @@ -442,22 +442,13 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() return; } - static const S32 max_concurrent_fetches(12); + static const S32 max_concurrent_fetches(50); if (mFetchCount >= max_concurrent_fetches) { return; } - // Start with recursive queue since it can get multiple categories - // in a single request and might contain what other requests want - while (!mRecursiveFetchQueue.empty() && mFetchCount < max_concurrent_fetches) - { - const FetchQueueInfo & fetch_info(mRecursiveFetchQueue.front()); - bulkFetchViaAis(fetch_info); - mRecursiveFetchQueue.pop_front(); - } - while (!mFetchQueue.empty() && mFetchCount < max_concurrent_fetches) { const FetchQueueInfo & fetch_info(mFetchQueue.front()); @@ -522,7 +513,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc it != categories->end(); ++it) { - mRecursiveFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); + mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); } } } @@ -598,13 +589,6 @@ void LLInventoryModelBackgroundFetch::bulkFetch() LLSD item_request_body; LLSD item_request_body_lib; - if (!mRecursiveFetchQueue.empty()) - { - LL_DEBUGS(LOG_INV) << "Request was sheduled for AIS, using legacy" << LL_ENDL; - mFetchQueue.insert(mFetchQueue.begin(), mRecursiveFetchQueue.begin(), mRecursiveFetchQueue.end()); - mRecursiveFetchQueue.clear(); - } - while (! mFetchQueue.empty() && (item_count + folder_count) < max_batch_size) { diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index 4c4de6ac7c..14557ea92d 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -114,7 +114,6 @@ private: LLFrameTimer mFetchTimer; F32 mMinTimeBetweenFetches; fetch_queue_t mFetchQueue; - fetch_queue_t mRecursiveFetchQueue; }; -- cgit v1.3 From 3a5c41a20e6044c8cfa71dfd1583fea0809d6a68 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 17 Mar 2023 03:23:15 +0200 Subject: SL-18629 Fetch Inventory using AIS caps #4 --- indra/newview/llinventorymodelbackgroundfetch.cpp | 28 +++++++++++++---------- indra/newview/llstartup.cpp | 5 ++++ 2 files changed, 21 insertions(+), 12 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 098ced4ec9..282d234cf3 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -293,23 +293,20 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) } else { - if (AISAPI::isAvailable() && !recursive) + if (mFetchQueue.empty() || mFetchQueue.front().mUUID != id) { - // Specific folder requests go to front of queue. - if (mFetchQueue.empty() || mFetchQueue.back().mUUID != id) + if (AISAPI::isAvailable()) { + // On AIS make sure root goes to the top and follow up recursive + // fetches, not individual requests mFetchQueue.push_back(FetchQueueInfo(id, recursion_type)); - gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } - } - else - { - // Specific folder requests go to front of queue. - if (mFetchQueue.empty() || mFetchQueue.front().mUUID != id) + else { + // Specific folder requests go to front of queue. mFetchQueue.push_front(FetchQueueInfo(id, recursion_type)); - gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } + gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } if (id == gInventory.getLibraryRootFolderID()) @@ -419,7 +416,7 @@ void LLInventoryModelBackgroundFetch::onAISCalback(const LLUUID &request_id, con it != categories->end(); ++it) { - mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), RT_RECURSIVE)); + mFetchQueue.push_front(FetchQueueInfo((*it)->getUUID(), RT_RECURSIVE)); } if (!mFetchQueue.empty()) { @@ -449,11 +446,17 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() return; } - while (!mFetchQueue.empty() && mFetchCount < max_concurrent_fetches) + // Don't loop for too long (in case of large, fully loaded inventory) + F64 curent_time = LLTimer::getTotalSeconds(); + const F64 max_time = 0.006f; // 6 ms + const F64 end_time = curent_time + max_time; + + while (!mFetchQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time) { const FetchQueueInfo & fetch_info(mFetchQueue.front()); bulkFetchViaAis(fetch_info); mFetchQueue.pop_front(); + curent_time = LLTimer::getTotalSeconds(); } if (isBulkFetchProcessingComplete()) @@ -513,6 +516,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc it != categories->end(); ++it) { + // not push_front to not cause an infinite loop mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); } } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 842192a62b..a1f2753ada 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2930,6 +2930,11 @@ void reset_login() LLFloaterReg::hideVisibleInstances(); LLStartUp::setStartupState( STATE_BROWSER_INIT ); + if (LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->terminate(); + } + // Clear any verified certs and verify them again on next login // to ensure cert matches server instead of just getting reused LLPointer store = gSecAPIHandler->getCertificateStore(""); -- cgit v1.3 From 70d99cde5826893be4964d4673ff875320b7220f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 17 Mar 2023 23:44:28 +0200 Subject: SL-18629 Track request depth to be able to distinguish incomplete folder reliably --- indra/newview/llaisapi.cpp | 87 ++++++++++++++--------- indra/newview/llaisapi.h | 13 ++-- indra/newview/llinventorymodelbackgroundfetch.cpp | 73 ++++++++++--------- indra/newview/llviewerinventory.cpp | 6 +- 4 files changed, 102 insertions(+), 77 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index bb963d77c9..5e243476d8 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -384,7 +384,7 @@ void AISAPI::FetchItem(const LLUUID &itemId, ITEM_TYPE type, completion_t callba } std::string url = cap + std::string("/item/") + itemId.asString(); - invokationFn_t patchFn = boost::bind( + invokationFn_t getFn = boost::bind( // Humans ignore next line. It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload. static_cast //---- @@ -397,7 +397,7 @@ void AISAPI::FetchItem(const LLUUID &itemId, ITEM_TYPE type, completion_t callba (&LLCoreHttpUtil::HttpCoroutineAdapter::getAndSuspend), _1, _2, _3, _5, _6); LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, - _1, patchFn, url, itemId, LLSD(), callback, FETCHITEM)); + _1, getFn, url, itemId, LLSD(), callback, FETCHITEM)); EnqueueAISCommand("FetchItem", proc); } @@ -425,7 +425,7 @@ void AISAPI::FetchCategoryChildren(const LLUUID &catId, ITEM_TYPE type, bool rec url += "?depth=" + std::to_string(depth); } - invokationFn_t patchFn = boost::bind( + invokationFn_t getFn = boost::bind( // Humans ignore next line. It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload. static_cast //---- @@ -437,8 +437,11 @@ void AISAPI::FetchCategoryChildren(const LLUUID &catId, ITEM_TYPE type, bool rec // _6 -> httpHeaders (&LLCoreHttpUtil::HttpCoroutineAdapter::getAndSuspend), _1, _2, _3, _5, _6); + // get doesn't use body, can pass additional data + LLSD body; + body["depth"] = recursive ? S32_MAX : depth; LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, - _1, patchFn, url, catId, LLSD(), callback, FETCHCATEGORYCHILDREN)); + _1, getFn, url, catId, body, callback, FETCHCATEGORYCHILDREN)); EnqueueAISCommand("FetchCategoryChildren", proc); } @@ -465,7 +468,7 @@ void AISAPI::FetchCategoryCategories(const LLUUID &catId, ITEM_TYPE type, bool r url += "?depth=" + std::to_string(depth); } - invokationFn_t patchFn = boost::bind( + invokationFn_t getFn = boost::bind( // Humans ignore next line. It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload. static_cast //---- @@ -477,8 +480,11 @@ void AISAPI::FetchCategoryCategories(const LLUUID &catId, ITEM_TYPE type, bool r // _6 -> httpHeaders (&LLCoreHttpUtil::HttpCoroutineAdapter::getAndSuspend), _1, _2, _3, _5, _6); + // get doesn't use body, can pass additional data + LLSD body; + body["depth"] = depth; LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, - _1, patchFn, url, catId, LLSD(), callback, FETCHCATEGORYCATEGORIES)); + _1, getFn, url, catId, body, callback, FETCHCATEGORYCATEGORIES)); EnqueueAISCommand("FetchCategoryCategories", proc); } @@ -534,7 +540,7 @@ void AISAPI::onIdle(void *userdata) } /*static*/ -void AISAPI::onUpdateReceived(const std::string& context, const LLSD& update, COMMAND_TYPE type) +void AISAPI::onUpdateReceived(const std::string& context, const LLSD& update, COMMAND_TYPE type, const LLSD& request_body) { LLTimer timer; if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage")) @@ -545,7 +551,12 @@ void AISAPI::onUpdateReceived(const std::string& context, const LLSD& update, CO || (type == FETCHCATEGORYCHILDREN) || (type == FETCHCATEGORYCATEGORIES); // parse update llsd into stuff to do or parse received items. - AISUpdate ais_update(update, is_fetch); + S32 depth = 0; + if (is_fetch && request_body.has("depth")) + { + depth = request_body["depth"].asInteger(); + } + AISUpdate ais_update(update, is_fetch, depth); ais_update.doUpdate(); // execute the updates in the appropriate order. LL_INFOS("Inventory") << "elapsed: " << timer.getElapsedTimeF32() << LL_ENDL; } @@ -559,11 +570,6 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); LLCore::HttpHeaders::ptr_t httpHeaders; - /*if (type == FETCHCATEGORYCHILDREN && (url.find("?depth=*") != std::string::npos)) - { - LL_WARNS() << "testy test start"<< LL_ENDL; - }*/ - httpOptions->setTimeout(180); LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; @@ -624,7 +630,12 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht } LL_DEBUGS("Inventory") << result << LL_ENDL; - onUpdateReceived("AISCommand", result, type); + onUpdateReceived("AISCommand", result, type, body); + + if (type == FETCHITEM) + { + LL_WARNS() << "test" << LL_ENDL; + } if (callback && !callback.empty()) { @@ -638,6 +649,17 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht { id = result["category_id"]; } + if (type == FETCHITEM) + { + if (result.has("item_id")) + { + id = result["item_id"]; + } + if (result.has("linked_id")) + { + id = result["linked_id"]; + } + } if (type == CREATEINVENTORY) { // CREATEINVENTORY can have multiple callbacks @@ -676,8 +698,9 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht } //------------------------------------------------------------------------- -AISUpdate::AISUpdate(const LLSD& update, bool fetch) +AISUpdate::AISUpdate(const LLSD& update, bool fetch, S32 depth) : mFetch(fetch) +, mFetchDepth(depth) { parseUpdate(update); } @@ -794,13 +817,13 @@ void AISUpdate::parseContent(const LLSD& update) if (update.has("category_id")) { - parseCategory(update); + parseCategory(update, mFetchDepth); } else { if (update.has("_embedded")) { - parseEmbedded(update["_embedded"]); + parseEmbedded(update["_embedded"], mFetchDepth); } } } @@ -899,7 +922,7 @@ void AISUpdate::parseLink(const LLSD& link_map) } -void AISUpdate::parseCategory(const LLSD& category_map) +void AISUpdate::parseCategory(const LLSD& category_map, S32 depth) { LLUUID category_id = category_map["category_id"].asUUID(); S32 version = LLViewerInventoryCategory::VERSION_UNKNOWN; @@ -948,17 +971,17 @@ void AISUpdate::parseCategory(const LLSD& category_map) } BOOL rv = new_cat->unpackMessage(category_map); // *NOTE: unpackMessage does not unpack version or descendent count. - //if (category_map.has("version")) - //{ - // mCatVersionsUpdated[category_id] = category_map["version"].asInteger(); - //} if (rv) { if (mFetch) { - // Set version/descendents for newly created categories. - if (version > LLViewerInventoryCategory::VERSION_UNKNOWN) + // set version only if previous one was already known + // or if we are sure this update has full data and embeded items (depth 0+) + // since bulk fetch uses this to decide what still needs fetching + if (version > LLViewerInventoryCategory::VERSION_UNKNOWN + && (depth >= 0 || (curr_cat && curr_cat->getVersion() > LLViewerInventoryCategory::VERSION_UNKNOWN))) { + // Set version/descendents for newly fetched categories. LL_DEBUGS("Inventory") << "Setting version to " << version << " for category " << category_id << LL_ENDL; new_cat->setVersion(version); @@ -1015,7 +1038,7 @@ void AISUpdate::parseCategory(const LLSD& category_map) // Check for more embedded content. if (category_map.has("_embedded")) { - parseEmbedded(category_map["_embedded"]); + parseEmbedded(category_map["_embedded"], depth - 1); } } @@ -1032,7 +1055,7 @@ void AISUpdate::parseDescendentCount(const LLUUID& category_id, const LLSD& embe } } -void AISUpdate::parseEmbedded(const LLSD& embedded) +void AISUpdate::parseEmbedded(const LLSD& embedded, S32 depth) { if (embedded.has("links")) // _embedded in a category { @@ -1048,11 +1071,11 @@ void AISUpdate::parseEmbedded(const LLSD& embedded) } if (embedded.has("categories")) // _embedded in a category { - parseEmbeddedCategories(embedded["categories"]); + parseEmbeddedCategories(embedded["categories"], depth); } if (embedded.has("category")) // _embedded in a link { - parseEmbeddedCategory(embedded["category"]); + parseEmbeddedCategory(embedded["category"], depth); } } @@ -1120,19 +1143,19 @@ void AISUpdate::parseEmbeddedItems(const LLSD& items) } } -void AISUpdate::parseEmbeddedCategory(const LLSD& category) +void AISUpdate::parseEmbeddedCategory(const LLSD& category, S32 depth) { // a single category (_embedded in a link) if (category.has("category_id")) { if (mFetch || mCategoryIds.end() != mCategoryIds.find(category["category_id"].asUUID())) { - parseCategory(category); + parseCategory(category, depth); } } } -void AISUpdate::parseEmbeddedCategories(const LLSD& categories) +void AISUpdate::parseEmbeddedCategories(const LLSD& categories, S32 depth) { // a map of categories (_embedded in a category) for(LLSD::map_const_iterator categoryit = categories.beginMap(), @@ -1147,7 +1170,7 @@ void AISUpdate::parseEmbeddedCategories(const LLSD& categories) } else { - parseCategory(category_map); + parseCategory(category_map, depth); } } } diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h index 58f6a17650..93bbbedb3b 100644 --- a/indra/newview/llaisapi.h +++ b/indra/newview/llaisapi.h @@ -85,7 +85,7 @@ private: static void EnqueueAISCommand(const std::string &procName, LLCoprocedureManager::CoProcedure_t proc); static void onIdle(void *userdata); // launches postponed AIS commands - static void onUpdateReceived(const std::string& context, const LLSD& update, COMMAND_TYPE type); + static void onUpdateReceived(const std::string& context, const LLSD& update, COMMAND_TYPE type, const LLSD& request_body); static std::string getInvCap(); static std::string getLibCap(); @@ -101,21 +101,21 @@ private: class AISUpdate { public: - AISUpdate(const LLSD& update, bool fetch); + AISUpdate(const LLSD& update, bool fetch, S32 depth); void parseUpdate(const LLSD& update); void parseMeta(const LLSD& update); void parseContent(const LLSD& update); void parseUUIDArray(const LLSD& content, const std::string& name, uuid_list_t& ids); void parseLink(const LLSD& link_map); void parseItem(const LLSD& link_map); - void parseCategory(const LLSD& link_map); + void parseCategory(const LLSD& link_map, S32 depth); void parseDescendentCount(const LLUUID& category_id, const LLSD& embedded); - void parseEmbedded(const LLSD& embedded); + void parseEmbedded(const LLSD& embedded, S32 depth); void parseEmbeddedLinks(const LLSD& links); void parseEmbeddedItems(const LLSD& items); - void parseEmbeddedCategories(const LLSD& categories); + void parseEmbeddedCategories(const LLSD& categories, S32 depth); void parseEmbeddedItem(const LLSD& item); - void parseEmbeddedCategory(const LLSD& category); + void parseEmbeddedCategory(const LLSD& category, S32 depth); void doUpdate(); private: void clearParseResults(); @@ -138,6 +138,7 @@ private: uuid_list_t mItemIds; uuid_list_t mCategoryIds; bool mFetch; + S32 mFetchDepth; }; #endif diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 282d234cf3..6cae035fcf 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -478,10 +478,10 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc else { - if (!gInventory.isCategoryComplete(cat_id)) + const LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); + if (cat) { - const LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); - if (cat) + if (!gInventory.isCategoryComplete(cat_id)) { if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) { @@ -502,25 +502,24 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc } mFetchCount++; } - // else? - } - else - { - // Already fetched, check if anything inside needs fetching - if (fetch_info.mRecursive) + else { - LLInventoryModel::cat_array_t * categories(NULL); - LLInventoryModel::item_array_t * items(NULL); - gInventory.getDirectDescendentsOf(cat_id, categories, items); - for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); - it != categories->end(); - ++it) + // Already fetched, check if anything inside needs fetching + if (fetch_info.mRecursive) { - // not push_front to not cause an infinite loop - mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); + LLInventoryModel::cat_array_t * categories(NULL); + LLInventoryModel::item_array_t * items(NULL); + gInventory.getDirectDescendentsOf(cat_id, categories, items); + for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); + it != categories->end(); + ++it) + { + // not push_front to not cause an infinite loop + mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); + } } } - } + } // else? } } else @@ -613,10 +612,10 @@ void LLInventoryModelBackgroundFetch::bulkFetch() } else { - if (!gInventory.isCategoryComplete(cat_id)) + const LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); + if (cat) { - const LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); - if (cat) + if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) { LLSD folder_sd; folder_sd["folder_id"] = cat->getUUID(); @@ -635,23 +634,23 @@ void LLInventoryModelBackgroundFetch::bulkFetch() } folder_count++; } + else + { + // May already have this folder, but append child folders to list. + if (fetch_info.mRecursive) + { + LLInventoryModel::cat_array_t * categories(NULL); + LLInventoryModel::item_array_t * items(NULL); + gInventory.getDirectDescendentsOf(cat_id, categories, items); + for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); + it != categories->end(); + ++it) + { + mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); + } + } + } } - else - { - // May already have this folder, but append child folders to list. - if (fetch_info.mRecursive) - { - LLInventoryModel::cat_array_t * categories(NULL); - LLInventoryModel::item_array_t * items(NULL); - gInventory.getDirectDescendentsOf(cat_id, categories, items); - for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); - it != categories->end(); - ++it) - { - mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); - } - } - } } if (fetch_info.mRecursive) { diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 07338b7b6b..2f2bc3f91f 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1928,11 +1928,13 @@ const LLUUID& LLViewerInventoryItem::getThumbnailUUID() const } if (mThumbnailUUID.isNull() && mType == LLAssetType::AT_LINK) { - return gInventory.getItem(getLinkedUUID())->getThumbnailUUID(); + LLViewerInventoryItem *linked_item = gInventory.getItem(mAssetUUID); + return linked_item ? linked_item->getThumbnailUUID() : LLUUID::null; } if (mThumbnailUUID.isNull() && mType == LLAssetType::AT_LINK_FOLDER) { - return gInventory.getCategory(getLinkedUUID())->getThumbnailUUID(); + LLViewerInventoryCategory *linked_cat = gInventory.getCategory(mAssetUUID); + return linked_cat ? linked_cat->getThumbnailUUID() : LLUUID::null; } return mThumbnailUUID; } -- cgit v1.3 From 72131418aa943b93f61508993d7006b02ebd9c35 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sun, 19 Mar 2023 16:11:21 +0200 Subject: SL-18629 Rebuild brocken link on fetch compeltion. --- indra/newview/llinventorymodel.cpp | 47 +++++++++++++++++++++-- indra/newview/llinventorymodel.h | 6 +++ indra/newview/llinventorymodelbackgroundfetch.cpp | 10 ++++- indra/newview/llinventorymodelbackgroundfetch.h | 5 +++ 4 files changed, 64 insertions(+), 4 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index c54a59d12f..b82f0c3ede 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -41,6 +41,7 @@ #include "llinventorypanel.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" +#include "llinventorymodelbackgroundfetch.h" #include "llinventoryobserver.h" #include "llinventorypanel.h" #include "llfloaterpreviewtrash.h" @@ -439,6 +440,7 @@ LLInventoryModel::LLInventoryModel() mIsNotifyObservers(FALSE), mModifyMask(LLInventoryObserver::ALL), mChangedItemIDs(), + mBulckFecthCallbackSlot(), mObservers(), mHttpRequestFG(NULL), mHttpRequestBG(NULL), @@ -470,6 +472,11 @@ void LLInventoryModel::cleanupInventory() mObservers.erase(iter); delete observer; } + + if (mBulckFecthCallbackSlot.connected()) + { + mBulckFecthCallbackSlot.disconnect(); + } mObservers.clear(); // Run down HTTP transport @@ -1750,6 +1757,15 @@ void LLInventoryModel::changeCategoryParent(LLViewerInventoryCategory* cat, notifyObservers(); } +void LLInventoryModel::rebuildBrockenLinks() +{ + for (LLUUID link_id : mPossiblyBrockenLinks) + { + addChangedMask(LLInventoryObserver::REBUILD, link_id); + } + mPossiblyBrockenLinks.clear(); +} + // Does not appear to be used currently. void LLInventoryModel::onItemUpdated(const LLUUID& item_id, const LLSD& updates, bool update_parent_version) { @@ -2368,9 +2384,34 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) // The item will show up as a broken link. if (item->getIsBrokenLink()) { - LL_INFOS(LOG_INV) << "Adding broken link [ name: " << item->getName() - << " itemID: " << item->getUUID() - << " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << LL_ENDL; + if (!LLInventoryModelBackgroundFetch::getInstance()->isEverythingFetched()) + { + // isEverythingFetched is actually 'initial' fetch only. + // Schedule this link for a recheck once inventory gets loaded + mPossiblyBrockenLinks.insert(item->getUUID()); + if (!mBulckFecthCallbackSlot.connected()) + { + // Links might take a while to update this way, and there + // might be a lot of them. A better option might be to check + // links periodically with final check on fetch completion. + mBulckFecthCallbackSlot = + LLInventoryModelBackgroundFetch::getInstance()->setAllFoldersFetchedCallback( + []() + { + gInventory.rebuildBrockenLinks(); + }); + } + LL_DEBUGS(LOG_INV) << "Scheduling a link to be rebuilt later [ name: " << item->getName() + << " itemID: " << item->getUUID() + << " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << LL_ENDL; + + } + else + { + LL_INFOS(LOG_INV) << "Adding broken link [ name: " << item->getName() + << " itemID: " << item->getUUID() + << " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << LL_ENDL; + } } if (item->getIsLinkType()) { diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index d1ee7b6144..02278ed957 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -407,6 +407,10 @@ public: const LLUUID& new_parent_id, BOOL restamp); + // Marks links from a "possibly" broken list for a rebuild + // clears the list + void rebuildBrockenLinks(); + //-------------------------------------------------------------------- // Delete //-------------------------------------------------------------------- @@ -574,6 +578,8 @@ private: U32 mModifyMaskBacklog; changed_items_t mChangedItemIDsBacklog; changed_items_t mAddedItemIDsBacklog; + changed_items_t mPossiblyBrockenLinks; + boost::signals2::connection mBulckFecthCallbackSlot; //-------------------------------------------------------------------- diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 6cae035fcf..ea721b3a40 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -347,12 +347,20 @@ void LLInventoryModelBackgroundFetch::setAllFoldersFetched() mAllFoldersFetched = true; //LL_INFOS(LOG_INV) << "All folders fetched, validating" << LL_ENDL; //gInventory.validate(); + + // For now only informs about initial fetch being done + mAllFoldersFetchedSignal(); } mFolderFetchActive = false; mBackgroundFetchActive = false; LL_INFOS(LOG_INV) << "Inventory background fetch completed" << LL_ENDL; } +boost::signals2::connection LLInventoryModelBackgroundFetch::setAllFoldersFetchedCallback(folders_fetched_callback_t cb) +{ + return mAllFoldersFetchedSignal.connect(cb); +} + void LLInventoryModelBackgroundFetch::backgroundFetchCB(void *) { LLInventoryModelBackgroundFetch::instance().backgroundFetch(); @@ -481,7 +489,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc const LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); if (cat) { - if (!gInventory.isCategoryComplete(cat_id)) + if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) { if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) { diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index 14557ea92d..038b634180 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -68,6 +68,9 @@ public: bool isBulkFetchProcessingComplete() const; void setAllFoldersFetched(); + typedef boost::function folders_fetched_callback_t; + boost::signals2::connection setAllFoldersFetchedCallback(folders_fetched_callback_t cb); + void addRequestAtFront(const LLUUID & id, bool recursive, bool is_category); void addRequestAtBack(const LLUUID & id, bool recursive, bool is_category); @@ -106,6 +109,8 @@ private: bool mRecursiveInventoryFetchStarted; bool mRecursiveLibraryFetchStarted; bool mAllFoldersFetched; + typedef boost::signals2::signal folders_fetched_signal_t; + folders_fetched_signal_t mAllFoldersFetchedSignal; bool mBackgroundFetchActive; bool mFolderFetchActive; -- cgit v1.3 From c9d9f1c54e104dd0ac670fbac2f4e9e053eea25c Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 24 Mar 2023 18:52:15 +0200 Subject: SL-18003 Make ais fetch faster --- indra/newview/app_settings/settings.xml | 2 +- indra/newview/llinventorymodelbackgroundfetch.cpp | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 87b0ad8faf..a2a1b3f117 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -15290,7 +15290,7 @@ Type U32 Value - 1 + 20 PoolSizeUpload diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index ea721b3a40..023cc05ee7 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -33,6 +33,7 @@ #include "llcallbacklist.h" #include "llinventorypanel.h" #include "llinventorymodel.h" +#include "llstartup.h" #include "llviewercontrol.h" #include "llviewerinventory.h" #include "llviewermessage.h" @@ -447,7 +448,8 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() return; } - static const S32 max_concurrent_fetches(50); + static LLCachedControl ais_pool(gSavedSettings, "", 20); + const U32 max_concurrent_fetches = llmax(1, ais_pool - 1); if (mFetchCount >= max_concurrent_fetches) { @@ -456,7 +458,9 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() // Don't loop for too long (in case of large, fully loaded inventory) F64 curent_time = LLTimer::getTotalSeconds(); - const F64 max_time = 0.006f; // 6 ms + const F64 max_time = LLStartUp::getStartupState() > STATE_WEARABLES_WAIT + ? 0.006f // 6 ms + : 1.f; const F64 end_time = curent_time + max_time; while (!mFetchQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time) @@ -480,8 +484,10 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc const LLUUID & cat_id(fetch_info.mUUID); if (cat_id.isNull()) // Lost and found { - AISAPI::FetchCategoryChildren(LLUUID::null, AISAPI::INVENTORY, false, ais_simple_callback); - mFetchCount++; + LL_WARNS() << "Lost and found not implemented yet" << LL_ENDL; + // todo: needs to be requested from ais in special manner? + /*AISAPI::FetchCategoryChildren(LLUUID::null, AISAPI::INVENTORY, false, ais_simple_callback); + mFetchCount++;*/ } else { -- cgit v1.3 From 6fd7427c576ec922b6c670b4ff9381c7cb738b5b Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sun, 26 Mar 2023 13:44:50 +0300 Subject: SL-18003 Bulk fetch some items by fetching whole folder --- indra/newview/llaisapi.cpp | 4 +- indra/newview/llappearancemgr.cpp | 64 +++++++++++++++++++++++ indra/newview/llinventorymodelbackgroundfetch.cpp | 6 ++- indra/newview/llinventoryobserver.cpp | 1 + indra/newview/llinventoryobserver.h | 2 +- indra/newview/llviewerinventory.cpp | 2 +- 6 files changed, 75 insertions(+), 4 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index d204a752ec..6a43c901e7 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -373,7 +373,6 @@ void AISAPI::UpdateItem(const LLUUID &itemId, const LLSD &updates, completion_t /*static*/ void AISAPI::FetchItem(const LLUUID &itemId, ITEM_TYPE type, completion_t callback) { - std::string cap; cap = (type == INVENTORY) ? getInvCap() : getLibCap(); @@ -859,6 +858,7 @@ void AISUpdate::parseItem(const LLSD& item_map) { mItemsCreated[item_id] = new_item; mCatDescendentDeltas[new_item->getParentUUID()]++; + new_item->setComplete(true); } } else @@ -893,6 +893,7 @@ void AISUpdate::parseLink(const LLSD& link_map) //LL_DEBUGS("Inventory") << "creating link from llsd: " << ll_pretty_print_sd(link_map) << LL_ENDL; mItemsCreated[item_id] = new_link; mCatDescendentDeltas[parent_id]; + new_link->setComplete(true); } else if (curr_link) { @@ -913,6 +914,7 @@ void AISUpdate::parseLink(const LLSD& link_map) //LL_DEBUGS("Inventory") << "creating link from llsd: " << ll_pretty_print_sd(link_map) << LL_ENDL; mItemsCreated[item_id] = new_link; mCatDescendentDeltas[parent_id]++; + new_link->setComplete(true); } } else diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 1de3cef3ba..b36ea1c457 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -4385,6 +4385,70 @@ public: ~CallAfterCategoryFetchStage1() { } + /*virtual*/ void startFetch() + { + bool ais3 = AISAPI::isAvailable(); + for (uuid_vec_t::const_iterator it = mIDs.begin(); it != mIDs.end(); ++it) + { + LLViewerInventoryCategory* cat = gInventory.getCategory(*it); + if (!cat) continue; + if (!isCategoryComplete(cat)) + { + // CHECK IT: isCategoryComplete() checks both version and descendant count but + // fetch() only works for Unknown version and doesn't care about descentants, + // as result fetch won't start and folder will potentially get stuck as + // incomplete in observer. + // Likely either both should use only version or both should check descendants. + 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 (ais3) + { + LLInventoryModel::cat_array_t* cats; + LLInventoryModel::item_array_t* items; + gInventory.getDirectDescendentsOf(cat->getUUID(), cats, items); + + if (items) + { + S32 complete_count = 0; + S32 incomplete_count = 0; + for (LLInventoryModel::item_array_t::const_iterator it = items->begin(); it < items->end(); ++it) + { + if (!(*it)->isFinished()) + { + incomplete_count++; + } + else + { + complete_count++; + } + } + // AIS can fetch couple items, but if there + // is more than a dozen it will be very slow + // it's faster to get whole folder in such case + const S32 MAX_INDIVIDUAL_FETCH = 10; + 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); + LLInventoryModelBackgroundFetch::instance().start(*it, false); + mIncomplete.push_back(*it); + } + else + { + // let stage2 handle incomplete ones + mComplete.push_back(*it); + } + } + } + else + { + mComplete.push_back(*it); + } + } + } virtual void done() { if (mComplete.size() <= 0) diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 023cc05ee7..0d366e43f4 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -31,8 +31,9 @@ #include "llagent.h" #include "llappviewer.h" #include "llcallbacklist.h" -#include "llinventorypanel.h" #include "llinventorymodel.h" +#include "llinventoryobserver.h" +#include "llinventorypanel.h" #include "llstartup.h" #include "llviewercontrol.h" #include "llviewerinventory.h" @@ -349,6 +350,9 @@ void LLInventoryModelBackgroundFetch::setAllFoldersFetched() //LL_INFOS(LOG_INV) << "All folders fetched, validating" << LL_ENDL; //gInventory.validate(); + gInventory.addChangedMask(LLInventoryObserver::INTERNAL, gInventory.getRootFolderID()); + gInventory.addChangedMask(LLInventoryObserver::INTERNAL, gInventory.getLibraryRootFolderID()); + // For now only informs about initial fetch being done mAllFoldersFetchedSignal(); } diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index 25f1854765..79917fb11b 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -40,6 +40,7 @@ #include "llaisapi.h" #include "llfloater.h" #include "llfocusmgr.h" +#include "llinventorymodelbackgroundfetch.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h index 02f73a5892..f0ed2f7003 100644 --- a/indra/newview/llinventoryobserver.h +++ b/indra/newview/llinventoryobserver.h @@ -126,7 +126,7 @@ public: LLInventoryFetchDescendentsObserver(const LLUUID& cat_id = LLUUID::null); LLInventoryFetchDescendentsObserver(const uuid_vec_t& cat_ids); - /*virtual*/ void startFetch(); + virtual void startFetch(); /*virtual*/ void changed(U32 mask); protected: BOOL isCategoryComplete(const LLViewerInventoryCategory* cat) const; diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index d8de269c3c..6c7e815b04 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -671,7 +671,7 @@ bool LLViewerInventoryCategory::fetch() } if (!url.empty() || AISAPI::isAvailable()) { - LLInventoryModelBackgroundFetch::instance().start(mUUID, false); + LLInventoryModelBackgroundFetch::instance().start(mUUID, false); } return true; } -- cgit v1.3 From b00e2da9e23f4dad9c754ce479253ac07eeec154 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 27 Mar 2023 21:04:51 +0300 Subject: SL-18003 Faster cof fetching --- indra/newview/llinventorymodelbackgroundfetch.cpp | 151 ++++++++++++++-------- indra/newview/llinventorymodelbackgroundfetch.h | 3 +- indra/newview/llinventoryobserver.cpp | 13 +- 3 files changed, 101 insertions(+), 66 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 0d366e43f4..4947c6bfe5 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -201,7 +201,7 @@ LLInventoryModelBackgroundFetch::~LLInventoryModelBackgroundFetch() bool LLInventoryModelBackgroundFetch::isBulkFetchProcessingComplete() const { - return mFetchQueue.empty() && mFetchCount <= 0; + return mFetchFolderQueue.empty() && mFetchItemQueue.empty() && mFetchCount <= 0; } bool LLInventoryModelBackgroundFetch::libraryFetchStarted() const @@ -247,13 +247,27 @@ BOOL LLInventoryModelBackgroundFetch::folderFetchActive() const void LLInventoryModelBackgroundFetch::addRequestAtFront(const LLUUID & id, bool recursive, bool is_category) { ERecursionType recursion_type = recursive ? RT_RECURSIVE : RT_NONE; - mFetchQueue.push_front(FetchQueueInfo(id, recursion_type, is_category)); + if (is_category) + { + mFetchFolderQueue.push_front(FetchQueueInfo(id, recursion_type, is_category)); + } + else + { + mFetchItemQueue.push_front(FetchQueueInfo(id, recursion_type, is_category)); + } } void LLInventoryModelBackgroundFetch::addRequestAtBack(const LLUUID & id, bool recursive, bool is_category) { ERecursionType recursion_type = recursive ? RT_RECURSIVE : RT_NONE; - mFetchQueue.push_back(FetchQueueInfo(id, recursion_type, is_category)); + if (is_category) + { + mFetchFolderQueue.push_back(FetchQueueInfo(id, recursion_type, is_category)); + } + else + { + mFetchItemQueue.push_back(FetchQueueInfo(id, recursion_type, is_category)); + } } void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) @@ -278,37 +292,38 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) // Not only root folder can be massive, but // most system folders will be requested independently // so request root folder and content separately - mFetchQueue.push_front(FetchQueueInfo(gInventory.getRootFolderID(), RT_CONTENT)); + mFetchFolderQueue.push_front(FetchQueueInfo(gInventory.getRootFolderID(), RT_CONTENT)); } else { - mFetchQueue.push_back(FetchQueueInfo(gInventory.getRootFolderID(), recursion_type)); + mFetchFolderQueue.push_back(FetchQueueInfo(gInventory.getRootFolderID(), recursion_type)); } gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } if (! mRecursiveLibraryFetchStarted) { mRecursiveLibraryFetchStarted |= recursive; - mFetchQueue.push_back(FetchQueueInfo(gInventory.getLibraryRootFolderID(), recursion_type)); + mFetchFolderQueue.push_back(FetchQueueInfo(gInventory.getLibraryRootFolderID(), recursion_type)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } } else { - if (mFetchQueue.empty() || mFetchQueue.front().mUUID != id) + if (AISAPI::isAvailable()) { - if (AISAPI::isAvailable()) + if (mFetchFolderQueue.empty() || mFetchFolderQueue.back().mUUID != id) { // On AIS make sure root goes to the top and follow up recursive // fetches, not individual requests - mFetchQueue.push_back(FetchQueueInfo(id, recursion_type)); + mFetchFolderQueue.push_back(FetchQueueInfo(id, recursion_type)); + gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } - else - { + } + else if (mFetchFolderQueue.empty() || mFetchFolderQueue.front().mUUID != id) + { // Specific folder requests go to front of queue. - mFetchQueue.push_front(FetchQueueInfo(id, recursion_type)); - } - gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); + mFetchFolderQueue.push_front(FetchQueueInfo(id, recursion_type)); + gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } if (id == gInventory.getLibraryRootFolderID()) @@ -323,11 +338,11 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) } else if (LLViewerInventoryItem * itemp = gInventory.getItem(id)) { - if (! itemp->mIsComplete && (mFetchQueue.empty() || mFetchQueue.front().mUUID != id)) + if (! itemp->mIsComplete && (mFetchItemQueue.empty() || mFetchItemQueue.front().mUUID != id)) { mBackgroundFetchActive = true; - mFetchQueue.push_front(FetchQueueInfo(id, RT_NONE, false)); + mFetchItemQueue.push_front(FetchQueueInfo(id, RT_NONE, false)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } } @@ -335,10 +350,17 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) void LLInventoryModelBackgroundFetch::findLostItems() { - mBackgroundFetchActive = true; - mFolderFetchActive = true; - mFetchQueue.push_back(FetchQueueInfo(LLUUID::null, RT_RECURSIVE)); - gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); + if (AISAPI::isAvailable()) + { + LL_WARNS() << "Not implemented yet" << LL_ENDL; + } + else + { + mBackgroundFetchActive = true; + mFolderFetchActive = true; + mFetchFolderQueue.push_back(FetchQueueInfo(LLUUID::null, RT_RECURSIVE)); + gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); + } } void LLInventoryModelBackgroundFetch::setAllFoldersFetched() @@ -413,7 +435,7 @@ void LLInventoryModelBackgroundFetch::onAISCalback(const LLUUID &request_id, con // Try requesting folder and nested content separately mBackgroundFetchActive = true; mFolderFetchActive = true; - mFetchQueue.push_front(FetchQueueInfo(request_id, RT_CONTENT)); + mFetchFolderQueue.push_front(FetchQueueInfo(request_id, RT_CONTENT)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } } @@ -429,9 +451,9 @@ void LLInventoryModelBackgroundFetch::onAISCalback(const LLUUID &request_id, con it != categories->end(); ++it) { - mFetchQueue.push_front(FetchQueueInfo((*it)->getUUID(), RT_RECURSIVE)); + mFetchFolderQueue.push_front(FetchQueueInfo((*it)->getUUID(), RT_RECURSIVE)); } - if (!mFetchQueue.empty()) + if (!mFetchFolderQueue.empty()) { mBackgroundFetchActive = true; mFolderFetchActive = true; @@ -467,11 +489,19 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() : 1.f; const F64 end_time = curent_time + max_time; - while (!mFetchQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time) + while (!mFetchFolderQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time) { - const FetchQueueInfo & fetch_info(mFetchQueue.front()); + const FetchQueueInfo & fetch_info(mFetchFolderQueue.front()); bulkFetchViaAis(fetch_info); - mFetchQueue.pop_front(); + mFetchFolderQueue.pop_front(); + curent_time = LLTimer::getTotalSeconds(); + } + + while (!mFetchFolderQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time) + { + const FetchQueueInfo & fetch_info(mFetchFolderQueue.front()); + bulkFetchViaAis(fetch_info); + mFetchFolderQueue.pop_front(); curent_time = LLTimer::getTotalSeconds(); } @@ -533,7 +563,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc ++it) { // not push_front to not cause an infinite loop - mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); + mFetchFolderQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); } } } @@ -610,10 +640,10 @@ void LLInventoryModelBackgroundFetch::bulkFetch() LLSD item_request_body; LLSD item_request_body_lib; - while (! mFetchQueue.empty() + while (! mFetchFolderQueue.empty() && (item_count + folder_count) < max_batch_size) { - const FetchQueueInfo & fetch_info(mFetchQueue.front()); + const FetchQueueInfo & fetch_info(mFetchFolderQueue.front()); if (fetch_info.mIsCategory) { const LLUUID & cat_id(fetch_info.mUUID); @@ -664,7 +694,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch() it != categories->end(); ++it) { - mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); + mFetchFolderQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); } } } @@ -675,29 +705,36 @@ void LLInventoryModelBackgroundFetch::bulkFetch() recursive_cats.push_back(cat_id); } } - else - { - LLViewerInventoryItem * itemp(gInventory.getItem(fetch_info.mUUID)); - if (itemp) - { - LLSD item_sd; - item_sd["owner_id"] = itemp->getPermissions().getOwner(); - item_sd["item_id"] = itemp->getUUID(); - if (itemp->getPermissions().getOwner() == gAgent.getID()) - { - item_request_body.append(item_sd); - } - else - { - item_request_body_lib.append(item_sd); - } - //itemp->fetchFromServer(); - item_count++; - } - } + mFetchFolderQueue.pop_front(); + } + + + while (!mFetchItemQueue.empty() + && (item_count + folder_count) < max_batch_size) + { + const FetchQueueInfo & fetch_info(mFetchItemQueue.front()); + + LLViewerInventoryItem * itemp(gInventory.getItem(fetch_info.mUUID)); - mFetchQueue.pop_front(); + if (itemp) + { + LLSD item_sd; + item_sd["owner_id"] = itemp->getPermissions().getOwner(); + item_sd["item_id"] = itemp->getUUID(); + if (itemp->getPermissions().getOwner() == gAgent.getID()) + { + item_request_body.append(item_sd); + } + else + { + item_request_body_lib.append(item_sd); + } + //itemp->fetchFromServer(); + item_count++; + } + + mFetchItemQueue.pop_front(); } // Issue HTTP POST requests to fetch folders and items @@ -768,14 +805,22 @@ void LLInventoryModelBackgroundFetch::bulkFetch() bool LLInventoryModelBackgroundFetch::fetchQueueContainsNoDescendentsOf(const LLUUID & cat_id) const { - for (fetch_queue_t::const_iterator it = mFetchQueue.begin(); - it != mFetchQueue.end(); + for (fetch_queue_t::const_iterator it = mFetchFolderQueue.begin(); + it != mFetchFolderQueue.end(); ++it) { const LLUUID & fetch_id = (*it).mUUID; if (gInventory.isObjectDescendentOf(fetch_id, cat_id)) return false; } + for (fetch_queue_t::const_iterator it = mFetchItemQueue.begin(); + it != mFetchItemQueue.end(); + ++it) + { + const LLUUID & fetch_id = (*it).mUUID; + if (gInventory.isObjectDescendentOf(fetch_id, cat_id)) + return false; + } return true; } diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index 038b634180..8d82f093d2 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -118,7 +118,8 @@ private: LLFrameTimer mFetchTimer; F32 mMinTimeBetweenFetches; - fetch_queue_t mFetchQueue; + fetch_queue_t mFetchFolderQueue; + fetch_queue_t mFetchItemQueue; }; diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index 79917fb11b..fe33be4abe 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -300,18 +300,7 @@ void LLInventoryFetchItemsObserver::startFetch() if (aisv3) { - // doesn't support bulk fetching, request one by one - if (owner_id == ALEXANDRIA_LINDEN_ID) - { - AISAPI::FetchItem(*it, AISAPI::LIBRARY); - } - else - { - AISAPI::FetchItem(*it, AISAPI::INVENTORY); - } - // Todo: remove item from mIncomplete on callback - // but keep in mind that observer can expire before - // callback or use LLInventoryModelBackgroundFetch + LLInventoryModelBackgroundFetch::getInstance()->start(*it); } else { -- cgit v1.3 From 0eff9756494a268f6aa68b66ce4d09cb5aa5460a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 27 Mar 2023 21:24:21 +0300 Subject: SL-18003 Basic dupplicate prevention --- indra/newview/llinventorymodelbackgroundfetch.cpp | 35 ++++++++++++++++------- indra/newview/llinventorymodelbackgroundfetch.h | 2 +- indra/newview/llviewerinventory.cpp | 19 +++++++++++- indra/newview/llviewerinventory.h | 2 ++ 4 files changed, 46 insertions(+), 12 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 4947c6bfe5..21f7e3e059 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -419,12 +419,19 @@ void LLInventoryModelBackgroundFetch::incrFetchCount(S32 fetching) } } -void ais_simple_callback(const LLUUID& inv_id) +void ais_simple_folder_callback(const LLUUID& inv_id) { LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); + LLViewerInventoryCategory * cat(gInventory.getCategory(inv_id)); + if (cat) cat->setFetching(false); } -void LLInventoryModelBackgroundFetch::onAISCalback(const LLUUID &request_id, const LLUUID &response_id, ERecursionType recursion) +void ais_simple_item_callback(const LLUUID& inv_id) +{ + LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); +} + +void LLInventoryModelBackgroundFetch::onAISFodlerCalback(const LLUUID &request_id, const LLUUID &response_id, ERecursionType recursion) { incrFetchCount(-1); if (response_id.isNull()) // Failure @@ -460,6 +467,13 @@ void LLInventoryModelBackgroundFetch::onAISCalback(const LLUUID &request_id, con gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } } + + // done + LLViewerInventoryCategory * cat(gInventory.getCategory(request_id)); + if (cat) + { + cat->setFetching(false); + } } } @@ -497,11 +511,11 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() curent_time = LLTimer::getTotalSeconds(); } - while (!mFetchFolderQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time) + while (!mFetchItemQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time) { - const FetchQueueInfo & fetch_info(mFetchFolderQueue.front()); + const FetchQueueInfo & fetch_info(mFetchItemQueue.front()); bulkFetchViaAis(fetch_info); - mFetchFolderQueue.pop_front(); + mFetchItemQueue.pop_front(); curent_time = LLTimer::getTotalSeconds(); } @@ -526,14 +540,14 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc else { - const LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); + LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); if (cat) { if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) { if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) { - AISAPI::FetchCategoryChildren(cat->getUUID(), AISAPI::LIBRARY, fetch_info.mRecursive == RT_RECURSIVE, ais_simple_callback); + AISAPI::FetchCategoryChildren(cat->getUUID(), AISAPI::LIBRARY, fetch_info.mRecursive == RT_RECURSIVE, ais_simple_folder_callback); } else { @@ -545,10 +559,11 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc type == RT_RECURSIVE, [cat_id, type](const LLUUID &response_id) { - LLInventoryModelBackgroundFetch::instance().onAISCalback(cat_id, response_id, type); + LLInventoryModelBackgroundFetch::instance().onAISFodlerCalback(cat_id, response_id, type); }); } mFetchCount++; + cat->setFetching(true); } else { @@ -578,11 +593,11 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc { if (itemp->getPermissions().getOwner() == gAgent.getID()) { - AISAPI::FetchItem(itemp->getUUID(), AISAPI::INVENTORY, ais_simple_callback); + AISAPI::FetchItem(itemp->getUUID(), AISAPI::INVENTORY, ais_simple_item_callback); } else { - AISAPI::FetchItem(itemp->getUUID(), AISAPI::LIBRARY, ais_simple_callback); + AISAPI::FetchItem(itemp->getUUID(), AISAPI::LIBRARY, ais_simple_item_callback); } mFetchCount++; } diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index 8d82f093d2..0a5608c0c6 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -95,7 +95,7 @@ protected: }; typedef std::deque fetch_queue_t; - void onAISCalback(const LLUUID &request_id, const LLUUID &response_id, ERecursionType recursion); + void onAISFodlerCalback(const LLUUID &request_id, const LLUUID &response_id, ERecursionType recursion); void bulkFetchViaAis(); void bulkFetchViaAis(const FetchQueueInfo& fetch_info); void bulkFetch(); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 6c7e815b04..6bd86f7902 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -659,7 +659,6 @@ bool LLViewerInventoryCategory::fetch() mDescendentsRequested.reset(); mDescendentsRequested.setTimerExpirySec(FETCH_TIMER_EXPIRY); - std::string url; if (gAgent.getRegion()) { @@ -678,6 +677,24 @@ bool LLViewerInventoryCategory::fetch() return false; } +void LLViewerInventoryCategory::setFetching(bool fetching) +{ + if (fetching) + { + if ((VERSION_UNKNOWN == getVersion()) + && mDescendentsRequested.hasExpired()) + { + const F32 FETCH_TIMER_EXPIRY = 10.0f; + mDescendentsRequested.reset(); + mDescendentsRequested.setTimerExpirySec(FETCH_TIMER_EXPIRY); + } + } + else + { + mDescendentsRequested.stop(); + } +} + S32 LLViewerInventoryCategory::getViewerDescendentCount() const { LLInventoryModel::cat_array_t* cats; diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 1554c84137..2ae2cebe5c 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -211,6 +211,8 @@ public: // Returns true if a fetch was issued. bool fetch(); + // Returns true if a fetch was issued. + void setFetching(bool); // used to help make caching more robust - for example, if // someone is getting 4 packets but logs out after 3. the viewer -- cgit v1.3 From 110ed8f4d3152c91ddd7577234ad37b666be86c9 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 28 Mar 2023 00:53:35 +0300 Subject: SL-18003 Don't cause excessive full rebuild --- indra/newview/llinventorymodel.cpp | 3 +++ indra/newview/llinventorymodelbackgroundfetch.cpp | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 4c2383d211..47fd17ef86 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1759,6 +1759,9 @@ void LLInventoryModel::changeCategoryParent(LLViewerInventoryCategory* cat, void LLInventoryModel::rebuildBrockenLinks() { + // make sure we aren't adding expensive Rebuild to anything else. + notifyObservers(); + for (LLUUID link_id : mPossiblyBrockenLinks) { addChangedMask(LLInventoryObserver::REBUILD, link_id); diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 21f7e3e059..25e35915c3 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -372,9 +372,6 @@ void LLInventoryModelBackgroundFetch::setAllFoldersFetched() //LL_INFOS(LOG_INV) << "All folders fetched, validating" << LL_ENDL; //gInventory.validate(); - gInventory.addChangedMask(LLInventoryObserver::INTERNAL, gInventory.getRootFolderID()); - gInventory.addChangedMask(LLInventoryObserver::INTERNAL, gInventory.getLibraryRootFolderID()); - // For now only informs about initial fetch being done mAllFoldersFetchedSignal(); } -- cgit v1.3 From 89a8c96f36983738645a2116d9d432e3bd88f1df Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 28 Mar 2023 02:27:34 +0300 Subject: SL-18003 Bulk download items when possible And signal fodler fetch completion when folder of recursive fetch is done, do not hold it for individual items --- indra/newview/llappearancemgr.cpp | 42 ++++++--- indra/newview/llinventorymodel.cpp | 13 ++- indra/newview/llinventorymodelbackgroundfetch.cpp | 89 +++++++++++++----- indra/newview/llinventorymodelbackgroundfetch.h | 10 +- indra/newview/llinventoryobserver.cpp | 106 +++++++++++++++++----- indra/newview/llsidepanelinventory.cpp | 2 +- indra/newview/llviewerinventory.cpp | 9 +- 7 files changed, 191 insertions(+), 80 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index b36ea1c457..8e44411d52 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -2420,7 +2420,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions, if (gInventory.hasPosiblyBrockenLinks()) { // Inventory has either broken links or links that - // haven't loaded yet and fetch is still in progress. + // haven't loaded yet. // Check if LLAppearanceMgr needs to wait. LLUUID current_outfit_id = getCOF(); LLInventoryModel::item_array_t cof_items; @@ -2438,22 +2438,34 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions, // links are likely fine and we will have to wait for them to // load (if inventory takes too long to load, might be a good // idea to make this check periodical) - if (!mBulkFecthCallbackSlot.connected()) + if (LLInventoryModelBackgroundFetch::getInstance()->folderFetchActive()) { - nullary_func_t cb = post_update_func; - mBulkFecthCallbackSlot = - LLInventoryModelBackgroundFetch::getInstance()->setAllFoldersFetchedCallback( - [this, enforce_ordering, post_update_func, cb]() + if (!mBulkFecthCallbackSlot.connected()) { - // inventory model should be already tracking this - // callback, but make sure rebuildBrockenLinks gets - // called before a cof update - gInventory.rebuildBrockenLinks(); - updateAppearanceFromCOF(enforce_ordering, post_update_func, post_update_func); - mBulkFecthCallbackSlot.disconnect(); - }); + nullary_func_t cb = post_update_func; + mBulkFecthCallbackSlot = + LLInventoryModelBackgroundFetch::getInstance()->setFetchCompletionCallback( + [this, enforce_ordering, post_update_func, cb]() + { + // inventory model should be already tracking this + // callback, but make sure rebuildBrockenLinks gets + // called before a cof update + gInventory.rebuildBrockenLinks(); + updateAppearanceFromCOF(enforce_ordering, post_update_func, post_update_func); + mBulkFecthCallbackSlot.disconnect(); + }); + } + return; + } + else + { + // this should have happened on completion callback, + // check why it didn't then fix it + llassert(false); + + // try to recover now + gInventory.rebuildBrockenLinks(); } - return; } } @@ -4433,7 +4445,7 @@ public: // To prevent premature removal from mIncomplete and // since we are doing a full refetch anyway, mark unknown cat->setVersion(LLViewerInventoryCategory::VERSION_UNKNOWN); - LLInventoryModelBackgroundFetch::instance().start(*it, false); + cat->fetch(); mIncomplete.push_back(*it); } else diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 47fd17ef86..bfc7840708 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1762,7 +1762,7 @@ void LLInventoryModel::rebuildBrockenLinks() // make sure we aren't adding expensive Rebuild to anything else. notifyObservers(); - for (LLUUID link_id : mPossiblyBrockenLinks) + for (const LLUUID &link_id : mPossiblyBrockenLinks) { addChangedMask(LLInventoryObserver::REBUILD, link_id); } @@ -2388,7 +2388,7 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) // The item will show up as a broken link. if (item->getIsBrokenLink()) { - if (!LLInventoryModelBackgroundFetch::getInstance()->isEverythingFetched()) + if (LLInventoryModelBackgroundFetch::getInstance()->folderFetchActive()) { // isEverythingFetched is actually 'initial' fetch only. // Schedule this link for a recheck once inventory gets loaded @@ -2399,7 +2399,7 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) // might be a lot of them. A better option might be to check // links periodically with final check on fetch completion. mBulkFecthCallbackSlot = - LLInventoryModelBackgroundFetch::getInstance()->setAllFoldersFetchedCallback( + LLInventoryModelBackgroundFetch::getInstance()->setFetchCompletionCallback( [this]() { rebuildBrockenLinks(); @@ -3798,7 +3798,10 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) // Temporary workaround: just fetch the item using AIS to get missing fields. // If this works fine we might want to extract ids only from the message // then use AIS as a primary fetcher - LLInventoryModelBackgroundFetch::instance().start((*cit)->getUUID(), false); + + // Use AIS derectly to not reset folder's version + // Todo: May be LLInventoryModelBackgroundFetch needs a 'forced' option + AISAPI::FetchCategoryChildren((*cit)->getUUID(), AISAPI::INVENTORY); } for (item_array_t::iterator iit = items.begin(); iit != items.end(); ++iit) { @@ -3807,7 +3810,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) // Temporary workaround: just fetch the item using AIS to get missing fields. // If this works fine we might want to extract ids only from the message // then use AIS as a primary fetcher - LLInventoryModelBackgroundFetch::instance().start((*iit)->getUUID(), false); + LLInventoryModelBackgroundFetch::instance().scheduleItemFetch((*iit)->getUUID()); } gInventory.notifyObservers(); diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 25e35915c3..d58dd22ca1 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -190,6 +190,7 @@ LLInventoryModelBackgroundFetch::LLInventoryModelBackgroundFetch(): mBackgroundFetchActive(false), mFolderFetchActive(false), mFetchCount(0), + mFetchFolderCount(0), mAllFoldersFetched(false), mRecursiveInventoryFetchStarted(false), mRecursiveLibraryFetchStarted(false), @@ -204,6 +205,11 @@ bool LLInventoryModelBackgroundFetch::isBulkFetchProcessingComplete() const return mFetchFolderQueue.empty() && mFetchItemQueue.empty() && mFetchCount <= 0; } +bool LLInventoryModelBackgroundFetch::isFolderFetchProcessingComplete() const +{ + return mFetchFolderQueue.empty() && mFetchFolderCount <= 0; +} + bool LLInventoryModelBackgroundFetch::libraryFetchStarted() const { return mRecursiveLibraryFetchStarted; @@ -338,16 +344,24 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) } else if (LLViewerInventoryItem * itemp = gInventory.getItem(id)) { - if (! itemp->mIsComplete && (mFetchItemQueue.empty() || mFetchItemQueue.front().mUUID != id)) + if (! itemp->mIsComplete) { - mBackgroundFetchActive = true; - - mFetchItemQueue.push_front(FetchQueueInfo(id, RT_NONE, false)); - gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); + scheduleItemFetch(id); } } } +void LLInventoryModelBackgroundFetch::scheduleItemFetch(const LLUUID& item_id) +{ + if (mFetchItemQueue.empty() || mFetchItemQueue.front().mUUID != item_id) + { + mBackgroundFetchActive = true; + + mFetchItemQueue.push_front(FetchQueueInfo(item_id, RT_NONE, false)); + gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); + } +} + void LLInventoryModelBackgroundFetch::findLostItems() { if (AISAPI::isAvailable()) @@ -371,18 +385,23 @@ void LLInventoryModelBackgroundFetch::setAllFoldersFetched() mAllFoldersFetched = true; //LL_INFOS(LOG_INV) << "All folders fetched, validating" << LL_ENDL; //gInventory.validate(); - - // For now only informs about initial fetch being done - mAllFoldersFetchedSignal(); } + mFolderFetchActive = false; - mBackgroundFetchActive = false; + if (isBulkFetchProcessingComplete()) + { + mBackgroundFetchActive = false; + } + + // For now only informs about initial fetch being done + mFoldersFetchedSignal(); + LL_INFOS(LOG_INV) << "Inventory background fetch completed" << LL_ENDL; } -boost::signals2::connection LLInventoryModelBackgroundFetch::setAllFoldersFetchedCallback(folders_fetched_callback_t cb) +boost::signals2::connection LLInventoryModelBackgroundFetch::setFetchCompletionCallback(folders_fetched_callback_t cb) { - return mAllFoldersFetchedSignal.connect(cb); + return mFoldersFetchedSignal.connect(cb); } void LLInventoryModelBackgroundFetch::backgroundFetchCB(void *) @@ -415,10 +434,20 @@ void LLInventoryModelBackgroundFetch::incrFetchCount(S32 fetching) mFetchCount = 0; } } +void LLInventoryModelBackgroundFetch::incrFetchFolderCount(S32 fetching) +{ + incrFetchCount(fetching); + mFetchFolderCount += fetching; + if (mFetchCount < 0) + { + LL_WARNS_ONCE(LOG_INV) << "Inventory fetch count fell below zero (0)." << LL_ENDL; + mFetchFolderCount = 0; + } +} void ais_simple_folder_callback(const LLUUID& inv_id) { - LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); + LLInventoryModelBackgroundFetch::instance().incrFetchFolderCount(-1); LLViewerInventoryCategory * cat(gInventory.getCategory(inv_id)); if (cat) cat->setFetching(false); } @@ -430,7 +459,7 @@ void ais_simple_item_callback(const LLUUID& inv_id) void LLInventoryModelBackgroundFetch::onAISFodlerCalback(const LLUUID &request_id, const LLUUID &response_id, ERecursionType recursion) { - incrFetchCount(-1); + incrFetchFolderCount(-1); if (response_id.isNull()) // Failure { if (recursion == RT_RECURSIVE) @@ -464,13 +493,13 @@ void LLInventoryModelBackgroundFetch::onAISFodlerCalback(const LLUUID &request_i gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } } + } - // done - LLViewerInventoryCategory * cat(gInventory.getCategory(request_id)); - if (cat) - { - cat->setFetching(false); - } + // done + LLViewerInventoryCategory * cat(gInventory.getCategory(request_id)); + if (cat) + { + cat->setFetching(false); } } @@ -516,10 +545,15 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() curent_time = LLTimer::getTotalSeconds(); } - if (isBulkFetchProcessingComplete()) + if (isFolderFetchProcessingComplete() && mFolderFetchActive) { setAllFoldersFetched(); } + + if (isBulkFetchProcessingComplete()) + { + mBackgroundFetchActive = false; + } } void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetch_info) @@ -532,7 +566,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc LL_WARNS() << "Lost and found not implemented yet" << LL_ENDL; // todo: needs to be requested from ais in special manner? /*AISAPI::FetchCategoryChildren(LLUUID::null, AISAPI::INVENTORY, false, ais_simple_callback); - mFetchCount++;*/ + incrFetchFolderCount(1);*/ } else { @@ -559,7 +593,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc LLInventoryModelBackgroundFetch::instance().onAISFodlerCalback(cat_id, response_id, type); }); } - mFetchCount++; + incrFetchFolderCount(1); cat->setFetching(true); } else @@ -590,14 +624,19 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc { if (itemp->getPermissions().getOwner() == gAgent.getID()) { - AISAPI::FetchItem(itemp->getUUID(), AISAPI::INVENTORY, ais_simple_item_callback); + AISAPI::FetchItem(fetch_info.mUUID, AISAPI::INVENTORY, ais_simple_item_callback); } else { - AISAPI::FetchItem(itemp->getUUID(), AISAPI::LIBRARY, ais_simple_item_callback); + AISAPI::FetchItem(fetch_info.mUUID, AISAPI::LIBRARY, ais_simple_item_callback); } - mFetchCount++; } + else + { + // Assume agent's inventory, library wouldn't have gotten here + AISAPI::FetchItem(fetch_info.mUUID, AISAPI::INVENTORY, ais_simple_item_callback); + } + mFetchCount++; } } diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index 0a5608c0c6..6a8b616a82 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -47,9 +47,10 @@ class LLInventoryModelBackgroundFetch : public LLSingleton folders_fetched_callback_t; - boost::signals2::connection setAllFoldersFetchedCallback(folders_fetched_callback_t cb); + boost::signals2::connection setFetchCompletionCallback(folders_fetched_callback_t cb); void addRequestAtFront(const LLUUID & id, bool recursive, bool is_category); void addRequestAtBack(const LLUUID & id, bool recursive, bool is_category); @@ -110,11 +113,12 @@ private: bool mRecursiveLibraryFetchStarted; bool mAllFoldersFetched; typedef boost::signals2::signal folders_fetched_signal_t; - folders_fetched_signal_t mAllFoldersFetchedSignal; + folders_fetched_signal_t mFoldersFetchedSignal; bool mBackgroundFetchActive; bool mFolderFetchActive; S32 mFetchCount; + S32 mFetchFolderCount; LLFrameTimer mFetchTimer; F32 mMinTimeBetweenFetches; diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index fe33be4abe..4db913ed0d 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -255,29 +255,19 @@ void LLInventoryFetchItemsObserver::startFetch() { bool aisv3 = AISAPI::isAvailable(); - LLUUID owner_id; LLSD items_llsd; + + typedef std::map requests_by_fodlers_t; + requests_by_fodlers_t requests; for (uuid_vec_t::const_iterator it = mIDs.begin(); it < mIDs.end(); ++it) { - LLViewerInventoryItem* item = gInventory.getItem(*it); - if (item) - { - if (item->isFinished()) - { - // It's complete, so put it on the complete container. - mComplete.push_back(*it); - continue; - } - else - { - owner_id = item->getPermissions().getOwner(); - } - } - else - { - // assume it's agent inventory. - owner_id = gAgent.getID(); - } + LLViewerInventoryItem* item = gInventory.getItem(*it); + if (item && item->isFinished()) + { + // It's complete, so put it on the complete container. + mComplete.push_back(*it); + continue; + } // Ignore categories since they're not items. We // could also just add this to mComplete but not sure what the @@ -300,13 +290,31 @@ void LLInventoryFetchItemsObserver::startFetch() if (aisv3) { - LLInventoryModelBackgroundFetch::getInstance()->start(*it); + if (item) + { + LLUUID parent_id = item->getParentUUID(); + requests[parent_id].push_back(*it); + } + else + { + // Can happen for gestures and calling cards if server notified us before they fetched + // Request by id without checking for an item. + LLInventoryModelBackgroundFetch::getInstance()->scheduleItemFetch(*it); + } } else { // Prepare the data to fetch LLSD item_entry; - item_entry["owner_id"] = owner_id; + if (item) + { + item_entry["owner_id"] = item->getPermissions().getOwner(); + } + else + { + // assume it's agent inventory. + item_entry["owner_id"] = gAgent.getID(); + } item_entry["item_id"] = (*it); items_llsd.append(item_entry); } @@ -315,7 +323,59 @@ void LLInventoryFetchItemsObserver::startFetch() mFetchingPeriod.reset(); mFetchingPeriod.setTimerExpirySec(FETCH_TIMER_EXPIRY); - if (!aisv3) + if (aisv3) + { + const S32 MAX_INDIVIDUAL_REQUESTS = 10; + for (requests_by_fodlers_t::value_type &folder : requests) + { + if (folder.second.size() > MAX_INDIVIDUAL_REQUESTS) + { + // requesting one by one will take a while + // do whole folder + LLInventoryModelBackgroundFetch::getInstance()->start(folder.first); + } + else + { + LLViewerInventoryCategory* cat = gInventory.getCategory(folder.first); + if (cat) + { + if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN) + { + // start fetching whole folder since it's not ready either way + cat->fetch(); + } + else if (cat->getViewerDescendentCount() <= folder.second.size()) + { + // start fetching whole folder since we need all items + cat->setVersion(LLViewerInventoryCategory::VERSION_UNKNOWN); + cat->fetch(); + + } + else + { + // get items one by one + for (LLUUID &item_id : folder.second) + { + LLInventoryModelBackgroundFetch::getInstance()->scheduleItemFetch(item_id); + } + } + } + else + { + // Isn't supposed to happen? We should have all folders + // and if item exists, folder is supposed to exist as well. + llassert(false); + + // get items one by one + for (LLUUID &item_id : folder.second) + { + LLInventoryModelBackgroundFetch::getInstance()->scheduleItemFetch(item_id); + } + } + } + } + } + else { fetch_items_from_llsd(items_llsd); } diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index de0330588b..bd6f846268 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -545,7 +545,7 @@ void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox) } } - if (clearInbox && mInboxEnabled && mInventoryPanelInbox.get()) + if (clearInbox && mInboxEnabled && !mInventoryPanelInbox.isDead()) { mInventoryPanelInbox.get()->getRootFolder()->clearSelection(); } diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 6bd86f7902..6f62ba5409 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -432,14 +432,7 @@ void LLViewerInventoryItem::fetchFromServer(void) const { if (AISAPI::isAvailable()) // AIS v 3 { - if (gAgent.getID() != mPermissions.getOwner()) - { - AISAPI::FetchItem(mUUID, AISAPI::LIBRARY); - } - else - { - AISAPI::FetchItem(mUUID, AISAPI::INVENTORY); - } + LLInventoryModelBackgroundFetch::getInstance()->scheduleItemFetch(mUUID); } else { -- cgit v1.3 From d21a1aace63967fe62b12b71b7f683f662dfcf4a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 28 Mar 2023 03:41:51 +0300 Subject: SL-18003 Missed pool name --- indra/newview/llinventorymodelbackgroundfetch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index d58dd22ca1..4cb4b9ee9c 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -514,7 +514,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() return; } - static LLCachedControl ais_pool(gSavedSettings, "", 20); + static LLCachedControl ais_pool(gSavedSettings, "PoolSizeAIS", 20); const U32 max_concurrent_fetches = llmax(1, ais_pool - 1); if (mFetchCount >= max_concurrent_fetches) -- cgit v1.3 From 3bf9c78f564f0b6c4fd79163bd63c0a6c1fab7cb Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 28 Mar 2023 19:38:26 +0300 Subject: SL-18003 Improve dupplicate prevention Try getting lost and found --- indra/newview/llaisapi.cpp | 46 +++++++ indra/newview/llaisapi.h | 1 + indra/newview/llinventorymodel.cpp | 11 +- indra/newview/llinventorymodelbackgroundfetch.cpp | 147 +++++++++++++--------- indra/newview/llinventorymodelbackgroundfetch.h | 22 ++-- indra/newview/llviewerinventory.cpp | 28 +++-- indra/newview/llviewerinventory.h | 14 ++- 7 files changed, 183 insertions(+), 86 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 6a43c901e7..f869f1652b 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -445,6 +445,52 @@ void AISAPI::FetchCategoryChildren(const LLUUID &catId, ITEM_TYPE type, bool rec EnqueueAISCommand("FetchCategoryChildren", proc); } +// some folders can be requested by name, like +// animatn | bodypart | clothing | current | favorite | gesture | inbox | landmark | lsltext +// lstndfnd | my_otfts | notecard | object | outbox | root | snapshot | sound | texture | trash +void AISAPI::FetchCategoryChildren(const std::string &identifier, bool recursive, completion_t callback, S32 depth) +{ + std::string cap; + + cap = getInvCap(); + if (cap.empty()) + { + LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + callback(LLUUID::null); + return; + } + std::string url = cap + std::string("/category/") + identifier + "/children"; + + if (recursive) + { + url += "?depth=*"; + } + else + { + url += "?depth=" + std::to_string(depth); + } + + invokationFn_t getFn = boost::bind( + // Humans ignore next line. It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload. + static_cast + //---- + // _1 -> httpAdapter + // _2 -> httpRequest + // _3 -> url + // _4 -> body + // _5 -> httpOptions + // _6 -> httpHeaders + (&LLCoreHttpUtil::HttpCoroutineAdapter::getAndSuspend), _1, _2, _3, _5, _6); + + // get doesn't use body, can pass additional data + LLSD body; + body["depth"] = recursive ? S32_MAX : depth; + LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, + _1, getFn, url, LLUUID::null, body, callback, FETCHCATEGORYCHILDREN)); + + EnqueueAISCommand("FetchCategoryChildren", proc); +} + /*static*/ void AISAPI::FetchCategoryCategories(const LLUUID &catId, ITEM_TYPE type, bool recursive, completion_t callback, S32 depth) { diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h index dd02951cd4..d083004195 100644 --- a/indra/newview/llaisapi.h +++ b/indra/newview/llaisapi.h @@ -57,6 +57,7 @@ public: static void UpdateItem(const LLUUID &itemId, const LLSD &updates, completion_t callback = completion_t()); static void FetchItem(const LLUUID &itemId, ITEM_TYPE type, completion_t callback = completion_t()); static void FetchCategoryChildren(const LLUUID &catId, ITEM_TYPE type = AISAPI::ITEM_TYPE::INVENTORY, bool recursive = false, completion_t callback = completion_t(), S32 depth = 0); + static void FetchCategoryChildren(const std::string &identifier, bool recursive = false, completion_t callback = completion_t(), S32 depth = 0); static void FetchCategoryCategories(const LLUUID &catId, ITEM_TYPE type = AISAPI::ITEM_TYPE::INVENTORY, bool recursive = false, completion_t callback = completion_t(), S32 depth = 0); static void CopyLibraryCategory(const LLUUID& sourceId, const LLUUID& destId, bool copySubfolders, completion_t callback = completion_t()); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index bfc7840708..9a874350bf 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -3453,8 +3453,8 @@ void LLInventoryModel::processUpdateCreateInventoryItem(LLMessageSystem* msg, vo gInventoryCallbacks.fire(callback_id, item_id); // todo: instead of unpacking message fully, - // grab only an item_id, then fetch via AIS - LLInventoryModelBackgroundFetch::instance().start(item_id, false); + // grab only an item_id, then fetch + LLInventoryModelBackgroundFetch::instance().scheduleItemFetch(item_id, true); } } @@ -3798,10 +3798,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) // Temporary workaround: just fetch the item using AIS to get missing fields. // If this works fine we might want to extract ids only from the message // then use AIS as a primary fetcher - - // Use AIS derectly to not reset folder's version - // Todo: May be LLInventoryModelBackgroundFetch needs a 'forced' option - AISAPI::FetchCategoryChildren((*cit)->getUUID(), AISAPI::INVENTORY); + LLInventoryModelBackgroundFetch::instance().scheduleFolderFetch((*cit)->getUUID(), true /*force, since it has changes*/); } for (item_array_t::iterator iit = items.begin(); iit != items.end(); ++iit) { @@ -3810,7 +3807,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) // Temporary workaround: just fetch the item using AIS to get missing fields. // If this works fine we might want to extract ids only from the message // then use AIS as a primary fetcher - LLInventoryModelBackgroundFetch::instance().scheduleItemFetch((*iit)->getUUID()); + LLInventoryModelBackgroundFetch::instance().scheduleItemFetch((*iit)->getUUID(), true); } gInventory.notifyObservers(); diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 4cb4b9ee9c..a9357bfdb3 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -252,7 +252,7 @@ BOOL LLInventoryModelBackgroundFetch::folderFetchActive() const void LLInventoryModelBackgroundFetch::addRequestAtFront(const LLUUID & id, bool recursive, bool is_category) { - ERecursionType recursion_type = recursive ? RT_RECURSIVE : RT_NONE; + EFetchType recursion_type = recursive ? FT_RECURSIVE : FT_DEFAULT; if (is_category) { mFetchFolderQueue.push_front(FetchQueueInfo(id, recursion_type, is_category)); @@ -265,7 +265,7 @@ void LLInventoryModelBackgroundFetch::addRequestAtFront(const LLUUID & id, bool void LLInventoryModelBackgroundFetch::addRequestAtBack(const LLUUID & id, bool recursive, bool is_category) { - ERecursionType recursion_type = recursive ? RT_RECURSIVE : RT_NONE; + EFetchType recursion_type = recursive ? FT_RECURSIVE : FT_DEFAULT; if (is_category) { mFetchFolderQueue.push_back(FetchQueueInfo(id, recursion_type, is_category)); @@ -287,7 +287,7 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) mBackgroundFetchActive = true; mFolderFetchActive = true; - ERecursionType recursion_type = recursive ? RT_RECURSIVE : RT_NONE; + EFetchType recursion_type = recursive ? FT_RECURSIVE : FT_DEFAULT; if (id.isNull()) { if (! mRecursiveInventoryFetchStarted) @@ -298,7 +298,7 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) // Not only root folder can be massive, but // most system folders will be requested independently // so request root folder and content separately - mFetchFolderQueue.push_front(FetchQueueInfo(gInventory.getRootFolderID(), RT_CONTENT)); + mFetchFolderQueue.push_front(FetchQueueInfo(gInventory.getRootFolderID(), FT_CONTENT_RECURSIVE)); } else { @@ -351,32 +351,45 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) } } -void LLInventoryModelBackgroundFetch::scheduleItemFetch(const LLUUID& item_id) +void LLInventoryModelBackgroundFetch::scheduleFolderFetch(const LLUUID& cat_id, bool forced) { - if (mFetchItemQueue.empty() || mFetchItemQueue.front().mUUID != item_id) + if (AISAPI::isAvailable()) { - mBackgroundFetchActive = true; - - mFetchItemQueue.push_front(FetchQueueInfo(item_id, RT_NONE, false)); + if (mFetchFolderQueue.empty() || mFetchFolderQueue.back().mUUID != cat_id) + { + // On AIS make sure root goes to the top and follow up recursive + // fetches, not individual requests + mFetchFolderQueue.push_back(FetchQueueInfo(cat_id, forced ? FT_FORCED : FT_DEFAULT)); + gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); + } + } + else if (mFetchFolderQueue.empty() || mFetchFolderQueue.front().mUUID != cat_id) + { + // Specific folder requests go to front of queue. + mFetchFolderQueue.push_front(FetchQueueInfo(cat_id, forced ? FT_FORCED : FT_DEFAULT)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } } -void LLInventoryModelBackgroundFetch::findLostItems() +void LLInventoryModelBackgroundFetch::scheduleItemFetch(const LLUUID& item_id, bool forced) { - if (AISAPI::isAvailable()) - { - LL_WARNS() << "Not implemented yet" << LL_ENDL; - } - else + if (mFetchItemQueue.empty() || mFetchItemQueue.front().mUUID != item_id) { mBackgroundFetchActive = true; - mFolderFetchActive = true; - mFetchFolderQueue.push_back(FetchQueueInfo(LLUUID::null, RT_RECURSIVE)); + + mFetchItemQueue.push_front(FetchQueueInfo(item_id, forced ? FT_FORCED : FT_DEFAULT, false)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } } +void LLInventoryModelBackgroundFetch::findLostItems() +{ + mBackgroundFetchActive = true; + mFolderFetchActive = true; + mFetchFolderQueue.push_back(FetchQueueInfo(LLUUID::null, FT_RECURSIVE)); + gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); +} + void LLInventoryModelBackgroundFetch::setAllFoldersFetched() { if (mRecursiveInventoryFetchStarted && @@ -449,7 +462,10 @@ void ais_simple_folder_callback(const LLUUID& inv_id) { LLInventoryModelBackgroundFetch::instance().incrFetchFolderCount(-1); LLViewerInventoryCategory * cat(gInventory.getCategory(inv_id)); - if (cat) cat->setFetching(false); + if (cat) + { + cat->setFetching(LLViewerInventoryCategory::FETCH_NONE); + } } void ais_simple_item_callback(const LLUUID& inv_id) @@ -457,24 +473,24 @@ void ais_simple_item_callback(const LLUUID& inv_id) LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); } -void LLInventoryModelBackgroundFetch::onAISFodlerCalback(const LLUUID &request_id, const LLUUID &response_id, ERecursionType recursion) +void LLInventoryModelBackgroundFetch::onAISFodlerCalback(const LLUUID &request_id, const LLUUID &response_id, EFetchType recursion) { incrFetchFolderCount(-1); if (response_id.isNull()) // Failure { - if (recursion == RT_RECURSIVE) + if (recursion == FT_RECURSIVE) { // A full recursive request failed. // Try requesting folder and nested content separately mBackgroundFetchActive = true; mFolderFetchActive = true; - mFetchFolderQueue.push_front(FetchQueueInfo(request_id, RT_CONTENT)); + mFetchFolderQueue.push_front(FetchQueueInfo(request_id, FT_CONTENT_RECURSIVE)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } } else { - if (recursion == RT_CONTENT) + if (recursion == FT_CONTENT_RECURSIVE) { // Got the folder, now recursively request content LLInventoryModel::cat_array_t * categories(NULL); @@ -484,7 +500,7 @@ void LLInventoryModelBackgroundFetch::onAISFodlerCalback(const LLUUID &request_i it != categories->end(); ++it) { - mFetchFolderQueue.push_front(FetchQueueInfo((*it)->getUUID(), RT_RECURSIVE)); + mFetchFolderQueue.push_front(FetchQueueInfo((*it)->getUUID(), FT_RECURSIVE)); } if (!mFetchFolderQueue.empty()) { @@ -499,7 +515,7 @@ void LLInventoryModelBackgroundFetch::onAISFodlerCalback(const LLUUID &request_i LLViewerInventoryCategory * cat(gInventory.getCategory(request_id)); if (cat) { - cat->setFetching(false); + cat->setFetching(LLViewerInventoryCategory::FETCH_NONE); } } @@ -561,12 +577,11 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc if (fetch_info.mIsCategory) { const LLUUID & cat_id(fetch_info.mUUID); - if (cat_id.isNull()) // Lost and found + if (cat_id.isNull()) { - LL_WARNS() << "Lost and found not implemented yet" << LL_ENDL; - // todo: needs to be requested from ais in special manner? - /*AISAPI::FetchCategoryChildren(LLUUID::null, AISAPI::INVENTORY, false, ais_simple_callback); - incrFetchFolderCount(1);*/ + // Lost and found + AISAPI::FetchCategoryChildren("lstndfnd", true, ais_simple_folder_callback); + incrFetchFolderCount(1); } else { @@ -574,32 +589,42 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); if (cat) { - if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) + if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion() || fetch_info.mFetchType == FT_FORCED) { - if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) - { - AISAPI::FetchCategoryChildren(cat->getUUID(), AISAPI::LIBRARY, fetch_info.mRecursive == RT_RECURSIVE, ais_simple_folder_callback); - } - else + LLViewerInventoryCategory::EFetchType target_state = + fetch_info.mFetchType >= FT_CONTENT_RECURSIVE + ? LLViewerInventoryCategory::FETCH_RECURSIVE + : LLViewerInventoryCategory::FETCH_NORMAL; + // start again if we did a non-recursive fetch before + if (cat->getFetching() < target_state) { - LLUUID cat_id = cat->getUUID(); - ERecursionType type = fetch_info.mRecursive; - AISAPI::FetchCategoryChildren( - cat_id, - AISAPI::INVENTORY, - type == RT_RECURSIVE, - [cat_id, type](const LLUUID &response_id) + + if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) { - LLInventoryModelBackgroundFetch::instance().onAISFodlerCalback(cat_id, response_id, type); - }); + AISAPI::FetchCategoryChildren(cat->getUUID(), AISAPI::LIBRARY, fetch_info.mFetchType == FT_RECURSIVE, ais_simple_folder_callback); + } + else + { + LLUUID cat_id = cat->getUUID(); + EFetchType type = fetch_info.mFetchType; + AISAPI::FetchCategoryChildren( + cat_id, + AISAPI::INVENTORY, + type == FT_RECURSIVE, + [cat_id, type](const LLUUID &response_id) + { + LLInventoryModelBackgroundFetch::instance().onAISFodlerCalback(cat_id, response_id, type); + }); + } + incrFetchFolderCount(1); + + cat->setFetching(target_state); } - incrFetchFolderCount(1); - cat->setFetching(true); } else { // Already fetched, check if anything inside needs fetching - if (fetch_info.mRecursive) + if (fetch_info.mFetchType >= FT_CONTENT_RECURSIVE) { LLInventoryModel::cat_array_t * categories(NULL); LLInventoryModel::item_array_t * items(NULL); @@ -609,7 +634,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc ++it) { // not push_front to not cause an infinite loop - mFetchFolderQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); + mFetchFolderQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mFetchType)); } } } @@ -622,21 +647,25 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc if (itemp) { - if (itemp->getPermissions().getOwner() == gAgent.getID()) - { - AISAPI::FetchItem(fetch_info.mUUID, AISAPI::INVENTORY, ais_simple_item_callback); - } - else + if (!itemp->isFinished() || fetch_info.mFetchType == FT_FORCED) { - AISAPI::FetchItem(fetch_info.mUUID, AISAPI::LIBRARY, ais_simple_item_callback); + if (itemp->getPermissions().getOwner() == gAgent.getID()) + { + AISAPI::FetchItem(fetch_info.mUUID, AISAPI::INVENTORY, ais_simple_item_callback); + } + else + { + AISAPI::FetchItem(fetch_info.mUUID, AISAPI::LIBRARY, ais_simple_item_callback); + } + mFetchCount++; } } - else + else // We don't know it, assume incomplete { // Assume agent's inventory, library wouldn't have gotten here AISAPI::FetchItem(fetch_info.mUUID, AISAPI::INVENTORY, ais_simple_item_callback); + mFetchCount++; } - mFetchCount++; } } @@ -736,7 +765,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch() else { // May already have this folder, but append child folders to list. - if (fetch_info.mRecursive) + if (fetch_info.mFetchType >= FT_CONTENT_RECURSIVE) { LLInventoryModel::cat_array_t * categories(NULL); LLInventoryModel::item_array_t * items(NULL); @@ -745,13 +774,13 @@ void LLInventoryModelBackgroundFetch::bulkFetch() it != categories->end(); ++it) { - mFetchFolderQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mRecursive)); + mFetchFolderQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mFetchType)); } } } } } - if (fetch_info.mRecursive) + if (fetch_info.mFetchType >= FT_CONTENT_RECURSIVE) { recursive_cats.push_back(cat_id); } diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index 6a8b616a82..eae2ba6af8 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -47,10 +47,11 @@ class LLInventoryModelBackgroundFetch : public LLSingleton fetch_queue_t; - void onAISFodlerCalback(const LLUUID &request_id, const LLUUID &response_id, ERecursionType recursion); + void onAISFodlerCalback(const LLUUID &request_id, const LLUUID &response_id, EFetchType recursion); void bulkFetchViaAis(); void bulkFetchViaAis(const FetchQueueInfo& fetch_info); void bulkFetch(); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 6f62ba5409..8ec7719ade 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -561,7 +561,8 @@ LLViewerInventoryCategory::LLViewerInventoryCategory(const LLUUID& uuid, LLInventoryCategory(uuid, parent_uuid, pref, name), mOwnerID(owner_id), mVersion(LLViewerInventoryCategory::VERSION_UNKNOWN), - mDescendentCount(LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN) + mDescendentCount(LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN), + mFetching(FETCH_NONE) { mDescendentsRequested.reset(); } @@ -569,7 +570,8 @@ LLViewerInventoryCategory::LLViewerInventoryCategory(const LLUUID& uuid, LLViewerInventoryCategory::LLViewerInventoryCategory(const LLUUID& owner_id) : mOwnerID(owner_id), mVersion(LLViewerInventoryCategory::VERSION_UNKNOWN), - mDescendentCount(LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN) + mDescendentCount(LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN), + mFetching(FETCH_NONE) { mDescendentsRequested.reset(); } @@ -670,21 +672,33 @@ bool LLViewerInventoryCategory::fetch() return false; } -void LLViewerInventoryCategory::setFetching(bool fetching) +LLViewerInventoryCategory::EFetchType LLViewerInventoryCategory::getFetching() { - if (fetching) + // if timer hasn't expired, request was scheduled, but not in progress + // if mFetching request was actually started + if (mDescendentsRequested.hasExpired()) { - if ((VERSION_UNKNOWN == getVersion()) - && mDescendentsRequested.hasExpired()) + mFetching = FETCH_NONE; + } + return mFetching; +} + +void LLViewerInventoryCategory::setFetching(LLViewerInventoryCategory::EFetchType fetching) +{ + if (fetching > mFetching) // allow a switch from normal to recursive + { + if (mDescendentsRequested.hasExpired() || (mFetching == FETCH_NONE)) { const F32 FETCH_TIMER_EXPIRY = 10.0f; mDescendentsRequested.reset(); mDescendentsRequested.setTimerExpirySec(FETCH_TIMER_EXPIRY); } + mFetching = fetching; } - else + else if (fetching = FETCH_NONE) { mDescendentsRequested.stop(); + mFetching = fetching; } } diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 2ae2cebe5c..95a4c84999 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -209,10 +209,17 @@ public: S32 getVersion() const; void setVersion(S32 version); - // Returns true if a fetch was issued. + // Returns true if a fetch was issued (not nessesary in progress). bool fetch(); - // Returns true if a fetch was issued. - void setFetching(bool); + + typedef enum { + FETCH_NONE = 0, + FETCH_NORMAL, + FETCH_RECURSIVE, + } EFetchType; + EFetchType getFetching(); + // marks as fetch being in progress or as done + void setFetching(EFetchType); // used to help make caching more robust - for example, if // someone is getting 4 packets but logs out after 3. the viewer @@ -242,6 +249,7 @@ protected: LLUUID mOwnerID; S32 mVersion; S32 mDescendentCount; + EFetchType mFetching; LLFrameTimer mDescendentsRequested; }; -- cgit v1.3 From 43ff8108f2d056b84ab2a7586951ad363c350f05 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 7 Apr 2023 20:12:09 +0300 Subject: SL-19534 Better fetch failure handling --- indra/newview/llinventorymodelbackgroundfetch.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index c8bf8f67ce..e988f949e2 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -487,6 +487,26 @@ void LLInventoryModelBackgroundFetch::onAISFodlerCalback(const LLUUID &request_i mFetchFolderQueue.push_front(FetchQueueInfo(request_id, FT_CONTENT_RECURSIVE)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } + else if (recursion == FT_CONTENT_RECURSIVE) + { + LL_WARNS() << "Failed to download folder: " << request_id << " Requesting known content separately" << LL_ENDL; + LLInventoryModel::cat_array_t *categories(NULL); + LLInventoryModel::item_array_t *items(NULL); + gInventory.getDirectDescendentsOf(request_id, categories, items); + if (categories) + { + for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); it != categories->end(); ++it) + { + mFetchFolderQueue.push_front(FetchQueueInfo((*it)->getUUID(), FT_RECURSIVE)); + } + if (!mFetchFolderQueue.empty()) + { + mBackgroundFetchActive = true; + mFolderFetchActive = true; + gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); + } + } + } } else { -- cgit v1.3 From 69e3b5fb4014ef900b129ebde49325f1b074e773 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 11 Apr 2023 01:33:24 +0300 Subject: SL-19533 Orphans plus additional logging --- indra/newview/llaisapi.cpp | 88 +++++++++++++++++++++-- indra/newview/llaisapi.h | 3 + indra/newview/llinventorymodelbackgroundfetch.cpp | 17 +++-- 3 files changed, 100 insertions(+), 8 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index f869f1652b..1efba0db7a 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -534,6 +534,35 @@ void AISAPI::FetchCategoryCategories(const LLUUID &catId, ITEM_TYPE type, bool r EnqueueAISCommand("FetchCategoryCategories", proc); } +/*static*/ +void AISAPI::FetchOrphans(completion_t callback) +{ + std::string cap = getInvCap(); + if (cap.empty()) + { + LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + return; + } + std::string url = cap + std::string("/orphans"); + + invokationFn_t getFn = boost::bind( + // Humans ignore next line. It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload. + static_cast + //---- + // _1 -> httpAdapter + // _2 -> httpRequest + // _3 -> url + // _4 -> body + // _5 -> httpOptions + // _6 -> httpHeaders + (&LLCoreHttpUtil::HttpCoroutineAdapter::getAndSuspend) , _1 , _2 , _3 , _5 , _6); + + LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro , + _1 , getFn , url , LLUUID::null , LLSD() , callback , FETCHORPHANS)); + + EnqueueAISCommand("FetchOrphans" , proc); +} + /*static*/ void AISAPI::EnqueueAISCommand(const std::string &procName, LLCoprocedureManager::CoProcedure_t proc) { @@ -595,7 +624,8 @@ void AISAPI::onUpdateReceived(const std::string& context, const LLSD& update, CO } bool is_fetch = (type == FETCHITEM) || (type == FETCHCATEGORYCHILDREN) - || (type == FETCHCATEGORYCATEGORIES); + || (type == FETCHCATEGORYCATEGORIES) + || (type == FETCHORPHANS); // parse update llsd into stuff to do or parse received items. S32 depth = 0; if (is_fetch && request_body.has("depth")) @@ -620,9 +650,30 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; - LLSD result = invoke(httpAdapter, httpRequest, url, body, httpOptions, httpHeaders); - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + LLSD result; + LLSD httpResults; + LLCore::HttpStatus status; + + if (debugLoggingEnabled("AIS3")) + { + LLTimer ais_timer; + ais_timer.start(); + result = invoke(httpAdapter , httpRequest , url , body , httpOptions , httpHeaders); + httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + F32MillisecondsImplicit elapsed_time = ais_timer.getElapsedTimeF32(); + LL_DEBUGS("AIS3") << "Request type: " << (S32)type + << " \nRequest url: " << url + << " \nRequest target: " << targetId + << " \nElapsed time: " << elapsed_time + << " \nstatus: " << status.toULong() << LL_ENDL; + } + else + { + result = invoke(httpAdapter , httpRequest , url , body , httpOptions , httpHeaders); + httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + } if (!status || !result.isMap()) { @@ -756,6 +807,7 @@ void AISUpdate::clearParseResults() mCatDescendentsKnown.clear(); mCatVersionsUpdated.clear(); mItemsCreated.clear(); + mItemsLost.clear(); mItemsUpdated.clear(); mCategoriesCreated.clear(); mCategoriesUpdated.clear(); @@ -891,6 +943,11 @@ void AISUpdate::parseItem(const LLSD& item_map) mItemsCreated[item_id] = new_item; mCatDescendentDeltas[new_item->getParentUUID()]; new_item->setComplete(true); + + if (new_item->getParentUUID().isNull()) + { + mItemsLost[item_id] = new_item; + } } else if (curr_item) { @@ -940,6 +997,11 @@ void AISUpdate::parseLink(const LLSD& link_map) mItemsCreated[item_id] = new_link; mCatDescendentDeltas[parent_id]; new_link->setComplete(true); + + if (new_link->getParentUUID().isNull()) + { + mItemsLost[item_id] = new_link; + } } else if (curr_link) { @@ -1299,6 +1361,24 @@ void AISUpdate::doUpdate() } } + // LOST ITEMS + if (!mItemsLost.empty()) + { + LL_INFOS("Inventory") << "Received " << (S32)mItemsLost.size() << " items without a parent" << LL_ENDL; + const LLUUID lost_uuid(gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND)); + if (lost_uuid.notNull()) + { + for (deferred_item_map_t::const_iterator lost_it = mItemsLost.begin(); + lost_it != mItemsLost.end(); ++lost_it) + { + LLPointer new_item = lost_it->second; + + new_item->setParent(lost_uuid); + new_item->updateParentOnServer(FALSE); + } + } + } + // CREATE ITEMS for (deferred_item_map_t::const_iterator create_it = mItemsCreated.begin(); create_it != mItemsCreated.end(); ++create_it) diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h index d083004195..4e1c6e5a7d 100644 --- a/indra/newview/llaisapi.h +++ b/indra/newview/llaisapi.h @@ -59,6 +59,7 @@ public: static void FetchCategoryChildren(const LLUUID &catId, ITEM_TYPE type = AISAPI::ITEM_TYPE::INVENTORY, bool recursive = false, completion_t callback = completion_t(), S32 depth = 0); static void FetchCategoryChildren(const std::string &identifier, bool recursive = false, completion_t callback = completion_t(), S32 depth = 0); static void FetchCategoryCategories(const LLUUID &catId, ITEM_TYPE type = AISAPI::ITEM_TYPE::INVENTORY, bool recursive = false, completion_t callback = completion_t(), S32 depth = 0); + static void FetchOrphans(completion_t callback = completion_t() ); static void CopyLibraryCategory(const LLUUID& sourceId, const LLUUID& destId, bool copySubfolders, completion_t callback = completion_t()); private: @@ -75,6 +76,7 @@ private: FETCHITEM, FETCHCATEGORYCHILDREN, FETCHCATEGORYCATEGORIES, + FETCHORPHANS, } COMMAND_TYPE; static const std::string INVENTORY_CAP_NAME; @@ -127,6 +129,7 @@ private: typedef std::map > deferred_item_map_t; deferred_item_map_t mItemsCreated; + deferred_item_map_t mItemsLost; deferred_item_map_t mItemsUpdated; typedef std::map > deferred_category_map_t; deferred_category_map_t mCategoriesCreated; diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index e988f949e2..35b9442966 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -461,10 +461,13 @@ void LLInventoryModelBackgroundFetch::incrFetchFolderCount(S32 fetching) void ais_simple_folder_callback(const LLUUID& inv_id) { LLInventoryModelBackgroundFetch::instance().incrFetchFolderCount(-1); - LLViewerInventoryCategory * cat(gInventory.getCategory(inv_id)); - if (cat) + if (inv_id.notNull()) // null normally means a failure, but is an expected response for orphans { - cat->setFetching(LLViewerInventoryCategory::FETCH_NONE); + LLViewerInventoryCategory* cat(gInventory.getCategory(inv_id)); + if (cat) + { + cat->setFetching(LLViewerInventoryCategory::FETCH_NONE); + } } } @@ -580,6 +583,11 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() mFetchItemQueue.pop_front(); curent_time = LLTimer::getTotalSeconds(); } + + LL_DEBUGS(LOG_INV , "AIS3") << "Total active fetches: " << mFetchCount + << ", scheduled fodler fetches: " << (S32)mFetchFolderQueue.size() + << ", scheduled item fetches: " << (S32)mFetchItemQueue.size() + << LL_ENDL; if (isFolderFetchProcessingComplete() && mFolderFetchActive) { @@ -600,7 +608,8 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc if (cat_id.isNull()) { // Lost and found - AISAPI::FetchCategoryChildren("lstndfnd", true, ais_simple_folder_callback); + // Should it actually be recursive? + AISAPI::FetchOrphans(ais_simple_folder_callback); incrFetchFolderCount(1); } else -- cgit v1.3 From 8171224a6510ac8b984dace5f10a6f92cb1e2942 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 11 Apr 2023 19:26:21 +0300 Subject: SL-19533 Don't fetch items if recursive fetch isn't done --- indra/newview/llinventorymodelbackgroundfetch.cpp | 21 +++++++++++++-------- indra/newview/llinventorymodelbackgroundfetch.h | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 35b9442966..0099e81b8f 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -191,7 +191,7 @@ LLInventoryModelBackgroundFetch::LLInventoryModelBackgroundFetch(): mFolderFetchActive(false), mFetchCount(0), mFetchFolderCount(0), - mAllFoldersFetched(false), + mAllRecursiveFoldersFetched(false), mRecursiveInventoryFetchStarted(false), mRecursiveLibraryFetchStarted(false), mMinTimeBetweenFetches(0.3f) @@ -242,7 +242,7 @@ bool LLInventoryModelBackgroundFetch::inventoryFetchInProgress() const bool LLInventoryModelBackgroundFetch::isEverythingFetched() const { - return mAllFoldersFetched; + return mAllRecursiveFoldersFetched; } BOOL LLInventoryModelBackgroundFetch::folderFetchActive() const @@ -395,7 +395,7 @@ void LLInventoryModelBackgroundFetch::setAllFoldersFetched() if (mRecursiveInventoryFetchStarted && mRecursiveLibraryFetchStarted) { - mAllFoldersFetched = true; + mAllRecursiveFoldersFetched = true; //LL_INFOS(LOG_INV) << "All folders fetched, validating" << LL_ENDL; //gInventory.validate(); } @@ -576,12 +576,17 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() curent_time = LLTimer::getTotalSeconds(); } - while (!mFetchItemQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time) + if (mRecursiveInventoryFetchStarted && mAllRecursiveFoldersFetched) { - const FetchQueueInfo & fetch_info(mFetchItemQueue.front()); - bulkFetchViaAis(fetch_info); - mFetchItemQueue.pop_front(); - curent_time = LLTimer::getTotalSeconds(); + // Don't fetch items if recursive fetch isn't done, + // it gets both items and folders and should get the items in question faster + while (!mFetchItemQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time) + { + const FetchQueueInfo& fetch_info(mFetchItemQueue.front()); + bulkFetchViaAis(fetch_info); + mFetchItemQueue.pop_front(); + curent_time = LLTimer::getTotalSeconds(); + } } LL_DEBUGS(LOG_INV , "AIS3") << "Total active fetches: " << mFetchCount diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index eae2ba6af8..bd54c17c8d 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -113,7 +113,7 @@ protected: private: bool mRecursiveInventoryFetchStarted; bool mRecursiveLibraryFetchStarted; - bool mAllFoldersFetched; + bool mAllRecursiveFoldersFetched; typedef boost::signals2::signal folders_fetched_signal_t; folders_fetched_signal_t mFoldersFetchedSignal; -- cgit v1.3 From 5e59ab0ab77d91f9d855bd5a3fc0e5c691220f01 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 11 Apr 2023 23:12:32 +0300 Subject: SL-19533 Further logging improvements --- indra/newview/llaisapi.cpp | 65 +++++++++++++++++++++-- indra/newview/llinventorymodelbackgroundfetch.cpp | 26 ++++++--- indra/newview/llinventorymodelbackgroundfetch.h | 1 + indra/newview/llviewerinventory.cpp | 2 +- 4 files changed, 82 insertions(+), 12 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 1efba0db7a..92589540f1 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -29,6 +29,7 @@ #include "llaisapi.h" #include "llagent.h" +#include "llappviewer.h" #include "llcallbacklist.h" #include "llinventorymodel.h" #include "llsdutil.h" @@ -95,7 +96,10 @@ void AISAPI::CreateInventory(const LLUUID& parentId, const LLSD& newInventory, c if (cap.empty()) { LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; - callback(LLUUID::null); + if (callback) + { + callback(LLUUID::null); + } return; } @@ -138,6 +142,10 @@ void AISAPI::SlamFolder(const LLUUID& folderId, const LLSD& newInventory, comple if (cap.empty()) { LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + if (callback) + { + callback(LLUUID::null); + } return; } @@ -173,6 +181,10 @@ void AISAPI::RemoveCategory(const LLUUID &categoryId, completion_t callback) if (cap.empty()) { LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + if (callback) + { + callback(LLUUID::null); + } return; } @@ -206,6 +218,10 @@ void AISAPI::RemoveItem(const LLUUID &itemId, completion_t callback) if (cap.empty()) { LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + if (callback) + { + callback(LLUUID::null); + } return; } @@ -238,6 +254,10 @@ void AISAPI::CopyLibraryCategory(const LLUUID& sourceId, const LLUUID& destId, b if (cap.empty()) { LL_WARNS("Inventory") << "Library cap not found!" << LL_ENDL; + if (callback) + { + callback(LLUUID::null); + } return; } @@ -282,6 +302,10 @@ void AISAPI::PurgeDescendents(const LLUUID &categoryId, completion_t callback) if (cap.empty()) { LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + if (callback) + { + callback(LLUUID::null); + } return; } @@ -316,6 +340,10 @@ void AISAPI::UpdateCategory(const LLUUID &categoryId, const LLSD &updates, compl if (cap.empty()) { LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + if (callback) + { + callback(LLUUID::null); + } return; } std::string url = cap + std::string("/category/") + categoryId.asString(); @@ -348,6 +376,10 @@ void AISAPI::UpdateItem(const LLUUID &itemId, const LLSD &updates, completion_t if (cap.empty()) { LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + if (callback) + { + callback(LLUUID::null); + } return; } std::string url = cap + std::string("/item/") + itemId.asString(); @@ -379,6 +411,10 @@ void AISAPI::FetchItem(const LLUUID &itemId, ITEM_TYPE type, completion_t callba if (cap.empty()) { LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + if (callback) + { + callback(LLUUID::null); + } return; } std::string url = cap + std::string("/item/") + itemId.asString(); @@ -410,7 +446,10 @@ void AISAPI::FetchCategoryChildren(const LLUUID &catId, ITEM_TYPE type, bool rec if (cap.empty()) { LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; - callback(LLUUID::null); + if (callback) + { + callback(LLUUID::null); + } return; } std::string url = cap + std::string("/category/") + catId.asString() + "/children"; @@ -456,7 +495,10 @@ void AISAPI::FetchCategoryChildren(const std::string &identifier, bool recursive if (cap.empty()) { LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; - callback(LLUUID::null); + if (callback) + { + callback(LLUUID::null); + } return; } std::string url = cap + std::string("/category/") + identifier + "/children"; @@ -500,6 +542,10 @@ void AISAPI::FetchCategoryCategories(const LLUUID &catId, ITEM_TYPE type, bool r if (cap.empty()) { LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + if (callback) + { + callback(LLUUID::null); + } return; } std::string url = cap + std::string("/category/") + catId.asString() + "/categories"; @@ -541,6 +587,10 @@ void AISAPI::FetchOrphans(completion_t callback) if (cap.empty()) { LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + if (callback) + { + callback(LLUUID::null); + } return; } std::string url = cap + std::string("/orphans"); @@ -642,6 +692,15 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht invokationFn_t invoke, std::string url, LLUUID targetId, LLSD body, completion_t callback, COMMAND_TYPE type) { + if (gDisconnected) + { + if (callback) + { + callback(LLUUID::null); + } + return; + } + LLCore::HttpOptions::ptr_t httpOptions(new LLCore::HttpOptions); LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); LLCore::HttpHeaders::ptr_t httpHeaders; diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 0099e81b8f..955f152195 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -190,6 +190,7 @@ LLInventoryModelBackgroundFetch::LLInventoryModelBackgroundFetch(): mBackgroundFetchActive(false), mFolderFetchActive(false), mFetchCount(0), + mLastFetchCount(0), mFetchFolderCount(0), mAllRecursiveFoldersFetched(false), mRecursiveInventoryFetchStarted(false), @@ -424,13 +425,13 @@ void LLInventoryModelBackgroundFetch::backgroundFetchCB(void *) void LLInventoryModelBackgroundFetch::backgroundFetch() { - if (mBackgroundFetchActive && gAgent.getRegion() && gAgent.getRegion()->capabilitiesReceived()) + if (mBackgroundFetchActive) { if (AISAPI::isAvailable()) { bulkFetchViaAis(); } - else + else if (gAgent.getRegion() && gAgent.getRegion()->capabilitiesReceived()) { // If we'll be using the capability, we'll be sending batches and the background thing isn't as important. bulkFetch(); @@ -460,6 +461,7 @@ void LLInventoryModelBackgroundFetch::incrFetchFolderCount(S32 fetching) void ais_simple_folder_callback(const LLUUID& inv_id) { + LL_DEBUGS("AIS3") << "Response for folder " << inv_id << LL_ENDL; LLInventoryModelBackgroundFetch::instance().incrFetchFolderCount(-1); if (inv_id.notNull()) // null normally means a failure, but is an expected response for orphans { @@ -473,6 +475,7 @@ void ais_simple_folder_callback(const LLUUID& inv_id) void ais_simple_item_callback(const LLUUID& inv_id) { + LL_DEBUGS("AIS3") << "Response for " << inv_id << LL_ENDL; LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); } @@ -481,6 +484,7 @@ void LLInventoryModelBackgroundFetch::onAISFodlerCalback(const LLUUID &request_i incrFetchFolderCount(-1); if (response_id.isNull()) // Failure { + LL_DEBUGS("AIS3") << "Failure response for folder " << request_id << LL_ENDL; if (recursion == FT_RECURSIVE) { // A full recursive request failed. @@ -513,6 +517,7 @@ void LLInventoryModelBackgroundFetch::onAISFodlerCalback(const LLUUID &request_i } else { + LL_DEBUGS("AIS3") << "Got folder " << request_id << LL_ENDL; if (recursion == FT_CONTENT_RECURSIVE) { // Got the folder, now recursively request content @@ -567,6 +572,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() ? 0.006f // 6 ms : 1.f; const F64 end_time = curent_time + max_time; + S32 last_fetch_count = mFetchCount; while (!mFetchFolderQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time) { @@ -589,10 +595,15 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() } } - LL_DEBUGS(LOG_INV , "AIS3") << "Total active fetches: " << mFetchCount - << ", scheduled fodler fetches: " << (S32)mFetchFolderQueue.size() - << ", scheduled item fetches: " << (S32)mFetchItemQueue.size() - << LL_ENDL; + if (last_fetch_count != mFetchCount // if anything was added + || mLastFetchCount != mFetchCount) // if anything was substracted + { + mLastFetchCount = mFetchCount; + LL_DEBUGS(LOG_INV , "AIS3") << "Total active fetches: " << last_fetch_count << "->" << mFetchCount + << ", scheduled fodler fetches: " << (S32)mFetchFolderQueue.size() + << ", scheduled item fetches: " << (S32)mFetchItemQueue.size() + << LL_ENDL; + } if (isFolderFetchProcessingComplete() && mFolderFetchActive) { @@ -619,7 +630,6 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc } else { - LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); if (cat) { @@ -630,9 +640,9 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc ? LLViewerInventoryCategory::FETCH_RECURSIVE : LLViewerInventoryCategory::FETCH_NORMAL; // start again if we did a non-recursive fetch before + // to get all children in a single request if (cat->getFetching() < target_state) { - if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) { AISAPI::FetchCategoryChildren(cat->getUUID(), AISAPI::LIBRARY, fetch_info.mFetchType == FT_RECURSIVE, ais_simple_folder_callback); diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index bd54c17c8d..6c2c3e96fa 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -120,6 +120,7 @@ private: bool mBackgroundFetchActive; bool mFolderFetchActive; S32 mFetchCount; + S32 mLastFetchCount; // for debug S32 mFetchFolderCount; LLFrameTimer mFetchTimer; diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index c4edc3952b..cd51a00c52 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -689,7 +689,7 @@ void LLViewerInventoryCategory::setFetching(LLViewerInventoryCategory::EFetchTyp { if (mDescendentsRequested.hasExpired() || (mFetching == FETCH_NONE)) { - const F32 FETCH_TIMER_EXPIRY = 10.0f; + const F32 FETCH_TIMER_EXPIRY = 30.0f; mDescendentsRequested.reset(); mDescendentsRequested.setTimerExpirySec(FETCH_TIMER_EXPIRY); } -- cgit v1.3 From 627c4e45baec177dd8e0a07b0c3137492819c0ca Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 12 Apr 2023 00:25:34 +0300 Subject: SL-19533 Track folder fetch requests in bulk fetch --- indra/newview/llinventorymodelbackgroundfetch.cpp | 108 ++++++++++++++-------- indra/newview/llinventorymodelbackgroundfetch.h | 4 +- 2 files changed, 73 insertions(+), 39 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 955f152195..cab3010cf1 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -459,29 +459,33 @@ void LLInventoryModelBackgroundFetch::incrFetchFolderCount(S32 fetching) } } -void ais_simple_folder_callback(const LLUUID& inv_id) -{ - LL_DEBUGS("AIS3") << "Response for folder " << inv_id << LL_ENDL; - LLInventoryModelBackgroundFetch::instance().incrFetchFolderCount(-1); - if (inv_id.notNull()) // null normally means a failure, but is an expected response for orphans - { - LLViewerInventoryCategory* cat(gInventory.getCategory(inv_id)); - if (cat) - { - cat->setFetching(LLViewerInventoryCategory::FETCH_NONE); - } - } -} - void ais_simple_item_callback(const LLUUID& inv_id) { LL_DEBUGS("AIS3") << "Response for " << inv_id << LL_ENDL; LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); } -void LLInventoryModelBackgroundFetch::onAISFodlerCalback(const LLUUID &request_id, const LLUUID &response_id, EFetchType recursion) +void LLInventoryModelBackgroundFetch::onAISFolderCalback(const LLUUID &request_id, const LLUUID &response_id, EFetchType recursion) { incrFetchFolderCount(-1); + std::list::const_iterator found = std::find(mExpectedFolderIds.begin() , mExpectedFolderIds.end(), request_id); + if (found != mExpectedFolderIds.end()) + { + mExpectedFolderIds.erase(found); + } + else + { + // ais shouldn't respond twice + llassert(false); + LL_WARNS() << "Unexpected folder response for " << request_id << LL_ENDL; + } + + if (request_id.isNull()) + { + // orhans, no other actions needed + return; + } + if (response_id.isNull()) // Failure { LL_DEBUGS("AIS3") << "Failure response for folder " << request_id << LL_ENDL; @@ -598,11 +602,36 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() if (last_fetch_count != mFetchCount // if anything was added || mLastFetchCount != mFetchCount) // if anything was substracted { - mLastFetchCount = mFetchCount; - LL_DEBUGS(LOG_INV , "AIS3") << "Total active fetches: " << last_fetch_count << "->" << mFetchCount + LL_DEBUGS(LOG_INV , "AIS3") << "Total active fetches: " << mLastFetchCount << "->" << last_fetch_count << "->" << mFetchCount << ", scheduled fodler fetches: " << (S32)mFetchFolderQueue.size() << ", scheduled item fetches: " << (S32)mFetchItemQueue.size() << LL_ENDL; + mLastFetchCount = mFetchCount; + + if (!mExpectedFolderIds.empty()) + { + // A folder seem to be stack fetching on QA account, print oldest folder out + LL_DEBUGS("AIS3") << "Oldest expected folder: "; + std::list::const_iterator iter = mExpectedFolderIds.begin(); + LL_CONT << *iter; + if ((*iter).notNull()) + { + LLViewerInventoryCategory* cat(gInventory.getCategory(*iter)); + if (cat) + { + LL_CONT << " Folder name: " << cat->getName() << " Parent: " << cat->getParentUUID(); + } + else + { + LL_CONT << " This folder doesn't exist"; + } + } + else + { + LL_CONT << " Orphans request"; + } + LL_CONT << LL_ENDL; + } } if (isFolderFetchProcessingComplete() && mFolderFetchActive) @@ -623,10 +652,16 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc const LLUUID & cat_id(fetch_info.mUUID); if (cat_id.isNull()) { + incrFetchFolderCount(1); + mExpectedFolderIds.push_back(cat_id); // Lost and found // Should it actually be recursive? - AISAPI::FetchOrphans(ais_simple_folder_callback); - incrFetchFolderCount(1); + AISAPI::FetchOrphans([](const LLUUID& response_id) + { + LLInventoryModelBackgroundFetch::instance().onAISFolderCalback(LLUUID::null, + response_id, + FT_DEFAULT); + }); } else { @@ -643,26 +678,25 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc // to get all children in a single request if (cat->getFetching() < target_state) { - if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) + // increment before call in case of immediate callback + incrFetchFolderCount(1); + cat->setFetching(target_state); + mExpectedFolderIds.push_back(cat_id); + + EFetchType type = fetch_info.mFetchType; + LLUUID cat_id = cat->getUUID(); + AISAPI::completion_t cb = [cat_id , type](const LLUUID& response_id) { - AISAPI::FetchCategoryChildren(cat->getUUID(), AISAPI::LIBRARY, fetch_info.mFetchType == FT_RECURSIVE, ais_simple_folder_callback); - } - else + LLInventoryModelBackgroundFetch::instance().onAISFolderCalback(cat_id , response_id , type); + }; + + AISAPI::ITEM_TYPE item_type = AISAPI::INVENTORY; + if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) { - LLUUID cat_id = cat->getUUID(); - EFetchType type = fetch_info.mFetchType; - AISAPI::FetchCategoryChildren( - cat_id, - AISAPI::INVENTORY, - type == FT_RECURSIVE, - [cat_id, type](const LLUUID &response_id) - { - LLInventoryModelBackgroundFetch::instance().onAISFodlerCalback(cat_id, response_id, type); - }); + item_type = AISAPI::LIBRARY; } - incrFetchFolderCount(1); - cat->setFetching(target_state); + AISAPI::FetchCategoryChildren(cat_id , item_type , type == FT_RECURSIVE , cb); } } else @@ -693,6 +727,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc { if (!itemp->isFinished() || fetch_info.mFetchType == FT_FORCED) { + mFetchCount++; if (itemp->getPermissions().getOwner() == gAgent.getID()) { AISAPI::FetchItem(fetch_info.mUUID, AISAPI::INVENTORY, ais_simple_item_callback); @@ -701,14 +736,13 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc { AISAPI::FetchItem(fetch_info.mUUID, AISAPI::LIBRARY, ais_simple_item_callback); } - mFetchCount++; } } else // We don't know it, assume incomplete { // Assume agent's inventory, library wouldn't have gotten here - AISAPI::FetchItem(fetch_info.mUUID, AISAPI::INVENTORY, ais_simple_item_callback); mFetchCount++; + AISAPI::FetchItem(fetch_info.mUUID, AISAPI::INVENTORY, ais_simple_item_callback); } } } diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index 6c2c3e96fa..1881322e7a 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -100,7 +100,7 @@ protected: }; typedef std::deque fetch_queue_t; - void onAISFodlerCalback(const LLUUID &request_id, const LLUUID &response_id, EFetchType recursion); + void onAISFolderCalback(const LLUUID &request_id, const LLUUID &response_id, EFetchType recursion); void bulkFetchViaAis(); void bulkFetchViaAis(const FetchQueueInfo& fetch_info); void bulkFetch(); @@ -127,7 +127,7 @@ private: F32 mMinTimeBetweenFetches; fetch_queue_t mFetchFolderQueue; fetch_queue_t mFetchItemQueue; - + std::list mExpectedFolderIds; // for debug, should this track time? }; #endif // LL_LLINVENTORYMODELBACKGROUNDFETCH_H -- cgit v1.3 From 1f2cbfdbe227bda2f3bd2b17b5ac1b125cb28b2d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 12 Apr 2023 00:53:48 +0300 Subject: SL-19533 Content should be recursive only --- indra/newview/llinventorymodelbackgroundfetch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index cab3010cf1..69f688d51e 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -712,7 +712,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc ++it) { // not push_front to not cause an infinite loop - mFetchFolderQueue.push_back(FetchQueueInfo((*it)->getUUID(), fetch_info.mFetchType)); + mFetchFolderQueue.push_back(FetchQueueInfo((*it)->getUUID(), FT_RECURSIVE)); } } } -- cgit v1.3 From 8b1a7085be07704a58e169d1133fc356a1745c74 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 12 Apr 2023 19:13:32 +0300 Subject: SL-19533 Logging tag change --- indra/newview/llaisapi.cpp | 13 ++++++------- indra/newview/llinventorymodelbackgroundfetch.cpp | 8 ++++---- 2 files changed, 10 insertions(+), 11 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 92589540f1..ef3305a69d 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -684,7 +684,7 @@ void AISAPI::onUpdateReceived(const std::string& context, const LLSD& update, CO } AISUpdate ais_update(update, is_fetch, depth); ais_update.doUpdate(); // execute the updates in the appropriate order. - LL_DEBUGS("Inventory") << "elapsed: " << timer.getElapsedTimeF32() << LL_ENDL; + LL_DEBUGS("Inventory", "AIS3") << "Elapsed processing: " << timer.getElapsedTimeF32() << LL_ENDL; } /*static*/ @@ -707,13 +707,11 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht httpOptions->setTimeout(180); - LL_DEBUGS("Inventory") << "url: " << url << LL_ENDL; - LLSD result; LLSD httpResults; LLCore::HttpStatus status; - if (debugLoggingEnabled("AIS3")) + if (debugLoggingEnabled("Inventory")) { LLTimer ais_timer; ais_timer.start(); @@ -721,10 +719,11 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); F32MillisecondsImplicit elapsed_time = ais_timer.getElapsedTimeF32(); - LL_DEBUGS("AIS3") << "Request type: " << (S32)type + + LL_DEBUGS("Inventory") << "Request type: " << (S32)type << " \nRequest url: " << url << " \nRequest target: " << targetId - << " \nElapsed time: " << elapsed_time + << " \nElapsed time ince request: " << elapsed_time << " \nstatus: " << status.toULong() << LL_ENDL; } else @@ -785,7 +784,7 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht LL_WARNS("Inventory") << ll_pretty_print_sd(result) << LL_ENDL; } - LL_DEBUGS("Inventory") << result << LL_ENDL; + LL_DEBUGS("Inventory", "AIS3") << "Result: " << result << LL_ENDL; onUpdateReceived("AISCommand", result, type, body); if (callback && !callback.empty()) diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 69f688d51e..f650cc383f 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -461,7 +461,7 @@ void LLInventoryModelBackgroundFetch::incrFetchFolderCount(S32 fetching) void ais_simple_item_callback(const LLUUID& inv_id) { - LL_DEBUGS("AIS3") << "Response for " << inv_id << LL_ENDL; + LL_DEBUGS(LOG_INV , "AIS3") << "Response for " << inv_id << LL_ENDL; LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); } @@ -488,7 +488,7 @@ void LLInventoryModelBackgroundFetch::onAISFolderCalback(const LLUUID &request_i if (response_id.isNull()) // Failure { - LL_DEBUGS("AIS3") << "Failure response for folder " << request_id << LL_ENDL; + LL_DEBUGS(LOG_INV , "AIS3") << "Failure response for folder " << request_id << LL_ENDL; if (recursion == FT_RECURSIVE) { // A full recursive request failed. @@ -521,7 +521,7 @@ void LLInventoryModelBackgroundFetch::onAISFolderCalback(const LLUUID &request_i } else { - LL_DEBUGS("AIS3") << "Got folder " << request_id << LL_ENDL; + LL_DEBUGS(LOG_INV , "AIS3") << "Got folder " << request_id << LL_ENDL; if (recursion == FT_CONTENT_RECURSIVE) { // Got the folder, now recursively request content @@ -611,7 +611,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() if (!mExpectedFolderIds.empty()) { // A folder seem to be stack fetching on QA account, print oldest folder out - LL_DEBUGS("AIS3") << "Oldest expected folder: "; + LL_DEBUGS(LOG_INV , "AIS3") << "Oldest expected folder: "; std::list::const_iterator iter = mExpectedFolderIds.begin(); LL_CONT << *iter; if ((*iter).notNull()) -- cgit v1.3 From 53f2e1710aab77361085fe2c2a41fea87ede0fb8 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 13 Apr 2023 02:20:33 +0300 Subject: SL-19533 Faster declouding --- indra/newview/llaisapi.cpp | 3 +- indra/newview/llappearancemgr.cpp | 98 ++++++++++++++++------- indra/newview/llappearancemgr.h | 1 - indra/newview/llinventorymodel.cpp | 50 ++++++++++-- indra/newview/llinventorymodel.h | 4 +- indra/newview/llinventorymodelbackgroundfetch.cpp | 20 +++-- indra/newview/llviewerinventory.cpp | 1 + 7 files changed, 126 insertions(+), 51 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index ef3305a69d..7a87fc6c3d 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -707,6 +707,8 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht httpOptions->setTimeout(180); + LL_DEBUGS("Inventory") << "Request url: " << url << LL_ENDL; + LLSD result; LLSD httpResults; LLCore::HttpStatus status; @@ -721,7 +723,6 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht F32MillisecondsImplicit elapsed_time = ais_timer.getElapsedTimeF32(); LL_DEBUGS("Inventory") << "Request type: " << (S32)type - << " \nRequest url: " << url << " \nRequest target: " << targetId << " \nElapsed time ince request: " << elapsed_time << " \nstatus: " << status.toULong() << LL_ENDL; diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 59bf418a00..e160b5813f 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -586,6 +586,66 @@ LLUpdateAppearanceAndEditWearableOnDestroy::~LLUpdateAppearanceAndEditWearableOn } } +class LLBrokenLinkObserver : public LLInventoryObserver +{ +public: + LLUUID mUUID; + bool mEnforceItemRestrictions; + bool mEnforceOrdering; + nullary_func_t mPostUpdateFunc; + + LLBrokenLinkObserver(const LLUUID& uuid, + bool enforce_item_restrictions , + bool enforce_ordering , + nullary_func_t post_update_func) : + mUUID(uuid), + mEnforceItemRestrictions(enforce_item_restrictions), + mEnforceOrdering(enforce_ordering), + mPostUpdateFunc(post_update_func) + { + } + /* virtual */ void changed(U32 mask); + void postProcess(); +}; + +void LLBrokenLinkObserver::changed(U32 mask) +{ + if (mask & LLInventoryObserver::REBUILD) + { + // This observer should be executed after LLInventoryPanel::itemChanged(), + // but if it isn't, consider calling updateAppearanceFromCOF with a delay + const uuid_set_t& changed_item_ids = gInventory.getChangedIDs(); + for (uuid_set_t::const_iterator it = changed_item_ids.begin(); it != changed_item_ids.end(); ++it) + { + const LLUUID& id = *it; + if (id == mUUID) + { + // Might not be processed yet and it is not a + // good idea to update appearane here, postpone. + doOnIdleOneTime([this]() + { + postProcess(); + }); + + gInventory.removeObserver(this); + return; + } + } + } +} + +void LLBrokenLinkObserver::postProcess() +{ + LLViewerInventoryItem* item = gInventory.getItem(mUUID); + llassert(item && !item->getIsBrokenLink()); // the whole point was to get a correct link + + LLAppearanceMgr::instance().updateAppearanceFromCOF( + mEnforceItemRestrictions , + mEnforceOrdering , + mPostUpdateFunc); + delete this; +} + struct LLFoundData { @@ -2435,35 +2495,16 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions, { // Some links haven't loaded yet, but fetch isn't complete so // links are likely fine and we will have to wait for them to - // load (if inventory takes too long to load, might be a good - // idea to make this check periodical) + // load if (LLInventoryModelBackgroundFetch::getInstance()->folderFetchActive()) { - if (!mBulkFecthCallbackSlot.connected()) - { - nullary_func_t cb = post_update_func; - mBulkFecthCallbackSlot = - LLInventoryModelBackgroundFetch::getInstance()->setFetchCompletionCallback( - [this, enforce_ordering, post_update_func, cb]() - { - // inventory model should be already tracking this - // callback, but make sure rebuildBrockenLinks gets - // called before a cof update - gInventory.rebuildBrockenLinks(); - updateAppearanceFromCOF(enforce_ordering, post_update_func, post_update_func); - mBulkFecthCallbackSlot.disconnect(); - }); - } - return; - } - else - { - // this should have happened on completion callback, - // check why it didn't then fix it - llassert(false); - // try to recover now - gInventory.rebuildBrockenLinks(); + LLBrokenLinkObserver* observer = new LLBrokenLinkObserver(cof_items.front()->getUUID(), + enforce_item_restrictions, + enforce_ordering, + post_update_func); + gInventory.addObserver(observer); + return; } } } @@ -4262,11 +4303,6 @@ LLAppearanceMgr::LLAppearanceMgr(): LLAppearanceMgr::~LLAppearanceMgr() { mActive = false; - - if (!mBulkFecthCallbackSlot.connected()) - { - mBulkFecthCallbackSlot.disconnect(); - } } void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val) diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index edb4be83bb..cf953d21ac 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -264,7 +264,6 @@ private: bool mIsInUpdateAppearanceFromCOF; // to detect recursive calls. bool mOutstandingAppearanceBakeRequest; // A bake request is outstanding. Do not overlap. bool mRerequestAppearanceBake; - boost::signals2::connection mBulkFecthCallbackSlot; /** * Lock for blocking operations on outfit until server reply or timeout exceed diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 4bca2ce650..32acd0eb03 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1764,11 +1764,19 @@ void LLInventoryModel::rebuildBrockenLinks() // make sure we aren't adding expensive Rebuild to anything else. notifyObservers(); - for (const LLUUID &link_id : mPossiblyBrockenLinks) + for (const broken_links_t::value_type &link_list : mPossiblyBrockenLinks) { - addChangedMask(LLInventoryObserver::REBUILD, link_id); + for (const LLUUID& link_id : link_list.second) + { + addChangedMask(LLInventoryObserver::REBUILD , link_id); + } + } + for (const LLUUID& link_id : mLinksRebuildList) + { + addChangedMask(LLInventoryObserver::REBUILD , link_id); } mPossiblyBrockenLinks.clear(); + mLinksRebuildList.clear(); notifyObservers(); } @@ -2075,6 +2083,20 @@ void LLInventoryModel::idleNotifyObservers() { // *FIX: Think I want this conditional or moved elsewhere... handleResponses(true); + + if (mLinksRebuildList.size() > 0) + { + if (mModifyMask != LLInventoryObserver::NONE || (mChangedItemIDs.size() != 0)) + { + notifyObservers(); + } + for (const LLUUID& link_id : mLinksRebuildList) + { + addChangedMask(LLInventoryObserver::REBUILD , link_id); + } + mLinksRebuildList.clear(); + notifyObservers(); + } if (mModifyMask == LLInventoryObserver::NONE && (mChangedItemIDs.size() == 0)) { @@ -2394,11 +2416,14 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) // The item will show up as a broken link. if (item->getIsBrokenLink()) { - if (LLInventoryModelBackgroundFetch::getInstance()->folderFetchActive()) + if (item->getAssetUUID().notNull() + && LLInventoryModelBackgroundFetch::getInstance()->folderFetchActive()) { - // isEverythingFetched is actually 'initial' fetch only. - // Schedule this link for a recheck once inventory gets loaded - mPossiblyBrockenLinks.insert(item->getUUID()); + // Schedule this link for a recheck as inventory gets loaded + // Todo: expand to cover not just an initial fetch + mPossiblyBrockenLinks[item->getAssetUUID()].insert(item->getUUID()); + + // Do a blank rebuild of links once fetch is done if (!mBulkFecthCallbackSlot.connected()) { // Links might take a while to update this way, and there @@ -2408,6 +2433,9 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) LLInventoryModelBackgroundFetch::getInstance()->setFetchCompletionCallback( [this]() { + // rebuild is just in case, primary purpose is to wipe + // the list since we won't be getting anything 'new' + // see mLinksRebuildList rebuildBrockenLinks(); mBulkFecthCallbackSlot.disconnect(); }); @@ -2424,6 +2452,16 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) << " assetID: " << item->getAssetUUID() << " ) parent: " << item->getParentUUID() << LL_ENDL; } } + if (!mPossiblyBrockenLinks.empty()) + { + // check if we are waiting for this item + broken_links_t::iterator iter = mPossiblyBrockenLinks.find(item->getUUID()); + if (iter != mPossiblyBrockenLinks.end()) + { + mLinksRebuildList.insert(iter->second.begin() , iter->second.end()); + mPossiblyBrockenLinks.erase(iter); + } + } if (item->getIsLinkType()) { // Add back-link from linked-to UUID. diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index b506eaac62..db159d480a 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -580,7 +580,9 @@ private: U32 mModifyMaskBacklog; changed_items_t mChangedItemIDsBacklog; changed_items_t mAddedItemIDsBacklog; - changed_items_t mPossiblyBrockenLinks; + typedef std::map broken_links_t; + broken_links_t mPossiblyBrockenLinks; // there can be multiple links per item + changed_items_t mLinksRebuildList; boost::signals2::connection mBulkFecthCallbackSlot; diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index f650cc383f..56646830a2 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -586,17 +586,15 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() curent_time = LLTimer::getTotalSeconds(); } - if (mRecursiveInventoryFetchStarted && mAllRecursiveFoldersFetched) + // Ideally we shouldn't fetch items if recursive fetch isn't done, + // but there is a chance some request will start timeouting and recursive + // fetch will get stuck on a signle folder, don't block item fetch in such case + while (!mFetchItemQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time) { - // Don't fetch items if recursive fetch isn't done, - // it gets both items and folders and should get the items in question faster - while (!mFetchItemQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time) - { - const FetchQueueInfo& fetch_info(mFetchItemQueue.front()); - bulkFetchViaAis(fetch_info); - mFetchItemQueue.pop_front(); - curent_time = LLTimer::getTotalSeconds(); - } + const FetchQueueInfo& fetch_info(mFetchItemQueue.front()); + bulkFetchViaAis(fetch_info); + mFetchItemQueue.pop_front(); + curent_time = LLTimer::getTotalSeconds(); } if (last_fetch_count != mFetchCount // if anything was added @@ -696,7 +694,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc item_type = AISAPI::LIBRARY; } - AISAPI::FetchCategoryChildren(cat_id , item_type , type == FT_RECURSIVE , cb); + AISAPI::FetchCategoryChildren(cat_id , item_type , type == FT_RECURSIVE , cb, 0); } } else diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index cd51a00c52..01ad4f0f09 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -579,6 +579,7 @@ LLViewerInventoryCategory::LLViewerInventoryCategory(const LLUUID& owner_id) : LLViewerInventoryCategory::LLViewerInventoryCategory(const LLViewerInventoryCategory* other) { copyViewerCategory(other); + mFetching = FETCH_NONE; } LLViewerInventoryCategory::~LLViewerInventoryCategory() -- cgit v1.3 From 97b0f637dfbd4ab2b3fe79442e9f847cf7a6efca Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 19 Apr 2023 00:20:09 +0300 Subject: SL-19533 Check descendants even for a recursive fetch --- indra/newview/llinventorymodelbackgroundfetch.cpp | 48 ++++++++++++----------- 1 file changed, 25 insertions(+), 23 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 56646830a2..bfb5ad9d12 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -486,6 +486,7 @@ void LLInventoryModelBackgroundFetch::onAISFolderCalback(const LLUUID &request_i return; } + bool request_descendants = false; if (response_id.isNull()) // Failure { LL_DEBUGS(LOG_INV , "AIS3") << "Failure response for folder " << request_id << LL_ENDL; @@ -501,36 +502,37 @@ void LLInventoryModelBackgroundFetch::onAISFolderCalback(const LLUUID &request_i else if (recursion == FT_CONTENT_RECURSIVE) { LL_WARNS() << "Failed to download folder: " << request_id << " Requesting known content separately" << LL_ENDL; - LLInventoryModel::cat_array_t *categories(NULL); - LLInventoryModel::item_array_t *items(NULL); - gInventory.getDirectDescendentsOf(request_id, categories, items); - if (categories) - { - for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); it != categories->end(); ++it) - { - mFetchFolderQueue.push_front(FetchQueueInfo((*it)->getUUID(), FT_RECURSIVE)); - } - if (!mFetchFolderQueue.empty()) - { - mBackgroundFetchActive = true; - mFolderFetchActive = true; - gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); - } - } + request_descendants = true; } } else { - LL_DEBUGS(LOG_INV , "AIS3") << "Got folder " << request_id << LL_ENDL; - if (recursion == FT_CONTENT_RECURSIVE) + if (recursion == FT_CONTENT_RECURSIVE || recursion == FT_RECURSIVE) { // Got the folder, now recursively request content - LLInventoryModel::cat_array_t * categories(NULL); - LLInventoryModel::item_array_t * items(NULL); - gInventory.getDirectDescendentsOf(request_id, categories, items); + // Request content even for FT_RECURSIVE in case of changes, failures + // or if depth limit gets imlemented. + // This shouldn't redownload folders if they already have version + request_descendants = true; + LL_DEBUGS(LOG_INV, "AIS3") << "Got folder " << request_id << ". Requesting content" << LL_ENDL; + } + else + { + LL_DEBUGS(LOG_INV, "AIS3") << "Got folder " << request_id << "." << LL_ENDL; + } + + } + + if (request_descendants) + { + LLInventoryModel::cat_array_t* categories(NULL); + LLInventoryModel::item_array_t* items(NULL); + gInventory.getDirectDescendentsOf(request_id, categories, items); + if (categories) + { for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); - it != categories->end(); - ++it) + it != categories->end(); + ++it) { mFetchFolderQueue.push_front(FetchQueueInfo((*it)->getUUID(), FT_RECURSIVE)); } -- cgit v1.3 From 9c2b0c709b3d1cf1a9243853a8df7089e2494057 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 25 Apr 2023 01:34:35 +0300 Subject: SL-19533 Special COF handling --- indra/newview/llaisapi.cpp | 40 +++++++++++++++++++++++ indra/newview/llaisapi.h | 2 ++ indra/newview/llinventorymodelbackgroundfetch.cpp | 6 ++++ indra/newview/llinventorymodelbackgroundfetch.h | 1 + indra/newview/llstartup.cpp | 1 + 5 files changed, 50 insertions(+) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index d39bb57304..117a596cd2 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -592,6 +592,40 @@ void AISAPI::FetchCategoryCategories(const LLUUID &catId, ITEM_TYPE type, bool r EnqueueAISCommand("FetchCategoryCategories", proc); } +/*static*/ +// Will get COF folder, links in it and items those links point to +void AISAPI::FetchCOF(completion_t callback) +{ + std::string cap = getInvCap(); + if (cap.empty()) + { + LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + if (callback) + { + callback(LLUUID::null); + } + return; + } + std::string url = cap + std::string("/category/current/links"); + + invokationFn_t getFn = boost::bind( + // Humans ignore next line. It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload. + static_cast + //---- + // _1 -> httpAdapter + // _2 -> httpRequest + // _3 -> url + // _4 -> body + // _5 -> httpOptions + // _6 -> httpHeaders + (&LLCoreHttpUtil::HttpCoroutineAdapter::getAndSuspend), _1, _2, _3, _5, _6); + + LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, + _1, getFn, url, LLUUID::null, LLSD(), callback, FETCHCOF)); + + EnqueueAISCommand("FetchCOF", proc); +} + /*static*/ void AISAPI::FetchOrphans(completion_t callback) { @@ -687,6 +721,7 @@ void AISAPI::onUpdateReceived(const std::string& context, const LLSD& update, CO bool is_fetch = (type == FETCHITEM) || (type == FETCHCATEGORYCHILDREN) || (type == FETCHCATEGORYCATEGORIES) + || (type == FETCHCOF) || (type == FETCHORPHANS); // parse update llsd into stuff to do or parse received items. S32 depth = 0; @@ -1095,6 +1130,11 @@ void AISUpdate::parseLink(const LLSD& link_map) mCatDescendentDeltas[parent_id]++; new_link->setComplete(true); } + + if (link_map.has("_embedded")) + { + parseEmbedded(link_map["_embedded"], S32_MAX); + } } else { diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h index 4e1c6e5a7d..0ca0144d7b 100644 --- a/indra/newview/llaisapi.h +++ b/indra/newview/llaisapi.h @@ -59,6 +59,7 @@ public: static void FetchCategoryChildren(const LLUUID &catId, ITEM_TYPE type = AISAPI::ITEM_TYPE::INVENTORY, bool recursive = false, completion_t callback = completion_t(), S32 depth = 0); static void FetchCategoryChildren(const std::string &identifier, bool recursive = false, completion_t callback = completion_t(), S32 depth = 0); static void FetchCategoryCategories(const LLUUID &catId, ITEM_TYPE type = AISAPI::ITEM_TYPE::INVENTORY, bool recursive = false, completion_t callback = completion_t(), S32 depth = 0); + static void FetchCOF(completion_t callback = completion_t()); static void FetchOrphans(completion_t callback = completion_t() ); static void CopyLibraryCategory(const LLUUID& sourceId, const LLUUID& destId, bool copySubfolders, completion_t callback = completion_t()); @@ -76,6 +77,7 @@ private: FETCHITEM, FETCHCATEGORYCHILDREN, FETCHCATEGORYCATEGORIES, + FETCHCOF, FETCHORPHANS, } COMMAND_TYPE; diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index bfb5ad9d12..f56532ff8c 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -391,6 +391,12 @@ void LLInventoryModelBackgroundFetch::findLostItems() gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } +void LLInventoryModelBackgroundFetch::fetchCOF() +{ + // Will get COF folder, links in it and items those links point to + AISAPI::FetchCOF(); +} + void LLInventoryModelBackgroundFetch::setAllFoldersFetched() { if (mRecursiveInventoryFetchStarted && diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index 1881322e7a..db2d6db323 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -65,6 +65,7 @@ public: bool inventoryFetchInProgress() const; void findLostItems(); + void fetchCOF(); void incrFetchCount(S32 fetching); void incrFetchFolderCount(S32 fetching); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index a1f2753ada..161beaff19 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1898,6 +1898,7 @@ bool idle_startup() } LLInventoryModelBackgroundFetch::instance().start(); + LLInventoryModelBackgroundFetch::instance().fetchCOF(); gInventory.createCommonSystemCategories(); // It's debatable whether this flag is a good idea - sets all -- cgit v1.3 From 154ab03bf8a5dacc3128718d1f15160f0cbe2b33 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 25 Apr 2023 03:38:26 +0300 Subject: SL-19533 Special COF handling #2 --- indra/newview/llappearancemgr.cpp | 33 ++++++++++++++++------- indra/newview/llappearancemgr.h | 1 + indra/newview/llinventorymodelbackgroundfetch.cpp | 18 +------------ indra/newview/llinventorymodelbackgroundfetch.h | 5 ++-- indra/newview/llstartup.cpp | 3 +-- 5 files changed, 28 insertions(+), 32 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 9115d7e5c2..297403fc6c 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -4561,18 +4561,31 @@ protected: nullary_func_t mCallable; }; +void callAfterCOFFetch(nullary_func_t cb) +{ + if (AISAPI::isAvailable()) + { + AISAPI::FetchCOF([cb](const LLUUID& id) { cb(); }); + } + else + { + LLUUID cat_id = LLAppearanceMgr::instance().getCOF(); + callAfterCategoryFetch(cat_id, cb); + } +} + void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb) { - CallAfterCategoryFetchStage1 *stage1 = new CallAfterCategoryFetchStage1(cat_id, cb); - stage1->startFetch(); - if (stage1->isFinished()) - { - stage1->done(); - } - else - { - gInventory.addObserver(stage1); - } + CallAfterCategoryFetchStage1* stage1 = new CallAfterCategoryFetchStage1(cat_id, cb); + stage1->startFetch(); + if (stage1->isFinished()) + { + stage1->done(); + } + else + { + gInventory.addObserver(stage1); + } } void add_wearable_type_counts(const uuid_vec_t& ids, diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index cf953d21ac..f6aa30d865 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -338,6 +338,7 @@ public: LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name); // Invoke a given callable after category contents are fully fetched. +void callAfterCOFFetch(nullary_func_t cb); void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb); // Wear all items in a uuid vector. diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index f56532ff8c..277ddb16ba 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -354,17 +354,7 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) void LLInventoryModelBackgroundFetch::scheduleFolderFetch(const LLUUID& cat_id, bool forced) { - if (AISAPI::isAvailable()) - { - if (mFetchFolderQueue.empty() || mFetchFolderQueue.back().mUUID != cat_id) - { - // On AIS make sure root goes to the top and follow up recursive - // fetches, not individual requests - mFetchFolderQueue.push_back(FetchQueueInfo(cat_id, forced ? FT_FORCED : FT_DEFAULT)); - gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); - } - } - else if (mFetchFolderQueue.empty() || mFetchFolderQueue.front().mUUID != cat_id) + if (mFetchFolderQueue.empty() || mFetchFolderQueue.front().mUUID != cat_id) { // Specific folder requests go to front of queue. mFetchFolderQueue.push_front(FetchQueueInfo(cat_id, forced ? FT_FORCED : FT_DEFAULT)); @@ -391,12 +381,6 @@ void LLInventoryModelBackgroundFetch::findLostItems() gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); } -void LLInventoryModelBackgroundFetch::fetchCOF() -{ - // Will get COF folder, links in it and items those links point to - AISAPI::FetchCOF(); -} - void LLInventoryModelBackgroundFetch::setAllFoldersFetched() { if (mRecursiveInventoryFetchStarted && diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index db2d6db323..363d04486d 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -64,9 +64,8 @@ public: bool inventoryFetchCompleted() const; bool inventoryFetchInProgress() const; - void findLostItems(); - void fetchCOF(); - void incrFetchCount(S32 fetching); + void findLostItems(); + void incrFetchCount(S32 fetching); void incrFetchFolderCount(S32 fetching); bool isBulkFetchProcessingComplete() const; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 161beaff19..3a96a7bced 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1898,7 +1898,6 @@ bool idle_startup() } LLInventoryModelBackgroundFetch::instance().start(); - LLInventoryModelBackgroundFetch::instance().fetchCOF(); gInventory.createCommonSystemCategories(); // It's debatable whether this flag is a good idea - sets all @@ -2161,7 +2160,7 @@ bool idle_startup() gAgentWearables.notifyLoadingStarted(); gAgent.setOutfitChosen(TRUE); gAgentWearables.sendDummyAgentWearablesUpdate(); - callAfterCategoryFetch(LLAppearanceMgr::instance().getCOF(), set_flags_and_update_appearance); + callAfterCOFFetch(set_flags_and_update_appearance); } display_startup(); -- cgit v1.3 From c008d3e030ca4019e24de9a4831dc36727555fd2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 25 Apr 2023 12:25:15 +0300 Subject: SL-19533 Reduce inventory fetch stalls --- indra/newview/llaisapi.cpp | 11 ++++++++++- indra/newview/llaisapi.h | 6 ++++++ indra/newview/llinventoryfilter.cpp | 12 ++++++------ indra/newview/llinventorymodel.cpp | 3 ++- indra/newview/llinventorymodelbackgroundfetch.cpp | 9 +++++++-- 5 files changed, 31 insertions(+), 10 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 117a596cd2..7c293fcf63 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -771,7 +771,7 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht LL_DEBUGS("Inventory") << "Request type: " << (S32)type << " \nRequest target: " << targetId - << " \nElapsed time ince request: " << elapsed_time + << " \nElapsed time since request: " << elapsed_time << " \nstatus: " << status.toULong() << LL_ENDL; } else @@ -904,6 +904,8 @@ AISUpdate::AISUpdate(const LLSD& update, bool fetch, S32 depth) : mFetch(fetch) , mFetchDepth(depth) { + mTimer.setTimerExpirySec(debugLoggingEnabled("Inventory") ? EXPIRY_SECONDS_DEBUG : EXPIRY_SECONDS_LIVE); + mTimer.start(); parseUpdate(update); } @@ -1279,6 +1281,13 @@ void AISUpdate::parseDescendentCount(const LLUUID& category_id, const LLSD& embe void AISUpdate::parseEmbedded(const LLSD& embedded, S32 depth) { + if (mTimer.hasExpired()) + { + llcoro::suspend(); + LLCoros::checkStop(); + mTimer.setTimerExpirySec(debugLoggingEnabled("Inventory") ? EXPIRY_SECONDS_DEBUG : EXPIRY_SECONDS_LIVE); + } + if (embedded.has("links")) // _embedded in a category { parseEmbeddedLinks(embedded["links"]); diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h index 0ca0144d7b..1969448627 100644 --- a/indra/newview/llaisapi.h +++ b/indra/newview/llaisapi.h @@ -124,6 +124,11 @@ public: private: void clearParseResults(); + // Debug is very log-heavy, give it more time or it will take forever to process + // Todo: find a way to make throttle static isntead of per-request + const F32 EXPIRY_SECONDS_DEBUG = 1.f; + const F32 EXPIRY_SECONDS_LIVE = 0.01f; + typedef std::map uuid_int_map_t; uuid_int_map_t mCatDescendentDeltas; uuid_int_map_t mCatDescendentsKnown; @@ -144,6 +149,7 @@ private: uuid_list_t mCategoryIds; bool mFetch; S32 mFetchDepth; + LLTimer mTimer; }; #endif diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index d8e7b8ca67..5d6c3be168 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -195,11 +195,6 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const return true; } - if(!checkAgainstFilterThumbnails(folder_id)) - { - return false; - } - // when applying a filter, matching folders get their contents downloaded first // but make sure we are not interfering with pre-download if (isNotDefault() @@ -207,7 +202,7 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const && !LLInventoryModelBackgroundFetch::instance().inventoryFetchInProgress()) { LLViewerInventoryCategory* cat = gInventory.getCategory(folder_id); - if (!cat || (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)) + if ((!cat && folder_id.notNull()) || (cat && cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)) { // At the moment background fetch only cares about VERSION_UNKNOWN, // so do not check isCategoryComplete that compares descendant count @@ -215,6 +210,11 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const } } + if (!checkAgainstFilterThumbnails(folder_id)) + { + return false; + } + // Marketplace folder filtering const U32 filterTypes = mFilterOps.mFilterTypes; const U32 marketplace_filter = FILTERTYPE_MARKETPLACE_ACTIVE | FILTERTYPE_MARKETPLACE_INACTIVE | diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 873d3e1ccf..48539f4748 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -4681,7 +4681,6 @@ LLPointer LLInventoryModel::validate() const } else if (count_under_root > 1) { - LL_WARNS("Inventory") << "Fatal inventory corruption: system folder type has excess copies under root, type " << ft << " count " << count_under_root << LL_ENDL; validation_info->mDuplicateRequiredSystemFolders.insert(folder_type); if (!is_automatic && folder_type != LLFolderType::FT_SETTINGS) { @@ -4689,6 +4688,7 @@ LLPointer LLInventoryModel::validate() const // outfits, trash and other non-automatic folders. validation_info->mFatalSystemDuplicate++; fatal_errs++; + LL_WARNS("Inventory") << "Fatal inventory corruption: system folder type has excess copies under root, type " << ft << " count " << count_under_root << LL_ENDL; } else { @@ -4697,6 +4697,7 @@ LLPointer LLInventoryModel::validate() const // Exception: FT_SETTINGS is not automatic, but only deserves a warning. validation_info->mWarnings["non_fatal_system_duplicate_under_root"]++; warning_count++; + LL_WARNS("Inventory") << "System folder type has excess copies under root, type " << ft << " count " << count_under_root << LL_ENDL; } } if (count_elsewhere > 0) diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 277ddb16ba..c5fb40409f 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -555,6 +555,8 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() } static LLCachedControl ais_pool(gSavedSettings, "PoolSizeAIS", 20); + // Don't have too many requests at once + // Reserve one request for actions outside of fetch (like renames) const U32 max_concurrent_fetches = llmax(1, ais_pool - 1); if (mFetchCount >= max_concurrent_fetches) @@ -562,6 +564,9 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() return; } + // Don't fire all requests at once + const U32 max_requests_this_run = llmin(mFetchCount + 5, max_concurrent_fetches); + // Don't loop for too long (in case of large, fully loaded inventory) F64 curent_time = LLTimer::getTotalSeconds(); const F64 max_time = LLStartUp::getStartupState() > STATE_WEARABLES_WAIT @@ -570,7 +575,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() const F64 end_time = curent_time + max_time; S32 last_fetch_count = mFetchCount; - while (!mFetchFolderQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time) + while (!mFetchFolderQueue.empty() && mFetchCount < max_requests_this_run && curent_time < end_time) { const FetchQueueInfo & fetch_info(mFetchFolderQueue.front()); bulkFetchViaAis(fetch_info); @@ -581,7 +586,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() // Ideally we shouldn't fetch items if recursive fetch isn't done, // but there is a chance some request will start timeouting and recursive // fetch will get stuck on a signle folder, don't block item fetch in such case - while (!mFetchItemQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time) + while (!mFetchItemQueue.empty() && mFetchCount < max_requests_this_run && curent_time < end_time) { const FetchQueueInfo& fetch_info(mFetchItemQueue.front()); bulkFetchViaAis(fetch_info); -- cgit v1.3 From 697d3be3c9906a6d578a961710fc43816b6adeae Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 27 Apr 2023 01:30:57 +0300 Subject: SL-19533 Implement subset variant of children request --- indra/newview/llaisapi.cpp | 158 ++++++++++++++---- indra/newview/llaisapi.h | 13 +- indra/newview/llappearancemgr.cpp | 13 +- indra/newview/llinventorymodelbackgroundfetch.cpp | 195 +++++++++++++++++++--- indra/newview/llinventorymodelbackgroundfetch.h | 6 +- 5 files changed, 320 insertions(+), 65 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 6d13a06c54..c17b246ef1 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -51,6 +51,10 @@ std::list AISAPI::sPostponedQuery; const S32 MAX_SIMULTANEOUS_COROUTINES = 2048; +// AIS3 allows '*' requests, but in reality those will be cut at some point +// Specify own depth to be able to anticipate it and mark folders as incomplete +const S32 MAX_FOLDER_DEPTH_REQUEST = 50; + //------------------------------------------------------------------------- /*static*/ bool AISAPI::isAvailable() @@ -458,11 +462,11 @@ void AISAPI::FetchCategoryChildren(const LLUUID &catId, ITEM_TYPE type, bool rec { // can specify depth=*, but server side is going to cap requests // and reject everything 'over the top',. - depth = 50; + depth = MAX_FOLDER_DEPTH_REQUEST; } else { - depth = llmin(depth, 50); + depth = llmin(depth, MAX_FOLDER_DEPTH_REQUEST); } url += "?depth=" + std::to_string(depth); @@ -511,11 +515,11 @@ void AISAPI::FetchCategoryChildren(const std::string &identifier, bool recursive { // can specify depth=*, but server side is going to cap requests // and reject everything 'over the top',. - depth = 50; + depth = MAX_FOLDER_DEPTH_REQUEST; } else { - depth = llmin(depth, 50); + depth = llmin(depth, MAX_FOLDER_DEPTH_REQUEST); } url += "?depth=" + std::to_string(depth); @@ -562,11 +566,11 @@ void AISAPI::FetchCategoryCategories(const LLUUID &catId, ITEM_TYPE type, bool r { // can specify depth=*, but server side is going to cap requests // and reject everything 'over the top',. - depth = 50; + depth = MAX_FOLDER_DEPTH_REQUEST; } else { - depth = llmin(depth, 50); + depth = llmin(depth, MAX_FOLDER_DEPTH_REQUEST); } url += "?depth=" + std::to_string(depth); @@ -592,6 +596,83 @@ void AISAPI::FetchCategoryCategories(const LLUUID &catId, ITEM_TYPE type, bool r EnqueueAISCommand("FetchCategoryCategories", proc); } +void AISAPI::FetchCategorySubset(const LLUUID& catId, + const uuid_vec_t specificChildren, + ITEM_TYPE type, + bool recursive, + completion_t callback, + S32 depth) +{ + std::string cap = (type == INVENTORY) ? getInvCap() : getLibCap(); + if (cap.empty()) + { + LL_WARNS("Inventory") << "Inventory cap not found!" << LL_ENDL; + if (callback) + { + callback(LLUUID::null); + } + return; + } + if (specificChildren.empty()) + { + LL_WARNS("Inventory") << "Empty request!" << LL_ENDL; + if (callback) + { + callback(LLUUID::null); + } + return; + } + // category/any_folder_id/children?depth=*&children=child_id1,child_id2,child_id3 + std::string url = cap + std::string("/category/") + catId.asString() + "/children"; + + if (recursive) + { + depth = MAX_FOLDER_DEPTH_REQUEST; + } + else + { + depth = llmin(depth, MAX_FOLDER_DEPTH_REQUEST); + } + + uuid_vec_t::const_iterator iter = specificChildren.begin(); + uuid_vec_t::const_iterator end = specificChildren.end(); + + url += "?depth=" + std::to_string(depth) + "&children=" + iter->asString(); + iter++; + + while (iter != end) + { + url += "," + iter->asString(); + iter++; + } + + const S32 MAX_URL_LENGH = 2000; // RFC documentation specifies a maximum length of 2048 + if (url.length() > MAX_URL_LENGH) + { + LL_WARNS("Inventory") << "Request url is too long, url: " << url << LL_ENDL; + } + + invokationFn_t getFn = boost::bind( + // Humans ignore next line. It is just a cast to specify which LLCoreHttpUtil::HttpCoroutineAdapter routine overload. + static_cast + //---- + // _1 -> httpAdapter + // _2 -> httpRequest + // _3 -> url + // _4 -> body + // _5 -> httpOptions + // _6 -> httpHeaders + (&LLCoreHttpUtil::HttpCoroutineAdapter::getAndSuspend), _1, _2, _3, _5, _6); + + // get doesn't use body, can pass additional data + LLSD body; + body["depth"] = depth; + LLCoprocedureManager::CoProcedure_t proc(boost::bind(&AISAPI::InvokeAISCommandCoro, + _1, getFn, url, catId, body, callback, FETCHCATEGORYSUBSET)); + + EnqueueAISCommand("FetchCategorySubset", proc); +} + /*static*/ // Will get COF folder, links in it and items those links point to void AISAPI::FetchCOF(completion_t callback) @@ -710,7 +791,7 @@ void AISAPI::onIdle(void *userdata) } /*static*/ -void AISAPI::onUpdateReceived(const std::string& context, const LLSD& update, COMMAND_TYPE type, const LLSD& request_body) +void AISAPI::onUpdateReceived(const LLSD& update, COMMAND_TYPE type, const LLSD& request_body) { LLTimer timer; if ( (type == UPDATECATEGORY || type == UPDATEITEM) @@ -718,18 +799,8 @@ void AISAPI::onUpdateReceived(const std::string& context, const LLSD& update, CO { dump_sequential_xml(gAgentAvatarp->getFullname() + "_ais_update", update); } - bool is_fetch = (type == FETCHITEM) - || (type == FETCHCATEGORYCHILDREN) - || (type == FETCHCATEGORYCATEGORIES) - || (type == FETCHCOF) - || (type == FETCHORPHANS); - // parse update llsd into stuff to do or parse received items. - S32 depth = 0; - if (is_fetch && request_body.has("depth")) - { - depth = request_body["depth"].asInteger(); - } - AISUpdate ais_update(update, is_fetch, depth); + + AISUpdate ais_update(update, type, request_body); ais_update.doUpdate(); // execute the updates in the appropriate order. LL_DEBUGS("Inventory", "AIS3") << "Elapsed processing: " << timer.getElapsedTimeF32() << LL_ENDL; } @@ -833,7 +904,7 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht } LL_DEBUGS("Inventory", "AIS3") << "Result: " << result << LL_ENDL; - onUpdateReceived("AISCommand", result, type, body); + onUpdateReceived(result, type, body); if (callback && !callback.empty()) { @@ -900,10 +971,22 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht } //------------------------------------------------------------------------- -AISUpdate::AISUpdate(const LLSD& update, bool fetch, S32 depth) -: mFetch(fetch) -, mFetchDepth(depth) +AISUpdate::AISUpdate(const LLSD& update, AISAPI::COMMAND_TYPE type, const LLSD& request_body) +: mType(type) { + mFetch = (type == AISAPI::FETCHITEM) + || (type == AISAPI::FETCHCATEGORYCHILDREN) + || (type == AISAPI::FETCHCATEGORYCATEGORIES) + || (type == AISAPI::FETCHCATEGORYSUBSET) + || (type == AISAPI::FETCHCOF) + || (type == AISAPI::FETCHORPHANS); + // parse update llsd into stuff to do or parse received items. + mFetchDepth = MAX_FOLDER_DEPTH_REQUEST; + if (mFetch && request_body.has("depth")) + { + mFetchDepth = request_body["depth"].asInteger(); + } + mTimer.setTimerExpirySec(debugLoggingEnabled("Inventory") ? EXPIRY_SECONDS_DEBUG : EXPIRY_SECONDS_LIVE); mTimer.start(); parseUpdate(update); @@ -1023,17 +1106,26 @@ void AISUpdate::parseContent(const LLSD& update) { if (update.has("linked_id")) { - parseLink(update); + parseLink(update, mFetchDepth); } else if (update.has("item_id")) { parseItem(update); } - if (update.has("category_id")) - { - parseCategory(update, mFetchDepth); - } + if (mType == AISAPI::FETCHCATEGORYSUBSET) + { + // initial category is incomplete, don't process it, + // go for content instead + if (update.has("_embedded")) + { + parseEmbedded(update["_embedded"], mFetchDepth - 1); + } + } + else if (update.has("category_id")) + { + parseCategory(update, mFetchDepth); + } else { if (update.has("_embedded")) @@ -1089,7 +1181,7 @@ void AISUpdate::parseItem(const LLSD& item_map) } } -void AISUpdate::parseLink(const LLSD& link_map) +void AISUpdate::parseLink(const LLSD& link_map, S32 depth) { LLUUID item_id = link_map["item_id"].asUUID(); LLPointer new_link(new LLViewerInventoryItem); @@ -1145,7 +1237,7 @@ void AISUpdate::parseLink(const LLSD& link_map) if (link_map.has("_embedded")) { - parseEmbedded(link_map["_embedded"], S32_MAX); + parseEmbedded(link_map["_embedded"], depth); } } else @@ -1295,7 +1387,7 @@ void AISUpdate::parseEmbedded(const LLSD& embedded, S32 depth) if (embedded.has("links")) // _embedded in a category { - parseEmbeddedLinks(embedded["links"]); + parseEmbeddedLinks(embedded["links"], depth); } if (embedded.has("items")) // _embedded in a category { @@ -1328,7 +1420,7 @@ void AISUpdate::parseUUIDArray(const LLSD& content, const std::string& name, uui } } -void AISUpdate::parseEmbeddedLinks(const LLSD& links) +void AISUpdate::parseEmbeddedLinks(const LLSD& links, S32 depth) { for(LLSD::map_const_iterator linkit = links.beginMap(), linkend = links.endMap(); @@ -1342,7 +1434,7 @@ void AISUpdate::parseEmbeddedLinks(const LLSD& links) } else { - parseLink(link_map); + parseLink(link_map, depth); } } } diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h index 6afbbbd16e..691c5db592 100644 --- a/indra/newview/llaisapi.h +++ b/indra/newview/llaisapi.h @@ -59,11 +59,11 @@ public: static void FetchCategoryChildren(const LLUUID &catId, ITEM_TYPE type = AISAPI::ITEM_TYPE::INVENTORY, bool recursive = false, completion_t callback = completion_t(), S32 depth = 0); static void FetchCategoryChildren(const std::string &identifier, bool recursive = false, completion_t callback = completion_t(), S32 depth = 0); static void FetchCategoryCategories(const LLUUID &catId, ITEM_TYPE type = AISAPI::ITEM_TYPE::INVENTORY, bool recursive = false, completion_t callback = completion_t(), S32 depth = 0); + static void FetchCategorySubset(const LLUUID& catId, const uuid_vec_t specificChildren, ITEM_TYPE type = AISAPI::ITEM_TYPE::INVENTORY, bool recursive = false, completion_t callback = completion_t(), S32 depth = 0); static void FetchCOF(completion_t callback = completion_t()); static void FetchOrphans(completion_t callback = completion_t() ); static void CopyLibraryCategory(const LLUUID& sourceId, const LLUUID& destId, bool copySubfolders, completion_t callback = completion_t()); -private: typedef enum { COPYINVENTORY, SLAMFOLDER, @@ -77,10 +77,12 @@ private: FETCHITEM, FETCHCATEGORYCHILDREN, FETCHCATEGORYCATEGORIES, + FETCHCATEGORYSUBSET, FETCHCOF, FETCHORPHANS, } COMMAND_TYPE; +private: static const std::string INVENTORY_CAP_NAME; static const std::string LIBRARY_CAP_NAME; @@ -89,7 +91,7 @@ private: static void EnqueueAISCommand(const std::string &procName, LLCoprocedureManager::CoProcedure_t proc); static void onIdle(void *userdata); // launches postponed AIS commands - static void onUpdateReceived(const std::string& context, const LLSD& update, COMMAND_TYPE type, const LLSD& request_body); + static void onUpdateReceived(const LLSD& update, COMMAND_TYPE type, const LLSD& request_body); static std::string getInvCap(); static std::string getLibCap(); @@ -105,17 +107,17 @@ private: class AISUpdate { public: - AISUpdate(const LLSD& update, bool fetch, S32 depth); + AISUpdate(const LLSD& update, AISAPI::COMMAND_TYPE type, const LLSD& request_body); void parseUpdate(const LLSD& update); void parseMeta(const LLSD& update); void parseContent(const LLSD& update); void parseUUIDArray(const LLSD& content, const std::string& name, uuid_list_t& ids); - void parseLink(const LLSD& link_map); + 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 parseEmbedded(const LLSD& embedded, S32 depth); - void parseEmbeddedLinks(const LLSD& links); + void parseEmbeddedLinks(const LLSD& links, S32 depth); void parseEmbeddedItems(const LLSD& items); void parseEmbeddedCategories(const LLSD& categories, S32 depth); void parseEmbeddedItem(const LLSD& item); @@ -151,6 +153,7 @@ private: bool mFetch; S32 mFetchDepth; LLTimer mTimer; + AISAPI::COMMAND_TYPE mType; }; #endif diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index d79525ec62..4133470973 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -4568,7 +4568,18 @@ void callAfterCOFFetch(nullary_func_t cb) if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN && AISAPI::isAvailable()) { // Assume that we have no relevant cache. Fetch cof, and items cof's links point to. - AISAPI::FetchCOF([cb](const LLUUID& id) { cb(); }); + AISAPI::FetchCOF([cb](const LLUUID& id) + { + cb(); + LLUUID cat_id = LLAppearanceMgr::instance().getCOF(); + LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); + if (cat) + { + cat->setFetching(LLViewerInventoryCategory::FETCH_NONE); + } + }); + // Mark it so that background fetch won't request it if it didn't already + cat->setFetching(LLViewerInventoryCategory::FETCH_RECURSIVE); } else { diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index c5fb40409f..b8fdfab98a 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -299,7 +299,7 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& id, bool recursive) // Not only root folder can be massive, but // most system folders will be requested independently // so request root folder and content separately - mFetchFolderQueue.push_front(FetchQueueInfo(gInventory.getRootFolderID(), FT_CONTENT_RECURSIVE)); + mFetchFolderQueue.push_front(FetchQueueInfo(gInventory.getRootFolderID(), FT_FOLDER_AND_CONTENT)); } else { @@ -455,10 +455,67 @@ void ais_simple_item_callback(const LLUUID& inv_id) LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1); } -void LLInventoryModelBackgroundFetch::onAISFolderCalback(const LLUUID &request_id, const LLUUID &response_id, EFetchType recursion) +void LLInventoryModelBackgroundFetch::onAISContentCalback( + const LLUUID& request_id, + const uuid_vec_t& content_ids, + const LLUUID& response_id, + EFetchType fetch_type) { + // Don't push_front on failure - there is a chance it was fired from inside bulkFetchViaAis incrFetchFolderCount(-1); - std::list::const_iterator found = std::find(mExpectedFolderIds.begin() , mExpectedFolderIds.end(), request_id); + + uuid_vec_t::const_iterator folder_iter = content_ids.begin(); + uuid_vec_t::const_iterator folder_end = content_ids.end(); + while (folder_iter != folder_end) + { + std::list::const_iterator found = std::find(mExpectedFolderIds.begin(), mExpectedFolderIds.end(), *folder_iter); + if (found != mExpectedFolderIds.end()) + { + mExpectedFolderIds.erase(found); + } + + LLViewerInventoryCategory* cat(gInventory.getCategory(*folder_iter)); + if (cat) + { + cat->setFetching(LLViewerInventoryCategory::FETCH_NONE); + } + if (response_id.isNull()) + { + // Failed to fetch, get it individually + mFetchFolderQueue.push_back(FetchQueueInfo(*folder_iter, FT_RECURSIVE)); + } + else + { + // push descendant back to verify they are fetched fully (ex: didn't encounter depth limit) + LLInventoryModel::cat_array_t* categories(NULL); + LLInventoryModel::item_array_t* items(NULL); + gInventory.getDirectDescendentsOf(*folder_iter, categories, items); + if (categories) + { + for (LLInventoryModel::cat_array_t::const_iterator it = categories->begin(); + it != categories->end(); + ++it) + { + mFetchFolderQueue.push_back(FetchQueueInfo((*it)->getUUID(), FT_RECURSIVE)); + } + } + } + + folder_iter++; + } + + if (!mFetchFolderQueue.empty()) + { + mBackgroundFetchActive = true; + mFolderFetchActive = true; + gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); + } +} +void LLInventoryModelBackgroundFetch::onAISFolderCalback(const LLUUID &request_id, const LLUUID &response_id, EFetchType fetch_type) +{ + // Don't push_front on failure - there is a chance it was fired from inside bulkFetchViaAis + incrFetchFolderCount(-1); + std::list::const_iterator found = std::find(mExpectedFolderIds.begin(), mExpectedFolderIds.end(), request_id); if (found != mExpectedFolderIds.end()) { mExpectedFolderIds.erase(found); @@ -480,32 +537,34 @@ void LLInventoryModelBackgroundFetch::onAISFolderCalback(const LLUUID &request_i if (response_id.isNull()) // Failure { LL_DEBUGS(LOG_INV , "AIS3") << "Failure response for folder " << request_id << LL_ENDL; - if (recursion == FT_RECURSIVE) + if (fetch_type == FT_RECURSIVE) { // A full recursive request failed. // Try requesting folder and nested content separately - mBackgroundFetchActive = true; - mFolderFetchActive = true; - mFetchFolderQueue.push_front(FetchQueueInfo(request_id, FT_CONTENT_RECURSIVE)); - gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); + mFetchFolderQueue.push_back(FetchQueueInfo(request_id, FT_FOLDER_AND_CONTENT)); } - else if (recursion == FT_CONTENT_RECURSIVE) + else if (fetch_type == FT_FOLDER_AND_CONTENT) { LL_WARNS() << "Failed to download folder: " << request_id << " Requesting known content separately" << LL_ENDL; - request_descendants = true; + mFetchFolderQueue.push_back(FetchQueueInfo(request_id, FT_CONTENT_RECURSIVE)); } } else { - if (recursion == FT_CONTENT_RECURSIVE || recursion == FT_RECURSIVE) + if (fetch_type == FT_RECURSIVE) { - // Got the folder, now recursively request content + // Got the folder and content, now verify content // Request content even for FT_RECURSIVE in case of changes, failures // or if depth limit gets imlemented. // This shouldn't redownload folders if they already have version request_descendants = true; LL_DEBUGS(LOG_INV, "AIS3") << "Got folder " << request_id << ". Requesting content" << LL_ENDL; } + else if (fetch_type == FT_FOLDER_AND_CONTENT) + { + // readd folder for content request + mFetchFolderQueue.push_front(FetchQueueInfo(request_id, FT_CONTENT_RECURSIVE)); + } else { LL_DEBUGS(LOG_INV, "AIS3") << "Got folder " << request_id << "." << LL_ENDL; @@ -524,17 +583,18 @@ void LLInventoryModelBackgroundFetch::onAISFolderCalback(const LLUUID &request_i it != categories->end(); ++it) { - mFetchFolderQueue.push_front(FetchQueueInfo((*it)->getUUID(), FT_RECURSIVE)); - } - if (!mFetchFolderQueue.empty()) - { - mBackgroundFetchActive = true; - mFolderFetchActive = true; - gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); + mFetchFolderQueue.push_back(FetchQueueInfo((*it)->getUUID(), FT_RECURSIVE)); } } } + if (!mFetchFolderQueue.empty()) + { + mBackgroundFetchActive = true; + mFolderFetchActive = true; + gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); + } + // done LLViewerInventoryCategory * cat(gInventory.getCategory(request_id)); if (cat) @@ -555,9 +615,9 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() } static LLCachedControl ais_pool(gSavedSettings, "PoolSizeAIS", 20); - // Don't have too many requests at once + // Don't have too many requests at once, AIS throttles // Reserve one request for actions outside of fetch (like renames) - const U32 max_concurrent_fetches = llmax(1, ais_pool - 1); + const U32 max_concurrent_fetches = llclamp(ais_pool - 1, 1, 50); if (mFetchCount >= max_concurrent_fetches) { @@ -663,10 +723,97 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id)); if (cat) { - if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion() || fetch_info.mFetchType == FT_FORCED) + if (fetch_info.mFetchType == FT_CONTENT_RECURSIVE) + { + // fetch content only, ignore cat itself + uuid_vec_t children; + LLInventoryModel::cat_array_t* categories(NULL); + LLInventoryModel::item_array_t* items(NULL); + gInventory.getDirectDescendentsOf(cat_id, categories, items); + + LLViewerInventoryCategory::EFetchType target_state = + fetch_info.mFetchType > FT_CONTENT_RECURSIVE + ? LLViewerInventoryCategory::FETCH_RECURSIVE + : LLViewerInventoryCategory::FETCH_NORMAL; + // technically limit is 'as many as you can put into url', but for now stop at 10 + const S32 batch_limit = 10; + bool content_done = true; + + for (LLInventoryModel::cat_array_t::iterator it = categories->begin(); + it != categories->end(); + ++it) + { + LLViewerInventoryCategory* child_cat = (*it); + if (LLViewerInventoryCategory::VERSION_UNKNOWN != child_cat->getVersion() + || child_cat->getFetching() >= target_state) + { + // push it back to verify everything inside is fetched + mFetchFolderQueue.push_back(FetchQueueInfo((*it)->getUUID(), FT_RECURSIVE)); + continue; + } + + if (child_cat->getPreferredType() == LLFolderType::FT_MARKETPLACE_LISTINGS) + { + // special case + content_done = false; + if (children.empty()) + { + // fetch marketplace alone + children.push_back(child_cat->getUUID()); + mExpectedFolderIds.push_back(child_cat->getUUID()); + child_cat->setFetching(target_state); + break; + } + else + { + // fetch marketplace alone next run + continue; + } + } + + children.push_back(child_cat->getUUID()); + mExpectedFolderIds.push_back(child_cat->getUUID()); + child_cat->setFetching(target_state); + + if (children.size() >= batch_limit) + { + content_done = false; + break; + } + } + + if (!children.empty()) + { + // increment before call in case of immediate callback + incrFetchFolderCount(1); + + EFetchType type = fetch_info.mFetchType; + LLUUID cat_id = cat->getUUID(); // need a copy for lambda + AISAPI::completion_t cb = [cat_id, children, type](const LLUUID& response_id) + { + LLInventoryModelBackgroundFetch::instance().onAISContentCalback(cat_id, children, response_id, type); + }; + + AISAPI::ITEM_TYPE item_type = AISAPI::INVENTORY; + if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) + { + item_type = AISAPI::LIBRARY; + } + + AISAPI::FetchCategorySubset(cat_id, children, item_type, true, cb, 0); + } + + if (!content_done) + { + // send it back to get the rest + mFetchFolderQueue.push_back(FetchQueueInfo(cat_id, FT_CONTENT_RECURSIVE)); + } + } + else if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion() + || fetch_info.mFetchType == FT_FORCED) { LLViewerInventoryCategory::EFetchType target_state = - fetch_info.mFetchType >= FT_CONTENT_RECURSIVE + fetch_info.mFetchType > FT_CONTENT_RECURSIVE ? LLViewerInventoryCategory::FETCH_RECURSIVE : LLViewerInventoryCategory::FETCH_NORMAL; // start again if we did a non-recursive fetch before @@ -711,7 +858,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc } } } - } // else? + } // else try to fetch folder either way? } } else diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index 363d04486d..1fd7426312 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -82,8 +82,9 @@ protected: typedef enum { FT_DEFAULT = 0, - FT_FORCED, // request even if already loaded + FT_FORCED, // request non-recursively even if already loaded FT_CONTENT_RECURSIVE, // request content recursively + FT_FOLDER_AND_CONTENT, // request content recursively FT_RECURSIVE, // request everything recursively } EFetchType; struct FetchQueueInfo @@ -100,7 +101,8 @@ protected: }; typedef std::deque fetch_queue_t; - void onAISFolderCalback(const LLUUID &request_id, const LLUUID &response_id, EFetchType recursion); + void onAISContentCalback(const LLUUID& request_id, const uuid_vec_t &content_ids, const LLUUID& response_id, EFetchType fetch_type); + void onAISFolderCalback(const LLUUID &request_id, const LLUUID &response_id, EFetchType fetch_type); void bulkFetchViaAis(); void bulkFetchViaAis(const FetchQueueInfo& fetch_info); void bulkFetch(); -- cgit v1.3 From 7bb564496997e26a4c9770cb509955d0a22d1617 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 27 Apr 2023 20:23:13 +0300 Subject: SL-19533 Subset fetch fixes --- indra/newview/llaisapi.cpp | 2 ++ indra/newview/llinventorymodelbackgroundfetch.cpp | 28 ++++++++++++++++------- indra/newview/llinventorymodelbackgroundfetch.h | 2 +- 3 files changed, 23 insertions(+), 9 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index c17b246ef1..e63d77cea3 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -916,6 +916,8 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht case COPYLIBRARYCATEGORY: case FETCHCATEGORYCATEGORIES: case FETCHCATEGORYCHILDREN: + case FETCHCATEGORYSUBSET: + case FETCHCOF: if (result.has("category_id")) { id = result["category_id"]; diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index b8fdfab98a..3a2120750b 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -731,10 +731,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc LLInventoryModel::item_array_t* items(NULL); gInventory.getDirectDescendentsOf(cat_id, categories, items); - LLViewerInventoryCategory::EFetchType target_state = - fetch_info.mFetchType > FT_CONTENT_RECURSIVE - ? LLViewerInventoryCategory::FETCH_RECURSIVE - : LLViewerInventoryCategory::FETCH_NORMAL; + LLViewerInventoryCategory::EFetchType target_state = LLViewerInventoryCategory::FETCH_RECURSIVE; // technically limit is 'as many as you can put into url', but for now stop at 10 const S32 batch_limit = 10; bool content_done = true; @@ -747,8 +744,6 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc if (LLViewerInventoryCategory::VERSION_UNKNOWN != child_cat->getVersion() || child_cat->getFetching() >= target_state) { - // push it back to verify everything inside is fetched - mFetchFolderQueue.push_back(FetchQueueInfo((*it)->getUUID(), FT_RECURSIVE)); continue; } @@ -759,6 +754,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc if (children.empty()) { // fetch marketplace alone + // Should it actually be fetched as FT_FOLDER_AND_CONTENT? children.push_back(child_cat->getUUID()); mExpectedFolderIds.push_back(child_cat->getUUID()); child_cat->setFetching(target_state); @@ -803,7 +799,23 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc AISAPI::FetchCategorySubset(cat_id, children, item_type, true, cb, 0); } - if (!content_done) + if (content_done) + { + // This will have a bit of overlap with onAISContentCalback, + // but something else might have dowloaded folders, so verify + // every child that is complete has it's children done as well + for (LLInventoryModel::cat_array_t::iterator it = categories->begin(); + it != categories->end(); + ++it) + { + LLViewerInventoryCategory* child_cat = (*it); + if (LLViewerInventoryCategory::VERSION_UNKNOWN != child_cat->getVersion()) + { + mFetchFolderQueue.push_back(FetchQueueInfo(child_cat->getUUID(), FT_RECURSIVE)); + } + } + } + else { // send it back to get the rest mFetchFolderQueue.push_back(FetchQueueInfo(cat_id, FT_CONTENT_RECURSIVE)); @@ -844,7 +856,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc else { // Already fetched, check if anything inside needs fetching - if (fetch_info.mFetchType >= FT_CONTENT_RECURSIVE) + if (fetch_info.mFetchType == FT_RECURSIVE) { LLInventoryModel::cat_array_t * categories(NULL); LLInventoryModel::item_array_t * items(NULL); diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index 1fd7426312..e7be265a3d 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -84,7 +84,7 @@ protected: FT_DEFAULT = 0, FT_FORCED, // request non-recursively even if already loaded FT_CONTENT_RECURSIVE, // request content recursively - FT_FOLDER_AND_CONTENT, // request content recursively + FT_FOLDER_AND_CONTENT, // request folder, then content recursively FT_RECURSIVE, // request everything recursively } EFetchType; struct FetchQueueInfo -- cgit v1.3 From 377f177a8667702eee12414fb5534fd6732da1d2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 27 Apr 2023 21:32:17 +0300 Subject: SL-19533 Removed per-run limit Doesn't seem to work like expected and I never get more than 7-9 requests running total --- indra/newview/llinventorymodelbackgroundfetch.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 3a2120750b..5b8ee6e244 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -624,9 +624,6 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() return; } - // Don't fire all requests at once - const U32 max_requests_this_run = llmin(mFetchCount + 5, max_concurrent_fetches); - // Don't loop for too long (in case of large, fully loaded inventory) F64 curent_time = LLTimer::getTotalSeconds(); const F64 max_time = LLStartUp::getStartupState() > STATE_WEARABLES_WAIT @@ -635,7 +632,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() const F64 end_time = curent_time + max_time; S32 last_fetch_count = mFetchCount; - while (!mFetchFolderQueue.empty() && mFetchCount < max_requests_this_run && curent_time < end_time) + while (!mFetchFolderQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time) { const FetchQueueInfo & fetch_info(mFetchFolderQueue.front()); bulkFetchViaAis(fetch_info); @@ -646,7 +643,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() // Ideally we shouldn't fetch items if recursive fetch isn't done, // but there is a chance some request will start timeouting and recursive // fetch will get stuck on a signle folder, don't block item fetch in such case - while (!mFetchItemQueue.empty() && mFetchCount < max_requests_this_run && curent_time < end_time) + while (!mFetchItemQueue.empty() && mFetchCount < max_concurrent_fetches && curent_time < end_time) { const FetchQueueInfo& fetch_info(mFetchItemQueue.front()); bulkFetchViaAis(fetch_info); -- cgit v1.3 From 9349a9b5d4ccb21f195e5c156d897836399fd11b Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 28 Apr 2023 00:18:46 +0300 Subject: SL-19533 More children per subset fetch request --- indra/newview/llinventorymodelbackgroundfetch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 5b8ee6e244..5f7950df08 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -730,7 +730,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc LLViewerInventoryCategory::EFetchType target_state = LLViewerInventoryCategory::FETCH_RECURSIVE; // technically limit is 'as many as you can put into url', but for now stop at 10 - const S32 batch_limit = 10; + const S32 batch_limit = 20; bool content_done = true; for (LLInventoryModel::cat_array_t::iterator it = categories->begin(); -- cgit v1.3 From 03c263a1cdd88ec5967e751cba8640edf9896e51 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 28 Apr 2023 23:37:34 +0300 Subject: SL-19533 Fix 'fetching' state timeout --- indra/newview/app_settings/settings.xml | 11 +++++++++++ indra/newview/llaisapi.cpp | 3 ++- indra/newview/llaisapi.h | 1 + indra/newview/llinventorymodelbackgroundfetch.cpp | 6 ++++-- indra/newview/llviewerinventory.cpp | 11 +++++++++-- 5 files changed, 27 insertions(+), 5 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index a2a1b3f117..43d3f63a34 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -15283,6 +15283,17 @@ Value 1 + BatchSizeAIS3 + + Comment + Amount of folder ais packs into category subset request + Persist + 1 + Type + S32 + Value + 20 + PoolSizeAIS Comment diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 951860e39d..b09b8ec517 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -46,6 +46,7 @@ //========================================================================= const std::string AISAPI::INVENTORY_CAP_NAME("InventoryAPIv3"); const std::string AISAPI::LIBRARY_CAP_NAME("LibraryAPIv3"); +const S32 AISAPI::HTTP_TIMEOUT = 180; std::list AISAPI::sPostponedQuery; @@ -823,7 +824,7 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest()); LLCore::HttpHeaders::ptr_t httpHeaders; - httpOptions->setTimeout(180); + httpOptions->setTimeout(HTTP_TIMEOUT); LL_DEBUGS("Inventory") << "Request url: " << url << LL_ENDL; diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h index 6270a34081..973c82a847 100644 --- a/indra/newview/llaisapi.h +++ b/indra/newview/llaisapi.h @@ -38,6 +38,7 @@ class AISAPI { public: + static const S32 HTTP_TIMEOUT; typedef enum { INVENTORY, LIBRARY diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 5f7950df08..8f1012868f 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -729,10 +729,12 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc gInventory.getDirectDescendentsOf(cat_id, categories, items); LLViewerInventoryCategory::EFetchType target_state = LLViewerInventoryCategory::FETCH_RECURSIVE; - // technically limit is 'as many as you can put into url', but for now stop at 10 - const S32 batch_limit = 20; bool content_done = true; + // Top limit is 'as many as you can put into url' + static LLCachedControl ais_batch(gSavedSettings, "BatchSizeAIS3", 20); + S32 batch_limit = llclamp(ais_batch(), 1, 40); + for (LLInventoryModel::cat_array_t::iterator it = categories->begin(); it != categories->end(); ++it) diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 96f0b500a0..80e4f5f6d5 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -690,9 +690,16 @@ void LLViewerInventoryCategory::setFetching(LLViewerInventoryCategory::EFetchTyp { if (mDescendentsRequested.hasExpired() || (mFetching == FETCH_NONE)) { - const F32 FETCH_TIMER_EXPIRY = 30.0f; mDescendentsRequested.reset(); - mDescendentsRequested.setTimerExpirySec(FETCH_TIMER_EXPIRY); + if (AISAPI::isAvailable()) + { + mDescendentsRequested.setTimerExpirySec(AISAPI::HTTP_TIMEOUT); + } + else + { + const F32 FETCH_TIMER_EXPIRY = 30.0f; + mDescendentsRequested.setTimerExpirySec(FETCH_TIMER_EXPIRY); + } } mFetching = fetching; } -- cgit v1.3 From 352ca2f881b02bd455d0f191d93737d3dc3dd52d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 25 Apr 2023 22:47:31 +0300 Subject: SL-19652 Folder fetch dupplicate protection and over limit handling --- indra/newview/llinventorymodelbackgroundfetch.cpp | 73 ++++++++++++++++++----- 1 file changed, 59 insertions(+), 14 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 8f1012868f..b0ebe83f57 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -945,6 +945,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch() // *TODO: Think I'd like to get a shared pointer to this and share it // among all the folder requests. uuid_vec_t recursive_cats; + uuid_vec_t all_cats; // dupplicate avoidance LLSD folder_request_body; LLSD folder_request_body_lib; @@ -976,22 +977,25 @@ void LLInventoryModelBackgroundFetch::bulkFetch() { if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()) { - LLSD folder_sd; - folder_sd["folder_id"] = cat->getUUID(); - folder_sd["owner_id"] = cat->getOwnerID(); - folder_sd["sort_order"] = LLSD::Integer(sort_order); - folder_sd["fetch_folders"] = LLSD::Boolean(true); //(LLSD::Boolean)sFullFetchStarted; - folder_sd["fetch_items"] = LLSD::Boolean(true); - - if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) - { - folder_request_body_lib["folders"].append(folder_sd); - } - else + if (std::find(all_cats.begin(), all_cats.end(), cat_id) == all_cats.end()) { - folder_request_body["folders"].append(folder_sd); + LLSD folder_sd; + folder_sd["folder_id"] = cat->getUUID(); + folder_sd["owner_id"] = cat->getOwnerID(); + folder_sd["sort_order"] = LLSD::Integer(sort_order); + folder_sd["fetch_folders"] = LLSD::Boolean(TRUE); //(LLSD::Boolean)sFullFetchStarted; + folder_sd["fetch_items"] = LLSD::Boolean(TRUE); + + if (ALEXANDRIA_LINDEN_ID == cat->getOwnerID()) + { + folder_request_body_lib["folders"].append(folder_sd); + } + else + { + folder_request_body["folders"].append(folder_sd); + } + folder_count++; } - folder_count++; } else { @@ -1015,6 +1019,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch() { recursive_cats.push_back(cat_id); } + all_cats.push_back(cat_id); } mFetchFolderQueue.pop_front(); @@ -1349,6 +1354,46 @@ void BGFolderHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::Http << LLCoreHttpUtil::responseToString(response) << "]" << LL_ENDL; // Could use a 404 test here to try to detect revoked caps... + + if(status == LLCore::HttpStatus(HTTP_FORBIDDEN)) + { + // too large, split into two, assume that this isn't the library + const std::string url(gAgent.getRegionCapability("FetchInventoryDescendents2")); + S32 size = mRequestSD["folders"].size(); + + if (!gDisconnected && !LLApp::isExiting() && !url.empty() && size > 1) + { + LLSD folders; + uuid_vec_t recursive_cats; + LLSD::array_iterator iter = mRequestSD["folders"].beginArray(); + LLSD::array_iterator end = mRequestSD["folders"].endArray(); + while (iter != end) + { + folders.append(*iter); + LLUUID fodler_id = iter->get("folder_id").asUUID(); + if (std::find(mRecursiveCatUUIDs.begin(), mRecursiveCatUUIDs.end(), fodler_id) != mRecursiveCatUUIDs.end()) + { + recursive_cats.push_back(fodler_id); + } + if (folders.size() == (S32)(size / 2)) + { + LLSD request_body; + request_body["folders"] = folders; + LLCore::HttpHandler::ptr_t handler(new BGFolderHttpHandler(request_body, recursive_cats)); + gInventory.requestPost(false, url, request_body, handler, "Inventory Folder"); + recursive_cats.clear(); + folders.clear(); + } + iter++; + } + + LLSD request_body; + request_body["folders"] = folders; + LLCore::HttpHandler::ptr_t handler(new BGFolderHttpHandler(request_body, recursive_cats)); + gInventory.requestPost(false, url, request_body, handler, "Inventory Folder"); + return; + } + } // This was originally the request retry logic for the inventory // request which tested on HTTP_INTERNAL_ERROR status. This -- cgit v1.3 From b9fad316a356fd223dcf29ed000de1b86e6a93d3 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 29 May 2023 23:37:58 +0300 Subject: SL-17429 Message user when their inventory hits AIS2 limits --- indra/newview/llinventorymodelbackgroundfetch.cpp | 22 ++++++++++++++++++++-- .../newview/skins/default/xui/en/notifications.xml | 8 ++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index b0ebe83f57..0eb07523ae 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -34,6 +34,7 @@ #include "llinventorymodel.h" #include "llinventoryobserver.h" #include "llinventorypanel.h" +#include "llnotificationsutil.h" #include "llstartup.h" #include "llviewercontrol.h" #include "llviewerinventory.h" @@ -1357,12 +1358,24 @@ void BGFolderHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::Http if(status == LLCore::HttpStatus(HTTP_FORBIDDEN)) { - // too large, split into two, assume that this isn't the library + // Too large, split into two if possible + if (gDisconnected || LLApp::isExiting()) + { + return; + } + const std::string url(gAgent.getRegionCapability("FetchInventoryDescendents2")); + if (url.empty()) + { + LL_WARNS(LOG_INV) << "Failed to get AIS2 cap" << LL_ENDL; + return; + } + S32 size = mRequestSD["folders"].size(); - if (!gDisconnected && !LLApp::isExiting() && !url.empty() && size > 1) + if (size > 1) { + // Can split, assume that this isn't the library LLSD folders; uuid_vec_t recursive_cats; LLSD::array_iterator iter = mRequestSD["folders"].beginArray(); @@ -1393,6 +1406,11 @@ void BGFolderHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::Http gInventory.requestPost(false, url, request_body, handler, "Inventory Folder"); return; } + else + { + // Can't split + LLNotificationsUtil::add("InventoryLimitReachedAIS"); + } } // This was originally the request retry logic for the inventory diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index e8fdc84fae..4c8d7fbd83 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6440,6 +6440,14 @@ Your trash is overflowing. This may cause problems logging in. yestext="Check trash folder"/> + +Your inventory is experiencing issues. Please, contact support. + fail + + Date: Wed, 21 Jun 2023 18:38:10 +0300 Subject: SL-19898 FIXED Contents purchased from items do not show in Recent Items until selecting folder --- indra/newview/llinventorymodelbackgroundfetch.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 0eb07523ae..26288e6b0a 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -357,6 +357,8 @@ void LLInventoryModelBackgroundFetch::scheduleFolderFetch(const LLUUID& cat_id, { if (mFetchFolderQueue.empty() || mFetchFolderQueue.front().mUUID != cat_id) { + mBackgroundFetchActive = true; + // Specific folder requests go to front of queue. mFetchFolderQueue.push_front(FetchQueueInfo(cat_id, forced ? FT_FORCED : FT_DEFAULT)); gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL); -- cgit v1.3 From 74a1d2582c457aff738bf73c21e137015acfe6cb Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 17 Aug 2023 19:49:37 +0300 Subject: SL-20162 Better cof version logging And fixed some typos --- indra/newview/llaisapi.cpp | 4 ++-- indra/newview/llinventorymodelbackgroundfetch.cpp | 8 ++++---- indra/newview/llpanellandmarkinfo.cpp | 4 ++-- indra/newview/llpanellandmarkinfo.h | 2 +- indra/newview/llvoavatar.cpp | 9 ++++++++- 5 files changed, 17 insertions(+), 10 deletions(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 4546574955..d8d30037c8 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -1646,7 +1646,7 @@ void AISUpdate::doUpdate() gInventory.updateCategory(new_category, LLInventoryObserver::CREATE); LL_DEBUGS("Inventory") << "created category " << category_id << LL_ENDL; - // fetching can receive massive amount of items and fodlers + // fetching can receive massive amount of items and folders if (gInventory.getChangedIDs().size() > MAX_UPDATE_BACKLOG) { gInventory.notifyObservers(); @@ -1707,7 +1707,7 @@ void AISUpdate::doUpdate() LL_DEBUGS("Inventory") << "created item " << item_id << LL_ENDL; gInventory.updateItem(new_item, LLInventoryObserver::CREATE); - // fetching can receive massive amount of items and fodlers + // fetching can receive massive amount of items and folders if (gInventory.getChangedIDs().size() > MAX_UPDATE_BACKLOG) { gInventory.notifyObservers(); diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 03205cfbda..44eccd955e 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -657,7 +657,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis() || mLastFetchCount != mFetchCount) // if anything was substracted { LL_DEBUGS(LOG_INV , "AIS3") << "Total active fetches: " << mLastFetchCount << "->" << last_fetch_count << "->" << mFetchCount - << ", scheduled fodler fetches: " << (S32)mFetchFolderQueue.size() + << ", scheduled folder fetches: " << (S32)mFetchFolderQueue.size() << ", scheduled item fetches: " << (S32)mFetchItemQueue.size() << LL_ENDL; mLastFetchCount = mFetchCount; @@ -1384,10 +1384,10 @@ void BGFolderHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::Http while (iter != end) { folders.append(*iter); - LLUUID fodler_id = iter->get("folder_id").asUUID(); - if (std::find(mRecursiveCatUUIDs.begin(), mRecursiveCatUUIDs.end(), fodler_id) != mRecursiveCatUUIDs.end()) + LLUUID folder_id = iter->get("folder_id").asUUID(); + if (std::find(mRecursiveCatUUIDs.begin(), mRecursiveCatUUIDs.end(), folder_id) != mRecursiveCatUUIDs.end()) { - recursive_cats.push_back(fodler_id); + recursive_cats.push_back(folder_id); } if (folders.size() == (S32)(size / 2)) { diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp index 834e664723..cc3c51dd83 100644 --- a/indra/newview/llpanellandmarkinfo.cpp +++ b/indra/newview/llpanellandmarkinfo.cpp @@ -111,9 +111,9 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type) } // Sets CREATE_LANDMARK infotype and creates landmark at desired folder -void LLPanelLandmarkInfo::setInfoAndCreateLandmark(const LLUUID& fodler_id) +void LLPanelLandmarkInfo::setInfoAndCreateLandmark(const LLUUID& folder_id) { - setInfoType(CREATE_LANDMARK, fodler_id); + setInfoType(CREATE_LANDMARK, folder_id); } void LLPanelLandmarkInfo::setInfoType(EInfoType type, const LLUUID &folder_id) diff --git a/indra/newview/llpanellandmarkinfo.h b/indra/newview/llpanellandmarkinfo.h index 46e2a1935b..8802ce066e 100644 --- a/indra/newview/llpanellandmarkinfo.h +++ b/indra/newview/llpanellandmarkinfo.h @@ -48,7 +48,7 @@ public: /*virtual*/ void setInfoType(EInfoType type); // Sets CREATE_LANDMARK infotype and creates landmark at desired folder - void setInfoAndCreateLandmark(const LLUUID& fodler_id); + void setInfoAndCreateLandmark(const LLUUID& folder_id); /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 305c489cc8..57a78181bd 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -9447,7 +9447,14 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) // RequestAgentUpdateAppearanceResponder::onRequestRequested() // assumes that cof version is only updated with server-bake // appearance messages. - LL_INFOS("Avatar") << "Processing appearance message version " << thisAppearanceVersion << LL_ENDL; + if (isSelf()) + { + LL_INFOS("Avatar") << "Processing appearance message version " << thisAppearanceVersion << LL_ENDL; + } + else + { + LL_INFOS("Avatar") << "Processing appearance message for " << getID() << ", version " << thisAppearanceVersion << LL_ENDL; + } // Note: // locally the COF is maintained via LLInventoryModel::accountForUpdate -- cgit v1.3 From f107d8431ccbd85bbe6f2ac0fd47cd409b8c0cfc Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 11 Sep 2023 17:31:08 +0300 Subject: SL-20199 Fix invalid or oversized folder being refetched indefinetely --- indra/newview/llinventorymodelbackgroundfetch.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 44eccd955e..07d5713fc8 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -549,6 +549,13 @@ void LLInventoryModelBackgroundFetch::onAISFolderCalback(const LLUUID &request_i { LL_WARNS() << "Failed to download folder: " << request_id << " Requesting known content separately" << LL_ENDL; mFetchFolderQueue.push_back(FetchQueueInfo(request_id, FT_CONTENT_RECURSIVE)); + + // set folder's version to prevent viewer from trying to request folder indefinetely + LLViewerInventoryCategory* cat(gInventory.getCategory(request_id)); + if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN) + { + cat->setVersion(0); + } } } else -- cgit v1.3 From 81752116e1243d68ae67c4771f267c4170dd9028 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 20 Sep 2023 18:48:13 +0300 Subject: SL-20298 Fix recursive fetch not working properly. --- indra/newview/llinventorymodelbackgroundfetch.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/newview/llinventorymodelbackgroundfetch.cpp') diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 07d5713fc8..91adef8047 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -864,7 +864,8 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc else { // Already fetched, check if anything inside needs fetching - if (fetch_info.mFetchType == FT_RECURSIVE) + if (fetch_info.mFetchType == FT_RECURSIVE + || fetch_info.mFetchType == FT_FOLDER_AND_CONTENT) { LLInventoryModel::cat_array_t * categories(NULL); LLInventoryModel::item_array_t * items(NULL); -- cgit v1.3