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 23:15:47 +0200
commit3c05bd984ada9e146e614165f009b9b45fb05992 (patch)
tree32d3b5de83688e1f903096edc7a2058f5c796f5d
parentba315b4bbb5520cab5424c98d824013d6ff046fe (diff)
downloadqtlocation-mapboxgl-3c05bd984ada9e146e614165f009b9b45fb05992.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();