LLMeshHeaderResponder and LLMeshLODResponder retry mechanisms.
This commit is contained in:
@@ -213,16 +213,30 @@ class LLMeshHeaderResponder : public LLHTTPClient::ResponderWithCompleted
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LLVolumeParams mMeshParams;
|
LLVolumeParams mMeshParams;
|
||||||
|
bool mProcessed;
|
||||||
|
|
||||||
LLMeshHeaderResponder(const LLVolumeParams& mesh_params)
|
LLMeshHeaderResponder(const LLVolumeParams& mesh_params)
|
||||||
: mMeshParams(mesh_params)
|
: mMeshParams(mesh_params)
|
||||||
{
|
{
|
||||||
LLMeshRepoThread::sActiveHeaderRequests++;
|
LLMeshRepoThread::incActiveHeaderRequests();
|
||||||
|
mProcessed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
~LLMeshHeaderResponder()
|
~LLMeshHeaderResponder()
|
||||||
{
|
{
|
||||||
LLMeshRepoThread::sActiveHeaderRequests--;
|
if (!LLApp::isQuitting())
|
||||||
|
{
|
||||||
|
if (!mProcessed)
|
||||||
|
{ //something went wrong, retry
|
||||||
|
llwarns << "Timeout or service unavailable, retrying." << llendl;
|
||||||
|
LLMeshRepository::sHTTPRetryCount++;
|
||||||
|
LLMeshRepoThread::HeaderRequest req(mMeshParams);
|
||||||
|
LLMutexLock lock(gMeshRepo.mThread->mMutex);
|
||||||
|
gMeshRepo.mThread->mHeaderReqQ.push(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
LLMeshRepoThread::decActiveHeaderRequests();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*virtual*/ void completedRaw(U32 status, const std::string& reason,
|
/*virtual*/ void completedRaw(U32 status, const std::string& reason,
|
||||||
@@ -241,16 +255,27 @@ public:
|
|||||||
S32 mLOD;
|
S32 mLOD;
|
||||||
U32 mRequestedBytes;
|
U32 mRequestedBytes;
|
||||||
U32 mOffset;
|
U32 mOffset;
|
||||||
|
bool mProcessed;
|
||||||
|
|
||||||
LLMeshLODResponder(const LLVolumeParams& mesh_params, S32 lod, U32 offset, U32 requested_bytes)
|
LLMeshLODResponder(const LLVolumeParams& mesh_params, S32 lod, U32 offset, U32 requested_bytes)
|
||||||
: mMeshParams(mesh_params), mLOD(lod), mOffset(offset), mRequestedBytes(requested_bytes)
|
: mMeshParams(mesh_params), mLOD(lod), mOffset(offset), mRequestedBytes(requested_bytes)
|
||||||
{
|
{
|
||||||
LLMeshRepoThread::sActiveLODRequests++;
|
LLMeshRepoThread::incActiveLODRequests();
|
||||||
|
mProcessed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
~LLMeshLODResponder()
|
~LLMeshLODResponder()
|
||||||
{
|
{
|
||||||
LLMeshRepoThread::sActiveLODRequests--;
|
if (!LLApp::isQuitting())
|
||||||
|
{
|
||||||
|
if (!mProcessed)
|
||||||
|
{
|
||||||
|
llwarns << "Killed without being processed, retrying." << llendl;
|
||||||
|
LLMeshRepository::sHTTPRetryCount++;
|
||||||
|
gMeshRepo.mThread->lockAndLoadMeshLOD(mMeshParams, mLOD);
|
||||||
|
}
|
||||||
|
LLMeshRepoThread::decActiveLODRequests();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*virtual*/ void completedRaw(U32 status, const std::string& reason,
|
/*virtual*/ void completedRaw(U32 status, const std::string& reason,
|
||||||
@@ -268,10 +293,17 @@ public:
|
|||||||
LLUUID mMeshID;
|
LLUUID mMeshID;
|
||||||
U32 mRequestedBytes;
|
U32 mRequestedBytes;
|
||||||
U32 mOffset;
|
U32 mOffset;
|
||||||
|
bool mProcessed;
|
||||||
|
|
||||||
LLMeshSkinInfoResponder(const LLUUID& id, U32 offset, U32 size)
|
LLMeshSkinInfoResponder(const LLUUID& id, U32 offset, U32 size)
|
||||||
: mMeshID(id), mRequestedBytes(size), mOffset(offset)
|
: mMeshID(id), mRequestedBytes(size), mOffset(offset)
|
||||||
{
|
{
|
||||||
|
mProcessed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
~LLMeshSkinInfoResponder()
|
||||||
|
{
|
||||||
|
llassert(mProcessed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*virtual*/ void completedRaw(U32 status, const std::string& reason,
|
/*virtual*/ void completedRaw(U32 status, const std::string& reason,
|
||||||
@@ -289,10 +321,17 @@ public:
|
|||||||
LLUUID mMeshID;
|
LLUUID mMeshID;
|
||||||
U32 mRequestedBytes;
|
U32 mRequestedBytes;
|
||||||
U32 mOffset;
|
U32 mOffset;
|
||||||
|
bool mProcessed;
|
||||||
|
|
||||||
LLMeshDecompositionResponder(const LLUUID& id, U32 offset, U32 size)
|
LLMeshDecompositionResponder(const LLUUID& id, U32 offset, U32 size)
|
||||||
: mMeshID(id), mRequestedBytes(size), mOffset(offset)
|
: mMeshID(id), mRequestedBytes(size), mOffset(offset)
|
||||||
{
|
{
|
||||||
|
mProcessed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
~LLMeshDecompositionResponder()
|
||||||
|
{
|
||||||
|
llassert(mProcessed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*virtual*/ void completedRaw(U32 status, const std::string& reason,
|
/*virtual*/ void completedRaw(U32 status, const std::string& reason,
|
||||||
@@ -310,10 +349,17 @@ public:
|
|||||||
LLUUID mMeshID;
|
LLUUID mMeshID;
|
||||||
U32 mRequestedBytes;
|
U32 mRequestedBytes;
|
||||||
U32 mOffset;
|
U32 mOffset;
|
||||||
|
bool mProcessed;
|
||||||
|
|
||||||
LLMeshPhysicsShapeResponder(const LLUUID& id, U32 offset, U32 size)
|
LLMeshPhysicsShapeResponder(const LLUUID& id, U32 offset, U32 size)
|
||||||
: mMeshID(id), mRequestedBytes(size), mOffset(offset)
|
: mMeshID(id), mRequestedBytes(size), mOffset(offset)
|
||||||
{
|
{
|
||||||
|
mProcessed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
~LLMeshPhysicsShapeResponder()
|
||||||
|
{
|
||||||
|
llassert(mProcessed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*virtual*/ void completedRaw(U32 status, const std::string& reason,
|
/*virtual*/ void completedRaw(U32 status, const std::string& reason,
|
||||||
@@ -680,16 +726,22 @@ void LLMeshRepoThread::loadMeshPhysicsShape(const LLUUID& mesh_id)
|
|||||||
mPhysicsShapeRequests.insert(mesh_id);
|
mPhysicsShapeRequests.insert(mesh_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
|
||||||
|
{
|
||||||
|
if (!LLAppViewer::isQuitting())
|
||||||
|
{
|
||||||
|
loadMeshLOD(mesh_params, lod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
|
void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
|
||||||
{ //protected by mSignal, no locking needed here
|
{ //could be called from any thread
|
||||||
|
LLMutexLock lock(mMutex);
|
||||||
mesh_header_map::iterator iter = mMeshHeader.find(mesh_params.getSculptID());
|
mesh_header_map::iterator iter = mMeshHeader.find(mesh_params.getSculptID());
|
||||||
if (iter != mMeshHeader.end())
|
if (iter != mMeshHeader.end())
|
||||||
{ //if we have the header, request LOD byte range
|
{ //if we have the header, request LOD byte range
|
||||||
LODRequest req(mesh_params, lod);
|
LODRequest req(mesh_params, lod);
|
||||||
{
|
{
|
||||||
LLMutexLock lock(mMutex);
|
|
||||||
mLODReqQ.push(req);
|
mLODReqQ.push(req);
|
||||||
LLMeshRepository::sLODProcessing++;
|
LLMeshRepository::sLODProcessing++;
|
||||||
}
|
}
|
||||||
@@ -707,7 +759,6 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //if no header request is pending, fetch header
|
{ //if no header request is pending, fetch header
|
||||||
LLMutexLock lock(mMutex);
|
|
||||||
mHeaderReqQ.push(req);
|
mHeaderReqQ.push(req);
|
||||||
mPendingLOD[mesh_params].push_back(lod);
|
mPendingLOD[mesh_params].push_back(lod);
|
||||||
}
|
}
|
||||||
@@ -961,6 +1012,34 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
void LLMeshRepoThread::incActiveLODRequests()
|
||||||
|
{
|
||||||
|
LLMutexLock lock(gMeshRepo.mThread->mMutex);
|
||||||
|
++LLMeshRepoThread::sActiveLODRequests;
|
||||||
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
void LLMeshRepoThread::decActiveLODRequests()
|
||||||
|
{
|
||||||
|
LLMutexLock lock(gMeshRepo.mThread->mMutex);
|
||||||
|
--LLMeshRepoThread::sActiveLODRequests;
|
||||||
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
void LLMeshRepoThread::incActiveHeaderRequests()
|
||||||
|
{
|
||||||
|
LLMutexLock lock(gMeshRepo.mThread->mMutex);
|
||||||
|
++LLMeshRepoThread::sActiveHeaderRequests;
|
||||||
|
}
|
||||||
|
|
||||||
|
//static
|
||||||
|
void LLMeshRepoThread::decActiveHeaderRequests()
|
||||||
|
{
|
||||||
|
LLMutexLock lock(gMeshRepo.mThread->mMutex);
|
||||||
|
--LLMeshRepoThread::sActiveHeaderRequests;
|
||||||
|
}
|
||||||
|
|
||||||
//return false if failed to get header
|
//return false if failed to get header
|
||||||
bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count)
|
bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count)
|
||||||
{
|
{
|
||||||
@@ -1776,7 +1855,8 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,
|
|||||||
const LLChannelDescriptors& channels,
|
const LLChannelDescriptors& channels,
|
||||||
const LLIOPipe::buffer_ptr_t& buffer)
|
const LLIOPipe::buffer_ptr_t& buffer)
|
||||||
{
|
{
|
||||||
|
mProcessed = true;
|
||||||
|
|
||||||
S32 data_size = buffer->countAfter(channels.in(), NULL);
|
S32 data_size = buffer->countAfter(channels.in(), NULL);
|
||||||
|
|
||||||
if (status < 200 || status >= 400)
|
if (status < 200 || status >= 400)
|
||||||
@@ -1788,6 +1868,7 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,
|
|||||||
{
|
{
|
||||||
if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE)
|
if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE)
|
||||||
{ //timeout or service unavailable, try again
|
{ //timeout or service unavailable, try again
|
||||||
|
llwarns << "Timeout or service unavailable, retrying." << llendl;
|
||||||
LLMeshRepository::sHTTPRetryCount++;
|
LLMeshRepository::sHTTPRetryCount++;
|
||||||
gMeshRepo.mThread->loadMeshLOD(mMeshParams, mLOD);
|
gMeshRepo.mThread->loadMeshLOD(mMeshParams, mLOD);
|
||||||
}
|
}
|
||||||
@@ -1831,6 +1912,8 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason
|
|||||||
const LLChannelDescriptors& channels,
|
const LLChannelDescriptors& channels,
|
||||||
const LLIOPipe::buffer_ptr_t& buffer)
|
const LLIOPipe::buffer_ptr_t& buffer)
|
||||||
{
|
{
|
||||||
|
mProcessed = true;
|
||||||
|
|
||||||
S32 data_size = buffer->countAfter(channels.in(), NULL);
|
S32 data_size = buffer->countAfter(channels.in(), NULL);
|
||||||
|
|
||||||
if (status < 200 || status >= 400)
|
if (status < 200 || status >= 400)
|
||||||
@@ -1842,6 +1925,7 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason
|
|||||||
{
|
{
|
||||||
if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE)
|
if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE)
|
||||||
{ //timeout or service unavailable, try again
|
{ //timeout or service unavailable, try again
|
||||||
|
llwarns << "Timeout or service unavailable, retrying." << llendl;
|
||||||
LLMeshRepository::sHTTPRetryCount++;
|
LLMeshRepository::sHTTPRetryCount++;
|
||||||
gMeshRepo.mThread->loadMeshSkinInfo(mMeshID);
|
gMeshRepo.mThread->loadMeshSkinInfo(mMeshID);
|
||||||
}
|
}
|
||||||
@@ -1885,6 +1969,8 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r
|
|||||||
const LLChannelDescriptors& channels,
|
const LLChannelDescriptors& channels,
|
||||||
const LLIOPipe::buffer_ptr_t& buffer)
|
const LLIOPipe::buffer_ptr_t& buffer)
|
||||||
{
|
{
|
||||||
|
mProcessed = true;
|
||||||
|
|
||||||
S32 data_size = buffer->countAfter(channels.in(), NULL);
|
S32 data_size = buffer->countAfter(channels.in(), NULL);
|
||||||
|
|
||||||
if (status < 200 || status >= 400)
|
if (status < 200 || status >= 400)
|
||||||
@@ -1896,6 +1982,7 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r
|
|||||||
{
|
{
|
||||||
if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE)
|
if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE)
|
||||||
{ //timeout or service unavailable, try again
|
{ //timeout or service unavailable, try again
|
||||||
|
llwarns << "Timeout or service unavailable, retrying." << llendl;
|
||||||
LLMeshRepository::sHTTPRetryCount++;
|
LLMeshRepository::sHTTPRetryCount++;
|
||||||
gMeshRepo.mThread->loadMeshDecomposition(mMeshID);
|
gMeshRepo.mThread->loadMeshDecomposition(mMeshID);
|
||||||
}
|
}
|
||||||
@@ -1939,6 +2026,8 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re
|
|||||||
const LLChannelDescriptors& channels,
|
const LLChannelDescriptors& channels,
|
||||||
const LLIOPipe::buffer_ptr_t& buffer)
|
const LLIOPipe::buffer_ptr_t& buffer)
|
||||||
{
|
{
|
||||||
|
mProcessed = true;
|
||||||
|
|
||||||
S32 data_size = buffer->countAfter(channels.in(), NULL);
|
S32 data_size = buffer->countAfter(channels.in(), NULL);
|
||||||
|
|
||||||
if (status < 200 || status >= 400)
|
if (status < 200 || status >= 400)
|
||||||
@@ -1950,6 +2039,7 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re
|
|||||||
{
|
{
|
||||||
if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE)
|
if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE)
|
||||||
{ //timeout or service unavailable, try again
|
{ //timeout or service unavailable, try again
|
||||||
|
llwarns << "Timeout or service unavailable, retrying." << llendl;
|
||||||
LLMeshRepository::sHTTPRetryCount++;
|
LLMeshRepository::sHTTPRetryCount++;
|
||||||
gMeshRepo.mThread->loadMeshPhysicsShape(mMeshID);
|
gMeshRepo.mThread->loadMeshPhysicsShape(mMeshID);
|
||||||
}
|
}
|
||||||
@@ -1993,6 +2083,8 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
|
|||||||
const LLChannelDescriptors& channels,
|
const LLChannelDescriptors& channels,
|
||||||
const LLIOPipe::buffer_ptr_t& buffer)
|
const LLIOPipe::buffer_ptr_t& buffer)
|
||||||
{
|
{
|
||||||
|
mProcessed = true;
|
||||||
|
|
||||||
if (status < 200 || status >= 400)
|
if (status < 200 || status >= 400)
|
||||||
{
|
{
|
||||||
//llwarns
|
//llwarns
|
||||||
@@ -2007,6 +2099,7 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
|
|||||||
// again after some set period of time
|
// again after some set period of time
|
||||||
if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE)
|
if (is_internal_http_error_that_warrants_a_retry(status) || status == HTTP_SERVICE_UNAVAILABLE)
|
||||||
{ //retry
|
{ //retry
|
||||||
|
llwarns << "Timeout or service unavailable, retrying." << llendl;
|
||||||
LLMeshRepository::sHTTPRetryCount++;
|
LLMeshRepository::sHTTPRetryCount++;
|
||||||
LLMeshRepoThread::HeaderRequest req(mMeshParams);
|
LLMeshRepoThread::HeaderRequest req(mMeshParams);
|
||||||
LLMutexLock lock(gMeshRepo.mThread->mMutex);
|
LLMutexLock lock(gMeshRepo.mThread->mMutex);
|
||||||
@@ -2014,6 +2107,10 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
llwarns << "Unhandled status." << llendl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
S32 data_size = buffer->countAfter(channels.in(), NULL);
|
S32 data_size = buffer->countAfter(channels.in(), NULL);
|
||||||
@@ -2028,7 +2125,11 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
|
|||||||
|
|
||||||
LLMeshRepository::sBytesReceived += llmin(data_size, 4096);
|
LLMeshRepository::sBytesReceived += llmin(data_size, 4096);
|
||||||
|
|
||||||
if (!gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size))
|
bool success = gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size);
|
||||||
|
|
||||||
|
llassert(success);
|
||||||
|
|
||||||
|
if (!success)
|
||||||
{
|
{
|
||||||
llwarns
|
llwarns
|
||||||
<< "Unable to parse mesh header: "
|
<< "Unable to parse mesh header: "
|
||||||
|
|||||||
@@ -321,6 +321,7 @@ public:
|
|||||||
|
|
||||||
virtual void run();
|
virtual void run();
|
||||||
|
|
||||||
|
void lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
|
||||||
void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
|
void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
|
||||||
bool fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count);
|
bool fetchMeshHeader(const LLVolumeParams& mesh_params, U32& count);
|
||||||
void fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count);
|
void fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, U32& count);
|
||||||
@@ -350,6 +351,10 @@ public:
|
|||||||
// (should hold onto mesh_id and try again later if header info does not exist)
|
// (should hold onto mesh_id and try again later if header info does not exist)
|
||||||
bool fetchMeshPhysicsShape(const LLUUID& mesh_id);
|
bool fetchMeshPhysicsShape(const LLUUID& mesh_id);
|
||||||
|
|
||||||
|
static void incActiveLODRequests();
|
||||||
|
static void decActiveLODRequests();
|
||||||
|
static void incActiveHeaderRequests();
|
||||||
|
static void decActiveHeaderRequests();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user