Cleanup work. Use http constants for content-type and
accept headers in mesh and textures. For texture metrics reporting, use the AP_INVENTORY policy class which is non-pipelined and pointing (usually) in the right direction. Use a do-while(false) structure to manage common exit path code in onCompleted() methods. Identical to a 'goto' but might amuse the pedantic. Tuning on background fetch to have it cycle faster. This is experimental. I suspect with HTTP balancing in llcorehttp, we can do away with the timers here.master
parent
ca333c5777
commit
11036d7bf4
|
|
@ -3,11 +3,8 @@
|
|||
* @brief Implementation of the HTTP request / response constant lookups
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
*
|
||||
* Copyright (c) 2013, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2013, Linden Research, Inc.
|
||||
* Copyright (C) 2013-2014, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -107,6 +104,7 @@ const std::string HTTP_IN_HEADER_X_FORWARDED_FOR("x-forwarded-for");
|
|||
|
||||
const std::string HTTP_CONTENT_LLSD_XML("application/llsd+xml");
|
||||
const std::string HTTP_CONTENT_OCTET_STREAM("application/octet-stream");
|
||||
const std::string HTTP_CONTENT_VND_LL_MESH("application/vnd.ll.mesh");
|
||||
const std::string HTTP_CONTENT_XML("application/xml");
|
||||
const std::string HTTP_CONTENT_JSON("application/json");
|
||||
const std::string HTTP_CONTENT_TEXT_HTML("text/html");
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2001-2013, Linden Research, Inc.
|
||||
* Copyright (C) 2001-2014, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -203,6 +203,7 @@ extern const std::string HTTP_IN_HEADER_X_FORWARDED_FOR;
|
|||
|
||||
extern const std::string HTTP_CONTENT_LLSD_XML;
|
||||
extern const std::string HTTP_CONTENT_OCTET_STREAM;
|
||||
extern const std::string HTTP_CONTENT_VND_LL_MESH;
|
||||
extern const std::string HTTP_CONTENT_XML;
|
||||
extern const std::string HTTP_CONTENT_JSON;
|
||||
extern const std::string HTTP_CONTENT_TEXT_HTML;
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public:
|
|||
/// baking service. Deep queueing of requests.
|
||||
/// Do not share. GET requests only.
|
||||
///
|
||||
/// Destination: simhost:12046 & bake-texture:80
|
||||
/// Destination: simhost:12046 & {bake-texture,cdn}:80
|
||||
/// Protocol: http:
|
||||
/// Transfer size: KB-MB
|
||||
/// Long poll: no
|
||||
|
|
@ -95,7 +95,7 @@ public:
|
|||
/// Very deeply queued. Do not share. GET
|
||||
/// requests only.
|
||||
///
|
||||
/// Destination: simhost:12046
|
||||
/// Destination: simhost:12046 & cdn:80
|
||||
/// Protocol: http:
|
||||
/// Transfer size: KB-MB
|
||||
/// Long poll: no
|
||||
|
|
@ -113,7 +113,7 @@ public:
|
|||
/// traffic that can wait for longish stalls
|
||||
/// (default timeout 600S).
|
||||
///
|
||||
/// Destination: simhost:12046
|
||||
/// Destination: simhost:12046 & cdn:80
|
||||
/// Protocol: http:
|
||||
/// Transfer size: MB
|
||||
/// Long poll: no
|
||||
|
|
@ -163,7 +163,8 @@ public:
|
|||
/// Request rate: high
|
||||
/// Pipelined: no
|
||||
AP_INVENTORY,
|
||||
|
||||
AP_REPORTING = AP_INVENTORY, // Piggy-back on inventory
|
||||
|
||||
AP_COUNT // Must be last
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3974,64 +3974,68 @@ LLInventoryModel::FetchItemHttpHandler::~FetchItemHttpHandler()
|
|||
void LLInventoryModel::FetchItemHttpHandler::onCompleted(LLCore::HttpHandle handle,
|
||||
LLCore::HttpResponse * response)
|
||||
{
|
||||
LLCore::HttpStatus status(response->getStatus());
|
||||
// status = LLCore::HttpStatus(404); // Dev tool to force error handling
|
||||
if (! status)
|
||||
// Single-pass do-while used for common exit handling
|
||||
do
|
||||
{
|
||||
processFailure(status, response);
|
||||
LLCore::HttpStatus status(response->getStatus());
|
||||
// status = LLCore::HttpStatus(404); // Dev tool to force error handling
|
||||
if (! status)
|
||||
{
|
||||
processFailure(status, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLCore::BufferArray * body(response->getBody());
|
||||
// body = NULL; // Dev tool to force error handling
|
||||
if (! body || ! body->size())
|
||||
{
|
||||
LL_WARNS(LOG_INV) << "Missing data in inventory item query." << LL_ENDL;
|
||||
processFailure("HTTP response for inventory item query missing body", response);
|
||||
break; // Goto common exit
|
||||
}
|
||||
|
||||
// body->write(0, "Garbage Response", 16); // Dev tool to force error handling
|
||||
LLSD body_llsd;
|
||||
if (! LLCoreHttpUtil::responseToLLSD(response, true, body_llsd))
|
||||
{
|
||||
// INFOS-level logging will occur on the parsed failure
|
||||
processFailure("HTTP response for inventory item query has malformed LLSD", response);
|
||||
break; // Goto common exit
|
||||
}
|
||||
|
||||
// Expect top-level structure to be a map
|
||||
// body_llsd = LLSD::emptyArray(); // Dev tool to force error handling
|
||||
if (! body_llsd.isMap())
|
||||
{
|
||||
processFailure("LLSD response for inventory item not a map", response);
|
||||
break; // Goto common exit
|
||||
}
|
||||
|
||||
// Check for 200-with-error failures
|
||||
//
|
||||
// Original Responder-based serivce model didn't check for these errors.
|
||||
// It may be more robust to ignore this condition. With aggregated requests,
|
||||
// an error in one inventory item might take down the entire request.
|
||||
// So if this instead broke up the aggregated items into single requests,
|
||||
// maybe that would make progress. Or perhaps there's structured information
|
||||
// that can tell us what went wrong. Need to dig into this and firm up
|
||||
// the API.
|
||||
//
|
||||
// body_llsd["error"] = LLSD::emptyMap(); // Dev tool to force error handling
|
||||
// body_llsd["error"]["identifier"] = "Development";
|
||||
// body_llsd["error"]["message"] = "You left development code in the viewer";
|
||||
if (body_llsd.has("error"))
|
||||
{
|
||||
processFailure("Inventory application error (200-with-error)", response);
|
||||
break; // Goto common exit
|
||||
}
|
||||
|
||||
// Okay, process data if possible
|
||||
processData(body_llsd, response);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLCore::BufferArray * body(response->getBody());
|
||||
// body = NULL; // Dev tool to force error handling
|
||||
if (! body || ! body->size())
|
||||
{
|
||||
LL_WARNS(LOG_INV) << "Missing data in inventory item query." << LL_ENDL;
|
||||
processFailure("HTTP response for inventory item query missing body", response);
|
||||
goto only_exit;
|
||||
}
|
||||
while (false);
|
||||
|
||||
// body->write(0, "Garbage Response", 16); // Dev tool to force error handling
|
||||
LLSD body_llsd;
|
||||
if (! LLCoreHttpUtil::responseToLLSD(response, true, body_llsd))
|
||||
{
|
||||
// INFOS-level logging will occur on the parsed failure
|
||||
processFailure("HTTP response for inventory item query has malformed LLSD", response);
|
||||
goto only_exit;
|
||||
}
|
||||
|
||||
// Expect top-level structure to be a map
|
||||
// body_llsd = LLSD::emptyArray(); // Dev tool to force error handling
|
||||
if (! body_llsd.isMap())
|
||||
{
|
||||
processFailure("LLSD response for inventory item not a map", response);
|
||||
goto only_exit;
|
||||
}
|
||||
|
||||
// Check for 200-with-error failures
|
||||
//
|
||||
// Original Responder-based serivce model didn't check for these errors.
|
||||
// It may be more robust to ignore this condition. With aggregated requests,
|
||||
// an error in one inventory item might take down the entire request.
|
||||
// So if this instead broke up the aggregated items into single requests,
|
||||
// maybe that would make progress. Or perhaps there's structured information
|
||||
// that can tell us what went wrong. Need to dig into this and firm up
|
||||
// the API.
|
||||
//
|
||||
// body_llsd["error"] = LLSD::emptyMap(); // Dev tool to force error handling
|
||||
// body_llsd["error"]["identifier"] = "Development";
|
||||
// body_llsd["error"]["message"] = "You left development code in the viewer";
|
||||
if (body_llsd.has("error"))
|
||||
{
|
||||
processFailure("Inventory application error (200-with-error)", response);
|
||||
goto only_exit;
|
||||
}
|
||||
|
||||
// Okay, process data if possible
|
||||
processData(body_llsd, response);
|
||||
}
|
||||
|
||||
only_exit:
|
||||
// Must delete on completion.
|
||||
delete this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -288,6 +288,7 @@ void LLInventoryModelBackgroundFetch::setAllFoldersFetched()
|
|||
}
|
||||
mFolderFetchActive = false;
|
||||
mBackgroundFetchActive = false;
|
||||
LL_INFOS(LOG_INV) << "Inventory background fetch completed" << LL_ENDL;
|
||||
}
|
||||
|
||||
void LLInventoryModelBackgroundFetch::backgroundFetchCB(void *)
|
||||
|
|
@ -314,12 +315,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()
|
|||
// No more categories to fetch, stop fetch process.
|
||||
if (mFetchQueue.empty())
|
||||
{
|
||||
LL_INFOS(LOG_INV) << "Inventory fetch completed" << LL_ENDL;
|
||||
|
||||
setAllFoldersFetched();
|
||||
mBackgroundFetchActive = false;
|
||||
mFolderFetchActive = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -493,9 +489,10 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
|
|||
// is mostly loaded, we could turn up the throttle and fill missing
|
||||
// inventory more quickly.
|
||||
static const S32 max_concurrent_fetches(12); // Outstanding requests, not connections
|
||||
static const F32 new_min_time(0.5f); // *HACK: Clean this up when old code goes away entirely.
|
||||
static const F32 new_min_time(0.05f); // *HACK: Clean this up when old code goes away entirely.
|
||||
static const U32 max_batch_size(10);
|
||||
|
||||
mMinTimeBetweenFetches = 0.01f;
|
||||
if (mMinTimeBetweenFetches < new_min_time)
|
||||
{
|
||||
mMinTimeBetweenFetches = new_min_time; // *HACK: See above.
|
||||
|
|
@ -705,62 +702,66 @@ namespace
|
|||
|
||||
void BGFolderHttpHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
|
||||
{
|
||||
LLCore::HttpStatus status(response->getStatus());
|
||||
// status = LLCore::HttpStatus(404); // Dev tool to force error handling
|
||||
if (! status)
|
||||
// Single-pass do-while used for common exit handling
|
||||
do
|
||||
{
|
||||
processFailure(status, response);
|
||||
LLCore::HttpStatus status(response->getStatus());
|
||||
// status = LLCore::HttpStatus(404); // Dev tool to force error handling
|
||||
if (! status)
|
||||
{
|
||||
processFailure(status, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Response body should be present.
|
||||
LLCore::BufferArray * body(response->getBody());
|
||||
// body = NULL; // Dev tool to force error handling
|
||||
if (! body || ! body->size())
|
||||
{
|
||||
LL_WARNS(LOG_INV) << "Missing data in inventory folder query." << LL_ENDL;
|
||||
processFailure("HTTP response missing expected body", response);
|
||||
break; // Goto common exit
|
||||
}
|
||||
|
||||
// Could test 'Content-Type' header but probably unreliable.
|
||||
|
||||
// Convert response to LLSD
|
||||
// body->write(0, "Garbage Response", 16); // Dev tool to force error handling
|
||||
LLSD body_llsd;
|
||||
if (! LLCoreHttpUtil::responseToLLSD(response, true, body_llsd))
|
||||
{
|
||||
// INFOS-level logging will occur on the parsed failure
|
||||
processFailure("HTTP response contained malformed LLSD", response);
|
||||
break; // goto common exit
|
||||
}
|
||||
|
||||
// Expect top-level structure to be a map
|
||||
// body_llsd = LLSD::emptyArray(); // Dev tool to force error handling
|
||||
if (! body_llsd.isMap())
|
||||
{
|
||||
processFailure("LLSD response not a map", response);
|
||||
break; // goto common exit
|
||||
}
|
||||
|
||||
// Check for 200-with-error failures
|
||||
//
|
||||
// See comments in llinventorymodel.cpp about this mode of error.
|
||||
//
|
||||
// body_llsd["error"] = LLSD::emptyMap(); // Dev tool to force error handling
|
||||
// body_llsd["error"]["identifier"] = "Development";
|
||||
// body_llsd["error"]["message"] = "You left development code in the viewer";
|
||||
if (body_llsd.has("error"))
|
||||
{
|
||||
processFailure("Inventory application error (200-with-error)", response);
|
||||
break; // goto common exit
|
||||
}
|
||||
|
||||
// Okay, process data if possible
|
||||
processData(body_llsd, response);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Response body should be present.
|
||||
LLCore::BufferArray * body(response->getBody());
|
||||
// body = NULL; // Dev tool to force error handling
|
||||
if (! body || ! body->size())
|
||||
{
|
||||
LL_WARNS(LOG_INV) << "Missing data in inventory folder query." << LL_ENDL;
|
||||
processFailure("HTTP response missing expected body", response);
|
||||
goto only_exit;
|
||||
}
|
||||
while (false);
|
||||
|
||||
// Could test 'Content-Type' header but probably unreliable.
|
||||
|
||||
// Convert response to LLSD
|
||||
// body->write(0, "Garbage Response", 16); // Dev tool to force error handling
|
||||
LLSD body_llsd;
|
||||
if (! LLCoreHttpUtil::responseToLLSD(response, true, body_llsd))
|
||||
{
|
||||
// INFOS-level logging will occur on the parsed failure
|
||||
processFailure("HTTP response contained malformed LLSD", response);
|
||||
goto only_exit;
|
||||
}
|
||||
|
||||
// Expect top-level structure to be a map
|
||||
// body_llsd = LLSD::emptyArray(); // Dev tool to force error handling
|
||||
if (! body_llsd.isMap())
|
||||
{
|
||||
processFailure("LLSD response not a map", response);
|
||||
goto only_exit;
|
||||
}
|
||||
|
||||
// Check for 200-with-error failures
|
||||
//
|
||||
// See comments in llinventorymodel.cpp about this mode of error.
|
||||
//
|
||||
// body_llsd["error"] = LLSD::emptyMap(); // Dev tool to force error handling
|
||||
// body_llsd["error"]["identifier"] = "Development";
|
||||
// body_llsd["error"]["message"] = "You left development code in the viewer";
|
||||
if (body_llsd.has("error"))
|
||||
{
|
||||
processFailure("Inventory application error (200-with-error)", response);
|
||||
goto only_exit;
|
||||
}
|
||||
|
||||
// Okay, process data if possible
|
||||
processData(body_llsd, response);
|
||||
}
|
||||
|
||||
only_exit:
|
||||
// Must delete on completion.
|
||||
delete this;
|
||||
}
|
||||
|
|
@ -895,7 +896,6 @@ void BGFolderHttpHandler::processData(LLSD & content, LLCore::HttpResponse * res
|
|||
|
||||
if (fetcher->isBulkFetchProcessingComplete())
|
||||
{
|
||||
LL_INFOS(LOG_INV) << "Inventory fetch completed" << LL_ENDL;
|
||||
fetcher->setAllFoldersFetched();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -760,7 +760,7 @@ LLMeshRepoThread::LLMeshRepoThread()
|
|||
mHttpLargeOptions->setTransferTimeout(LARGE_MESH_XFER_TIMEOUT);
|
||||
mHttpLargeOptions->setUseRetryAfter(gSavedSettings.getBOOL("MeshUseHttpRetryAfter"));
|
||||
mHttpHeaders = new LLCore::HttpHeaders;
|
||||
mHttpHeaders->append("Accept", "application/vnd.ll.mesh");
|
||||
mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_VND_LL_MESH);
|
||||
mHttpPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_MESH2);
|
||||
mHttpLegacyPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_MESH1);
|
||||
mHttpLargePolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_LARGE_MESH);
|
||||
|
|
@ -1887,7 +1887,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,
|
|||
mHttpOptions->setUseRetryAfter(gSavedSettings.getBOOL("MeshUseHttpRetryAfter"));
|
||||
mHttpOptions->setRetries(UPLOAD_RETRY_LIMIT);
|
||||
mHttpHeaders = new LLCore::HttpHeaders;
|
||||
mHttpHeaders->append("Content-Type", "application/llsd+xml");
|
||||
mHttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
|
||||
mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_UPLOADS);
|
||||
mHttpPriority = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2514,8 +2514,9 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
|
|||
mHttpOptions(NULL),
|
||||
mHttpOptionsWithHeaders(NULL),
|
||||
mHttpHeaders(NULL),
|
||||
mHttpMetricsHeaders(NULL),
|
||||
mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
|
||||
mHttpMetricsHeaders(NULL),
|
||||
mHttpMetricsPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
|
||||
mTotalCacheReadCount(0U),
|
||||
mTotalCacheWriteCount(0U),
|
||||
mTotalResourceWaitCount(0U),
|
||||
|
|
@ -2528,15 +2529,16 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
|
|||
mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), U32Bytes(gSavedSettings.getU32("TextureLoggingThreshold")));
|
||||
|
||||
LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
|
||||
mHttpPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_TEXTURE);
|
||||
mHttpRequest = new LLCore::HttpRequest;
|
||||
mHttpOptions = new LLCore::HttpOptions;
|
||||
mHttpOptionsWithHeaders = new LLCore::HttpOptions;
|
||||
mHttpOptionsWithHeaders->setWantHeaders(true);
|
||||
mHttpHeaders = new LLCore::HttpHeaders;
|
||||
mHttpHeaders->append("Accept", "image/x-j2c");
|
||||
mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_IMAGE_X_J2C);
|
||||
mHttpPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_TEXTURE);
|
||||
mHttpMetricsHeaders = new LLCore::HttpHeaders;
|
||||
mHttpMetricsHeaders->append("Content-Type", "application/llsd+xml");
|
||||
mHttpMetricsHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
|
||||
mHttpMetricsPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_REPORTING);
|
||||
mHttpHighWater = HTTP_NONPIPE_REQUESTS_HIGH_WATER;
|
||||
mHttpLowWater = HTTP_NONPIPE_REQUESTS_LOW_WATER;
|
||||
mHttpSemaphore = 0;
|
||||
|
|
@ -4037,10 +4039,9 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
|
|||
|
||||
if (! mCapsURL.empty())
|
||||
{
|
||||
// *TODO: Move this to a different class that expects POSTs sometime.
|
||||
// Don't care about handle, this is a fire-and-forget operation.
|
||||
LLCoreHttpUtil::requestPostWithLLSD(&fetcher->getHttpRequest(),
|
||||
fetcher->getPolicyClass(),
|
||||
fetcher->getMetricsPolicyClass(),
|
||||
report_priority,
|
||||
mCapsURL,
|
||||
sd,
|
||||
|
|
@ -4227,7 +4228,7 @@ void LLTextureFetchDebugger::init()
|
|||
if (! mHttpHeaders)
|
||||
{
|
||||
mHttpHeaders = new LLCore::HttpHeaders;
|
||||
mHttpHeaders->append("Accept", "image/x-j2c");
|
||||
mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_IMAGE_X_J2C);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -179,6 +179,9 @@ public:
|
|||
// Threads: T*
|
||||
LLCore::HttpHeaders * getMetricsHeaders() const { return mHttpMetricsHeaders; }
|
||||
|
||||
// Threads: T*
|
||||
LLCore::HttpRequest::policy_t getMetricsPolicyClass() const { return mHttpMetricsPolicyClass; }
|
||||
|
||||
bool isQAMode() const { return mQAMode; }
|
||||
|
||||
// ----------------------------------
|
||||
|
|
@ -354,8 +357,9 @@ private:
|
|||
LLCore::HttpOptions * mHttpOptions; // Ttf
|
||||
LLCore::HttpOptions * mHttpOptionsWithHeaders; // Ttf
|
||||
LLCore::HttpHeaders * mHttpHeaders; // Ttf
|
||||
LLCore::HttpHeaders * mHttpMetricsHeaders; // Ttf
|
||||
LLCore::HttpRequest::policy_t mHttpPolicyClass; // T*
|
||||
LLCore::HttpHeaders * mHttpMetricsHeaders; // Ttf
|
||||
LLCore::HttpRequest::policy_t mHttpMetricsPolicyClass; // T*
|
||||
S32 mHttpHighWater; // Ttf
|
||||
S32 mHttpLowWater; // Ttf
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue