Improved texture fetch fallback from HTTP to UDP. From Ansariel Hiller, fixes FIRE-952.

meow-7.2.2
Tonya Souther 2011-04-25 15:53:19 -05:00
parent 13b954bb44
commit e9577da553
5 changed files with 113 additions and 10 deletions

View File

@ -13563,5 +13563,27 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>1</integer>
</map>
<key>ImagePipelineUseHTTPFetchMaxRequests</key>
<map>
<key>Comment</key>
<string>Max number of simultaneous textures to request when using HTTP texture fetch. Changing this setting above 8 will most likely cause texture loading problems, setting above 32 *WILL* cause loading failures.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>8</integer>
</map>
<key>ImagePipelineHTTPMaxFailCountFallback</key>
<map>
<key>Comment</key>
<string>Maximum failures during HTTP GET texture fetch per region before fallback to UDP fetch occurs.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>25</integer>
</map>
</map>
</llsd>

View File

@ -1018,7 +1018,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
else
region = LLWorld::getInstance()->getRegion(mHost);
if (region)
if (region && !LLAppViewer::getTextureFetch()->isHttpFailLimitReached())
{
std::string http_url = region->getHttpUrl() ;
if (!http_url.empty())
@ -1134,14 +1134,15 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == SEND_HTTP_REQ)
{
if(mCanUseHTTP)
if(mCanUseHTTP && !LLAppViewer::getTextureFetch()->isHttpFailLimitReached())
{
//NOTE:
//control the number of the http requests issued for:
//1, not openning too many file descriptors at the same time;
//2, control the traffic of http so udp gets bandwidth.
//
static const S32 MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE = 8 ;
//static const S32 MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE = 8 ;
static LLCachedControl<S32> MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE(gSavedSettings, "ImagePipelineUseHTTPFetchMaxRequests");
if(mFetcher->getNumHTTPRequests() > MAX_NUM_OF_HTTP_REQUESTS_IN_QUEUE)
{
return false ; //wait.
@ -1213,7 +1214,15 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
else //can not use http fetch.
{
return true ; //abort
// Ansariel: roll back to try UDP
if(mCanUseNET)
{
mState = INIT ;
mCanUseHTTP = false ;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
return false ;
}
else return true ; //abort
}
}
@ -1245,7 +1254,13 @@ bool LLTextureFetchWorker::doWork(S32 param)
// for a short time (~1s) to ease server load? Ideally the server would queue
// requests instead of returning 503... we already limit the number pending.
++mHTTPFailCount;
max_attempts = mHTTPFailCount+1; // Keep retrying
// Ansariel: Just increase the normal counter. We're gonna fallback to UDP
// if problem continues.
//max_attempts = mHTTPFailCount+1; // Keep retrying
const S32 HTTP_MAX_RETRY_COUNT = 3;
max_attempts = HTTP_MAX_RETRY_COUNT + 1;
LLAppViewer::getTextureFetch()->addHttpFailCount();
LL_INFOS_ONCE("Texture") << "Texture server busy (503): " << mUrl << LL_ENDL;
}
else
@ -1253,6 +1268,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
const S32 HTTP_MAX_RETRY_COUNT = 3;
max_attempts = HTTP_MAX_RETRY_COUNT + 1;
++mHTTPFailCount;
LLAppViewer::getTextureFetch()->addHttpFailCount();
llinfos << "HTTP GET failed for: " << mUrl
<< " Status: " << mGetStatus << " Reason: '" << mGetReason << "'"
<< " Attempt:" << mHTTPFailCount+1 << "/" << max_attempts << llendl;
@ -1269,9 +1285,22 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
else
{
resetFormattedData();
mState = DONE;
return true; // failed
// Ansariel: What's this? On any other HTTP failure except
// not found we simply give up? No way! Let's
// try UDP as fallback!
if (mCanUseNET)
{
mState = INIT;
mCanUseHTTP = false;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
return false;
}
else
{
resetFormattedData();
mState = DONE;
return true; // failed
}
}
}
else
@ -1824,11 +1853,14 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mHTTPTextureBits(0),
mTotalHTTPRequests(0),
mCurlGetRequest(NULL),
mQAMode(qa_mode)
mQAMode(qa_mode),
mTotalHttpFailCount(0),
mHttpFailMutex(NULL)
{
mCurlPOSTRequestCount = 0;
mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");
mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), gSavedSettings.getU32("TextureLoggingThreshold"));
mMaxHttpFailCountBeforeFallback = gSavedSettings.getU32("ImagePipelineHTTPMaxFailCountFallback");
}
LLTextureFetch::~LLTextureFetch()
@ -1894,7 +1926,6 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
desired_size = TEXTURE_CACHE_ENTRY_SIZE;
desired_discard = MAX_DISCARD_LEVEL;
}
if (worker)
{
@ -2803,6 +2834,30 @@ void LLTextureFetch::cmdDoWork()
}
}
void LLTextureFetch::addHttpFailCount()
{
LLMutexLock lock(&mHttpFailMutex);
++mTotalHttpFailCount;
llwarns << "Increasing HTTP GET fail count to: " << mTotalHttpFailCount << llendl;
}
void LLTextureFetch::processRegionChanged()
{
llinfos << "Region changed. Resetting HTTP GET failure counter." << llendl;
LLMutexLock lock(&mHttpFailMutex);
mTotalHttpFailCount = 0;
}
void LLTextureFetch::setMaxHttpFailCountBeforeFallback(U32 maxFailCount)
{
llinfos << "Setting max failure count before fallback for HTTP GET to " << maxFailCount << llendl;
mMaxHttpFailCountBeforeFallback = maxFailCount;
}
bool LLTextureFetch::isHttpFailLimitReached()
{
return mTotalHttpFailCount >= mMaxHttpFailCountBeforeFallback;
}
//////////////////////////////////////////////////////////////////////////////

