summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRider Linden <none@none>2015-04-03 14:23:31 -0700
committerRider Linden <none@none>2015-04-03 14:23:31 -0700
commit17641c8427d05c4cde1fadd2ca059264d89bc818 (patch)
tree08f12a5bc407e770a99bc69a78807bf1d2bc4d5a
parentfbd58959c2ac2216fb451bd687558763ceb2ab30 (diff)
Added a class to automate pumping the HttpRequest on the mainloop.
Converted AccountingCostManager to use the new LLCore::Http library and coroutines.
-rwxr-xr-xindra/llmessage/llavatarnamecache.h2
-rw-r--r--indra/llmessage/llcorehttputil.cpp21
-rw-r--r--indra/llmessage/llcorehttputil.h18
-rwxr-xr-xindra/newview/llaccountingcostmanager.cpp284
-rwxr-xr-xindra/newview/llaccountingcostmanager.h15
5 files changed, 215 insertions, 125 deletions
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index fdfd4e972d..17b948f799 100755
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -29,8 +29,6 @@
#define LLAVATARNAMECACHE_H
#include "llavatarname.h" // for convenience
-//#include "httpcommon.h"
-//#include "httpheaders.h"
#include <boost/signals2.hpp>
class LLSD;
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
index 991985b1cf..30f5f3d3ed 100644
--- a/indra/llmessage/llcorehttputil.cpp
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -279,6 +279,27 @@ void HttpCoroHandler::buildStatusEntry(LLCore::HttpResponse *response, LLCore::H
result["http_result"] = httpresults;
}
+HttpRequestPumper::HttpRequestPumper(const LLCore::HttpRequest::ptr_t &request):
+ mHttpRequest(request)
+{
+ mBoundListener = LLEventPumps::instance().obtain("mainloop").
+ listen(LLEventPump::inventName(), boost::bind(&HttpRequestPumper::pollRequest, this, _1));
+}
+
+HttpRequestPumper::~HttpRequestPumper()
+{
+ if (mBoundListener.connected())
+ {
+ mBoundListener.disconnect();
+ }
+}
+
+bool HttpRequestPumper::pollRequest(const LLSD&)
+{
+ mHttpRequest->update(0L);
+ return false;
+}
+
} // end namespace LLCoreHttpUtil
diff --git a/indra/llmessage/llcorehttputil.h b/indra/llmessage/llcorehttputil.h
index 0bc102a0a3..4ae6e112b3 100644
--- a/indra/llmessage/llcorehttputil.h
+++ b/indra/llmessage/llcorehttputil.h
@@ -165,8 +165,6 @@ LLCore::HttpHandle requestPutWithLLSD(LLCore::HttpRequest::ptr_t & request,
/// +- ["url"] - The URL used to make the call.
/// +- ["headers"] - A map of name name value pairs with the HTTP headers.
///
-
-///
class HttpCoroHandler : public LLCore::HttpHandler
{
public:
@@ -182,6 +180,22 @@ private:
LLEventStream &mReplyPump;
};
+/// The HttpRequestPumper is a utility class. When constructed it will poll the
+/// supplied HttpRequest once per frame until it is destroyed.
+///
+class HttpRequestPumper
+{
+public:
+ HttpRequestPumper(const LLCore::HttpRequest::ptr_t &request);
+ ~HttpRequestPumper();
+
+private:
+ bool pollRequest(const LLSD&);
+
+ LLTempBoundListener mBoundListener;
+ LLCore::HttpRequest::ptr_t mHttpRequest;
+};
+
} // end namespace LLCoreHttpUtil
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
{
diff --git a/indra/newview/llaccountingcostmanager.h b/indra/newview/llaccountingcostmanager.h
index 3ade34c81d..7d544b15e8 100755
--- a/indra/newview/llaccountingcostmanager.h
+++ b/indra/newview/llaccountingcostmanager.h
@@ -30,6 +30,13 @@
#include "llhandle.h"
#include "llaccountingcost.h"
+#include "httpcommon.h"
+#include "llcoros.h"
+#include "lleventcoro.h"
+#include "httprequest.h"
+#include "httpheaders.h"
+#include "httpoptions.h"
+
//===============================================================================
// An interface class for panels which display the parcel accounting information.
class LLAccountingCostObserver
@@ -69,6 +76,14 @@ private:
//a fetch has been instigated.
std::set<LLUUID> mPendingObjectQuota;
typedef std::set<LLUUID>::iterator IDIt;
+
+ void accountingCostCoro(LLCoros::self& self, std::string url, eSelectionType selectionType, const LLHandle<LLAccountingCostObserver> observerHandle);
+
+ LLCore::HttpRequest::ptr_t mHttpRequest;
+ LLCore::HttpHeaders::ptr_t mHttpHeaders;
+ LLCore::HttpOptions::ptr_t mHttpOptions;
+ LLCore::HttpRequest::policy_t mHttpPolicy;
+ LLCore::HttpRequest::priority_t mHttpPriority;
};
//===============================================================================