From 9be955262edbedca91cb95f90d921dd24ef217b2 Mon Sep 17 00:00:00 2001 From: Automatic Release Builder Date: Thu, 1 Oct 2020 10:00:22 +0100 Subject: [PATCH] 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) --- simgear/scene/tsync/terrasync.cxx | 82 ++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/simgear/scene/tsync/terrasync.cxx b/simgear/scene/tsync/terrasync.cxx index 28b56839..e37c0067 100644 --- a/simgear/scene/tsync/terrasync.cxx +++ b/simgear/scene/tsync/terrasync.cxx @@ -319,7 +319,9 @@ public: bool isDirActive(const std::string& path) const; -private: + void setCachePath(const SGPath &p) { _persistentCachePath = p; } + + private: void incrementCacheHits() { std::lock_guard g(_stateLock); @@ -341,6 +343,9 @@ private: void fail(SyncItem failedItem); void notFound(SyncItem notFoundItem); + void initCompletedTilesPersistentCache(); + void writeCompletedTilesPersistentCache() const; + HTTP::Client _http; SyncSlot _syncSlots[NUM_SYNC_SLOTS]; @@ -530,6 +535,7 @@ void SGTerraSync::WorkerThread::run() _running = true; } + initCompletedTilesPersistentCache(); runInternal(); { @@ -730,6 +736,7 @@ void SGTerraSync::WorkerThread::notFound(SyncItem item) item._status = SyncItem::NotFound; _freshTiles.push_back(item); _notFoundItems[ item._dir ] = now + UpdateInterval::SuccessfulAttempt; + writeCompletedTilesPersistentCache(); } void SGTerraSync::WorkerThread::updated(SyncItem item, bool isNewDirectory) @@ -750,6 +757,8 @@ void SGTerraSync::WorkerThread::updated(SyncItem item, bool isNewDirectory) _freshTiles.push_back(item); _completedTiles[ item._dir ] = now + UpdateInterval::SuccessfulAttempt; } + + writeCompletedTilesPersistentCache(); } void SGTerraSync::WorkerThread::drainWaitingTiles() @@ -803,6 +812,68 @@ bool SGTerraSync::WorkerThread::isDirActive(const std::string& path) const 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 //////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// @@ -882,10 +953,17 @@ void SGTerraSync::reinit() #else _workerThread->setDNSDN( _terraRoot->getStringValue("dnsdn","terrasync.flightgear.org") ); #endif - _workerThread->setLocalDir(_terraRoot->getStringValue("scenery-dir","")); + + SGPath sceneryRoot{_terraRoot->getStringValue("scenery-dir", "")}; + _workerThread->setLocalDir(sceneryRoot.utf8Str()); SGPath installPath(_terraRoot->getStringValue("installation-dir")); _workerThread->setInstalledDir(installPath); + + if (_terraRoot->getBoolValue("enable-persistent-cache", true)) { + _workerThread->setCachePath(sceneryRoot / "RecheckCache"); + } + _workerThread->setCacheHits(_terraRoot->getIntValue("cache-hit", 0)); if (_workerThread->start())