Initial AISv3 merge. New HTTP messages not plugged in yet.

This commit is contained in:
Shyotl
2015-06-25 20:16:30 -05:00
parent 09f4528bfb
commit 9f10d9510d
71 changed files with 4962 additions and 3452 deletions

View File

@@ -40,23 +40,112 @@
#include "hippogridmanager.h"
class AIHTTPTimeoutPolicy;
extern AIHTTPTimeoutPolicy inventoryModelFetchDescendentsResponder_timeout;
extern AIHTTPTimeoutPolicy inventoryModelFetchItemResponder_timeout;
extern AIHTTPTimeoutPolicy BGItemHttpHandler_timeout;
extern AIHTTPTimeoutPolicy BGFolderHttpHandler_timeout;
const F32 MAX_TIME_FOR_SINGLE_FETCH = 10.f;
const S32 MAX_FETCH_RETRIES = 10;
///----------------------------------------------------------------------------
/// Class <anonymous>::BGItemHttpHandler
///----------------------------------------------------------------------------
//
// Http request handler class for single inventory item requests.
//
// We'll use a handler-per-request pattern here rather than
// a shared handler. Mainly convenient as this was converted
// from a Responder class model.
//
// Derives from and is identical to the normal FetchItemHttpHandler
// except that: 1) it uses the background request object which is
// updated more slowly than the foreground and 2) keeps a count of
// active requests on the LLInventoryModelBackgroundFetch object
// to indicate outstanding operations are in-flight.
//
class BGItemHttpHandler : public LLInventoryModel::FetchItemHttpHandler
{
LOG_CLASS(BGItemHttpHandler);
public:
BGItemHttpHandler(const LLSD & request_sd)
: LLInventoryModel::FetchItemHttpHandler(request_sd)
{
LLInventoryModelBackgroundFetch::instance().incrFetchCount(1);
}
virtual ~BGItemHttpHandler()
{
LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);
}
/*virtual*/ AICapabilityType capability_type(void) const { return cap_inventory; }
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return BGItemHttpHandler_timeout; }
/*virtual*/ char const* getName(void) const { return "BGItemHttpHandler"; }
protected:
BGItemHttpHandler(const BGItemHttpHandler &); // Not defined
void operator=(const BGItemHttpHandler &); // Not defined
};
///----------------------------------------------------------------------------
/// Class <anonymous>::BGFolderHttpHandler
///----------------------------------------------------------------------------
// Http request handler class for folders.
//
// Handler for FetchInventoryDescendents2 and FetchLibDescendents2
// caps requests for folders.
//
class BGFolderHttpHandler : public LLHTTPClient::ResponderWithResult
{
LOG_CLASS(BGFolderHttpHandler);
public:
BGFolderHttpHandler(const LLSD & request_sd, const uuid_vec_t & recursive_cats)
: LLHTTPClient::ResponderWithResult(),
mRequestSD(request_sd),
mRecursiveCatUUIDs(recursive_cats)
{
LLInventoryModelBackgroundFetch::instance().incrFetchCount(1);
}
virtual ~BGFolderHttpHandler()
{
LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);
}
/*virtual*/ AICapabilityType capability_type(void) const { return cap_inventory; }
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return BGFolderHttpHandler_timeout; }
/*virtual*/ char const* getName(void) const { return "BGFolderHttpHandler"; }
protected:
BGFolderHttpHandler(const BGFolderHttpHandler &); // Not defined
void operator=(const BGFolderHttpHandler &); // Not defined
BOOL getIsRecursive(const LLUUID& cat_id) const;
private:
/*virtual*/ void httpSuccess(void);
/*virtual*/ void httpFailure(void);
LLSD mRequestSD;
uuid_vec_t mRecursiveCatUUIDs; // hack for storing away which cat fetches are recursive
};
const char * const LOG_INV("Inventory");
LLInventoryModelBackgroundFetch::LLInventoryModelBackgroundFetch() :
mBackgroundFetchActive(FALSE),
mFolderFetchActive(false),
mFetchCount(0),
mAllFoldersFetched(FALSE),
mRecursiveInventoryFetchStarted(FALSE),
mRecursiveLibraryFetchStarted(FALSE),
mNumFetchRetries(0),
mMinTimeBetweenFetches(0.3f),
mMaxTimeBetweenFetches(10.f),
mTimelyFetchPending(FALSE),
mFetchCount(0)
mTimelyFetchPending(FALSE)
{
}
@@ -109,12 +198,24 @@ BOOL LLInventoryModelBackgroundFetch::folderFetchActive() const
return mFolderFetchActive;
}
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)
{
mFetchQueue.push_back(FetchQueueInfo(id, recursive, is_category));
}
void LLInventoryModelBackgroundFetch::start(const LLUUID& id, BOOL recursive)
{
LLViewerInventoryCategory* cat = gInventory.getCategory(id);
if (cat || (id.isNull() && !isEverythingFetched()))
{ // it's a folder, do a bulk fetch
LL_DEBUGS("InventoryFetch") << "Start fetching category: " << id << ", recursive: " << recursive << LL_ENDL;
LLViewerInventoryCategory * cat(gInventory.getCategory(id));
if (cat || (id.isNull() && ! isEverythingFetched()))
{
// it's a folder, do a bulk fetch
LL_DEBUGS(LOG_INV) << "Start fetching category: " << id << ", recursive: " << recursive << LL_ENDL;
mFolderFetchActive = true;
if (id.isNull())
@@ -181,11 +282,13 @@ void LLInventoryModelBackgroundFetch::setAllFoldersFetched()
mAllFoldersFetched = TRUE;
}
mFolderFetchActive = false;
if (mBackgroundFetchActive)
{
gIdleCallbacks.deleteFunction(&LLInventoryModelBackgroundFetch::backgroundFetchCB, NULL);
mBackgroundFetchActive = FALSE;
}
mBackgroundFetchActive = false;
LL_INFOS(LOG_INV) << "Inventory background fetch completed" << LL_ENDL;
}
void LLInventoryModelBackgroundFetch::backgroundFetchCB(void *)
@@ -385,241 +488,41 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()
}
}
void LLInventoryModelBackgroundFetch::incrFetchCount(S16 fetching)
void LLInventoryModelBackgroundFetch::incrFetchCount(S32 fetching)
{
mFetchCount += fetching;
if (mFetchCount < 0)
{
LL_WARNS_ONCE(LOG_INV) << "Inventory fetch count fell below zero (0)." << LL_ENDL;
mFetchCount = 0;
}
}
class LLInventoryModelFetchItemResponder : public LLInventoryModel::fetchInventoryResponder
{
public:
LLInventoryModelFetchItemResponder(const LLSD& request_sd) : LLInventoryModel::fetchInventoryResponder(request_sd) {};
/*virtual*/ void httpSuccess(void);
/*virtual*/ void httpFailure(void);
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return inventoryModelFetchItemResponder_timeout; }
/*virtual*/ char const* getName(void) const { return "LLInventoryModelFetchItemResponder"; }
};
void LLInventoryModelFetchItemResponder::httpSuccess(void)
{
LLInventoryModel::fetchInventoryResponder::httpSuccess();
LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);
}
void LLInventoryModelFetchItemResponder::httpFailure(void)
{
LLInventoryModel::fetchInventoryResponder::httpFailure();
LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);
}
class LLInventoryModelFetchDescendentsResponder : public LLHTTPClient::ResponderWithResult
{
public:
LLInventoryModelFetchDescendentsResponder(const LLSD& request_sd, uuid_vec_t recursive_cats) :
mRequestSD(request_sd),
mRecursiveCatUUIDs(recursive_cats)
{};
/*virtual*/ void httpSuccess(void);
/*virtual*/ void httpFailure(void);
/*virtual*/ AICapabilityType capability_type(void) const { return cap_inventory; }
/*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return inventoryModelFetchDescendentsResponder_timeout; }
/*virtual*/ char const* getName(void) const { return "LLInventoryModelFetchDescendentsResponder"; }
protected:
BOOL getIsRecursive(const LLUUID& cat_id) const;
private:
LLSD mRequestSD;
uuid_vec_t mRecursiveCatUUIDs; // hack for storing away which cat fetches are recursive
};
// If we get back a normal response, handle it here.
void LLInventoryModelFetchDescendentsResponder::httpSuccess(void)
{
LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
if (mContent.has("folders"))
{
for(LLSD::array_const_iterator folder_it = mContent["folders"].beginArray();
folder_it != mContent["folders"].endArray();
++folder_it)
{
LLSD folder_sd = *folder_it;
//LLUUID agent_id = folder_sd["agent_id"];
//if(agent_id != gAgent.getID()) //This should never happen.
//{
// LL_WARNS() << "Got a UpdateInventoryItem for the wrong agent."
// << LL_ENDL;
// break;
//}
LLUUID parent_id = folder_sd["folder_id"];
LLUUID owner_id = folder_sd["owner_id"];
S32 version = (S32)folder_sd["version"].asInteger();
S32 descendents = (S32)folder_sd["descendents"].asInteger();
LLPointer<LLViewerInventoryCategory> tcategory = new LLViewerInventoryCategory(owner_id);
if (parent_id.isNull())
{
LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
for(LLSD::array_const_iterator item_it = folder_sd["items"].beginArray();
item_it != folder_sd["items"].endArray();
++item_it)
{
LLUUID lost_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
if (lost_uuid.notNull())
{
LLSD item = *item_it;
titem->unpackMessage(item);
LLInventoryModel::update_list_t update;
LLInventoryModel::LLCategoryUpdate new_folder(lost_uuid, 1);
update.push_back(new_folder);
gInventory.accountForUpdate(update);
titem->setParent(lost_uuid);
titem->updateParentOnServer(FALSE);
gInventory.updateItem(titem);
gInventory.notifyObservers();
}
}
}
LLViewerInventoryCategory* pcat = gInventory.getCategory(parent_id);
if (!pcat)
{
continue;
}
for(LLSD::array_const_iterator category_it = folder_sd["categories"].beginArray();
category_it != folder_sd["categories"].endArray();
++category_it)
{
LLSD category = *category_it;
tcategory->fromLLSD(category);
const BOOL recursive = getIsRecursive(tcategory->getUUID());
if (recursive)
{
fetcher->mFetchQueue.push_back(LLInventoryModelBackgroundFetch::FetchQueueInfo(tcategory->getUUID(), recursive));
}
else if ( !gInventory.isCategoryComplete(tcategory->getUUID()) )
{
gInventory.updateCategory(tcategory);
}
}
LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
for(LLSD::array_const_iterator item_it = folder_sd["items"].beginArray();
item_it != folder_sd["items"].endArray();
++item_it)
{
LLSD item = *item_it;
titem->unpackMessage(item);
gInventory.updateItem(titem);
}
// set version and descendentcount according to message.
LLViewerInventoryCategory* cat = gInventory.getCategory(parent_id);
if(cat)
{
cat->setVersion(version);
cat->setDescendentCount(descendents);
cat->determineFolderType();
}
}
}
if (mContent.has("bad_folders"))
{
for(LLSD::array_const_iterator folder_it = mContent["bad_folders"].beginArray();
folder_it != mContent["bad_folders"].endArray();
++folder_it)
{
LLSD folder_sd = *folder_it;
//These folders failed on the dataserver. We probably don't want to retry them.
LL_INFOS() << "Folder " << folder_sd["folder_id"].asString()
<< "Error: " << folder_sd["error"].asString() << LL_ENDL;
}
}
fetcher->incrFetchCount(-1);
if (fetcher->isBulkFetchProcessingComplete())
{
LL_INFOS() << "Inventory fetch completed" << LL_ENDL;
fetcher->setAllFoldersFetched();
}
gInventory.notifyObservers();
}
//If we get back an error (not found, etc...), handle it here
void LLInventoryModelFetchDescendentsResponder::httpFailure(void)
{
LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
LL_INFOS() << "LLInventoryModelFetchDescendentsResponder::error "
<< mStatus << ": " << mReason << LL_ENDL;
fetcher->incrFetchCount(-1);
if (is_internal_http_error_that_warrants_a_retry(mStatus)) // timed out
{
for(LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray();
folder_it != mRequestSD["folders"].endArray();
++folder_it)
{
LLSD folder_sd = *folder_it;
LLUUID folder_id = folder_sd["folder_id"];
const BOOL recursive = getIsRecursive(folder_id);
fetcher->mFetchQueue.push_front(LLInventoryModelBackgroundFetch::FetchQueueInfo(folder_id, recursive));
}
}
else
{
if (fetcher->isBulkFetchProcessingComplete())
{
fetcher->setAllFoldersFetched();
}
}
gInventory.notifyObservers();
}
BOOL LLInventoryModelFetchDescendentsResponder::getIsRecursive(const LLUUID& cat_id) const
{
return (std::find(mRecursiveCatUUIDs.begin(),mRecursiveCatUUIDs.end(), cat_id) != mRecursiveCatUUIDs.end());
}
// Bundle up a bunch of requests to send all at once.
void LLInventoryModelBackgroundFetch::bulkFetch()
{
//Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped.
//If there are items in mFetchQueue, we want to check the time since the last bulkFetch was
//sent. If it exceeds our retry time, go ahead and fire off another batch.
LLViewerRegion* region = gAgent.getRegion();
if (gDisconnected || !region) return;
LLViewerRegion * region(gAgent.getRegion());
if (! region || gDisconnected)
{
return;
}
// *TODO: These values could be tweaked at runtime to effect
// a fast/slow fetch throttle. Once login is complete and the scene
U32 const max_batch_size = 5;
U32 sort_order = gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER) & 0x1;
U32 item_count(0);
U32 folder_count(0);
const U32 sort_order(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER) & 0x1);
uuid_vec_t recursive_cats;
U32 folder_count=0;
U32 folder_lib_count=0;
U32 item_count=0;
U32 item_lib_count=0;
// This function can do up to four requests at once.
@@ -633,15 +536,26 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
LLSD item_request_body;
LLSD item_request_body_lib;
while (!mFetchQueue.empty())
while (! mFetchQueue.empty())
{
const FetchQueueInfo& fetch_info = mFetchQueue.front();
const FetchQueueInfo & fetch_info(mFetchQueue.front());
if (fetch_info.mIsCategory)
{
const LLUUID &cat_id = fetch_info.mUUID;
if (!cat_id.isNull())
const LLUUID & cat_id(fetch_info.mUUID);
if (cat_id.isNull()) //DEV-17797
{
const LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
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_request_body["folders"].append(folder_sd);
folder_count++;
}
else
{
const LLViewerInventoryCategory * cat(gInventory.getCategory(cat_id));
if (cat)
{
@@ -650,9 +564,9 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
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"] = TRUE; //(LLSD::Boolean)sFullFetchStarted;
folder_sd["fetch_items"] = (LLSD::Boolean)TRUE;
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())
{
@@ -680,8 +594,8 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
// May already have this folder, but append child folders to list.
if (fetch_info.mRecursive)
{
LLInventoryModel::cat_array_t* categories;
LLInventoryModel::item_array_t* items;
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();
@@ -691,13 +605,16 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
}
}
}
if (fetch_info.mRecursive)
recursive_cats.push_back(cat_id);
}
if (fetch_info.mRecursive)
{
recursive_cats.push_back(cat_id);
}
}
else
{
LLViewerInventoryItem* itemp = gInventory.getItem(fetch_info.mUUID);
LLViewerInventoryItem * itemp(gInventory.getItem(fetch_info.mUUID));
if (itemp)
{
LLSD item_sd;
@@ -735,39 +652,62 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
{
if (folder_count)
{
std::string url = region->getCapability("FetchInventoryDescendents2");
llassert(!url.empty());
++mFetchCount;
LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats);
LLHTTPClient::post_approved(url, folder_request_body, fetcher, approved_folder);
if (folder_request_body["folders"].size())
{
const std::string url(region->getCapability("FetchInventoryDescendents2"));
if (! url.empty())
{
BGFolderHttpHandler * handler(new BGFolderHttpHandler(folder_request_body, recursive_cats));
LLHTTPClient::post_approved(url, folder_request_body, handler, approved_folder);
}
}
}
if (folder_lib_count)
{
std::string url = gAgent.getRegion()->getCapability("FetchLibDescendents2");
llassert(!url.empty());
++mFetchCount;
LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats);
LLHTTPClient::post_approved(url, folder_request_body_lib, fetcher, approved_folder_lib);
if (folder_request_body_lib["folders"].size())
{
const std::string url(region->getCapability("FetchLibDescendents2"));
if (! url.empty())
{
BGFolderHttpHandler * handler(new BGFolderHttpHandler(folder_request_body_lib, recursive_cats));
LLHTTPClient::post_approved(url, folder_request_body_lib, handler, approved_folder_lib);
}
}
}
if (item_count)
{
std::string url = region->getCapability("FetchInventory2");
llassert(!url.empty());
++mFetchCount;
LLSD body;
body["agent_id"] = gAgent.getID();
body["items"] = item_request_body;
LLHTTPClient::post_approved(url, body, new LLInventoryModelFetchItemResponder(body), approved_item);
if (item_request_body.size())
{
const std::string url(region->getCapability("FetchInventory2"));
if (! url.empty())
{
LLSD body;
body["agent_id"] = gAgent.getID();
body["items"] = item_request_body;
BGItemHttpHandler * handler(new BGItemHttpHandler(body));
LLHTTPClient::post_approved(url, body, handler, approved_item);
}
}
}
if (item_lib_count)
{
std::string url = region->getCapability("FetchLib2");
llassert(!url.empty());
++mFetchCount;
LLSD body;
body["agent_id"] = gAgent.getID();
body["items"] = item_request_body_lib;
LLHTTPClient::post_approved(url, body, new LLInventoryModelFetchItemResponder(body), approved_item_lib);
if (item_request_body_lib.size())
{
const std::string url(region->getCapability("FetchLib2"));
if (! url.empty())
{
LLSD body;
body["agent_id"] = gAgent.getID();
body["items"] = item_request_body_lib;
BGItemHttpHandler * handler(new BGItemHttpHandler(body));
LLHTTPClient::post_approved(url, body, handler, approved_item_lib);
}
}
}
mFetchTimer.reset();
}
@@ -781,7 +721,8 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
bool LLInventoryModelBackgroundFetch::fetchQueueContainsNoDescendentsOf(const LLUUID& cat_id) const
{
for (fetch_queue_t::const_iterator it = mFetchQueue.begin();
it != mFetchQueue.end(); ++it)
it != mFetchQueue.end();
++it)
{
const LLUUID& fetch_id = (*it).mUUID;
if (gInventory.isObjectDescendentOf(fetch_id, cat_id))
@@ -789,4 +730,175 @@ bool LLInventoryModelBackgroundFetch::fetchQueueContainsNoDescendentsOf(const LL
}
return true;
}
// If we get back a normal response, handle it here.
void BGFolderHttpHandler::httpSuccess(void)
{
LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
const LLSD& content = mContent;
// in response as an application-level error.
// Instead, we assume success and attempt to extract information.
if (content.has("folders"))
{
LLSD folders(content["folders"]);
for (LLSD::array_const_iterator folder_it = folders.beginArray();
folder_it != folders.endArray();
++folder_it)
{
LLSD folder_sd(*folder_it);
//LLUUID agent_id = folder_sd["agent_id"];
//if(agent_id != gAgent.getID()) //This should never happen.
//{
// LL_WARNS(LOG_INV) << "Got a UpdateInventoryItem for the wrong agent."
// << LL_ENDL;
// break;
//}
LLUUID parent_id(folder_sd["folder_id"].asUUID());
LLUUID owner_id(folder_sd["owner_id"].asUUID());
S32 version(folder_sd["version"].asInteger());
S32 descendents(folder_sd["descendents"].asInteger());
LLPointer<LLViewerInventoryCategory> tcategory = new LLViewerInventoryCategory(owner_id);
if (parent_id.isNull())
{
LLSD items(folder_sd["items"]);
LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
for (LLSD::array_const_iterator item_it = items.beginArray();
item_it != items.endArray();
++item_it)
{
const LLUUID lost_uuid(gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND));
if (lost_uuid.notNull())
{
LLSD item(*item_it);
titem->unpackMessage(item);
LLInventoryModel::update_list_t update;
LLInventoryModel::LLCategoryUpdate new_folder(lost_uuid, 1);
update.push_back(new_folder);
gInventory.accountForUpdate(update);
titem->setParent(lost_uuid);
titem->updateParentOnServer(FALSE);
gInventory.updateItem(titem);
gInventory.notifyObservers();
}
}
}
LLViewerInventoryCategory * pcat(gInventory.getCategory(parent_id));
if (! pcat)
{
continue;
}
LLSD categories(folder_sd["categories"]);
for (LLSD::array_const_iterator category_it = categories.beginArray();
category_it != categories.endArray();
++category_it)
{
LLSD category(*category_it);
tcategory->fromLLSD(category);
const bool recursive(getIsRecursive(tcategory->getUUID()));
if (recursive)
{
fetcher->addRequestAtBack(tcategory->getUUID(), recursive, true);
}
else if (! gInventory.isCategoryComplete(tcategory->getUUID()))
{
gInventory.updateCategory(tcategory);
}
}
LLSD items(folder_sd["items"]);
LLPointer<LLViewerInventoryItem> titem = new LLViewerInventoryItem;
for (LLSD::array_const_iterator item_it = items.beginArray();
item_it != items.endArray();
++item_it)
{
LLSD item(*item_it);
titem->unpackMessage(item);
gInventory.updateItem(titem);
}
// Set version and descendentcount according to message.
LLViewerInventoryCategory * cat(gInventory.getCategory(parent_id));
if (cat)
{
cat->setVersion(version);
cat->setDescendentCount(descendents);
cat->determineFolderType();
}
}
}
if (content.has("bad_folders"))
{
LLSD bad_folders(content["bad_folders"]);
for (LLSD::array_const_iterator folder_it = bad_folders.beginArray();
folder_it != bad_folders.endArray();
++folder_it)
{
// *TODO: Stop copying data [ed: this isn't copying data]
LLSD folder_sd(*folder_it);
// These folders failed on the dataserver. We probably don't want to retry them.
LL_WARNS(LOG_INV) << "Folder " << folder_sd["folder_id"].asString()
<< "Error: " << folder_sd["error"].asString() << LL_ENDL;
}
}
if (fetcher->isBulkFetchProcessingComplete())
{
LL_INFOS() << "Inventory fetch completed" << LL_ENDL;
fetcher->setAllFoldersFetched();
}
gInventory.notifyObservers();
}
//If we get back an error (not found, etc...), handle it here
void BGFolderHttpHandler::httpFailure(void)
{
LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
LL_INFOS() << "BGFolderHttpHandler::error "
<< mStatus << ": " << mReason << LL_ENDL;
if (is_internal_http_error_that_warrants_a_retry(mStatus)) // timed out
{
for(LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray();
folder_it != mRequestSD["folders"].endArray();
++folder_it)
{
LLSD folder_sd(*folder_it);
LLUUID folder_id(folder_sd["folder_id"].asUUID());
const BOOL recursive = getIsRecursive(folder_id);
fetcher->addRequestAtFront(folder_id, recursive, true);
}
}
else
{
if (fetcher->isBulkFetchProcessingComplete())
{
fetcher->setAllFoldersFetched();
}
}
gInventory.notifyObservers();
}
BOOL BGFolderHttpHandler::getIsRecursive(const LLUUID& cat_id) const
{
return (std::find(mRecursiveCatUUIDs.begin(),mRecursiveCatUUIDs.end(), cat_id) != mRecursiveCatUUIDs.end());
}