Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[core] initialize OfflineDatabase asynchronously in DefaultFileSource
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kkaefer committed Aug 28, 2017
1 parent 6cbeeff commit c6ab20e
Showing 1 changed file with 18 additions and 13 deletions.
31 changes: 18 additions & 13 deletions platform/default/default_file_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,15 @@ namespace mbgl {

class DefaultFileSource::Impl {
public:
Impl(ActorRef<Impl>, std::shared_ptr<FileSource> assetFileSource_, const std::string& cachePath, uint64_t maximumCacheSize)
Impl(ActorRef<Impl> self, std::shared_ptr<FileSource> assetFileSource_, const std::string& cachePath, uint64_t maximumCacheSize)
: assetFileSource(assetFileSource_)
, localFileSource(std::make_unique<LocalFileSource>())
, offlineDatabase(cachePath, maximumCacheSize) {
, localFileSource(std::make_unique<LocalFileSource>()) {
// 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<OfflineDatabase>(cachePath, maximumCacheSize);
}

void setAPIBaseURL(const std::string& url) {
Expand All @@ -56,7 +61,7 @@ class DefaultFileSource::Impl {

void listRegions(std::function<void (std::exception_ptr, optional<std::vector<OfflineRegion>>)> callback) {
try {
callback({}, offlineDatabase.listRegions());
callback({}, offlineDatabase->listRegions());
} catch (...) {
callback(std::current_exception(), {});
}
Expand All @@ -66,7 +71,7 @@ class DefaultFileSource::Impl {
const OfflineRegionMetadata& metadata,
std::function<void (std::exception_ptr, optional<OfflineRegion>)> callback) {
try {
callback({}, offlineDatabase.createRegion(definition, metadata));
callback({}, offlineDatabase->createRegion(definition, metadata));
} catch (...) {
callback(std::current_exception(), {});
}
Expand All @@ -76,7 +81,7 @@ class DefaultFileSource::Impl {
const OfflineRegionMetadata& metadata,
std::function<void (std::exception_ptr, optional<OfflineRegionMetadata>)> callback) {
try {
callback({}, offlineDatabase.updateMetadata(regionID, metadata));
callback({}, offlineDatabase->updateMetadata(regionID, metadata));
} catch (...) {
callback(std::current_exception(), {});
}
Expand All @@ -93,7 +98,7 @@ class DefaultFileSource::Impl {
void deleteRegion(OfflineRegion&& region, std::function<void (std::exception_ptr)> callback) {
try {
downloads.erase(region.getID());
offlineDatabase.deleteRegion(std::move(region));
offlineDatabase->deleteRegion(std::move(region));
callback({});
} catch (...) {
callback(std::current_exception());
Expand Down Expand Up @@ -125,7 +130,7 @@ class DefaultFileSource::Impl {

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
Expand Down Expand Up @@ -157,7 +162,7 @@ class DefaultFileSource::Impl {
// 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);
});
}
Expand All @@ -169,11 +174,11 @@ class DefaultFileSource::Impl {
}

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:
Expand All @@ -183,13 +188,13 @@ class DefaultFileSource::Impl {
return *it->second;
}
return *downloads.emplace(regionID,
std::make_unique<OfflineDownload>(regionID, offlineDatabase.getRegionDefinition(regionID), offlineDatabase, onlineFileSource)).first->second;
std::make_unique<OfflineDownload>(regionID, offlineDatabase->getRegionDefinition(regionID), *offlineDatabase, onlineFileSource)).first->second;
}

// shared so that destruction is done on the creating thread
const std::shared_ptr<FileSource> assetFileSource;
const std::unique_ptr<FileSource> localFileSource;
OfflineDatabase offlineDatabase;
std::unique_ptr<OfflineDatabase> offlineDatabase;
OnlineFileSource onlineFileSource;
std::unordered_map<AsyncRequest*, std::unique_ptr<AsyncRequest>> tasks;
std::unordered_map<int64_t, std::unique_ptr<OfflineDownload>> downloads;
Expand Down

0 comments on commit c6ab20e

Please sign in to comment.