Terrasync: re-add persistent update cache

Re-add (with some tweaks) the persistent tile-cache code, so that
TerraSync checks the server at most once per 24 hour period, for a
given repository path.

(Disbale the cache by setting /sim/terrasync/enable-persistent-cache=0)
This commit is contained in:
Automatic Release Builder 2020-10-01 10:00:22 +01:00 committed by James Turner
parent 6d892e8d18
commit ed357c5c8f

View File

@ -318,7 +318,9 @@ public:
bool isDirActive(const std::string& path) const; bool isDirActive(const std::string& path) const;
private: void setCachePath(const SGPath &p) { _persistentCachePath = p; }
private:
void incrementCacheHits() void incrementCacheHits()
{ {
std::lock_guard<std::mutex> g(_stateLock); std::lock_guard<std::mutex> g(_stateLock);
@ -340,6 +342,9 @@ private:
void fail(SyncItem failedItem); void fail(SyncItem failedItem);
void notFound(SyncItem notFoundItem); void notFound(SyncItem notFoundItem);
void initCompletedTilesPersistentCache();
void writeCompletedTilesPersistentCache() const;
HTTP::Client _http; HTTP::Client _http;
SyncSlot _syncSlots[NUM_SYNC_SLOTS]; SyncSlot _syncSlots[NUM_SYNC_SLOTS];
@ -529,6 +534,7 @@ void SGTerraSync::WorkerThread::run()
_running = true; _running = true;
} }
initCompletedTilesPersistentCache();
runInternal(); runInternal();
{ {
@ -729,6 +735,7 @@ void SGTerraSync::WorkerThread::notFound(SyncItem item)
item._status = SyncItem::NotFound; item._status = SyncItem::NotFound;
_freshTiles.push_back(item); _freshTiles.push_back(item);
_notFoundItems[ item._dir ] = now + UpdateInterval::SuccessfulAttempt; _notFoundItems[ item._dir ] = now + UpdateInterval::SuccessfulAttempt;
writeCompletedTilesPersistentCache();
} }
void SGTerraSync::WorkerThread::updated(SyncItem item, bool isNewDirectory) void SGTerraSync::WorkerThread::updated(SyncItem item, bool isNewDirectory)
@ -749,6 +756,8 @@ void SGTerraSync::WorkerThread::updated(SyncItem item, bool isNewDirectory)
_freshTiles.push_back(item); _freshTiles.push_back(item);
_completedTiles[ item._dir ] = now + UpdateInterval::SuccessfulAttempt; _completedTiles[ item._dir ] = now + UpdateInterval::SuccessfulAttempt;
} }
writeCompletedTilesPersistentCache();
} }
void SGTerraSync::WorkerThread::drainWaitingTiles() void SGTerraSync::WorkerThread::drainWaitingTiles()
@ -802,6 +811,68 @@ bool SGTerraSync::WorkerThread::isDirActive(const std::string& path) const
return false; return false;
} }
void SGTerraSync::WorkerThread::initCompletedTilesPersistentCache() {
if (!_persistentCachePath.exists()) {
return;
}
SGPropertyNode_ptr cacheRoot(new SGPropertyNode);
time_t now = time(0);
try {
readProperties(_persistentCachePath, cacheRoot);
} catch (sg_exception &e) {
SG_LOG(SG_TERRASYNC, SG_INFO, "corrupted persistent cache, discarding");
return;
}
for (int i = 0; i < cacheRoot->nChildren(); ++i) {
SGPropertyNode *entry = cacheRoot->getChild(i);
bool isNotFound = (strcmp(entry->getName(), "not-found") == 0);
string tileName = entry->getStringValue("path");
time_t stamp = entry->getIntValue("stamp");
if (stamp < now) {
continue;
}
if (isNotFound) {
_notFoundItems[tileName] = stamp;
} else {
_completedTiles[tileName] = stamp;
}
}
}
void SGTerraSync::WorkerThread::writeCompletedTilesPersistentCache() const {
// cache is disabled
if (_persistentCachePath.isNull()) {
return;
}
sg_ofstream f(_persistentCachePath, std::ios::trunc);
if (!f.is_open()) {
return;
}
SGPropertyNode_ptr cacheRoot(new SGPropertyNode);
TileAgeCache::const_iterator it = _completedTiles.begin();
for (; it != _completedTiles.end(); ++it) {
SGPropertyNode *entry = cacheRoot->addChild("entry");
entry->setStringValue("path", it->first);
entry->setIntValue("stamp", it->second);
}
it = _notFoundItems.begin();
for (; it != _notFoundItems.end(); ++it) {
SGPropertyNode *entry = cacheRoot->addChild("not-found");
entry->setStringValue("path", it->first);
entry->setIntValue("stamp", it->second);
}
writeProperties(f, cacheRoot, true /* write_all */);
f.close();
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// SGTerraSync //////////////////////////////////////////////////////////////// // SGTerraSync ////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -881,10 +952,17 @@ void SGTerraSync::reinit()
#else #else
_workerThread->setDNSDN( _terraRoot->getStringValue("dnsdn","terrasync.flightgear.org") ); _workerThread->setDNSDN( _terraRoot->getStringValue("dnsdn","terrasync.flightgear.org") );
#endif #endif
_workerThread->setLocalDir(_terraRoot->getStringValue("scenery-dir",""));
SGPath sceneryRoot{_terraRoot->getStringValue("scenery-dir", "")};
_workerThread->setLocalDir(sceneryRoot.utf8Str());
SGPath installPath(_terraRoot->getStringValue("installation-dir")); SGPath installPath(_terraRoot->getStringValue("installation-dir"));
_workerThread->setInstalledDir(installPath); _workerThread->setInstalledDir(installPath);
if (_terraRoot->getBoolValue("enable-persistent-cache", true)) {
_workerThread->setCachePath(sceneryRoot / "RecheckCache");
}
_workerThread->setCacheHits(_terraRoot->getIntValue("cache-hit", 0)); _workerThread->setCacheHits(_terraRoot->getIntValue("cache-hit", 0));
if (_workerThread->start()) if (_workerThread->start())