SL-20436 New accounts that select outfit in web fail to download clothing

master
Andrey Kleshchev 2023-10-11 22:34:00 +03:00 committed by akleshchev
parent 067f3790da
commit cebbdf2d12
5 changed files with 101 additions and 65 deletions

View File

@ -2779,23 +2779,13 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool
if (AISAPI::isAvailable() && category->getPreferredType() == LLFolderType::FT_OUTFIT)
{
// for reliability just fetch it whole, linked items included
LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)category;
LLUUID cat_id = category->getUUID();
cat->setFetching(LLViewerInventoryCategory::FETCH_RECURSIVE);
AISAPI::FetchCategoryLinks(cat_id,
[cat_id, copy, append](const LLUUID& id)
{
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
if (cat)
{
cat->setFetching(LLViewerInventoryCategory::FETCH_NONE);
}
if (id.isNull())
{
LL_WARNS() << "failed to fetch category, attempting to wear as is " << cat_id << LL_ENDL;
}
LLAppearanceMgr::instance().wearCategoryFinal(cat_id, copy, append);
});
LLInventoryModelBackgroundFetch::getInstance()->fetchFolderAndLinks(
cat_id,
[cat_id, copy, append]
{
LLAppearanceMgr::instance().wearCategoryFinal(cat_id, copy, append);
});
}
else
{
@ -4595,30 +4585,20 @@ protected:
void callAfterCOFFetch(nullary_func_t cb)
{
LLUUID cat_id = LLAppearanceMgr::instance().getCOF();
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
if (AISAPI::isAvailable())
{
// Mark cof (update timer) so that background fetch won't request it
cat->setFetching(LLViewerInventoryCategory::FETCH_RECURSIVE);
// For reliability assume that we have no relevant cache, so
// fetch cof along with items cof's links point to.
AISAPI::FetchCOF([cb](const LLUUID& id)
{
cb();
LLUUID cat_id = LLAppearanceMgr::instance().getCOF();
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
if (cat)
{
cat->setFetching(LLViewerInventoryCategory::FETCH_NONE);
}
});
LLInventoryModelBackgroundFetch::getInstance()->fetchCOF(cb);
}
else
{
LL_INFOS() << "AIS API v3 not available, using callAfterCategoryFetch" << LL_ENDL;
// startup should have marked folder as fetching, remove that
LLUUID cat_id = LLAppearanceMgr::instance().getCOF();
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
// Special case, startup should have marked cof as FETCH_RECURSIVE
// to prevent dupplicate request, remove that
cat->setFetching(LLViewerInventoryCategory::FETCH_NONE);
callAfterCategoryFetch(cat_id, cb);
}
@ -4640,30 +4620,16 @@ void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb)
void callAfterCategoryLinksFetch(const LLUUID &cat_id, nullary_func_t cb)
{
LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
if (AISAPI::isAvailable())
{
// Mark folder (update timer) so that background fetch won't request it
cat->setFetching(LLViewerInventoryCategory::FETCH_RECURSIVE);
// Assume that we have no relevant cache. Fetch folder, and items folder's links point to.
AISAPI::FetchCategoryLinks(cat_id,
[cb, cat_id](const LLUUID &id)
{
cb();
LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
if (cat)
{
cat->setFetching(LLViewerInventoryCategory::FETCH_NONE);
}
});
}
else
{
LL_WARNS() << "AIS API v3 not available, can't use AISAPI::FetchCOF" << LL_ENDL;
// startup should have marked folder as fetching, remove that
cat->setFetching(LLViewerInventoryCategory::FETCH_NONE);
callAfterCategoryFetch(cat_id, cb);
}
LLInventoryModelBackgroundFetch::getInstance()->fetchFolderAndLinks(cat_id, cb);
}
else
{
LL_WARNS() << "AIS API v3 not available, can't use AISAPI::FetchCOF" << LL_ENDL;
callAfterCategoryFetch(cat_id, cb);
}
}

View File

