From 7e9f79d3e115642e61b254677bcda5797a672875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Fri, 25 Aug 2017 17:55:32 +0200 Subject: [core] initialize OfflineDatabase asynchronously in DefaultFileSource Sometimes, initialization can take hundreds of milliseconds, in particular when the database doesn't exist yet, or when the app/device is doing a lot of I/O already. Instead of synchronously initializing the OfflineDatabase objects, we're now asynchronously initializing the object through a self-sent message that by virtue of being the first message for this actor guarantees that the object is there when it's needed by other member functions. --- platform/default/default_file_source.cpp | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/platform/default/default_file_source.cpp b/platform/default/default_file_source.cpp index 9c8a38a308..b9d35ae4ed 100644 --- a/platform/default/default_file_source.cpp +++ b/platform/default/default_file_source.cpp @@ -28,10 +28,15 @@ namespace mbgl { class DefaultFileSource::Impl { public: - Impl(ActorRef, std::shared_ptr assetFileSource_, const std::string& cachePath, uint64_t maximumCacheSize) + Impl(ActorRef self, std::shared_ptr assetFileSource_, const std::string& cachePath, uint64_t maximumCacheSize) : assetFileSource(assetFileSource_) - , localFileSource(std::make_unique()) - , offlineDatabase(cachePath, maximumCacheSize) { + , localFileSource(std::make_unique()) { + // Initialize the Database asynchronously so as to not block Actor creation. + self.invoke(&Impl::initializeOfflineDatabase, cachePath, maximumCacheSize); + } + + void initializeOfflineDatabase(std::string cachePath, uint64_t maximumCacheSize) { + offlineDatabase = std::make_unique(cachePath, maximumCacheSize); } void setAPIBaseURL(const std::string& url) { @@ -56,7 +61,7 @@ public: void listRegions(std::function>)> callback) { try { - callback({}, offlineDatabase.listRegions()); + callback({}, offlineDatabase->listRegions()); } catch (...) { callback(std::current_exception(), {}); } @@ -66,7 +71,7 @@ public: const OfflineRegionMetadata& metadata, std::function)> callback) { try { - callback({}, offlineDatabase.createRegion(definition, metadata)); + callback({}, offlineDatabase->createRegion(definition, metadata)); } catch (...) { callback(std::current_exception(), {}); } @@ -76,7 +81,7 @@ public: const OfflineRegionMetadata& metadata, std::function)> callback) { try { - callback({}, offlineDatabase.updateMetadata(regionID, metadata)); + callback({}, offlineDatabase->updateMetadata(regionID, metadata)); } catch (...) { callback(std::current_exception(), {}); } @@ -93,7 +98,7 @@ public: void deleteRegion(OfflineRegion&& region, std::function callback) { try { downloads.erase(region.getID()); - offlineDatabase.deleteRegion(std::move(region)); + offlineDatabase->deleteRegion(std::move(region)); callback({}); } catch (...) { callback(std::current_exception()); @@ -125,7 +130,7 @@ public: const bool hasPrior = resource.priorEtag || resource.priorModified || resource.priorExpires; if (!hasPrior || resource.necessity == Resource::Optional) { - auto offlineResponse = offlineDatabase.get(resource); + auto offlineResponse = offlineDatabase->get(resource); if (resource.necessity == Resource::Optional && !offlineResponse) { // Ensure there's always a response that we can send, so the caller knows that @@ -157,7 +162,7 @@ public: // Get from the online file source if (resource.necessity == Resource::Required) { tasks[req] = onlineFileSource.request(revalidation, [=] (Response onlineResponse) mutable { - this->offlineDatabase.put(revalidation, onlineResponse); + this->offlineDatabase->put(revalidation, onlineResponse); callback(onlineResponse); }); } @@ -169,11 +174,11 @@ public: } void setOfflineMapboxTileCountLimit(uint64_t limit) { - offlineDatabase.setOfflineMapboxTileCountLimit(limit); + offlineDatabase->setOfflineMapboxTileCountLimit(limit); } void put(const Resource& resource, const Response& response) { - offlineDatabase.put(resource, response); + offlineDatabase->put(resource, response); } private: @@ -183,13 +188,13 @@ private: return *it->second; } return *downloads.emplace(regionID, - std::make_unique(regionID, offlineDatabase.getRegionDefinition(regionID), offlineDatabase, onlineFileSource)).first->second; + std::make_unique(regionID, offlineDatabase->getRegionDefinition(regionID), *offlineDatabase, onlineFileSource)).first->second; } // shared so that destruction is done on the creating thread const std::shared_ptr assetFileSource; const std::unique_ptr localFileSource; - OfflineDatabase offlineDatabase; + std::unique_ptr offlineDatabase; OnlineFileSource onlineFileSource; std::unordered_map> tasks; std::unordered_map> downloads; -- cgit v1.2.1