View File

@ -106,6 +106,11 @@ public:
inline void incrCurlPOSTCount() { mCurlPOSTRequestCount++; }
inline void decrCurlPOSTCount() { mCurlPOSTRequestCount--; }
void addHttpFailCount();
bool isHttpFailLimitReached();
void processRegionChanged();
void setMaxHttpFailCountBeforeFallback(U32 maxFailCount);
protected:
void addToNetworkQueue(LLTextureFetchWorker* worker);
void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);
@ -161,6 +166,11 @@ public:
S32 mBadPacketCount;
private:
LLMutex mHttpFailMutex;
U32 mTotalHttpFailCount;
U32 mMaxHttpFailCountBeforeFallback;
LLMutex mQueueMutex; //to protect mRequestMap and mCommands only
LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue.

View File

@ -73,6 +73,7 @@
#include "llcombobox.h"
#include "llstatusbar.h"
#include "llupdaterservice.h"
#include "lltexturefetch.h"
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
BOOL gHackGodmode = FALSE;
@ -549,6 +550,12 @@ void toggle_updater_service_active(LLControlVariable* control, const LLSD& new_v
}
}
static bool handleImagePipelineHTTPMaxFailCountFallback(const LLSD& newvalue)
{
LLAppViewer::getTextureFetch()->setMaxHttpFailCountBeforeFallback(newvalue.asInteger());
return true;
}
////////////////////////////////////////////////////////////////////////////
void settings_setup_listeners()
@ -704,6 +711,7 @@ void settings_setup_listeners()
gSavedSettings.getControl("UpdaterServiceSetting")->getSignal()->connect(&toggle_updater_service_active);
gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2));
gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2));
gSavedSettings.getControl("ImagePipelineHTTPMaxFailCountFallback")->getSignal()->connect(boost::bind(&handleImagePipelineHTTPMaxFailCountFallback, _2));
}
#if TEST_CACHED_CONTROL

View File

@ -119,6 +119,8 @@
#include "llnotificationmanager.h" //
#include "lltexturefetch.h"
#if LL_MSVC
// disable boost::lexical_cast warning
#pragma warning (disable:4702)
@ -4021,6 +4023,9 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
// Viewer trusts the simulator.
gMessageSystem->enableCircuit(sim_host, TRUE);
LLViewerRegion* regionp = LLWorld::getInstance()->addRegion(region_handle, sim_host);
// Ansariel: New region -> reset fail counter for texture fetcher
LLAppViewer::getTextureFetch()->processRegionChanged();
/*
// send camera update to new region
@ -4299,6 +4304,9 @@ void process_crossed_region(LLMessageSystem* msg, void**)
LLViewerRegion* regionp = LLWorld::getInstance()->addRegion(region_handle, sim_host);
regionp->setSeedCapability(seedCap);
// Ansariel: New region -> reset fail counter for texture fetcher
LLAppViewer::getTextureFetch()->processRegionChanged();
}