TerraSync: allow an explicit osm2city server

Fixes an error case where a manual TerraSync server is specified; we
would attempt to use an empty string as the OSM2City server, with
hilarious consequences.

Sentry-Id: FLIGHTGEAR-NCZ
This commit is contained in:
James Turner 2021-03-12 12:47:51 +00:00
parent a9615869e3
commit 4a1809b566

View File

@ -310,9 +310,10 @@ public:
SyncItem getNewTile() { return _freshTiles.pop_front();} SyncItem getNewTile() { return _freshTiles.pop_front();}
void setHTTPServer(const std::string& server) void setHTTPServer(const std::string& server, const std::string& osmServer)
{ {
_httpServer = stripPath(server); _httpServer = stripPath(server);
_osmCityServer = stripPath(osmServer);
_isAutomaticServer = (server == "automatic"); _isAutomaticServer = (server == "automatic");
} }
@ -376,9 +377,9 @@ public:
void runInternal(); void runInternal();
void updateSyncSlot(SyncSlot& slot); void updateSyncSlot(SyncSlot& slot);
void beginSyncAirports(SyncSlot& slot); bool beginSyncAirports(SyncSlot& slot);
void beginSyncTile(SyncSlot& slot); bool beginSyncTile(SyncSlot& slot);
void beginNormalSync(SyncSlot& slot); bool beginNormalSync(SyncSlot& slot);
void drainWaitingTiles(); void drainWaitingTiles();
@ -631,6 +632,9 @@ void SGTerraSync::WorkerThread::updateSyncSlot(SyncSlot &slot)
HTTPRepository::ResultCode res = slot.repository->failure(); HTTPRepository::ResultCode res = slot.repository->failure();
if (res == HTTPRepository::REPO_ERROR_NOT_FOUND) { if (res == HTTPRepository::REPO_ERROR_NOT_FOUND) {
// not founds should never happen any more (unless the server-
// side data is incorrect), since we now check top-down that
// a 1x1 dir exists or not.
notFound(slot.currentItem); notFound(slot.currentItem);
} else if (res != HTTPRepository::REPO_NO_ERROR) { } else if (res != HTTPRepository::REPO_NO_ERROR) {
fail(slot.currentItem); fail(slot.currentItem);
@ -667,12 +671,23 @@ void SGTerraSync::WorkerThread::updateSyncSlot(SyncSlot &slot)
slot.isNewDirectory = !path.exists(); slot.isNewDirectory = !path.exists();
const auto type = slot.currentItem._type; const auto type = slot.currentItem._type;
bool ok = false;
if (type == SyncItem::AirportData) { if (type == SyncItem::AirportData) {
beginSyncAirports(slot); ok = beginSyncAirports(slot);
} else if ((type == SyncItem::Tile) || (type == SyncItem::OSMTile)) { } else if (type == SyncItem::OSMTile) {
beginSyncTile(slot); ok = beginSyncTile(slot);
} else if (type == SyncItem::Tile) {
ok = beginSyncTile(slot);
} else { } else {
beginNormalSync(slot); ok = beginNormalSync(slot);
}
if (!ok) {
SG_LOG(SG_TERRASYNC, SG_INFO, "sync of " << slot.currentItem._dir << " failed to start");
fail(slot.currentItem);
slot.busy = false;
slot.repository.reset();
return;
} }
try { try {
@ -692,15 +707,14 @@ void SGTerraSync::WorkerThread::updateSyncSlot(SyncSlot &slot)
slot.pendingKBytes = slot.repository->bytesToDownload() >> 10; slot.pendingKBytes = slot.repository->bytesToDownload() >> 10;
slot.pendingExtractKBytes = slot.repository->bytesToExtract() >> 10; slot.pendingExtractKBytes = slot.repository->bytesToExtract() >> 10;
SG_LOG(SG_TERRASYNC, SG_INFO, "sync of " << slot.repository->baseUrl() << " started, queue size is " << slot.queue.size()); SG_LOG(SG_TERRASYNC, SG_INFO, "sync of " << slot.repository->baseUrl() << ":" << slot.currentItem._dir << " started, queue size is " << slot.queue.size());
} }
} }
void SGTerraSync::WorkerThread::beginSyncAirports(SyncSlot& slot) bool SGTerraSync::WorkerThread::beginSyncAirports(SyncSlot& slot)
{ {
if (!slot.isNewDirectory) { if (!slot.isNewDirectory) {
beginNormalSync(slot); return beginNormalSync(slot);
return;
} }
SG_LOG(SG_TERRASYNC, SG_INFO, "doing Airports download via tarball"); SG_LOG(SG_TERRASYNC, SG_INFO, "doing Airports download via tarball");
@ -720,9 +734,10 @@ void SGTerraSync::WorkerThread::beginSyncAirports(SyncSlot& slot)
}; };
slot.repository->setFilter(f); slot.repository->setFilter(f);
return true;
} }
void SGTerraSync::WorkerThread::beginSyncTile(SyncSlot& slot) bool SGTerraSync::WorkerThread::beginSyncTile(SyncSlot& slot)
{ {
// avoid 404 requests by doing a sync which excludes all paths // avoid 404 requests by doing a sync which excludes all paths
// except our tile path. In the case of a missing 1x1 tile, we will // except our tile path. In the case of a missing 1x1 tile, we will
@ -731,8 +746,7 @@ void SGTerraSync::WorkerThread::beginSyncTile(SyncSlot& slot)
auto comps = strutils::split(slot.currentItem._dir, "/"); auto comps = strutils::split(slot.currentItem._dir, "/");
if (comps.size() != 3) { if (comps.size() != 3) {
SG_LOG(SG_TERRASYNC, SG_ALERT, "Bad tile path:" << slot.currentItem._dir); SG_LOG(SG_TERRASYNC, SG_ALERT, "Bad tile path:" << slot.currentItem._dir);
beginNormalSync(slot); return false;
return;
} }
const auto tileCategory = comps.front(); const auto tileCategory = comps.front();
@ -743,6 +757,11 @@ void SGTerraSync::WorkerThread::beginSyncTile(SyncSlot& slot)
slot.repository.reset(new HTTPRepository(path, &_http)); slot.repository.reset(new HTTPRepository(path, &_http));
if (slot.currentItem._type == SyncItem::OSMTile) { if (slot.currentItem._type == SyncItem::OSMTile) {
if (_osmCityServer.empty()) {
SG_LOG(SG_TERRASYNC, SG_WARN, "No OSM2City server defined for:" << slot.currentItem._dir);
return false;
}
slot.repository->setBaseUrl(_osmCityServer + "/" + tileCategory); slot.repository->setBaseUrl(_osmCityServer + "/" + tileCategory);
} else { } else {
slot.repository->setBaseUrl(_httpServer + "/" + tileCategory); slot.repository->setBaseUrl(_httpServer + "/" + tileCategory);
@ -779,9 +798,10 @@ void SGTerraSync::WorkerThread::beginSyncTile(SyncSlot& slot)
}; };
slot.repository->setFilter(f); slot.repository->setFilter(f);
return true;
} }
void SGTerraSync::WorkerThread::beginNormalSync(SyncSlot& slot) bool SGTerraSync::WorkerThread::beginNormalSync(SyncSlot& slot)
{ {
SGPath path(_local_dir); SGPath path(_local_dir);
path.append(slot.currentItem._dir); path.append(slot.currentItem._dir);
@ -793,6 +813,8 @@ void SGTerraSync::WorkerThread::beginNormalSync(SyncSlot& slot)
p.append(slot.currentItem._dir); p.append(slot.currentItem._dir);
slot.repository->setInstalledCopyPath(p); slot.repository->setInstalledCopyPath(p);
} }
return true;
} }
void SGTerraSync::WorkerThread::runInternal() void SGTerraSync::WorkerThread::runInternal()
@ -893,12 +915,19 @@ void SGTerraSync::WorkerThread::fail(SyncItem failedItem)
{ {
std::lock_guard<std::mutex> g(_stateLock); std::lock_guard<std::mutex> g(_stateLock);
time_t now = time(0); time_t now = time(0);
_state._consecutive_errors++;
_state._fail_count++; if (_osmCityServer.empty() && (failedItem._type == SyncItem::OSMTile)) {
// don't count these as errors, otherwise normla sync will keep
// being abandoned
} else {
_state._consecutive_errors++;
_state._fail_count++;
}
failedItem._status = SyncItem::Failed; failedItem._status = SyncItem::Failed;
_freshTiles.push_back(failedItem); _freshTiles.push_back(failedItem);
// not we also end up here for partial syncs // not we also end up here for partial syncs
SG_LOG(SG_TERRASYNC,SG_ALERT, SG_LOG(SG_TERRASYNC, SG_WARN,
"Failed to sync'" << failedItem._dir << "'"); "Failed to sync'" << failedItem._dir << "'");
_completedTiles[ failedItem._dir ] = now + UpdateInterval::FailedAttempt; _completedTiles[ failedItem._dir ] = now + UpdateInterval::FailedAttempt;
} }
@ -910,6 +939,8 @@ void SGTerraSync::WorkerThread::notFound(SyncItem item)
// we don't spam the server with lookups for models that don't // we don't spam the server with lookups for models that don't
// exist // exist
SG_LOG(SG_TERRASYNC, SG_WARN, "Not found for: '" << item._dir << "'");
time_t now = time(0); time_t now = time(0);
item._status = SyncItem::NotFound; item._status = SyncItem::NotFound;
_freshTiles.push_back(item); _freshTiles.push_back(item);
@ -1135,7 +1166,9 @@ void SGTerraSync::reinit()
if (enabled) if (enabled)
{ {
_availableNode->setBoolValue(true); _availableNode->setBoolValue(true);
_workerThread->setHTTPServer( _terraRoot->getStringValue("http-server","automatic") ); _workerThread->setHTTPServer(
_terraRoot->getStringValue("http-server", "automatic"),
_terraRoot->getStringValue("osm2city-server", ""));
_workerThread->setSceneryVersion( _terraRoot->getStringValue("scenery-version","ws20") ); _workerThread->setSceneryVersion( _terraRoot->getStringValue("scenery-version","ws20") );
_workerThread->setOSMCityVersion(_terraRoot->getStringValue("osm2city-version", "o2c")); _workerThread->setOSMCityVersion(_terraRoot->getStringValue("osm2city-version", "o2c"));
_workerThread->setProtocol( _terraRoot->getStringValue("protocol","") ); _workerThread->setProtocol( _terraRoot->getStringValue("protocol","") );
@ -1325,7 +1358,6 @@ void SGTerraSync::syncAreaByPath(const std::string& aPath)
if (_workerThread->isDirActive(dir)) { if (_workerThread->isDirActive(dir)) {
continue; continue;
} }
SyncItem w(dir, isOSMSuffix(suffix) ? SyncItem::OSMTile : SyncItem::Tile); SyncItem w(dir, isOSMSuffix(suffix) ? SyncItem::OSMTile : SyncItem::Tile);
_workerThread->request( w ); _workerThread->request( w );
} }