diff options
-rwxr-xr-x | indra/newview/llhttpretrypolicy.cpp | 18 | ||||
-rwxr-xr-x | indra/newview/llhttpretrypolicy.h | 16 | ||||
-rwxr-xr-x | indra/newview/lltexturefetch.cpp | 4 | ||||
-rwxr-xr-x | indra/newview/tests/llhttpretrypolicy_test.cpp | 35 | ||||
-rwxr-xr-x[-rw-r--r--] | indra/test/lltut.h | 10 |
5 files changed, 69 insertions, 14 deletions
diff --git a/indra/newview/llhttpretrypolicy.cpp b/indra/newview/llhttpretrypolicy.cpp index 10b923be5a..80d97e4362 100755 --- a/indra/newview/llhttpretrypolicy.cpp +++ b/indra/newview/llhttpretrypolicy.cpp @@ -32,11 +32,16 @@ LLAdaptiveRetryPolicy::LLAdaptiveRetryPolicy(F32 min_delay, F32 max_delay, F32 b mMinDelay(min_delay), mMaxDelay(max_delay), mBackoffFactor(backoff_factor), - mMaxRetries(max_retries), - mDelay(min_delay), - mRetryCount(0), - mShouldRetry(true) + mMaxRetries(max_retries) { + init(); +} + +void LLAdaptiveRetryPolicy::init() +{ + mDelay = mMinDelay; + mRetryCount = 0; + mShouldRetry = true; } bool LLAdaptiveRetryPolicy::getRetryAfter(const LLSD& headers, F32& retry_header_time) @@ -59,6 +64,11 @@ bool LLAdaptiveRetryPolicy::getRetryAfter(const LLCore::HttpHeaders *headers, F3 return false; } +void LLAdaptiveRetryPolicy::onSuccess() +{ + init(); +} + void LLAdaptiveRetryPolicy::onFailure(S32 status, const LLSD& headers) { F32 retry_header_time; diff --git a/indra/newview/llhttpretrypolicy.h b/indra/newview/llhttpretrypolicy.h index 6f63f047de..1fb0cac03f 100755 --- a/indra/newview/llhttpretrypolicy.h +++ b/indra/newview/llhttpretrypolicy.h @@ -42,7 +42,11 @@ class LLHTTPRetryPolicy: public LLThreadSafeRefCount { public: LLHTTPRetryPolicy() {} + virtual ~LLHTTPRetryPolicy() {} + // Call after a sucess to reset retry state. + + virtual void onSuccess() = 0; // Call once after an HTTP failure to update state. virtual void onFailure(S32 status, const LLSD& headers) = 0; @@ -59,6 +63,9 @@ public: LLAdaptiveRetryPolicy(F32 min_delay, F32 max_delay, F32 backoff_factor, U32 max_retries); // virtual + void onSuccess(); + + // virtual void onFailure(S32 status, const LLSD& headers); // virtual void onFailure(const LLCore::HttpResponse *response); @@ -66,16 +73,17 @@ public: bool shouldRetry(F32& seconds_to_wait) const; protected: + void init(); bool getRetryAfter(const LLSD& headers, F32& retry_header_time); bool getRetryAfter(const LLCore::HttpHeaders *headers, F32& retry_header_time); void onFailureCommon(S32 status, bool has_retry_header_time, F32 retry_header_time); 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. + const F32 mMinDelay; // delay never less than this value + const F32 mMaxDelay; // delay never exceeds this value + const F32 mBackoffFactor; // delay increases by this factor after each retry, up to mMaxDelay. + const U32 mMaxRetries; // maximum number of times shouldRetry will return true. F32 mDelay; // current default delay. U32 mRetryCount; // number of times shouldRetry has been called. LLTimer mRetryTimer; // time until next retry. diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 1a6a308230..774c925fa1 100755 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1976,6 +1976,10 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe llinfos << mID << " will not retry" << llendl; } } + else + { + mFetchRetryPolicy.onSuccess(); + } LL_DEBUGS("Texture") << "HTTP COMPLETE: " << mID << " status: " << status.toHex() diff --git a/indra/newview/tests/llhttpretrypolicy_test.cpp b/indra/newview/tests/llhttpretrypolicy_test.cpp index 6fa3a57364..ed7f3ba326 100755 --- a/indra/newview/tests/llhttpretrypolicy_test.cpp +++ b/indra/newview/tests/llhttpretrypolicy_test.cpp @@ -45,7 +45,7 @@ void RetryPolicyTestObject::test<1>() LLSD headers; F32 wait_seconds; - // No retry until we've finished a try. + // No retry until we've failed a try. ensure("never retry 0", !never_retry.shouldRetry(wait_seconds)); // 0 retries max. @@ -74,7 +74,7 @@ void RetryPolicyTestObject::test<3>() bool should_retry; U32 frac_bits = 6; - // No retry until we've finished a try. + // No retry until we've failed a try. ensure("basic_retry 0", !basic_retry.shouldRetry(wait_seconds)); // Starting wait 1.0 @@ -105,6 +105,29 @@ void RetryPolicyTestObject::test<3>() basic_retry.onFailure(500,headers); should_retry = basic_retry.shouldRetry(wait_seconds); ensure("basic_retry 5", !should_retry); + + // Max retries, should fail now. + basic_retry.onFailure(500,headers); + should_retry = basic_retry.shouldRetry(wait_seconds); + ensure("basic_retry 5", !should_retry); + + // After a success, should reset to the starting state. + basic_retry.onSuccess(); + + // No retry until we've failed a try. + ensure("basic_retry 6", !basic_retry.shouldRetry(wait_seconds)); + + // Starting wait 1.0 + basic_retry.onFailure(500,headers); + should_retry = basic_retry.shouldRetry(wait_seconds); + ensure("basic_retry 7", should_retry); + ensure_approximately_equals("basic_retry 7", wait_seconds, 1.0F, frac_bits); + + // Double wait to 2.0 + basic_retry.onFailure(500,headers); + should_retry = basic_retry.shouldRetry(wait_seconds); + ensure("basic_retry 8", should_retry); + ensure_approximately_equals("basic_retry 8", wait_seconds, 2.0F, frac_bits); } // Retries should stop as soon as a non-5xx error is received. @@ -221,7 +244,7 @@ void RetryPolicyTestObject::test<6>() success = getSecondsUntilRetryAfter(str3, seconds_to_wait); std::cerr << " str3 [" << str3 << "]" << std::endl; ensure("parse 3", success); - ensure_approximately_equals("parse 3", seconds_to_wait, 44.0F, 2); + ensure_approximately_equals_range("parse 3", seconds_to_wait, 44.0F, 2.0F); } // Test retry-after field in both llmessage and CoreHttp headers. @@ -237,7 +260,7 @@ void RetryPolicyTestObject::test<7>() F32 seconds_to_wait; bool should_retry; - // No retry until we've finished a try. + // No retry until we've failed a try. ensure("header 0", !policy.shouldRetry(seconds_to_wait)); // no retry header, use default. @@ -252,7 +275,7 @@ void RetryPolicyTestObject::test<7>() policy.onFailure(503,sd_headers); should_retry = policy.shouldRetry(seconds_to_wait); ensure("header 2", should_retry); - ensure_approximately_equals("header 2", seconds_to_wait, 7.0F, 2); + ensure_approximately_equals_range("header 2", seconds_to_wait, 7.0F, 2.0F); LLCore::HttpResponse *response; LLCore::HttpHeaders *headers; @@ -279,7 +302,7 @@ void RetryPolicyTestObject::test<7>() policy.onFailure(response); should_retry = policy.shouldRetry(seconds_to_wait); ensure("header 4",should_retry); - ensure_approximately_equals("header 4", seconds_to_wait, 77.0F, 2); + ensure_approximately_equals_range("header 4", seconds_to_wait, 77.0F, 2.0F); response->release(); // Timeout should be clamped at max. diff --git a/indra/test/lltut.h b/indra/test/lltut.h index 55d84bcaca..243e869be7 100644..100755 --- a/indra/test/lltut.h +++ b/indra/test/lltut.h @@ -65,6 +65,16 @@ namespace tut ensure_approximately_equals(NULL, actual, expected, frac_bits); } + inline void ensure_approximately_equals_range(const char *msg, F32 actual, F32 expected, F32 delta) + { + if (fabs(actual-expected)>delta) + { + std::stringstream ss; + ss << (msg?msg:"") << (msg?": ":"") << "not equal actual: " << actual << " expected: " << expected << " tolerance: " << delta; + throw tut::failure(ss.str().c_str()); + } + } + inline void ensure_memory_matches(const char* msg,const void* actual, U32 actual_len, const void* expected,U32 expected_len) { if((expected_len != actual_len) || |