Added LL_WARNS_IF to llerror.h
If the coro is given something other than a map from the http then move the return into a body section. Changed windlight to use a coroutine and the new LLCore::Http libarary. Extra comments into Event Polling.meow-7.2.2
parent
fb082a185d
commit
e28a5b6ead
|
|
@ -354,6 +354,7 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
|
|||
#define LL_WARNS(...) lllog(LLError::LEVEL_WARN, false, ##__VA_ARGS__)
|
||||
#define LL_ERRS(...) lllog(LLError::LEVEL_ERROR, false, ##__VA_ARGS__)
|
||||
// alternative to llassert_always that prints explanatory message
|
||||
#define LL_WARNS_IF(exp, ...) if (exp) LL_WARNS(##__VA_ARGS__) << "(" #exp ")"
|
||||
#define LL_ERRS_IF(exp, ...) if (exp) LL_ERRS(##__VA_ARGS__) << "(" #exp ")"
|
||||
|
||||
// Only print the log message once (good for warnings or infos that would otherwise
|
||||
|
|
|
|||
|
|
@ -241,12 +241,19 @@ void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons
|
|||
}
|
||||
|
||||
if (result.isUndefined())
|
||||
{
|
||||
// If we've gotten to this point and the result LLSD is still undefined
|
||||
{ // If we've gotten to this point and the result LLSD is still undefined
|
||||
// either there was an issue deserializing the body or the response was
|
||||
// blank. Create an empty map to hold the result either way.
|
||||
result = LLSD::emptyMap();
|
||||
}
|
||||
else if (!result.isMap())
|
||||
{ // The results are not themselves a map. Move them down so that
|
||||
// this method can return a map to the caller.
|
||||
// *TODO: Should it always do this?
|
||||
LLSD newResult = LLSD::emptyMap();
|
||||
newResult["content"] = result;
|
||||
result = newResult;
|
||||
}
|
||||
}
|
||||
|
||||
buildStatusEntry(response, status, result);
|
||||
|
|
|
|||
|
|
@ -59,11 +59,11 @@ namespace Details
|
|||
// We will wait RETRY_SECONDS + (errorCount * RETRY_SECONDS_INC) before retrying after an error.
|
||||
// This means we attempt to recover relatively quickly but back off giving more time to recover
|
||||
// until we finally give up after MAX_EVENT_POLL_HTTP_ERRORS attempts.
|
||||
static const F32 EVENT_POLL_ERROR_RETRY_SECONDS;
|
||||
static const F32 EVENT_POLL_ERROR_RETRY_SECONDS_INC;
|
||||
static const S32 MAX_EVENT_POLL_HTTP_ERRORS;
|
||||
static const F32 EVENT_POLL_ERROR_RETRY_SECONDS;
|
||||
static const F32 EVENT_POLL_ERROR_RETRY_SECONDS_INC;
|
||||
static const S32 MAX_EVENT_POLL_HTTP_ERRORS;
|
||||
|
||||
void eventPollCoro(LLCoros::self& self, std::string url);
|
||||
void eventPollCoro(LLCoros::self& self, std::string url);
|
||||
|
||||
void handleMessage(const LLSD &content);
|
||||
|
||||
|
|
@ -138,11 +138,14 @@ namespace Details
|
|||
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("EventPoller", mHttpPolicy));
|
||||
LLSD acknowledge;
|
||||
int errorCount = 0;
|
||||
int counter = mCounter; // saved on the stack for debugging.
|
||||
int counter = mCounter; // saved on the stack for logging.
|
||||
|
||||
LL_INFOS("LLEventPollImpl") << " <" << counter << "> entering coroutine." << LL_ENDL;
|
||||
|
||||
mAdapter = httpAdapter;
|
||||
|
||||
// continually poll for a server update until we've been flagged as
|
||||
// finished
|
||||
while (!mDone)
|
||||
{
|
||||
LLSD request;
|
||||
|
|
@ -158,23 +161,23 @@ namespace Details
|
|||
// LL_DEBUGS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> result = "
|
||||
// << LLSDXMLStreamer(result) << LL_ENDL;
|
||||
|
||||
LLSD httpResults;
|
||||
httpResults = result["http_result"];
|
||||
LLSD httpResults = result["http_result"];
|
||||
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroHandler::getStatusFromLLSD(httpResults);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
|
||||
if (status == LLCore::HttpStatus(HTTP_BAD_GATEWAY))
|
||||
{
|
||||
// A HTTP_BAD_GATEWAY (502) error is our standard timeout response
|
||||
{ // A HTTP_BAD_GATEWAY (502) error is our standard timeout response
|
||||
// we get this when there are no events.
|
||||
errorCount = 0;
|
||||
continue;
|
||||
}
|
||||
else if ((status == LLCore::HttpStatus(LLCore::HttpStatus::LLCORE, LLCore::HE_OP_CANCELED)) ||
|
||||
(status == LLCore::HttpStatus(HTTP_NOT_FOUND)))
|
||||
{
|
||||
{ // Event polling for this server has been canceled. In
|
||||
// some cases the server gets ahead of the viewer and will
|
||||
// return a 404 error (Not Found) before the cancel event
|
||||
// comes back in the queue
|
||||
LL_WARNS() << "Canceling coroutine" << LL_ENDL;
|
||||
break;
|
||||
}
|
||||
|
|
@ -182,7 +185,11 @@ namespace Details
|
|||
<< status.toTerseString() << ": '" << httpResults["message"] << "'" << LL_ENDL;
|
||||
|
||||
if (errorCount < MAX_EVENT_POLL_HTTP_ERRORS)
|
||||
{
|
||||
{ // An unanticipated error has been received from our poll
|
||||
// request. Calculate a timeout and wait for it to expire(sleep)
|
||||
// before trying again. The sleep time is increased by 5 seconds
|
||||
// for each consecutive error.
|
||||
LLEventTimeout timeout;
|
||||
++errorCount;
|
||||
|
||||
F32 waitToRetry = EVENT_POLL_ERROR_RETRY_SECONDS
|
||||
|
|
@ -191,15 +198,12 @@ namespace Details
|
|||
LL_WARNS("LLEventPollImpl") << "<" << counter << "> Retrying in " << waitToRetry <<
|
||||
" seconds, error count is now " << errorCount << LL_ENDL;
|
||||
|
||||
{
|
||||
LLEventTimeout timeout;
|
||||
timeout.eventAfter(waitToRetry, LLSD());
|
||||
waitForEventOn(self, timeout);
|
||||
}
|
||||
timeout.eventAfter(waitToRetry, LLSD());
|
||||
waitForEventOn(self, timeout);
|
||||
|
||||
if (mDone)
|
||||
break;
|
||||
LL_INFOS("LLEventPollImpl") << "<" << counter << "> About to retry request." << LL_ENDL;
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
|
@ -208,7 +212,6 @@ namespace Details
|
|||
// IMs, teleports, about land, selecting land, region crossing and more will all fail.
|
||||
// They are essentially disconnected from the region even though some things may still work.
|
||||
// Since things won't get better until they relog we force a disconnect now.
|
||||
|
||||
mDone = true;
|
||||
|
||||
// *NOTE:Mani - The following condition check to see if this failing event poll
|
||||
|
|
@ -237,10 +240,7 @@ namespace Details
|
|||
acknowledge = result["id"];
|
||||
LLSD events = result["events"];
|
||||
|
||||
if (acknowledge.isUndefined())
|
||||
{
|
||||
LL_WARNS("LLEventPollImpl") << " id undefined" << LL_ENDL;
|
||||
}
|
||||
LL_WARNS_IF((acknowledge.isUndefined()), "LLEventPollImpl") << " id undefined" << LL_ENDL;
|
||||
|
||||
// was LL_INFOS() but now that CoarseRegionUpdate is TCP @ 1/second, it'd be too verbose for viewer logs. -MG
|
||||
LL_DEBUGS("LLEventPollImpl") << " <" << counter << "> " << events.size() << "events (id " << LLSDXMLStreamer(acknowledge) << ")" << LL_ENDL;
|
||||
|
|
@ -256,7 +256,6 @@ namespace Details
|
|||
}
|
||||
}
|
||||
LL_INFOS("LLEventPollImpl") << " <" << counter << "> Leaving coroutine." << LL_ENDL;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "llviewerregion.h"
|
||||
#include "llenvmanager.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llcorehttputil.h"
|
||||
|
||||
/****
|
||||
* LLEnvironmentRequest
|
||||
|
|
@ -81,55 +82,62 @@ bool LLEnvironmentRequest::doRequest()
|
|||
return false;
|
||||
}
|
||||
|
||||
LL_INFOS("WindlightCaps") << "Requesting region windlight settings via " << url << LL_ENDL;
|
||||
LLHTTPClient::get(url, new LLEnvironmentRequestResponder());
|
||||
return true;
|
||||
std::string coroname =
|
||||
LLCoros::instance().launch("LLEnvironmentRequest::environmentRequestCoro",
|
||||
boost::bind(&LLEnvironmentRequest::environmentRequestCoro, _1, url));
|
||||
|
||||
LL_INFOS("WindlightCaps") << "Requesting region windlight settings via " << url << LL_ENDL;
|
||||
return true;
|
||||
}
|
||||
|
||||
/****
|
||||
* LLEnvironmentRequestResponder
|
||||
****/
|
||||
int LLEnvironmentRequestResponder::sCount = 0; // init to 0
|
||||
S32 LLEnvironmentRequest::sLastRequest = 0;
|
||||
|
||||
LLEnvironmentRequestResponder::LLEnvironmentRequestResponder()
|
||||
//static
|
||||
void LLEnvironmentRequest::environmentRequestCoro(LLCoros::self& self, std::string url)
|
||||
{
|
||||
mID = ++sCount;
|
||||
}
|
||||
/*virtual*/ void LLEnvironmentRequestResponder::httpSuccess()
|
||||
{
|
||||
const LLSD& unvalidated_content = getContent();
|
||||
LL_INFOS("WindlightCaps") << "Received region windlight settings" << LL_ENDL;
|
||||
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
|
||||
S32 requestId = ++LLEnvironmentRequest::sLastRequest;
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
|
||||
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("EnvironmentRequest", httpPolicy));
|
||||
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
|
||||
|
||||
if (mID != sCount)
|
||||
{
|
||||
LL_INFOS("WindlightCaps") << "Got superseded by another responder; ignoring..." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
LLSD result = httpAdapter->getAndYield(self, httpRequest, url);
|
||||
|
||||
LLUUID regionId;
|
||||
if( gAgent.getRegion() )
|
||||
{
|
||||
regionId = gAgent.getRegion()->getRegionID();
|
||||
}
|
||||
|
||||
if (unvalidated_content[0]["regionID"].asUUID() != regionId )
|
||||
{
|
||||
LL_WARNS("WindlightCaps") << "Not in the region from where this data was received (wanting "
|
||||
<< regionId << " but got " << unvalidated_content[0]["regionID"].asUUID()
|
||||
<< ") - ignoring..." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
if (requestId != LLEnvironmentRequest::sLastRequest)
|
||||
{
|
||||
LL_INFOS("WindlightCaps") << "Got superseded by another responder; ignoring..." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LLEnvManagerNew::getInstance()->onRegionSettingsResponse(unvalidated_content);
|
||||
}
|
||||
/*virtual*/
|
||||
void LLEnvironmentRequestResponder::httpFailure()
|
||||
{
|
||||
LL_WARNS("WindlightCaps") << "Got an error, not using region windlight... "
|
||||
<< dumpResponse() << LL_ENDL;
|
||||
LLEnvManagerNew::getInstance()->onRegionSettingsResponse(LLSD());
|
||||
LLSD httpResults = result["http_result"];
|
||||
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroHandler::getStatusFromLLSD(httpResults);
|
||||
if (!status)
|
||||
{
|
||||
LL_WARNS("WindlightCaps") << "Got an error, not using region windlight... " << LL_ENDL;
|
||||
LLEnvManagerNew::getInstance()->onRegionSettingsResponse(LLSD());
|
||||
return;
|
||||
}
|
||||
result = result["content"];
|
||||
LL_INFOS("WindlightCaps") << "Received region windlight settings" << LL_ENDL;
|
||||
|
||||
LLUUID regionId;
|
||||
if (gAgent.getRegion())
|
||||
{
|
||||
regionId = gAgent.getRegion()->getRegionID();
|
||||
}
|
||||
|
||||
if (result[0]["regionID"].asUUID() != regionId)
|
||||
{
|
||||
LL_WARNS("WindlightCaps") << "Not in the region from where this data was received (wanting "
|
||||
<< regionId << " but got " << result[0]["regionID"].asUUID()
|
||||
<< ") - ignoring..." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LLEnvManagerNew::getInstance()->onRegionSettingsResponse(result);
|
||||
}
|
||||
|
||||
|
||||
/****
|
||||
* LLEnvironmentApply
|
||||
****/
|
||||
|
|
@ -161,53 +169,86 @@ bool LLEnvironmentApply::initiateRequest(const LLSD& content)
|
|||
return false;
|
||||
}
|
||||
|
||||
LL_INFOS("WindlightCaps") << "Sending windlight settings to " << url << LL_ENDL;
|
||||
LL_DEBUGS("WindlightCaps") << "content: " << content << LL_ENDL;
|
||||
LLHTTPClient::post(url, content, new LLEnvironmentApplyResponder());
|
||||
LL_INFOS("WindlightCaps") << "Sending windlight settings to " << url << LL_ENDL;
|
||||
LL_DEBUGS("WindlightCaps") << "content: " << content << LL_ENDL;
|
||||
|
||||
std::string coroname =
|
||||
LLCoros::instance().launch("LLEnvironmentApply::environmentApplyCoro",
|
||||
boost::bind(&LLEnvironmentApply::environmentApplyCoro, _1, url, content));
|
||||
return true;
|
||||
}
|
||||
|
||||
/****
|
||||
* LLEnvironmentApplyResponder
|
||||
****/
|
||||
/*virtual*/ void LLEnvironmentApplyResponder::httpSuccess()
|
||||
void LLEnvironmentApply::environmentApplyCoro(LLCoros::self& self, std::string url, LLSD content)
|
||||
{
|
||||
const LLSD& content = getContent();
|
||||
if (!content.isMap() || !content.has("regionID"))
|
||||
{
|
||||
failureResult(HTTP_INTERNAL_ERROR, "Malformed response contents", content);
|
||||
return;
|
||||
}
|
||||
if (content["regionID"].asUUID() != gAgent.getRegion()->getRegionID())
|
||||
{
|
||||
LL_WARNS("WindlightCaps") << "No longer in the region where data was sent (currently "
|
||||
<< gAgent.getRegion()->getRegionID() << ", reply is from " << content["regionID"].asUUID()
|
||||
<< "); ignoring..." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
else if (content["success"].asBoolean())
|
||||
{
|
||||
LL_DEBUGS("WindlightCaps") << "Success in applying windlight settings to region " << content["regionID"].asUUID() << LL_ENDL;
|
||||
LLEnvManagerNew::instance().onRegionSettingsApplyResponse(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("WindlightCaps") << "Region couldn't apply windlight settings! " << dumpResponse() << LL_ENDL;
|
||||
LLSD args(LLSD::emptyMap());
|
||||
args["FAIL_REASON"] = content["fail_reason"].asString();
|
||||
LLNotificationsUtil::add("WLRegionApplyFail", args);
|
||||
LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false);
|
||||
}
|
||||
}
|
||||
/*virtual*/
|
||||
void LLEnvironmentApplyResponder::httpFailure()
|
||||
{
|
||||
LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region! "
|
||||
<< dumpResponse() << LL_ENDL;
|
||||
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
|
||||
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
|
||||
httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("EnvironmentApply", httpPolicy));
|
||||
LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
|
||||
|
||||
LLSD args(LLSD::emptyMap());
|
||||
std::stringstream msg;
|
||||
msg << getReason() << " (Code " << getStatus() << ")";
|
||||
args["FAIL_REASON"] = msg.str();
|
||||
LLNotificationsUtil::add("WLRegionApplyFail", args);
|
||||
LLSD result = httpAdapter->postAndYield(self, httpRequest, url, content);
|
||||
|
||||
LLSD notify; // for error reporting. If there is something to report to user this will be defined.
|
||||
/*
|
||||
* Expecting reply from sim in form of:
|
||||
* {
|
||||
* regionID : uuid,
|
||||
* messageID: uuid,
|
||||
* success : true
|
||||
* }
|
||||
* or
|
||||
* {
|
||||
* regionID : uuid,
|
||||
* success : false,
|
||||
* fail_reason : string
|
||||
* }
|
||||
*/
|
||||
|
||||
do // while false.
|
||||
{ // Breaks from loop in the case of an error.
|
||||
|
||||
LLSD httpResults = result["http_result"];
|
||||
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroHandler::getStatusFromLLSD(httpResults);
|
||||
if (!status)
|
||||
{
|
||||
LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region! " << LL_ENDL;
|
||||
|
||||
std::stringstream msg;
|
||||
msg << status.toString() << " (Code " << status.toTerseString() << ")";
|
||||
notify = LLSD::emptyMap();
|
||||
notify["FAIL_REASON"] = msg.str();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!result.has("regionID"))
|
||||
{
|
||||
notify = LLSD::emptyMap();
|
||||
notify["FAIL_REASON"] = "Missing regionID, malformed response";
|
||||
break;
|
||||
}
|
||||
else if (result["regionID"].asUUID() != gAgent.getRegion()->getRegionID())
|
||||
{
|
||||
// note that there is no report to the user in this failure case.
|
||||
LL_WARNS("WindlightCaps") << "No longer in the region where data was sent (currently "
|
||||
<< gAgent.getRegion()->getRegionID() << ", reply is from " << result["regionID"].asUUID()
|
||||
<< "); ignoring..." << LL_ENDL;
|
||||
break;
|
||||
}
|
||||
else if (!result["success"].asBoolean())
|
||||
{
|
||||
LL_WARNS("WindlightCaps") << "Region couldn't apply windlight settings! " << LL_ENDL;
|
||||
notify = LLSD::emptyMap();
|
||||
notify["FAIL_REASON"] = result["fail_reason"].asString();
|
||||
break;
|
||||
}
|
||||
|
||||
LL_DEBUGS("WindlightCaps") << "Success in applying windlight settings to region " << result["regionID"].asUUID() << LL_ENDL;
|
||||
LLEnvManagerNew::instance().onRegionSettingsApplyResponse(true);
|
||||
|
||||
} while (false);
|
||||
|
||||
if (!notify.isUndefined())
|
||||
{
|
||||
LLNotificationsUtil::add("WLRegionApplyFail", notify);
|
||||
LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llhttpclient.h"
|
||||
#include "llcoros.h"
|
||||
|
||||
class LLEnvironmentRequest
|
||||
{
|
||||
|
|
@ -40,21 +41,10 @@ public:
|
|||
private:
|
||||
static void onRegionCapsReceived(const LLUUID& region_id);
|
||||
static bool doRequest();
|
||||
};
|
||||
|
||||
class LLEnvironmentRequestResponder: public LLHTTPClient::Responder
|
||||
{
|
||||
LOG_CLASS(LLEnvironmentRequestResponder);
|
||||
private:
|
||||
/* virtual */ void httpSuccess();
|
||||
/* virtual */ void httpFailure();
|
||||
static void environmentRequestCoro(LLCoros::self& self, std::string url);
|
||||
|
||||
private:
|
||||
friend class LLEnvironmentRequest;
|
||||
|
||||
LLEnvironmentRequestResponder();
|
||||
static int sCount;
|
||||
int mID;
|
||||
static S32 sLastRequest;
|
||||
};
|
||||
|
||||
class LLEnvironmentApply
|
||||
|
|
@ -67,8 +57,11 @@ public:
|
|||
private:
|
||||
static clock_t sLastUpdate;
|
||||
static clock_t UPDATE_WAIT_SECONDS;
|
||||
|
||||
static void environmentApplyCoro(LLCoros::self& self, std::string url, LLSD content);
|
||||
};
|
||||
|
||||
#if 0
|
||||
class LLEnvironmentApplyResponder: public LLHTTPClient::Responder
|
||||
{
|
||||
LOG_CLASS(LLEnvironmentApplyResponder);
|
||||
|
|
@ -97,5 +90,6 @@ private:
|
|||
|
||||
LLEnvironmentApplyResponder() {}
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // LL_LLWLHANDLERS_H
|
||||
|
|
|
|||
Loading…
Reference in New Issue