Skip to content
Snippets Groups Projects
Commit 9ec86c84 authored by Rye Mutt's avatar Rye Mutt :bread:
Browse files

Add proper retry support to skin info fetch

parent bd20b61b
No related branches found
No related tags found
No related merge requests found
...@@ -857,6 +857,12 @@ LLMeshRepoThread::~LLMeshRepoThread() ...@@ -857,6 +857,12 @@ LLMeshRepoThread::~LLMeshRepoThread()
mHttpRequestSet.clear(); mHttpRequestSet.clear();
mHttpHeaders.reset(); mHttpHeaders.reset();
while (!mSkinInfoQ.empty())
{
delete mSkinInfoQ.front();
mSkinInfoQ.pop_front();
}
while (!mDecompositionQ.empty()) while (!mDecompositionQ.empty())
{ {
delete mDecompositionQ.front(); delete mDecompositionQ.front();
...@@ -946,6 +952,7 @@ void LLMeshRepoThread::run() ...@@ -946,6 +952,7 @@ void LLMeshRepoThread::run()
else else
{ {
// too many fails // too many fails
LLMutexLock lock(mMutex);
mUnavailableQ.push(req); mUnavailableQ.push(req);
LL_WARNS() << "Failed to load " << req.mMeshParams << " , skip" << LL_ENDL; LL_WARNS() << "Failed to load " << req.mMeshParams << " , skip" << LL_ENDL;
} }
...@@ -1022,37 +1029,42 @@ void LLMeshRepoThread::run() ...@@ -1022,37 +1029,42 @@ void LLMeshRepoThread::run()
if (!mSkinRequests.empty()) if (!mSkinRequests.empty())
{ {
std::set<UUIDBasedRequest> incomplete; std::list<UUIDBasedRequest> incomplete;
while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
{ {
mMutex->lock();
std::set<UUIDBasedRequest>::iterator iter = mSkinRequests.begin();
UUIDBasedRequest req = *iter;
mSkinRequests.erase(iter);
mMutex->unlock();
if (req.isDelayed())
{
incomplete.insert(req);
}
else if (!fetchMeshSkinInfo(req.mId))
{
if (req.canRetry())
{
req.updateTime();
incomplete.insert(req);
}
else
{
LL_DEBUGS() << "mSkinRequests failed: " << req.mId << LL_ENDL;
}
}
}
if (!incomplete.empty()) mMutex->lock();
{ auto req = mSkinRequests.front();
LLMutexLock locker(mMutex); mSkinRequests.pop_front();
mSkinRequests.insert(incomplete.begin(), incomplete.end()); mMutex->unlock();
} if (req.isDelayed())
{
incomplete.emplace_back(req);
}
else if (!fetchMeshSkinInfo(req.mId, req.canRetry()))
{
if (req.canRetry())
{
req.updateTime();
incomplete.emplace_back(req);
}
else
{
LLMutexLock locker(mMutex);
mSkinUnavailableQ.push_back(req);
LL_DEBUGS() << "mSkinReqQ failed: " << req.mId << LL_ENDL;
}
}
}
if (!incomplete.empty())
{
LLMutexLock locker(mMutex);
for (const auto& req : incomplete)
{
mSkinRequests.push_back(req);
}
}
} }
// holding lock, try next list // holding lock, try next list
...@@ -1151,7 +1163,7 @@ void LLMeshRepoThread::run() ...@@ -1151,7 +1163,7 @@ void LLMeshRepoThread::run()
// Mutex: LLMeshRepoThread::mMutex must be held on entry // Mutex: LLMeshRepoThread::mMutex must be held on entry
void LLMeshRepoThread::loadMeshSkinInfo(const LLUUID& mesh_id) void LLMeshRepoThread::loadMeshSkinInfo(const LLUUID& mesh_id)
{ {
mSkinRequests.insert(UUIDBasedRequest(mesh_id)); mSkinRequests.push_back(UUIDBasedRequest(mesh_id));
} }
// Mutex: LLMeshRepoThread::mMutex must be held on entry // Mutex: LLMeshRepoThread::mMutex must be held on entry
...@@ -1308,7 +1320,7 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, ...@@ -1308,7 +1320,7 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url,
} }
bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry)
{ {
if (!mHeaderMutex) if (!mHeaderMutex)
...@@ -1390,13 +1402,28 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) ...@@ -1390,13 +1402,28 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
<< LL_ENDL; << LL_ENDL;
ret = false; ret = false;
} }
else else if(can_retry)
{ {
handler->mHttpHandle = handle; handler->mHttpHandle = handle;
mHttpRequestSet.insert(handler); mHttpRequestSet.insert(handler);
} }
else
{
LLMutexLock locker(mMutex);
mSkinUnavailableQ.emplace_back(mesh_id);
}
}
else
{
LLMutexLock locker(mMutex);
mSkinUnavailableQ.emplace_back(mesh_id);
} }
} }
else
{
LLMutexLock locker(mMutex);
mSkinUnavailableQ.emplace_back(mesh_id);
}
} }
else else
{ {
...@@ -2906,13 +2933,20 @@ void LLMeshRepoThread::notifyLoadedMeshes() ...@@ -2906,13 +2933,20 @@ void LLMeshRepoThread::notifyLoadedMeshes()
{ {
if (mMutex->trylock()) if (mMutex->trylock())
{ {
std::list<LLMeshSkinInfo*> skin_info_q; std::deque<LLMeshSkinInfo*> skin_info_q;
std::deque<UUIDBasedRequest> skin_info_unavail_q;
std::list<LLModel::Decomposition*> decomp_q; std::list<LLModel::Decomposition*> decomp_q;
if (! mSkinInfoQ.empty()) if (! mSkinInfoQ.empty())
{ {
skin_info_q.swap(mSkinInfoQ); skin_info_q.swap(mSkinInfoQ);
} }
if (! mSkinUnavailableQ.empty())
{
skin_info_unavail_q.swap(mSkinUnavailableQ);
}
if (! mDecompositionQ.empty()) if (! mDecompositionQ.empty())
{ {
decomp_q.swap(mDecompositionQ); decomp_q.swap(mDecompositionQ);
...@@ -2926,6 +2960,11 @@ void LLMeshRepoThread::notifyLoadedMeshes() ...@@ -2926,6 +2960,11 @@ void LLMeshRepoThread::notifyLoadedMeshes()
gMeshRepo.notifySkinInfoReceived(skin_info_q.front()); gMeshRepo.notifySkinInfoReceived(skin_info_q.front());
skin_info_q.pop_front(); skin_info_q.pop_front();
} }
while (! skin_info_unavail_q.empty())
{
gMeshRepo.notifySkinInfoUnavailable(skin_info_unavail_q.front().mId);
skin_info_unavail_q.pop_front();
}
while (! decomp_q.empty()) while (! decomp_q.empty())
{ {
...@@ -3357,9 +3396,8 @@ void LLMeshSkinInfoHandler::processFailure(LLCore::HttpStatus status) ...@@ -3357,9 +3396,8 @@ void LLMeshSkinInfoHandler::processFailure(LLCore::HttpStatus status)
<< ", Reason: " << status.toString() << ", Reason: " << status.toString()
<< " (" << status.toTerseString() << "). Not retrying." << " (" << status.toTerseString() << "). Not retrying."
<< LL_ENDL; << LL_ENDL;
LLMutexLock lock(gMeshRepo.mThread->mMutex);
// *TODO: Mark mesh unavailable on error. For now, simply leave gMeshRepo.mThread->mSkinUnavailableQ.emplace_back(mMeshID);
// request unfulfilled rather than retry forever.
} }
void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */, void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */,
...@@ -3390,7 +3428,8 @@ void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /* ...@@ -3390,7 +3428,8 @@ void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /*
LL_WARNS(LOG_MESH) << "Error during mesh skin info processing. ID: " << mMeshID LL_WARNS(LOG_MESH) << "Error during mesh skin info processing. ID: " << mMeshID
<< ", Unknown reason. Not retrying." << ", Unknown reason. Not retrying."
<< LL_ENDL; << LL_ENDL;
// *TODO: Mark mesh unavailable on error LLMutexLock lock(gMeshRepo.mThread->mMutex);
gMeshRepo.mThread->mSkinUnavailableQ.emplace_back(mMeshID);
} }
} }
......
...@@ -281,10 +281,13 @@ class LLMeshRepoThread : public LLThread ...@@ -281,10 +281,13 @@ class LLMeshRepoThread : public LLThread
}; };
//set of requested skin info //set of requested skin info
std::set<UUIDBasedRequest> mSkinRequests; std::deque<UUIDBasedRequest> mSkinRequests;
// list of completed skin info requests // list of completed skin info requests
std::list<LLMeshSkinInfo*> mSkinInfoQ; std::deque<LLMeshSkinInfo*> mSkinInfoQ;
// list of skin info requests that have failed or are unavailaibe
std::deque<UUIDBasedRequest> mSkinUnavailableQ;
//set of requested decompositions //set of requested decompositions
std::set<UUIDBasedRequest> mDecompositionRequests; std::set<UUIDBasedRequest> mDecompositionRequests;
...@@ -352,7 +355,7 @@ class LLMeshRepoThread : public LLThread ...@@ -352,7 +355,7 @@ class LLMeshRepoThread : public LLThread
//send request for skin info, returns true if header info exists //send request for skin info, returns true if header info exists
// (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 fetchMeshSkinInfo(const LLUUID& mesh_id); bool fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry = true);
//send request for decomposition, returns true if header info exists //send request for decomposition, returns true if header info exists
// (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)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment