diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-01-12 15:22:07 -0800 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-01-13 13:38:12 -0800 |
commit | 2126e34e52dc5dd94c5a3907b240e62ee17d1e70 (patch) | |
tree | 26e524f41de560a5948a1d85c0b1518faee72db9 /platform/default/online_file_source.cpp | |
parent | 54fc3831f2cef3128f3db2a3821cd2be455fc7fa (diff) | |
download | qtlocation-mapboxgl-2126e34e52dc5dd94c5a3907b240e62ee17d1e70.tar.gz |
[core] Further clarify timeout calculations
Diffstat (limited to 'platform/default/online_file_source.cpp')
-rw-r--r-- | platform/default/online_file_source.cpp | 67 |
1 files changed, 30 insertions, 37 deletions
diff --git a/platform/default/online_file_source.cpp b/platform/default/online_file_source.cpp index 42373283cb..480d2a8276 100644 --- a/platform/default/online_file_source.cpp +++ b/platform/default/online_file_source.cpp @@ -76,7 +76,7 @@ private: // Counts the number of subsequent failed requests. We're using this value for exponential // backoff when retrying requests. - int failedRequests = 0; + uint32_t failedRequests = 0; }; class OnlineFileSource::Impl { @@ -280,49 +280,42 @@ void OnlineFileRequestImpl::scheduleCacheRequest(OnlineFileSource::Impl& impl) { }); } -void OnlineFileRequestImpl::scheduleRealRequest(OnlineFileSource::Impl& impl, bool forceImmediate) { - if (realRequest) { - // There's already a request in progress; don't start another one. - return; - } - - // If we don't have a fresh response, we'll retry immediately. Otherwise, the timeout will - // depend on how many consecutive errors we've encountered, and on the expiration time. - Seconds timeout = (!response || response->stale) ? Seconds::zero() : Seconds::max(); - - if (response && response->error) { +static Seconds errorRetryTimeout(const Response& response, uint32_t failedRequests) { + if (response.error && response.error->reason == Response::Error::Reason::Server) { + // Retry after one second three times, then start exponential backoff. + return Seconds(failedRequests <= 3 ? 1 : 1 << std::min(failedRequests - 3, 31u)); + } else if (response.error && response.error->reason == Response::Error::Reason::Connection) { + // Immediate exponential backoff. assert(failedRequests > 0); - switch (response->error->reason) { - case Response::Error::Reason::Server: { - // Retry immediately, unless we have a certain number of attempts already - const int graceRetries = 3; - if (failedRequests <= graceRetries) { - timeout = Seconds(1); - } else { - timeout = Seconds(1 << std::min(failedRequests - graceRetries, 31)); - } - } break; - case Response::Error::Reason::Connection: { - // Exponential backoff - timeout = Seconds(1 << std::min(failedRequests - 1, 31)); - } break; - default: - // Do not retry due to error. - break; - } + return Seconds(1 << std::min(failedRequests - 1, 31u)); + } else { + // No error, or not an error that triggers retries. + return Seconds::max(); } +} - // Check to see if this response expires earlier than a potential error retry. - if (response && response->expires > Seconds::zero()) { - // Only update the timeout if we don't have one yet, and only if the new timeout is shorter - // than the previous one. - timeout = std::min(timeout, std::max(Seconds::zero(), response->expires - toSeconds(SystemClock::now()))); +static Seconds expirationTimeout(const Response& response) { + // Seconds::zero() is a special value meaning "no expiration". + if (response.expires > Seconds::zero()) { + return std::max(Seconds::zero(), response.expires - toSeconds(SystemClock::now())); + } else { + return Seconds::max(); } +} - if (forceImmediate) { - timeout = Seconds::zero(); +void OnlineFileRequestImpl::scheduleRealRequest(OnlineFileSource::Impl& impl, bool forceImmediate) { + if (realRequest) { + // There's already a request in progress; don't start another one. + return; } + // If we don't have a fresh response, retry immediately. Otherwise, calculate a timeout + // that depends on how many consecutive errors we've encountered, and on the expiration time. + Seconds timeout = (!response || response->stale || forceImmediate) + ? Seconds::zero() + : std::min(errorRetryTimeout(*response, failedRequests), + expirationTimeout(*response)); + if (timeout == Seconds::max()) { return; } |