diff options
author | Rider Linden <none@none> | 2015-04-03 14:23:31 -0700 |
---|---|---|
committer | Rider Linden <none@none> | 2015-04-03 14:23:31 -0700 |
commit | 17641c8427d05c4cde1fadd2ca059264d89bc818 (patch) | |
tree | 08f12a5bc407e770a99bc69a78807bf1d2bc4d5a /indra/newview/llaccountingcostmanager.cpp | |
parent | fbd58959c2ac2216fb451bd687558763ceb2ab30 (diff) |
Added a class to automate pumping the HttpRequest on the mainloop.
Converted AccountingCostManager to use the new LLCore::Http library and coroutines.
Diffstat (limited to 'indra/newview/llaccountingcostmanager.cpp')
-rwxr-xr-x | indra/newview/llaccountingcostmanager.cpp | 284 |
1 files changed, 163 insertions, 121 deletions
diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp index a42286a9e4..c52e6e1172 100755 --- a/indra/newview/llaccountingcostmanager.cpp +++ b/indra/newview/llaccountingcostmanager.cpp @@ -27,90 +27,171 @@ #include "llviewerprecompiledheaders.h" #include "llaccountingcostmanager.h" #include "llagent.h" -#include "llcurl.h" -#include "llhttpclient.h" +#include "httpcommon.h" +#include "llcoros.h" +#include "lleventcoro.h" +#include "llcorehttputil.h" + //=============================================================================== -LLAccountingCostManager::LLAccountingCostManager() +LLAccountingCostManager::LLAccountingCostManager(): + mHttpRequest(), + mHttpHeaders(), + mHttpOptions(), + mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID), + mHttpPriority(0) { + mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest()); + mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false); + mHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false); + //mHttpPolicy = LLCore::HttpRequest::DEFAULT_POLICY_ID; + } -//=============================================================================== -class LLAccountingCostResponder : public LLCurl::Responder + +// Coroutine for sending and processing avatar name cache requests. +// Do not call directly. See documentation in lleventcoro.h and llcoro.h for +// further explanation. +void LLAccountingCostManager::accountingCostCoro(LLCoros::self& self, std::string url, + eSelectionType selectionType, const LLHandle<LLAccountingCostObserver> observerHandle) { - LOG_CLASS(LLAccountingCostResponder); -public: - LLAccountingCostResponder( const LLSD& objectIDs, const LLHandle<LLAccountingCostObserver>& observer_handle ) - : mObjectIDs( objectIDs ), - mObserverHandle( observer_handle ) - { - LLAccountingCostObserver* observer = mObserverHandle.get(); - if (observer) - { - mTransactionID = observer->getTransactionID(); - } - } + LLEventStream replyPump("AccountingCostReply", true); + LLCoreHttpUtil::HttpCoroHandler::ptr_t httpHandler = + LLCoreHttpUtil::HttpCoroHandler::ptr_t(new LLCoreHttpUtil::HttpCoroHandler(replyPump)); - void clearPendingRequests ( void ) - { - for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter ) - { - LLAccountingCostManager::getInstance()->removePendingObject( iter->asUUID() ); - } - } - -protected: - void httpFailure() - { - LL_WARNS() << dumpResponse() << LL_ENDL; - clearPendingRequests(); - - LLAccountingCostObserver* observer = mObserverHandle.get(); - if (observer && observer->getTransactionID() == mTransactionID) - { - observer->setErrorStatus(getStatus(), getReason()); - } - } - - void httpSuccess() - { - const LLSD& content = getContent(); - //Check for error - if ( !content.isMap() || content.has("error") ) - { - failureResult(HTTP_INTERNAL_ERROR, "Error on fetched data", content); - return; - } - else if (content.has("selected")) - { - F32 physicsCost = 0.0f; - F32 networkCost = 0.0f; - F32 simulationCost = 0.0f; - - physicsCost = content["selected"]["physics"].asReal(); - networkCost = content["selected"]["streaming"].asReal(); - simulationCost = content["selected"]["simulation"].asReal(); - - SelectionCost selectionCost( /*transactionID,*/ physicsCost, networkCost, simulationCost ); - - LLAccountingCostObserver* observer = mObserverHandle.get(); - if (observer && observer->getTransactionID() == mTransactionID) - { - observer->onWeightsUpdate(selectionCost); - } - } - - clearPendingRequests(); - } - -private: - //List of posted objects - LLSD mObjectIDs; + LL_DEBUGS("LLAccountingCostManager") << "Entering coroutine " << LLCoros::instance().getName(self) + << " with url '" << url << LL_ENDL; + + try + { + LLSD objectList; + U32 objectIndex = 0; + + IDIt IDIter = mObjectList.begin(); + IDIt IDIterEnd = mObjectList.end(); + + for (; IDIter != IDIterEnd; ++IDIter) + { + // Check to see if a request for this object has already been made. + if (mPendingObjectQuota.find(*IDIter) == mPendingObjectQuota.end()) + { + mPendingObjectQuota.insert(*IDIter); + objectList[objectIndex++] = *IDIter; + } + } + + mObjectList.clear(); + + //Post results + if (objectList.size() == 0) + return; + + std::string keystr; + if (selectionType == Roots) + { + keystr = "selected_roots"; + } + else if (selectionType == Prims) + { + keystr = "selected_prims"; + } + else + { + LL_INFOS() << "Invalid selection type " << LL_ENDL; + mObjectList.clear(); + mPendingObjectQuota.clear(); + return; + } - // Current request ID - LLUUID mTransactionID; + LLSD dataToPost = LLSD::emptyMap(); + dataToPost[keystr.c_str()] = objectList; + + LLAccountingCostObserver* observer = observerHandle.get(); + LLUUID transactionId = observer->getTransactionID(); + observer = NULL; + + LLSD results; + { // Scoping block for pumper object + LL_INFOS() << "Requesting transaction " << transactionId << LL_ENDL; + LLCoreHttpUtil::HttpRequestPumper pumper(mHttpRequest); + LLCore::HttpHandle hhandle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, + mHttpPolicy, mHttpPriority, url, dataToPost, mHttpOptions, mHttpHeaders, + httpHandler.get()); + + if (hhandle == LLCORE_HTTP_HANDLE_INVALID) + { + LLCore::HttpStatus status = mHttpRequest->getStatus(); + LL_WARNS() << "Error posting to " << url << " Status=" << status.getStatus() << + " message = " << status.getMessage() << LL_ENDL; + mPendingObjectQuota.clear(); + return; + } + + results = waitForEventOn(self, replyPump); + LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL; + } + LLSD httpResults; + httpResults = results["http_result"]; + + do + { + observer = observerHandle.get(); + if ((!observer) || (observer->getTransactionID() != transactionId)) + { + if (!observer) + break; + LL_WARNS() << "Request transaction Id(" << transactionId + << ") does not match observer's transaction Id(" + << observer->getTransactionID() << ")." << LL_ENDL; + break; + } + + if (!httpResults["success"].asBoolean()) + { + LL_WARNS() << "Error result from LLCoreHttpUtil::HttpCoroHandler. Code " + << httpResults["status"] << ": '" << httpResults["message"] << "'" << LL_ENDL; + if (observer) + { + observer->setErrorStatus(httpResults["status"].asInteger(), httpResults["message"].asStringRef()); + } + break; + } + + if (!results.isMap() || results.has("error")) + { + LL_WARNS() << "Error on fetched data" << LL_ENDL; + observer->setErrorStatus(499, "Error on fetched data"); + break; + } + + if (results.has("selected")) + { + F32 physicsCost = 0.0f; + F32 networkCost = 0.0f; + F32 simulationCost = 0.0f; + + physicsCost = results["selected"]["physics"].asReal(); + networkCost = results["selected"]["streaming"].asReal(); + simulationCost = results["selected"]["simulation"].asReal(); + + SelectionCost selectionCost( physicsCost, networkCost, simulationCost); + + observer->onWeightsUpdate(selectionCost); + } + + } while (false); + + } + catch (std::exception e) + { + LL_WARNS() << "Caught exception '" << e.what() << "'" << LL_ENDL; + } + catch (...) + { + LL_WARNS() << "Caught unknown exception." << LL_ENDL; + } + + mPendingObjectQuota.clear(); +} - // Cost update observer handle - LLHandle<LLAccountingCostObserver> mObserverHandle; -}; //=============================================================================== void LLAccountingCostManager::fetchCosts( eSelectionType selectionType, const std::string& url, @@ -119,50 +200,11 @@ void LLAccountingCostManager::fetchCosts( eSelectionType selectionType, // Invoking system must have already determined capability availability if ( !url.empty() ) { - LLSD objectList; - U32 objectIndex = 0; - - IDIt IDIter = mObjectList.begin(); - IDIt IDIterEnd = mObjectList.end(); - - for ( ; IDIter != IDIterEnd; ++IDIter ) - { - // Check to see if a request for this object has already been made. - if ( mPendingObjectQuota.find( *IDIter ) == mPendingObjectQuota.end() ) - { - mPendingObjectQuota.insert( *IDIter ); - objectList[objectIndex++] = *IDIter; - } - } - - mObjectList.clear(); - - //Post results - if ( objectList.size() > 0 ) - { - std::string keystr; - if ( selectionType == Roots ) - { - keystr="selected_roots"; - } - else - if ( selectionType == Prims ) - { - keystr="selected_prims"; - } - else - { - LL_INFOS()<<"Invalid selection type "<<LL_ENDL; - mObjectList.clear(); - mPendingObjectQuota.clear(); - return; - } - - LLSD dataToPost = LLSD::emptyMap(); - dataToPost[keystr.c_str()] = objectList; - - LLHTTPClient::post( url, dataToPost, new LLAccountingCostResponder( objectList, observer_handle )); - } + std::string coroname = + LLCoros::instance().launch("LLAccountingCostManager::accountingCostCoro", + boost::bind(&LLAccountingCostManager::accountingCostCoro, this, _1, url, selectionType, observer_handle)); + LL_DEBUGS() << coroname << " with url '" << url << LL_ENDL; + } else { |