summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2020-02-25 12:44:44 +0200
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2020-02-25 12:44:44 +0200
commit8a675af4246c63ca409c099ff3b4fb7e775ab116 (patch)
tree4b564227ce4c6366bc7e20ca1d40c50e811f9585
parent75f861fe4701e82081566c76c949bada75169be7 (diff)
downloadqtlocation-mapboxgl-8a675af4246c63ca409c099ff3b4fb7e775ab116.tar.gz
[core] Fix offline region download freezing
Downloaded resources are put in the buffer and inserted in the database in batches. Before this change, the buffer was flushed only at the network response callback and thus it never got flushed if the last required resources were present locally and did not initiate network requests -> it caused freezing. Now the buffer is flushed every time the remaining resources container gets empty.
-rw-r--r--platform/default/include/mbgl/storage/offline_download.hpp1
-rw-r--r--platform/default/src/mbgl/storage/offline_download.cpp41
2 files changed, 26 insertions, 16 deletions
diff --git a/platform/default/include/mbgl/storage/offline_download.hpp b/platform/default/include/mbgl/storage/offline_download.hpp
index a001359b45..973fa826fa 100644
--- a/platform/default/include/mbgl/storage/offline_download.hpp
+++ b/platform/default/include/mbgl/storage/offline_download.hpp
@@ -40,6 +40,7 @@ private:
void activateDownload();
void continueDownload();
void deactivateDownload();
+ bool flushResourcesBuffer();
/*
* Ensure that the resource is stored in the database, requesting it if necessary.
diff --git a/platform/default/src/mbgl/storage/offline_download.cpp b/platform/default/src/mbgl/storage/offline_download.cpp
index 32fcb4f625..87927c5b98 100644
--- a/platform/default/src/mbgl/storage/offline_download.cpp
+++ b/platform/default/src/mbgl/storage/offline_download.cpp
@@ -360,10 +360,14 @@ void OfflineDownload::activateDownload() {
the first few errors is fruitless anyway.
*/
void OfflineDownload::continueDownload() {
- if (resourcesRemaining.empty() && status.complete()) {
- markPendingUsedResources();
- setState(OfflineRegionDownloadState::Inactive);
- return;
+ if (resourcesRemaining.empty()) {
+ // Flush pending buffers.
+ if (!flushResourcesBuffer()) return;
+ if (status.complete()) {
+ markPendingUsedResources();
+ setState(OfflineRegionDownloadState::Inactive);
+ return;
+ }
}
if (resourcesToBeMarkedAsUsed.size() >= kMarkBatchSize) markPendingUsedResources();
@@ -387,6 +391,19 @@ void OfflineDownload::deactivateDownload() {
buffer.clear();
}
+bool OfflineDownload::flushResourcesBuffer() {
+ if (buffer.empty()) return true;
+ try {
+ offlineDatabase.putRegionResources(id, buffer, status);
+ buffer.clear();
+ observer->statusChanged(status);
+ return true;
+ } catch (const MapboxTileLimitExceededException&) {
+ onMapboxTileCountLimitExceeded();
+ return false;
+ }
+}
+
void OfflineDownload::queueResource(Resource&& resource) {
resource.setPriority(Resource::Priority::Low);
resource.setUsage(Resource::Usage::Offline);
@@ -479,18 +496,10 @@ void OfflineDownload::ensureResource(Resource&& resource,
// Queue up for batched insertion
buffer.emplace_back(resource, onlineResponse);
- // Flush buffer periodically
- if (buffer.size() == kResourcesBatchSize || resourcesRemaining.empty()) {
- try {
- offlineDatabase.putRegionResources(id, buffer, status);
- } catch (const MapboxTileLimitExceededException&) {
- onMapboxTileCountLimitExceeded();
- return;
- }
-
- buffer.clear();
- observer->statusChanged(status);
- }
+ // Flush buffer periodically.
+ // Have to keep `resourcesRemaining.empty()` as the following condition would fail otherwise.
+ // TODO: Simplify the tile count limit check code path!
+ if ((buffer.size() == kResourcesBatchSize || resourcesRemaining.empty()) && !flushResourcesBuffer()) return;
if (offlineDatabase.exceedsOfflineMapboxTileCountLimit(resource)) {
onMapboxTileCountLimitExceeded();