@ -357,6 +357,7 @@ void LLInventoryModelBackgroundFetch::scheduleFolderFetch(const LLUUID& cat_id,
if (mFetchFolderQueue.empty() || mFetchFolderQueue.front().mUUID != cat_id)
{
mBackgroundFetchActive = true;
mFolderFetchActive = true;
// Specific folder requests go to front of queue.
mFetchFolderQueue.push_front(FetchQueueInfo(cat_id, forced ? FT_FORCED : FT_DEFAULT));
@ -375,6 +376,61 @@ void LLInventoryModelBackgroundFetch::scheduleItemFetch(const LLUUID& item_id, b
}
}
void LLInventoryModelBackgroundFetch::fetchFolderAndLinks(const LLUUID& cat_id, nullary_func_t callback)
{
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
if (cat)
{
// Mark folder (update timer) so that background fetch won't request it
cat->setFetching(LLViewerInventoryCategory::FETCH_RECURSIVE);
}
incrFetchFolderCount(1);
mExpectedFolderIds.push_back(cat_id);
// Assume that we have no relevant cache. Fetch folder, and items folder's links point to.
AISAPI::FetchCategoryLinks(cat_id,
[callback, cat_id](const LLUUID& id)
{
callback();
if (id.isNull())
{
LL_WARNS() << "Failed to fetch category links " << cat_id << LL_ENDL;
}
LLInventoryModelBackgroundFetch::getInstance()->onAISFolderCalback(cat_id, id, FT_DEFAULT);
});
// start idle loop to track completion
mBackgroundFetchActive = true;
mFolderFetchActive = true;
gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL);
}
void LLInventoryModelBackgroundFetch::fetchCOF(nullary_func_t callback)
{
LLUUID cat_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
if (cat)
{
// Mark cof (update timer) so that background fetch won't request it
cat->setFetching(LLViewerInventoryCategory::FETCH_RECURSIVE);
}
incrFetchFolderCount(1);
mExpectedFolderIds.push_back(cat_id);
// For reliability assume that we have no relevant cache, so
// fetch cof along with items cof's links point to.
AISAPI::FetchCOF([callback](const LLUUID& id)
{
callback();
LLUUID cat_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
LLInventoryModelBackgroundFetch::getInstance()->onAISFolderCalback(cat_id, id, FT_DEFAULT);
});
// start idle loop to track completion
mBackgroundFetchActive = true;
mFolderFetchActive = true;
gIdleCallbacks.addFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL);
}
void LLInventoryModelBackgroundFetch::findLostItems()
{
mBackgroundFetchActive = true;

View File

@ -53,6 +53,13 @@ public:
void scheduleFolderFetch(const LLUUID& cat_id, bool forced = false);
void scheduleItemFetch(const LLUUID& item_id, bool forced = false);
typedef boost::function<void()> nullary_func_t;
// AIS3 only, Fetches folder and everithing links inside the folder point to
// Intended for outfits
void fetchFolderAndLinks(const LLUUID& cat_id, nullary_func_t callback);
// AIS3 only
void fetchCOF(nullary_func_t callback);
BOOL folderFetchActive() const;
bool isEverythingFetched() const; // completing the fetch once per session should be sufficient

View File

@ -418,10 +418,22 @@ void LLInventoryFetchDescendentsObserver::changed(U32 mask)
}
++it;
}
if (mIncomplete.empty())
{
done();
}
if (mIncomplete.empty())
{
done();
}
else
{
LLInventoryModelBackgroundFetch* fetcher = LLInventoryModelBackgroundFetch::getInstance();
if (fetcher->isEverythingFetched()
&& !fetcher->folderFetchActive())
{
// If fetcher is done with folders yet we are waiting, fetch either
// failed or version is somehow stuck at -1
done();
}
}
}
void LLInventoryFetchDescendentsObserver::startFetch()
@ -432,12 +444,8 @@ void LLInventoryFetchDescendentsObserver::startFetch()
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.
//blindly fetch it without seeing if anything else is fetching it.
LLInventoryModelBackgroundFetch::getInstance()->scheduleFolderFetch(*it, true);
mIncomplete.push_back(*it); //Add to list of things being downloaded for this observer.
}
else

View File

@ -2877,8 +2877,7 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
// Need to fetch cof contents before we can wear.
if (do_copy)
{
callAfterCategoryFetch(LLAppearanceMgr::instance().getCOF(),
boost::bind(&LLAppearanceMgr::wearInventoryCategory, LLAppearanceMgr::getInstance(), cat, do_copy, do_append));
callAfterCOFFetch(boost::bind(&LLAppearanceMgr::wearInventoryCategory, LLAppearanceMgr::getInstance(), cat, do_copy, do_append));
}
else
{