Shoddy servers need shoddy workarounds

This commit is contained in:
siana
2010-12-28 03:47:40 +01:00
parent 105afc497a
commit 95a7fd83ff

View File

@@ -365,6 +365,78 @@ private:
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
class SGHostBlackList{
static const int MAX_ERRORCOUNT = 5;
struct BlackListEntry {
LLHost host;
clock_t timeUntil;
U32 reason;
int errorCount;
};
static LLMutex* sMutex;
typedef std::vector<BlackListEntry> blacklist_t;
typedef blacklist_t::iterator iter;
static blacklist_t blacklist;
static bool is_obsolete(BlackListEntry entry) {
clock_t now = clock();
return (now > entry.timeUntil);
} //should make a functor. if i cared.
static void cleanup() {
std::remove_if(blacklist.begin(), blacklist.end(), is_obsolete);
}
static iter find(LLHost& host) {
cleanup();
for(blacklist_t::iterator i = blacklist.begin(); i != blacklist.end(); ++i) {
if (i->host == host) return i;
}
return blacklist.end();
}
static void lock() {
if (!sMutex)
sMutex = new LLMutex(0);
sMutex->lock();
}
static void unlock() {
sMutex->unlock();
}
public:
static bool isBlacklisted(LLHost& host) {
lock();
iter found = find(host);
bool r = (found != blacklist.end()) && (found->errorCount > MAX_ERRORCOUNT);
unlock();
return r;
}
static void add(LLHost& host, float timeout, U32 reason) {
BlackListEntry entry;
entry.host = host;
entry.timeUntil = clock() + timeout*CLOCKS_PER_SEC;
entry.reason = reason;
entry.errorCount = 0;
lock();
iter found = find(host);
if(found != blacklist.end()) {
entry.errorCount = found->errorCount + 1;
*found = entry;
}
else blacklist.push_back(entry);
unlock();
}
};
LLMutex* SGHostBlackList::sMutex = 0;
SGHostBlackList::blacklist_t SGHostBlackList::blacklist;
//////////////////////////////////////////////////////////////////////////////
//static //static
const char* LLTextureFetchWorker::sStateDescs[] = { const char* LLTextureFetchWorker::sStateDescs[] = {
"INVALID", "INVALID",
@@ -766,6 +838,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (!mUrl.empty()) get_url = false; if (!mUrl.empty()) get_url = false;
// if (mHost != LLHost::invalid) get_url = false; // if (mHost != LLHost::invalid) get_url = false;
if (SGHostBlackList::isBlacklisted(mHost)) get_url = false;
if ( get_url && mCanUseHTTP && mUrl.empty())//get http url. if ( get_url && mCanUseHTTP && mUrl.empty())//get http url.
{ {
LLViewerRegion* region = NULL; LLViewerRegion* region = NULL;
@@ -928,10 +1002,19 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mRequestedSize < 0) if (mRequestedSize < 0)
{ {
S32 max_attempts; S32 max_attempts;
if (mGetStatus == HTTP_NOT_FOUND) if (mGetStatus == HTTP_NOT_FOUND || mGetStatus == 499 || mGetStatus == HTTP_SERVICE_UNAVAILABLE)
{ {
mHTTPFailCount = max_attempts = 1; // Don't retry mHTTPFailCount = max_attempts = 1; // Don't retry
llwarns << "Texture missing from server (404): " << mUrl << llendl; if(mGetStatus == HTTP_NOT_FOUND)
llwarns << "Texture missing from server (404): " << mUrl << llendl;
else if (mGetStatus == 499) {
llwarns << "No response from server (499): " << mUrl << llendl;
SGHostBlackList::add(mHost, 60.0, mGetStatus);
}
else if (mGetStatus == HTTP_SERVICE_UNAVAILABLE){
llwarns << "Texture server busy (503): " << mUrl << LL_ENDL;
SGHostBlackList::add(mHost, 60.0, mGetStatus);
}
//roll back to try UDP //roll back to try UDP
if(mCanUseNET) if(mCanUseNET)
@@ -948,18 +1031,18 @@ bool LLTextureFetchWorker::doWork(S32 param)
return true; // failed return true; // failed
} }
} }
else if (mGetStatus == HTTP_SERVICE_UNAVAILABLE) //else if (mGetStatus == HTTP_SERVICE_UNAVAILABLE)
{ //{
// *TODO: Should probably introduce a timer here to delay future HTTP requsts // // *TODO: Should probably introduce a timer here to delay future HTTP requsts
// for a short time (~1s) to ease server load? Ideally the server would queue // // 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. // // requests instead of returning 503... we already limit the number pending.
++mHTTPFailCount; // ++mHTTPFailCount;
max_attempts = mHTTPFailCount+1; // Keep retrying // max_attempts = mHTTPFailCount+1; // Keep retrying
LL_INFOS_ONCE("Texture") << "Texture server busy (503): " << mUrl << LL_ENDL; // LL_INFOS_ONCE("Texture") << "Texture server busy (503): " << mUrl << LL_ENDL;
} //}
else else
{ {
const S32 HTTP_MAX_RETRY_COUNT = 3; const S32 HTTP_MAX_RETRY_COUNT = 1;
max_attempts = HTTP_MAX_RETRY_COUNT + 1; max_attempts = HTTP_MAX_RETRY_COUNT + 1;
++mHTTPFailCount; ++mHTTPFailCount;
llinfos << "HTTP GET failed for: " << mUrl llinfos << "HTTP GET failed for: " << mUrl