diff options
author | Mikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com> | 2020-04-17 14:27:46 +0300 |
---|---|---|
committer | Mikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com> | 2020-04-20 21:54:31 +0300 |
commit | 64cbc9911dfd43af0c29034d92656b55bc16217a (patch) | |
tree | c2a631aa7ffdf92924d8b911b7a48a4ccadd77bb | |
parent | ee1d700a9bc764c86502978b5538df44aaa66905 (diff) | |
download | qtlocation-mapboxgl-64cbc9911dfd43af0c29034d92656b55bc16217a.tar.gz |
[core] Introduce `Resource::minimumUpdateInterval`
Introduce `Resource::minimumUpdateInterval` and consider it in the online file source.
The `minimumUpdateInterval` is used to throttle the requests, which were initiated due to resource expiration.
-rw-r--r-- | include/mbgl/storage/resource.hpp | 1 | ||||
-rw-r--r-- | platform/default/src/mbgl/storage/online_file_source.cpp | 55 | ||||
-rw-r--r-- | src/mbgl/util/http_timeout.cpp | 6 |
3 files changed, 34 insertions, 28 deletions
diff --git a/include/mbgl/storage/resource.hpp b/include/mbgl/storage/resource.hpp index b21265ef54..b7b394efc2 100644 --- a/include/mbgl/storage/resource.hpp +++ b/include/mbgl/storage/resource.hpp @@ -95,6 +95,7 @@ public: optional<Timestamp> priorExpires = {}; optional<std::string> priorEtag = {}; std::shared_ptr<const std::string> priorData; + Duration minimumUpdateInterval{Duration::zero()}; }; inline bool Resource::hasLoadingMethod(Resource::LoadingMethod method) const { diff --git a/platform/default/src/mbgl/storage/online_file_source.cpp b/platform/default/src/mbgl/storage/online_file_source.cpp index a5274c6b38..ca51234b56 100644 --- a/platform/default/src/mbgl/storage/online_file_source.cpp +++ b/platform/default/src/mbgl/storage/online_file_source.cpp @@ -40,14 +40,15 @@ struct OnlineFileRequest { ~OnlineFileRequest(); void networkIsReachableAgain(); - void schedule(); - void schedule(optional<Timestamp> expires); + void activate(); + void schedule(Duration timeout); void completed(Response); void setTransformedURL(const std::string& url); ActorRef<OnlineFileRequest> actor(); void onCancel(std::function<void()>); + Duration getUpdateInterval(optional<Timestamp> expires) const; OnlineFileSourceThread& impl; Resource resource; std::unique_ptr<AsyncRequest> request; @@ -100,7 +101,7 @@ public: ref.invoke(&OnlineFileRequest::setTransformedURL, url); }); } else { - req->schedule(); + req->activate(); } } @@ -176,11 +177,11 @@ public: maximumConcurrentRequests = maximumConcurrentRequests_; } - void setAPIBaseURL(const std::string& t) { apiBaseURL = t; } - std::string getAPIBaseURL() const { return apiBaseURL; } + void setAPIBaseURL(std::string t) { apiBaseURL = std::move(t); } + const std::string& getAPIBaseURL() const { return apiBaseURL; } - void setAccessToken(const std::string& t) { accessToken = t; } - std::string getAccessToken() const { return accessToken; } + void setAccessToken(std::string t) { accessToken = std::move(t); } + const std::string& getAccessToken() const { return accessToken; } private: friend struct OnlineFileRequest; @@ -383,15 +384,6 @@ OnlineFileRequest::OnlineFileRequest(Resource resource_, Callback callback_, Onl impl.add(this); } -void OnlineFileRequest::schedule() { - // Force an immediate first request if we don't have an expiration time. - if (resource.priorExpires) { - schedule(resource.priorExpires); - } else { - schedule(util::now()); - } -} - OnlineFileRequest::~OnlineFileRequest() { if (mailbox) { mailbox->close(); @@ -431,17 +423,21 @@ Timestamp interpolateExpiration(const Timestamp& current, optional<Timestamp> pr return now + std::max<Seconds>(delta, util::CLOCK_SKEW_RETRY_TIMEOUT); } -void OnlineFileRequest::schedule(optional<Timestamp> expires) { +void OnlineFileRequest::activate() { + // Force an immediate first request if we don't have an expiration time. + Duration timeout = Duration::zero(); + if (resource.priorExpires) { + timeout = getUpdateInterval(resource.priorExpires); + } + schedule(timeout); +} + +void OnlineFileRequest::schedule(Duration timeout) { if (impl.isPending(this) || impl.isActive(this)) { // There's already a request in progress; don't start another one. return; } - // If we're not being asked for a forced refresh, calculate a timeout that depends on how many - // consecutive errors we've encountered, and on the expiration time, if present. - Duration timeout = std::min(http::errorRetryTimeout(failedRequestReason, failedRequests, retryAfter), - http::expirationTimeout(std::move(expires), expiredRequests)); - if (timeout == Duration::max()) { return; } @@ -460,6 +456,15 @@ void OnlineFileRequest::schedule(optional<Timestamp> expires) { }); } +Duration OnlineFileRequest::getUpdateInterval(optional<Timestamp> expires) const { + // Calculate a timeout that depends on how many + // consecutive errors we've encountered, and on the expiration time, if present. + Duration errorRetryTimeout = http::errorRetryTimeout(failedRequestReason, failedRequests, retryAfter); + Duration expirationTimeout = + std::max(http::expirationTimeout(std::move(expires), expiredRequests), resource.minimumUpdateInterval); + return std::min(errorRetryTimeout, expirationTimeout); +} + namespace { inline std::string sanitizeURL(std::string& url) { @@ -519,7 +524,7 @@ void OnlineFileRequest::completed(Response response) { failedRequestReason = Response::Error::Reason::Success; } - schedule(response.expires); + schedule(getUpdateInterval(response.expires)); // Calling the callback may result in `this` being deleted. It needs to be done last, // and needs to make a local copy of the callback to ensure that it remains valid for @@ -532,13 +537,13 @@ void OnlineFileRequest::networkIsReachableAgain() { // We need all requests to fail at least once before we are going to start retrying // them, and we only immediately restart request that failed due to connection issues. if (failedRequestReason == Response::Error::Reason::Connection) { - schedule(util::now()); + schedule(Duration::zero()); } } void OnlineFileRequest::setTransformedURL(const std::string& url) { resource.url = url; - schedule(); + activate(); } ActorRef<OnlineFileRequest> OnlineFileRequest::actor() { diff --git a/src/mbgl/util/http_timeout.cpp b/src/mbgl/util/http_timeout.cpp index 04842e48be..cf4085d5dc 100644 --- a/src/mbgl/util/http_timeout.cpp +++ b/src/mbgl/util/http_timeout.cpp @@ -32,11 +32,11 @@ Duration errorRetryTimeout(Response::Error::Reason failedRequestReason, uint32_t Duration expirationTimeout(optional<Timestamp> expires, uint32_t expiredRequests) { if (expiredRequests) { return Seconds(1u << std::min(expiredRequests - 1, 31u)); - } else if (expires) { + } + if (expires) { return std::max(Seconds::zero(), *expires - util::now()); - } else { - return Duration::max(); } + return Duration::max(); } } // namespace http |