diff options
Diffstat (limited to 'indra/newview/lltexturefetch.cpp')
| -rwxr-xr-x | indra/newview/lltexturefetch.cpp | 168 | 
1 files changed, 134 insertions, 34 deletions
| diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index cc6dc64626..7b719190a4 100755 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -63,6 +63,8 @@  #include "bufferarray.h"  #include "bufferstream.h" +#include "llhttpretrypolicy.h" +  bool LLTextureFetchDebugger::sDebuggerEnabled = false ;  LLStat LLTextureFetch::sCacheHitRate("texture_cache_hits", 128);  LLStat LLTextureFetch::sCacheReadLatency("texture_cache_read_latency", 128); @@ -244,6 +246,25 @@ static const S32 HTTP_REQUESTS_IN_QUEUE_LOW_WATER = 20;			// Active level at whi  ////////////////////////////////////////////////////////////////////////////// +static const char* e_state_name[] = +{ +	"INVALID", +	"INIT", +	"LOAD_FROM_TEXTURE_CACHE", +	"CACHE_POST", +	"LOAD_FROM_NETWORK", +	"LOAD_FROM_SIMULATOR", +	"WAIT_HTTP_RESOURCE", +	"WAIT_HTTP_RESOURCE2", +	"SEND_HTTP_REQ", +	"WAIT_HTTP_REQ", +	"DECODE_IMAGE", +	"DECODE_IMAGE_UPDATE", +	"WRITE_TO_CACHE", +	"WAIT_ON_WRITE", +	"DONE" +}; +  class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler  { @@ -382,12 +403,14 @@ public:  	void setCanUseHTTP(bool can_use_http) { mCanUseHTTP = can_use_http; }  	bool getCanUseHTTP() const { return mCanUseHTTP; } +	void setUrl(const std::string& url) { mUrl = url; } +  	LLTextureFetch & getFetcher() { return *mFetcher; }  	// Inherited from LLCore::HttpHandler  	// Threads:  Ttf  	virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response); -	 +  protected:  	LLTextureFetchWorker(LLTextureFetch* fetcher, FTType f_type,  						 const std::string& url, const LLUUID& id, const LLHost& host, @@ -547,6 +570,8 @@ private:  	S32 mActiveCount;  	LLCore::HttpStatus mGetStatus;  	std::string mGetReason; +	LLAdaptiveRetryPolicy mFetchRetryPolicy; +  	// Work Data  	LLMutex mWorkMutex; @@ -889,7 +914,8 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,  	  mHttpHasResource(false),  	  mCacheReadCount(0U),  	  mCacheWriteCount(0U), -	  mResourceWaitCount(0U) +	  mResourceWaitCount(0U), +	  mFetchRetryPolicy(10.0,3600.0,2.0,10)  {  	mCanUseNET = mUrl.empty() ; @@ -1148,6 +1174,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  		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; +  		// fall through  	} @@ -1270,6 +1297,21 @@ bool LLTextureFetchWorker::doWork(S32 param)  	if (mState == LOAD_FROM_NETWORK)  	{ +		// Check for retries to previous server failures. +		F32 wait_seconds; +		if (mFetchRetryPolicy.shouldRetry(wait_seconds)) +		{ +			if (wait_seconds <= 0.0) +			{ +				llinfos << mID << " retrying now" << llendl; +			} +			else +			{ +				//llinfos << mID << " waiting to retry for " << wait_seconds << " seconds" << llendl; +				return false; +			} +		} +  		static LLCachedControl<bool> use_http(gSavedSettings,"ImagePipelineUseHTTP");  // 		if (mHost != LLHost::invalid) get_url = false; @@ -1286,7 +1328,7 @@ bool LLTextureFetchWorker::doWork(S32 param)  				std::string http_url = region->getHttpUrl() ;  				if (!http_url.empty())  				{ -					mUrl = http_url + "/?texture_id=" + mID.asString().c_str(); +					setUrl(http_url + "/?texture_id=" + mID.asString().c_str());  					mWriteToCacheState = CAN_WRITE ; //because this texture has a fixed texture id.  				}  				else @@ -1519,15 +1561,22 @@ bool LLTextureFetchWorker::doWork(S32 param)  			{  				if (http_not_found == mGetStatus)  				{ -					if(mWriteToCacheState == NOT_WRITE) //map tiles +					if (mFTType != FTT_MAP_TILE) +					{ +						llwarns << "Texture missing from server (404): " << mUrl << llendl; +					} + +					if(mWriteToCacheState == NOT_WRITE) //map tiles or server bakes  					{  						setState(DONE);  						releaseHttpSemaphore(); -						LL_DEBUGS("Texture") << mID << " abort: WAIT_HTTP_REQ not found" << llendl; -						return true; // failed, means no map tile on the empty region. +						if (mFTType != FTT_MAP_TILE) +						{ +							LL_WARNS("Texture") << mID << " abort: WAIT_HTTP_REQ not found" << llendl; +						} +						return true;   					} -					llwarns << "Texture missing from server (404): " << mUrl << llendl;  					// roll back to try UDP  					if (mCanUseNET) @@ -1543,6 +1592,10 @@ bool LLTextureFetchWorker::doWork(S32 param)  				else if (http_service_unavail == mGetStatus)  				{  					LL_INFOS_ONCE("Texture") << "Texture server busy (503): " << mUrl << LL_ENDL; +					llinfos << "503: HTTP GET failed for: " << mUrl +							<< " Status: " << mGetStatus.toHex() +							<< " Reason: '" << mGetReason << "'" +							<< llendl;  				}  				else if (http_not_sat == mGetStatus)  				{ @@ -1551,11 +1604,29 @@ bool LLTextureFetchWorker::doWork(S32 param)  				}  				else  				{ -					llinfos << "HTTP GET failed for: " << mUrl +					llinfos << "other: HTTP GET failed for: " << mUrl  							<< " Status: " << mGetStatus.toHex()  							<< " Reason: '" << mGetReason << "'"  							<< llendl;  				} +#if 0 +				if (isHttpServerErrorStatus(mGetStatus.mType)) +				{ +					// Check for retry +					F32 wait_seconds; +					if (mFetchRetryPolicy.shouldRetry(wait_seconds)) +					{ +						llinfos << mID  << " status " << (S32) mGetStatus.mType << " will retry after " << wait_seconds << llendl; +						setState(INIT); +						releaseHttpSemaphore(); +						return false; +					} +					else +					{ +						llinfos << mID << " will not retry on status " << (S32) mGetStatus.mType << llendl; +					} +				} +#endif  				mUrl.clear();  				if (cur_size > 0) @@ -1891,14 +1962,44 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe  		mFetcher->mTextureInfo.setRequestCompleteTimeAndLog(mID, timeNow);  	} +	static LLCachedControl<F32> fake_failure_rate(gSavedSettings, "TextureFetchFakeFailureRate"); +	F32 rand_val = ll_frand(); +	F32 rate = fake_failure_rate; +	if (mFTType == FTT_SERVER_BAKE && (fake_failure_rate > 0.0) && (rand_val < fake_failure_rate)) +	{ +		llwarns << mID << " for debugging, setting fake failure status for texture " << mID +				<< " (rand was " << rand_val << "/" << rate << ")" << llendl; +		response->setStatus(LLCore::HttpStatus(503)); +	}  	bool success = true;  	bool partial = false;  	LLCore::HttpStatus status(response->getStatus()); +	if (!status && (mFTType == FTT_SERVER_BAKE)) +	{ +		llinfos << mID << " state " << e_state_name[mState] << llendl; +		mFetchRetryPolicy.onFailure(response); +		F32 retry_after; +		if (mFetchRetryPolicy.shouldRetry(retry_after)) +		{ +			llinfos << mID << " will retry after " << retry_after << " seconds, resetting state to LOAD_FROM_NETWORK" << llendl; +			mFetcher->removeFromHTTPQueue(mID, 0); +			std::string reason(status.toString()); +			setGetStatus(status, reason); +			releaseHttpSemaphore(); +			setState(LOAD_FROM_NETWORK); +			return; +		} +		else +		{ +			llinfos << mID << " will not retry" << llendl; +		} +	}  	LL_DEBUGS("Texture") << "HTTP COMPLETE: " << mID  						 << " status: " << status.toHex()  						 << " '" << status.toString() << "'"  						 << llendl; +  //	unsigned int offset(0), length(0), full_length(0);  //	response->getRange(&offset, &length, &full_length);  // 	llwarns << "HTTP COMPLETE: " << mID << " handle: " << handle @@ -1907,13 +2008,16 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe  // 			<< " offset: " << offset << " length: " << length  // 			<< llendl; +	std::string reason(status.toString()); +	setGetStatus(status, reason);  	if (! status)  	{  		success = false; -		std::string reason(status.toString()); -		setGetStatus(status, reason); -		llwarns << "CURL GET FAILED, status: " << status.toHex() -				<< " reason: " << reason << llendl; +		if (mFTType != FTT_MAP_TILE) // missing map tiles are normal, don't complain about them. +		{ +			llwarns << mID << " CURL GET FAILED, status: " << status.toHex() +					<< " reason: " << reason << llendl; +		}  	}  	else  	{ @@ -2465,7 +2569,11 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const  	{  		return false;  	} -	 + +	if (f_type == FTT_SERVER_BAKE) +	{ +		llinfos << " requesting " << id << " " << w << "x" << h << " discard " << desired_discard << llendl; +	}  	LLTextureFetchWorker* worker = getWorker(id) ;  	if (worker)  	{ @@ -2523,7 +2631,8 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const  		worker->mNeedsAux = needs_aux;  		worker->setImagePriority(priority);  		worker->setDesiredDiscard(desired_discard, desired_size); -		worker->setCanUseHTTP(can_use_http) ; +		worker->setCanUseHTTP(can_use_http); +		worker->setUrl(url);  		if (!worker->haveWork())  		{  			worker->setState(LLTextureFetchWorker::INIT); @@ -2729,7 +2838,8 @@ LLTextureFetchWorker* LLTextureFetch::getWorker(const LLUUID& id)  // Threads:  T*  bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, -										LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux) +										LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux, +										LLCore::HttpStatus& last_http_get_status)  {  	bool res = false;  	LLTextureFetchWorker* worker = getWorker(id); @@ -2751,6 +2861,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,  		else if (worker->checkWork())  		{  			worker->lockWorkMutex();									// +Mw +			last_http_get_status = worker->mGetStatus;  			discard_level = worker->mDecodedDiscard;  			raw = worker->mRawImage;  			aux = worker->mAuxImage; @@ -3221,25 +3332,14 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)  void LLTextureFetchWorker::setState(e_state new_state)  { -	static const char* e_state_name[] = -	{ -		"INVALID", -		"INIT", -		"LOAD_FROM_TEXTURE_CACHE", -		"CACHE_POST", -		"LOAD_FROM_NETWORK", -		"LOAD_FROM_SIMULATOR", -		"WAIT_HTTP_RESOURCE", -		"WAIT_HTTP_RESOURCE2", -		"SEND_HTTP_REQ", -		"WAIT_HTTP_REQ", -		"DECODE_IMAGE", -		"DECODE_IMAGE_UPDATE", -		"WRITE_TO_CACHE", -		"WAIT_ON_WRITE", -		"DONE" -	}; -	LL_DEBUGS("Texture") << "id: " << mID << " FTType: " << mFTType << " disc: " << mDesiredDiscard << " sz: " << mDesiredSize << " state: " << e_state_name[mState] << " => " << e_state_name[new_state] << llendl; +	if (mFTType == FTT_SERVER_BAKE) +	{ +	// NOTE: turning on these log statements is a reliable way to get +	// blurry images fairly frequently. Presumably this is an +	// indication of some subtle timing or locking issue. + +//		LL_INFOS("Texture") << "id: " << mID << " FTType: " << mFTType << " disc: " << mDesiredDiscard << " sz: " << mDesiredSize << " state: " << e_state_name[mState] << " => " << e_state_name[new_state] << llendl; +	}  	mState = new_state;  } | 
