Skip to content
Snippets Groups Projects
Commit 8a76284e authored by Rider Linden's avatar Rider Linden
Browse files

Results from code review with Nat. Consolidate some of the coroutine/http code...

Results from code review with Nat. Consolidate some of the coroutine/http code into a single adapter.
parent 0962dd23
Branches
Tags
No related merge requests found
...@@ -189,10 +189,6 @@ namespace LLAvatarNameCache ...@@ -189,10 +189,6 @@ namespace LLAvatarNameCache
// further explanation. // further explanation.
void LLAvatarNameCache::requestAvatarNameCache_(LLCoros::self& self, std::string url, std::vector<LLUUID> agentIds) void LLAvatarNameCache::requestAvatarNameCache_(LLCoros::self& self, std::string url, std::vector<LLUUID> agentIds)
{ {
LLEventStream replyPump("NameCacheReply", true);
LLCoreHttpUtil::HttpCoroHandler::ptr_t httpHandler =
LLCoreHttpUtil::HttpCoroHandler::ptr_t(new LLCoreHttpUtil::HttpCoroHandler(replyPump));
LL_DEBUGS("AvNameCache") << "Entering coroutine " << LLCoros::instance().getName(self) LL_DEBUGS("AvNameCache") << "Entering coroutine " << LLCoros::instance().getName(self)
<< " with url '" << url << "', requesting " << agentIds.size() << " Agent Ids" << LL_ENDL; << " with url '" << url << "', requesting " << agentIds.size() << " Agent Ids" << LL_ENDL;
...@@ -200,12 +196,8 @@ void LLAvatarNameCache::requestAvatarNameCache_(LLCoros::self& self, std::string ...@@ -200,12 +196,8 @@ void LLAvatarNameCache::requestAvatarNameCache_(LLCoros::self& self, std::string
{ {
bool success = true; bool success = true;
LLAvatarNameCache::sHttpRequest->requestGet( LLCoreHttpUtil::HttpCoroutineAdapter httpAdapter("NameCache", LLAvatarNameCache::sHttpPolicy);
LLAvatarNameCache::sHttpPolicy, LLAvatarNameCache::sHttpPriority, LLSD results = httpAdapter.getAndYield(self, sHttpRequest, url);
url, LLAvatarNameCache::sHttpOptions.get(),
LLAvatarNameCache::sHttpHeaders.get(), httpHandler.get());
LLSD results = waitForEventOn(self, replyPump);
LLSD httpResults; LLSD httpResults;
LL_DEBUGS() << results << LL_ENDL; LL_DEBUGS() << results << LL_ENDL;
...@@ -564,8 +556,6 @@ void LLAvatarNameCache::idle() ...@@ -564,8 +556,6 @@ void LLAvatarNameCache::idle()
// By convention, start running at first idle() call // By convention, start running at first idle() call
sRunning = true; sRunning = true;
sHttpRequest->update(0L);
// *TODO: Possibly re-enabled this based on People API load measurements // *TODO: Possibly re-enabled this based on People API load measurements
// 100 ms is the threshold for "user speed" operations, so we can // 100 ms is the threshold for "user speed" operations, so we can
// stall for about that long to batch up requests. // stall for about that long to batch up requests.
......
...@@ -187,7 +187,7 @@ std::string responseToString(LLCore::HttpResponse * response) ...@@ -187,7 +187,7 @@ std::string responseToString(LLCore::HttpResponse * response)
return empty; return empty;
} }
//========================================================================
HttpCoroHandler::HttpCoroHandler(LLEventStream &reply) : HttpCoroHandler::HttpCoroHandler(LLEventStream &reply) :
mReplyPump(reply) mReplyPump(reply)
{ {
...@@ -251,11 +251,12 @@ void HttpCoroHandler::buildStatusEntry(LLCore::HttpResponse *response, LLCore::H ...@@ -251,11 +251,12 @@ void HttpCoroHandler::buildStatusEntry(LLCore::HttpResponse *response, LLCore::H
{ {
LLSD httpresults = LLSD::emptyMap(); LLSD httpresults = LLSD::emptyMap();
httpresults["success"] = static_cast<LLSD::Boolean>(status); writeStatusCodes(status, response->getRequestURL(), httpresults);
httpresults["type"] = static_cast<LLSD::Integer>(status.getType()); // httpresults["success"] = static_cast<LLSD::Boolean>(status);
httpresults["status"] = static_cast<LLSD::Integer>(status.getStatus()); // httpresults["type"] = static_cast<LLSD::Integer>(status.getType());
httpresults["message"] = static_cast<LLSD::String>(status.getMessage()); // httpresults["status"] = static_cast<LLSD::Integer>(status.getStatus());
httpresults["url"] = static_cast<LLSD::String>(response->getRequestURL()); // httpresults["message"] = static_cast<LLSD::String>(status.getMessage());
// httpresults["url"] = static_cast<LLSD::String>(response->getRequestURL());
LLSD httpHeaders = LLSD::emptyMap(); LLSD httpHeaders = LLSD::emptyMap();
LLCore::HttpHeaders * hdrs = response->getHeaders(); LLCore::HttpHeaders * hdrs = response->getHeaders();
...@@ -279,6 +280,17 @@ void HttpCoroHandler::buildStatusEntry(LLCore::HttpResponse *response, LLCore::H ...@@ -279,6 +280,17 @@ void HttpCoroHandler::buildStatusEntry(LLCore::HttpResponse *response, LLCore::H
result["http_result"] = httpresults; result["http_result"] = httpresults;
} }
void HttpCoroHandler::writeStatusCodes(LLCore::HttpStatus status, const std::string &url, LLSD &result)
{
result["success"] = static_cast<LLSD::Boolean>(status);
result["type"] = static_cast<LLSD::Integer>(status.getType());
result["status"] = static_cast<LLSD::Integer>(status.getStatus());
result["message"] = static_cast<LLSD::String>(status.getMessage());
result["url"] = static_cast<LLSD::String>(url);
}
//========================================================================
HttpRequestPumper::HttpRequestPumper(const LLCore::HttpRequest::ptr_t &request) : HttpRequestPumper::HttpRequestPumper(const LLCore::HttpRequest::ptr_t &request) :
mHttpRequest(request) mHttpRequest(request)
{ {
...@@ -300,6 +312,164 @@ bool HttpRequestPumper::pollRequest(const LLSD&) ...@@ -300,6 +312,164 @@ bool HttpRequestPumper::pollRequest(const LLSD&)
return false; return false;
} }
//========================================================================
HttpCoroutineAdapter::HttpCoroutineAdapter(const std::string &name,
LLCore::HttpRequest::policy_t policyId, LLCore::HttpRequest::priority_t priority) :
mAdapterName(name),
mPolicyId(policyId),
mPriority(priority)
{
}
HttpCoroutineAdapter::~HttpCoroutineAdapter()
{
}
LLSD HttpCoroutineAdapter::postAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t &request,
const std::string & url, const LLSD & body,
LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
{
if (!options)
{
options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false);
}
if (!headers)
{
headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false);
}
LLEventStream replyPump(mAdapterName, true);
LLCoreHttpUtil::HttpCoroHandler::ptr_t httpHandler =
LLCoreHttpUtil::HttpCoroHandler::ptr_t(new LLCoreHttpUtil::HttpCoroHandler(replyPump));
//LL_INFOS() << "Requesting transaction " << transactionId << LL_ENDL;
LLCoreHttpUtil::HttpRequestPumper pumper(request);
// The HTTPCoroHandler does not self delete, so retrieval of a the contained
// pointer from the smart pointer is safe in this case.
LLCore::HttpHandle hhandle = requestPostWithLLSD(request,
mPolicyId, mPriority, url, body, options, headers,
httpHandler.get());
if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
{
LLCore::HttpStatus status = request->getStatus();
LL_WARNS() << "Error posting to " << url << " Status=" << status.getStatus() <<
" message = " << status.getMessage() << LL_ENDL;
// Mimic the status results returned from an http error that we had
// to wait on
LLSD httpresults = LLSD::emptyMap();
httpHandler->writeStatusCodes(status, url, httpresults);
LLSD errorres = LLSD::emptyMap();
errorres["http_result"] = httpresults;
return errorres;
}
LLSD results = waitForEventOn(self, replyPump);
//LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL;
return results;
}
LLSD HttpCoroutineAdapter::putAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t & request,
const std::string & url, const LLSD & body,
LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
{
if (!options)
{
options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false);
}
if (!headers)
{
headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false);
}
LLEventStream replyPump(mAdapterName, true);
LLCoreHttpUtil::HttpCoroHandler::ptr_t httpHandler =
LLCoreHttpUtil::HttpCoroHandler::ptr_t(new LLCoreHttpUtil::HttpCoroHandler(replyPump));
//LL_INFOS() << "Requesting transaction " << transactionId << LL_ENDL;
LLCoreHttpUtil::HttpRequestPumper pumper(request);
// The HTTPCoroHandler does not self delete, so retrieval of a the contained
// pointer from the smart pointer is safe in this case.
LLCore::HttpHandle hhandle = requestPutWithLLSD(request,
mPolicyId, mPriority, url, body, options, headers,
httpHandler.get());
if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
{
LLCore::HttpStatus status = request->getStatus();
LL_WARNS() << "Error posting to " << url << " Status=" << status.getStatus() <<
" message = " << status.getMessage() << LL_ENDL;
// Mimic the status results returned from an http error that we had
// to wait on
LLSD httpresults = LLSD::emptyMap();
httpHandler->writeStatusCodes(status, url, httpresults);
LLSD errorres = LLSD::emptyMap();
errorres["http_result"] = httpresults;
return errorres;
}
LLSD results = waitForEventOn(self, replyPump);
//LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL;
return results;
}
LLSD HttpCoroutineAdapter::getAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t & request,
const std::string & url,
LLCore::HttpOptions::ptr_t options, LLCore::HttpHeaders::ptr_t headers)
{
if (!options)
{
options = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false);
}
if (!headers)
{
headers = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false);
}
LLEventStream replyPump(mAdapterName + "Reply", true);
LLCoreHttpUtil::HttpCoroHandler::ptr_t httpHandler =
LLCoreHttpUtil::HttpCoroHandler::ptr_t(new LLCoreHttpUtil::HttpCoroHandler(replyPump));
//LL_INFOS() << "Requesting transaction " << transactionId << LL_ENDL;
LLCoreHttpUtil::HttpRequestPumper pumper(request);
// The HTTPCoroHandler does not self delete, so retrieval of a the contained
// pointer from the smart pointer is safe in this case.
LLCore::HttpHandle hhandle = request->requestGet(mPolicyId, mPriority,
url, options.get(), headers.get(), httpHandler.get());
if (hhandle == LLCORE_HTTP_HANDLE_INVALID)
{
LLCore::HttpStatus status = request->getStatus();
LL_WARNS() << "Error posting to " << url << " Status=" << status.getStatus() <<
" message = " << status.getMessage() << LL_ENDL;
// Mimic the status results returned from an http error that we had
// to wait on
LLSD httpresults = LLSD::emptyMap();
httpHandler->writeStatusCodes(status, url, httpresults);
LLSD errorres = LLSD::emptyMap();
errorres["http_result"] = httpresults;
return errorres;
}
LLSD results = waitForEventOn(self, replyPump);
//LL_INFOS() << "Results for transaction " << transactionId << LL_ENDL;
return results;
}
} // end namespace LLCoreHttpUtil } // end namespace LLCoreHttpUtil
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
#include "bufferstream.h" #include "bufferstream.h"
#include "llsd.h" #include "llsd.h"
#include "llevents.h" #include "llevents.h"
#include "llcoros.h"
#include "lleventcoro.h"
/// ///
/// The base llcorehttp library implements many HTTP idioms /// The base llcorehttp library implements many HTTP idioms
...@@ -174,6 +176,7 @@ class HttpCoroHandler : public LLCore::HttpHandler ...@@ -174,6 +176,7 @@ class HttpCoroHandler : public LLCore::HttpHandler
typedef boost::shared_ptr<HttpCoroHandler> ptr_t; typedef boost::shared_ptr<HttpCoroHandler> ptr_t;
void writeStatusCodes(LLCore::HttpStatus status, const std::string &url, LLSD &result);
private: private:
void buildStatusEntry(LLCore::HttpResponse *response, LLCore::HttpStatus status, LLSD &result); void buildStatusEntry(LLCore::HttpResponse *response, LLCore::HttpStatus status, LLSD &result);
...@@ -196,7 +199,49 @@ class HttpRequestPumper ...@@ -196,7 +199,49 @@ class HttpRequestPumper
LLCore::HttpRequest::ptr_t mHttpRequest; LLCore::HttpRequest::ptr_t mHttpRequest;
}; };
} // end namespace LLCoreHttpUtil /// An adapter to handle some of the boilerplate code surrounding HTTP and coroutine
/// interaction.
///
/// Construct an HttpCoroutineAdapter giving it a name and policy Id. After
/// any application specific setup call the post, put or get method. The request
/// will be automatically pumped and the method will return with an LLSD describing
/// the result of the operation. See HttpCoroHandler for a description of the
/// decoration done to the returned LLSD.
class HttpCoroutineAdapter
{
public:
HttpCoroutineAdapter(const std::string &name, LLCore::HttpRequest::policy_t policyId,
LLCore::HttpRequest::priority_t priority = 0L);
~HttpCoroutineAdapter();
/// Execute a Post transaction on the supplied URL and yield execution of
/// the coroutine until a result is available.
LLSD postAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t & request,
const std::string & url, const LLSD & body,
LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(),
LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t());
/// Execute a Put transaction on the supplied URL and yield execution of
/// the coroutine until a result is available.
LLSD putAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t & request,
const std::string & url, const LLSD & body,
LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(),
LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t());
/// Execute a Get transaction on the supplied URL and yield execution of
/// the coroutine until a result is available.
LLSD getAndYield(LLCoros::self & self, LLCore::HttpRequest::ptr_t & request,
const std::string & url,
LLCore::HttpOptions::ptr_t options = LLCore::HttpOptions::ptr_t(),
LLCore::HttpHeaders::ptr_t headers = LLCore::HttpHeaders::ptr_t());
private:
std::string mAdapterName;
LLCore::HttpRequest::priority_t mPriority;
LLCore::HttpRequest::policy_t mPolicyId;
};
} // end namespace LLCoreHttpUtil
#endif // LL_LLCOREHTTPUTIL_H #endif // LL_LLCOREHTTPUTIL_H
...@@ -53,10 +53,6 @@ LLAccountingCostManager::LLAccountingCostManager(): ...@@ -53,10 +53,6 @@ LLAccountingCostManager::LLAccountingCostManager():
void LLAccountingCostManager::accountingCostCoro(LLCoros::self& self, std::string url, void LLAccountingCostManager::accountingCostCoro(LLCoros::self& self, std::string url,
eSelectionType selectionType, const LLHandle<LLAccountingCostObserver> observerHandle) eSelectionType selectionType, const LLHandle<LLAccountingCostObserver> observerHandle)
{ {
LLEventStream replyPump("AccountingCostReply", true);
LLCoreHttpUtil::HttpCoroHandler::ptr_t httpHandler =
LLCoreHttpUtil::HttpCoroHandler::ptr_t(new LLCoreHttpUtil::HttpCoroHandler(replyPump));
LL_DEBUGS("LLAccountingCostManager") << "Entering coroutine " << LLCoros::instance().getName(self) LL_DEBUGS("LLAccountingCostManager") << "Entering coroutine " << LLCoros::instance().getName(self)
<< " with url '" << url << LL_ENDL; << " with url '" << url << LL_ENDL;
...@@ -108,36 +104,22 @@ void LLAccountingCostManager::accountingCostCoro(LLCoros::self& self, std::strin ...@@ -108,36 +104,22 @@ void LLAccountingCostManager::accountingCostCoro(LLCoros::self& self, std::strin
LLUUID transactionId = observer->getTransactionID(); LLUUID transactionId = observer->getTransactionID();
observer = NULL; observer = NULL;
LLSD results; LLCoreHttpUtil::HttpCoroutineAdapter httpAdapter("AccountingCost", mHttpPolicy);
{ // 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) LLSD results = httpAdapter.postAndYield(self, mHttpRequest, url, dataToPost);
{
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; LLSD httpResults;
httpResults = results["http_result"]; httpResults = results["http_result"];
// do/while(false) allows error conditions to break out of following
// block while normal flow goes forward once.
do do
{ {
observer = observerHandle.get(); observer = observerHandle.get();
if ((!observer) || (observer->getTransactionID() != transactionId)) if ((!observer) || (observer->getTransactionID() != transactionId))
{ // *TODO: Rider: I've noticed that getTransactionID() does not { // *TODO: Rider: I've noticed that getTransactionID() does not
// always match transactionId (the new transaction Id does not show a // always match transactionId (the new transaction Id does not show a
// corresponding request.) // corresponding request.) (ask Vir)
if (!observer) if (!observer)
break; break;
LL_WARNS() << "Request transaction Id(" << transactionId LL_WARNS() << "Request transaction Id(" << transactionId
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment