fix for SH-3137: delay to issue new http fetching requests if http connection failure happens

meow-7.2.2
Xiaohong Bao 2012-05-25 14:08:33 -06:00
parent bda06182c4
commit cbb14e223c
3 changed files with 95 additions and 30 deletions

View File

@ -922,7 +922,7 @@ void LLCurlThread::CurlRequest::finishRequest(bool completed)
{
if(mMulti->isDead())
{
mCurlThread->deleteMulti(mMulti) ;
mCurlThread->deleteMulti(mMulti) ;
}
else
{
@ -968,8 +968,8 @@ void LLCurlThread::killMulti(LLCurl::Multi* multi)
if(multi->isValid())
{
multi->markDead() ;
}
multi->markDead() ;
}
else
{
deleteMulti(multi) ;
@ -1233,6 +1233,7 @@ LLCurlTextureRequest::LLCurlTextureRequest(S32 concurrency) :
mTotalIssuedRequests(0),
mTotalReceivedBits(0)
{
mGlobalTimer.reset();
}
LLCurlTextureRequest::~LLCurlTextureRequest()
@ -1251,12 +1252,12 @@ LLCurlTextureRequest::~LLCurlTextureRequest()
U32 LLCurlTextureRequest::getByteRange(const std::string& url,
const headers_t& headers,
S32 offset, S32 length, U32 pri,
LLCurl::ResponderPtr responder)
LLCurl::ResponderPtr responder, F32 delay_time)
{
U32 ret_val = 0;
bool success = false;
if(mInQueue < mConcurrency)
if(mInQueue < mConcurrency && delay_time < 0.f)
{
success = LLCurlRequest::getByteRange(url, headers, offset, length, responder);
}
@ -1271,6 +1272,11 @@ U32 LLCurlTextureRequest::getByteRange(const std::string& url,
else
{
request_t* request = new request_t(mHandleCounter, url, headers, offset, length, pri, responder);
if(delay_time > 0.f)
{
request->mStartTime = mGlobalTimer.getElapsedTimeF32() + delay_time;
}
mCachedRequests.insert(request);
mRequestMap[mHandleCounter] = request;
ret_val = mHandleCounter;
@ -1297,29 +1303,50 @@ void LLCurlTextureRequest::completeRequest(S32 received_bytes)
void LLCurlTextureRequest::nextRequests()
{
while(!mCachedRequests.empty() && mInQueue < mConcurrency)
if(mCachedRequests.empty() || mInQueue >= mConcurrency)
{
request_t* request;
{
LLMutexLock lock(&mMutex);
req_queue_t::iterator iter = mCachedRequests.begin();
request = *iter;
}
return;
}
if(!LLCurlRequest::getByteRange(request->mUrl, request->mHeaders, request->mOffset, request->mLength, request->mResponder))
{
break;
}
F32 cur_time = mGlobalTimer.getElapsedTimeF32();
req_queue_t::iterator iter;
{
LLMutexLock lock(&mMutex);
iter = mCachedRequests.begin();
}
while(1)
{
request_t* request = *iter;
if(request->mStartTime < cur_time)
{
if(!LLCurlRequest::getByteRange(request->mUrl, request->mHeaders, request->mOffset, request->mLength, request->mResponder))
{
break;
}
LLMutexLock lock(&mMutex);
++iter;
mInQueue++;
mTotalIssuedRequests++;
llassert_always(1 == mCachedRequests.erase(request));
mCachedRequests.erase(request);
mRequestMap.erase(request->mHandle);
delete request;
if(iter == mCachedRequests.end() || mInQueue >= mConcurrency)
{
break;
}
}
else
{
LLMutexLock lock(&mMutex);
++iter;
if(iter == mCachedRequests.end() || mInQueue >= mConcurrency)
{
break;
}
}
delete request;
}
return;
@ -1367,6 +1394,17 @@ void LLCurlTextureRequest::removeRequest(U32 handle)
}
}
bool LLCurlTextureRequest::isWaiting(U32 handle)
{
if(!handle)
{
return false;
}
LLMutexLock lock(&mMutex);
return mRequestMap.find(handle) != mRequestMap.end();
}
U32 LLCurlTextureRequest::getTotalReceivedBits()
{
LLMutexLock lock(&mMutex);

View File

@ -420,7 +420,7 @@ public:
LLCurlTextureRequest(S32 concurrency);
~LLCurlTextureRequest();
U32 getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, U32 pri, LLCurl::ResponderPtr responder);
U32 getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, U32 pri, LLCurl::ResponderPtr responder, F32 delay_time = -1.f);
void nextRequests();
void completeRequest(S32 received_bytes);
@ -430,6 +430,7 @@ public:
U32 getTotalReceivedBits();
U32 getTotalIssuedRequests();
S32 getNumRequests();
bool isWaiting(U32 handle);
private:
LLMutex mMutex;
@ -442,7 +443,7 @@ private:
typedef struct _request_t
{
_request_t(U32 handle, const std::string& url, const headers_t& headers, S32 offset, S32 length, U32 pri, LLCurl::ResponderPtr responder) :
mHandle(handle), mUrl(url), mHeaders(headers), mOffset(offset), mLength(length), mPriority(pri), mResponder(responder)
mHandle(handle), mUrl(url), mHeaders(headers), mOffset(offset), mLength(length), mPriority(pri), mResponder(responder), mStartTime(0.f)
{}
U32 mHandle;
@ -452,6 +453,7 @@ private:
S32 mLength;
LLCurl::ResponderPtr mResponder;
U32 mPriority;
F32 mStartTime; //start time to issue this request
} request_t;
struct request_compare
@ -472,6 +474,8 @@ private:
typedef std::set<request_t*, request_compare> req_queue_t;
req_queue_t mCachedRequests;
std::map<S32, request_t*> mRequestMap;
LLFrameTimer mGlobalTimer;
};
class LLCurlEasyRequest

View File

@ -278,6 +278,7 @@ private:
S32 mActiveCount;
U32 mGetStatus;
U32 mHTTPHandle;
F32 mDelay;
std::string mGetReason;
// Work Data
@ -696,7 +697,8 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mTotalPackets(0),
mImageCodec(IMG_CODEC_INVALID),
mMetricsStartTime(0),
mHTTPHandle(0)
mHTTPHandle(0),
mDelay(-1.f)
{
mCanUseNET = mUrl.empty() ;
@ -929,6 +931,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
mCacheWriteHandle = LLTextureCache::nullHandle();
mState = LOAD_FROM_TEXTURE_CACHE;
mInCache = FALSE;
mDelay = -1.f;
mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE); // min desired size is TEXTURE_CACHE_ENTRY_SIZE
LL_DEBUGS("Texture") << mID << ": Priority: " << llformat("%8.0f",mImagePriority)
<< " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL;
@ -1238,7 +1241,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
mRequestedSize = 0;
}
mHTTPHandle = mFetcher->mCurlGetRequest->getByteRange(mUrl, headers, offset, mRequestedSize, mWorkPriority,
new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset, true));
new HTTPGetResponder(mFetcher, mID, LLTimer::getTotalTime(), mRequestedSize, offset, true), mDelay);
mDelay = -1.f; //reset
res = true;
}
if (!res)
@ -1286,12 +1290,15 @@ bool LLTextureFetchWorker::doWork(S32 param)
++mHTTPFailCount;
max_attempts = mHTTPFailCount+1; // Keep retrying
LL_INFOS_ONCE("Texture") << "Texture server busy (503): " << mUrl << LL_ENDL;
mDelay = 2.0f; //delay 2 second to re-issue the http request
}
else
{
const S32 HTTP_MAX_RETRY_COUNT = 3;
max_attempts = HTTP_MAX_RETRY_COUNT + 1;
++mHTTPFailCount;
mDelay = 2.0f; //delay 2 second to re-issue the http request
llinfos << "HTTP GET failed for: " << mUrl
<< " Status: " << mGetStatus << " Reason: '" << mGetReason << "'"
<< " Attempt:" << mHTTPFailCount+1 << "/" << max_attempts << llendl;
@ -1376,13 +1383,29 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
else
{
if(FETCHING_TIMEOUT < mRequestedTimer.getElapsedTimeF32())
{
//timeout, abort.
removeFromHTTPQueue();
mState = DONE;
return true;
}
//
//No need to timeout, the responder should be triggered automatically.
//
//if(FETCHING_TIMEOUT < mRequestedTimer.getElapsedTimeF32())
//{
// if(mFetcher->getCurlRequest().isWaiting(mHTTPHandle))
// {
// mRequestedTimer.reset(); //still waiting, request not issued yet.
// }
// else if(!mHTTPWaitCount)
// {
// mHTTPWaitCount++;
// mRequestedTimer.reset(); //wait for one more FETCHING_TIMEOUT cycle in case the request is just issued.
// }
// else
// {
// //timeout, abort.
// removeFromHTTPQueue();
// mState = DONE;
// return true;
// }
//}
setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
return false;