SL-19533 Faster declouding

master
Andrey Kleshchev 2023-04-13 02:20:33 +03:00
parent 37530c9d73
commit 53f2e1710a
7 changed files with 126 additions and 51 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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.

View File

@ -580,7 +580,9 @@ private:
U32 mModifyMaskBacklog;
changed_items_t mChangedItemIDsBacklog;
changed_items_t mAddedItemIDsBacklog;
changed_items_t mPossiblyBrockenLinks;
typedef std::map<LLUUID , changed_items_t> broken_links_t;
broken_links_t mPossiblyBrockenLinks; // there can be multiple links per item
changed_items_t mLinksRebuildList;
boost::signals2::connection mBulkFecthCallbackSlot;

View File

@ -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

View File

@ -579,6 +579,7 @@ LLViewerInventoryCategory::LLViewerInventoryCategory(const LLUUID& owner_id) :
LLViewerInventoryCategory::LLViewerInventoryCategory(const LLViewerInventoryCategory* other)
{
copyViewerCategory(other);
mFetching = FETCH_NONE;
}
LLViewerInventoryCategory::~LLViewerInventoryCategory()