[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.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user