diff options
| -rwxr-xr-x | indra/newview/llappearancemgr.cpp | 85 | ||||
| -rwxr-xr-x | indra/newview/llappearancemgr.h | 2 | ||||
| -rwxr-xr-x[-rw-r--r--] | indra/newview/llcallbacklist.cpp | 49 | ||||
| -rw-r--r-- | indra/newview/llcallbacklist.h | 6 | 
4 files changed, 137 insertions, 5 deletions
| diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 51de2fd17b..b2a8a33ecf 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -2652,12 +2652,70 @@ void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id, bool update_base  	if (inventory_changed) gInventory.notifyObservers();  } +// This is intended for use with HTTP Clients/Responders, but is not +// specifically coupled with those classes. +class LLHTTPRetryPolicy: public LLThreadSafeRefCount +{ +public: +	LLHTTPRetryPolicy() {} +	virtual ~LLHTTPRetryPolicy() {} +	virtual bool shouldRetry(U32 status, F32& seconds_to_wait) = 0; +}; + +// Example of simplest possible policy, not necessarily recommended. +class LLAlwaysRetryImmediatelyPolicy: public LLHTTPRetryPolicy +{ +public: +	LLAlwaysRetryImmediatelyPolicy() {} +	bool shouldRetry(U32 status, F32& seconds_to_wait) +	{ +		seconds_to_wait = 0.0; +		return true; +	} +}; + +// Very general policy with geometric back-off after failures, +// up to a maximum delay, and maximum number of retries. +class LLAdaptiveRetryPolicy: public LLHTTPRetryPolicy +{ +public: +	LLAdaptiveRetryPolicy(F32 min_delay, F32 max_delay, F32 backoff_factor, U32 max_retries): +		mMinDelay(min_delay), +		mMaxDelay(max_delay), +		mBackoffFactor(backoff_factor), +		mMaxRetries(max_retries), +		mDelay(min_delay), +		mRetryCount(0) +	{ +	} + +	bool shouldRetry(U32 status, F32& seconds_to_wait) +	{ +		seconds_to_wait = mDelay; +		mDelay = llclamp(mDelay*mBackoffFactor,mMinDelay,mMaxDelay); +		mRetryCount++; +		return (mRetryCount<=mMaxRetries); +	} + +private: +	F32 mMinDelay; // delay never less than this value +	F32 mMaxDelay; // delay never exceeds this value +	F32 mBackoffFactor; // delay increases by this factor after each retry, up to mMaxDelay. +	U32 mMaxRetries; // maximum number of times shouldRetry will return true. +	F32 mDelay; // current delay. +	U32 mRetryCount; // number of times shouldRetry has been called. +}; +  class RequestAgentUpdateAppearanceResponder: public LLHTTPClient::Responder  {  public:  	RequestAgentUpdateAppearanceResponder()  	{ -		llinfos << "request created" << llendl; +		mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 16.0, 2.0, 5); +	} + +	virtual ~RequestAgentUpdateAppearanceResponder() +	{  	}  	// Successful completion. @@ -2669,11 +2727,25 @@ public:  	// Error  	/*virtual*/ void error(U32 status, const std::string& reason)  	{ -		llwarns << "appearance update request failed, reason: " << reason << llendl; +		llwarns << "appearance update request failed, status: " << status << " reason: " << reason << llendl; +		F32 seconds_to_wait; +		if (mRetryPolicy->shouldRetry(status,seconds_to_wait)) +		{ +			doAfterInterval(boost::bind(&LLAppearanceMgr::requestServerAppearanceUpdate, +										LLAppearanceMgr::getInstance(), +										LLCurl::ResponderPtr(this)), +							seconds_to_wait); +		} +		else +		{ +			llwarns << "giving up after too many retries" << llendl; +		}  	}	 + +	LLPointer<LLHTTPRetryPolicy> mRetryPolicy;  }; -void LLAppearanceMgr::requestServerAppearanceUpdate() +void LLAppearanceMgr::requestServerAppearanceUpdate(LLCurl::ResponderPtr responder_ptr)  {  	if (!gAgent.getRegion())  	{ @@ -2693,7 +2765,12 @@ void LLAppearanceMgr::requestServerAppearanceUpdate()  	LLSD body;  	S32 cof_version = getCOFVersion();  	body["cof_version"] = cof_version; -	LLHTTPClient::post(url, body, new RequestAgentUpdateAppearanceResponder); +	//LLCurl::ResponderPtr responder_ptr; +	if (!responder_ptr.get()) +	{ +		responder_ptr = new RequestAgentUpdateAppearanceResponder; +	} +	LLHTTPClient::post(url, body, responder_ptr);  	llassert(cof_version >= mLastUpdateRequestCOFVersion);  	mLastUpdateRequestCOFVersion = cof_version;  } diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 4baee10218..01ed66711c 100755 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -187,7 +187,7 @@ public:  	bool isInUpdateAppearanceFromCOF() { return mIsInUpdateAppearanceFromCOF; } -	void requestServerAppearanceUpdate(); +	void requestServerAppearanceUpdate(LLCurl::ResponderPtr responder_ptr = NULL);  protected:  	LLAppearanceMgr(); diff --git a/indra/newview/llcallbacklist.cpp b/indra/newview/llcallbacklist.cpp index 357a6582d1..79ec43dfe9 100644..100755 --- a/indra/newview/llcallbacklist.cpp +++ b/indra/newview/llcallbacklist.cpp @@ -27,6 +27,7 @@  #include "llviewerprecompiledheaders.h"  #include "llcallbacklist.h" +#include "lleventtimer.h"  // Library includes  #include "llerror.h" @@ -180,6 +181,54 @@ void doOnIdleRepeating(bool_func_t callable)  	gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor);  } +class NullaryFuncEventTimer: public LLEventTimer +{ +public: +	NullaryFuncEventTimer(nullary_func_t callable, F32 seconds): +		LLEventTimer(seconds), +		mCallable(callable) +	{ +	} + +private: +	BOOL tick() +	{ +		mCallable(); +		return TRUE; +	} + +	nullary_func_t mCallable; +}; + +// Call a given callable once after specified interval. +void doAfterInterval(nullary_func_t callable, F32 seconds) +{ +	new NullaryFuncEventTimer(callable, seconds); +} + +class BoolFuncEventTimer: public LLEventTimer +{ +public: +	BoolFuncEventTimer(bool_func_t callable, F32 seconds): +		LLEventTimer(seconds), +		mCallable(callable) +	{ +	} +private: +	BOOL tick() +	{ +		return mCallable(); +	} + +	bool_func_t mCallable; +}; + +// Call a given callable every specified number of seconds, until it returns true. +void doPeriodically(bool_func_t callable, F32 seconds) +{ +	new BoolFuncEventTimer(callable, seconds); +} +  #ifdef _DEBUG  void test1(void *data) diff --git a/indra/newview/llcallbacklist.h b/indra/newview/llcallbacklist.h index 97f3bfd9ee..0516c9cdb4 100644 --- a/indra/newview/llcallbacklist.h +++ b/indra/newview/llcallbacklist.h @@ -61,6 +61,12 @@ void doOnIdleOneTime(nullary_func_t callable);  // Repeatedly call a callable in idle loop until it returns true.  void doOnIdleRepeating(bool_func_t callable); +// Call a given callable once after specified interval. +void doAfterInterval(nullary_func_t callable, F32 seconds); + +// Call a given callable every specified number of seconds, until it returns true. +void doPeriodically(bool_func_t callable, F32 seconds); +  extern LLCallbackList gIdleCallbacks;  #endif | 
