summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2023-03-17 23:44:28 +0200
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2023-03-18 00:31:09 +0200
commit70d99cde5826893be4964d4673ff875320b7220f (patch)
treef251dde18af1ca74b9b037b600af18f0f2146f82 /indra/newview
parent4f9f149939cfd79ba6d18ed90202b29225c2969c (diff)
SL-18629 Track request depth to be able to distinguish incomplete folder reliably
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llaisapi.cpp87
-rw-r--r--indra/newview/llaisapi.h13
-rw-r--r--indra/newview/llinventorymodelbackgroundfetch.cpp73
-rw-r--r--indra/newview/llviewerinventory.cpp6
4 files changed, 102 insertions, 77 deletions
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<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)>
//----
@@ -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<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)>
//----
@@ -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<LLSD(LLCoreHttpUtil::HttpCoroutineAdapter::*)(LLCore::HttpRequest::ptr_t, const std::string &, LLCore::HttpOptions::ptr_t, LLCore::HttpHeaders::ptr_t)>
//----
@@ -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;
}