summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2020-04-17 14:27:46 +0300
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2020-04-20 21:54:31 +0300
commit64cbc9911dfd43af0c29034d92656b55bc16217a (patch)
treec2a631aa7ffdf92924d8b911b7a48a4ccadd77bb
parentee1d700a9bc764c86502978b5538df44aaa66905 (diff)
downloadqtlocation-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.hpp1
-rw-r--r--platform/default/src/mbgl/storage/online_file_source.cpp55
-rw-r--r--src/mbgl/util/http_timeout.cpp6
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