move TS dns lookup into the worker thread

This commit is contained in:
Torsten Dreyer 2017-03-07 10:47:38 +01:00
parent 41059a24a7
commit a4cf38925b

View File

@ -201,6 +201,7 @@ struct TerrasyncThreadState
TerrasyncThreadState() : TerrasyncThreadState() :
_busy(false), _busy(false),
_stalled(false), _stalled(false),
_hasServer(false),
_fail_count(0), _fail_count(0),
_updated_tile_count(0), _updated_tile_count(0),
_success_count(0), _success_count(0),
@ -214,6 +215,7 @@ struct TerrasyncThreadState
bool _busy; bool _busy;
bool _stalled; bool _stalled;
bool _hasServer;
int _fail_count; int _fail_count;
int _updated_tile_count; int _updated_tile_count;
int _success_count; int _success_count;
@ -224,7 +226,6 @@ struct TerrasyncThreadState
// kbytes, not bytes, because bytes might overflow 2^31 // kbytes, not bytes, because bytes might overflow 2^31
int _total_kb_downloaded; int _total_kb_downloaded;
unsigned int _totalKbPending; unsigned int _totalKbPending;
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -257,6 +258,20 @@ public:
return _state._stalled; return _state._stalled;
} }
bool hasServer()
{
SGGuard<SGMutex> g(_stateLock);
return _state._hasServer;
}
bool hasServer( bool flag )
{
SGGuard<SGMutex> g(_stateLock);
return (_state._hasServer = flag);
}
bool findServer();
void request(const SyncItem& dir) {waitingTiles.push_front(dir);} void request(const SyncItem& dir) {waitingTiles.push_front(dir);}
bool hasNewTiles() bool hasNewTiles()
@ -269,6 +284,7 @@ public:
void setHTTPServer(const std::string& server) void setHTTPServer(const std::string& server)
{ {
_httpServer = stripPath(server); _httpServer = stripPath(server);
_isAutomaticServer = (server == "automatic");
} }
void setDNSDN( const std::string & dn ) void setDNSDN( const std::string & dn )
@ -348,6 +364,7 @@ private:
string _local_dir; string _local_dir;
SGPath _persistentCachePath; SGPath _persistentCachePath;
string _httpServer; string _httpServer;
bool _isAutomaticServer;
SGPath _installRoot; SGPath _installRoot;
string _sceneryVersion; string _sceneryVersion;
string _protocol; string _protocol;
@ -359,7 +376,8 @@ private:
SGTerraSync::WorkerThread::WorkerThread() : SGTerraSync::WorkerThread::WorkerThread() :
_stop(false), _stop(false),
_running(false) _running(false),
_isAutomaticServer(true)
{ {
_http.setUserAgent("terrascenery-" SG_STRINGIZE(SIMGEAR_VERSION)); _http.setUserAgent("terrascenery-" SG_STRINGIZE(SIMGEAR_VERSION));
} }
@ -422,14 +440,10 @@ bool SGTerraSync::WorkerThread::start()
_stop = false; _stop = false;
_state = TerrasyncThreadState(); // clean state _state = TerrasyncThreadState(); // clean state
string status = "Using built-in HTTP support.";
// not really an alert - but we want to (always) see this message, so user is // not really an alert - but we want to (always) see this message, so user is
// aware we're downloading scenery (and using bandwidth). // aware we're downloading scenery (and using bandwidth).
SG_LOG(SG_TERRASYNC,SG_ALERT, SG_LOG(SG_TERRASYNC,SG_ALERT,
"Starting automatic scenery download/synchronization. " "Starting automatic scenery download/synchronization to '"<< _local_dir << "'.");
<< status
<< "Directory: '" << _local_dir << "'.");
SGThread::start(); SGThread::start();
return true; return true;
@ -441,16 +455,9 @@ static inline string MakeQService(string & protocol, string & version )
return protocol + "+" + version; return protocol + "+" + version;
} }
void SGTerraSync::WorkerThread::run() bool SGTerraSync::WorkerThread::findServer()
{ {
{ if ( false == _isAutomaticServer ) return true;
SGGuard<SGMutex> g(_stateLock);
_running = true;
}
initCompletedTilesPersistentCache();
if (_httpServer == "automatic" ) {
DNS::NAPTRRequest * naptrRequest = new DNS::NAPTRRequest(_dnsdn); DNS::NAPTRRequest * naptrRequest = new DNS::NAPTRRequest(_dnsdn);
naptrRequest->qservice = MakeQService(_protocol, _sceneryVersion); naptrRequest->qservice = MakeQService(_protocol, _sceneryVersion);
@ -460,13 +467,15 @@ void SGTerraSync::WorkerThread::run()
DNS::Client dnsClient; DNS::Client dnsClient;
dnsClient.makeRequest(r); dnsClient.makeRequest(r);
SG_LOG(SG_TERRASYNC,SG_DEBUG,"DNS NAPTR query for '" << _dnsdn << "' '" << naptrRequest->qservice << "'" );
while( !r->isComplete() && !r->isTimeout() ) while( !r->isComplete() && !r->isTimeout() )
dnsClient.update(0); dnsClient.update(0);
if( naptrRequest->entries.empty() ) { if( naptrRequest->entries.empty() ) {
SG_LOG(SG_TERRASYNC, SG_ALERT, "ERROR: automatic terrasync http-server requested, but no DNS entry found."); SG_LOG(SG_TERRASYNC, SG_ALERT, "Warning: no DNS entry found for '" << _dnsdn << "' '" << naptrRequest->qservice << "'" );
_httpServer = ""; _httpServer = "";
} else { return false;
}
// walk through responses, they are ordered by 1. order and 2. preference // walk through responses, they are ordered by 1. order and 2. preference
// For now, only take entries with lowest order // For now, only take entries with lowest order
// TODO: try all available servers in the order given by preferenc and order // TODO: try all available servers in the order given by preferenc and order
@ -505,23 +514,24 @@ void SGTerraSync::WorkerThread::run()
_httpServer = _httpServer.substr( 6, _httpServer.length()-7 ); // strip search pattern and separators _httpServer = _httpServer.substr( 6, _httpServer.length()-7 ); // strip search pattern and separators
SG_LOG(SG_TERRASYNC,SG_INFO, "picking entry # " << idx << ", server is " << _httpServer ); SG_LOG(SG_TERRASYNC,SG_INFO, "picking entry # " << idx << ", server is " << _httpServer );
} return true;
} }
if (_httpServer.empty()) { void SGTerraSync::WorkerThread::run()
SG_LOG(SG_TERRASYNC, SG_ALERT, "ERROR: no http-server found, terrasync will be disabled"); {
{
SGGuard<SGMutex> g(_stateLock); SGGuard<SGMutex> g(_stateLock);
_running = false; _running = true;
return;
} }
initCompletedTilesPersistentCache();
runInternal(); runInternal();
{ {
SGGuard<SGMutex> g(_stateLock); SGGuard<SGMutex> g(_stateLock);
_running = false; _running = false;
} }
} }
void SGTerraSync::WorkerThread::updateSyncSlot(SyncSlot &slot) void SGTerraSync::WorkerThread::updateSyncSlot(SyncSlot &slot)
@ -607,7 +617,22 @@ void SGTerraSync::WorkerThread::updateSyncSlot(SyncSlot &slot)
void SGTerraSync::WorkerThread::runInternal() void SGTerraSync::WorkerThread::runInternal()
{ {
unsigned dnsRetryCount = 0;
while (!_stop) { while (!_stop) {
// try to find a terrasync server
if( !hasServer() ) {
if( ++dnsRetryCount > 5 ) {
SG_LOG(SG_TERRASYNC, SG_WARN, "Can't find a terrasync server. TS disabled.");
break;
}
if( hasServer( findServer() ) ) {
SG_LOG(SG_TERRASYNC, SG_INFO, "terrasync scenery provider of the day is '" << _httpServer << "'");
}
continue;
}
dnsRetryCount = 0;
try { try {
_http.update(10); _http.update(10);
} catch (sg_exception& e) { } catch (sg_exception& e) {
@ -861,7 +886,7 @@ void SGTerraSync::reinit()
if (_terraRoot->getBoolValue("enabled",false)) if (_terraRoot->getBoolValue("enabled",false))
{ {
_workerThread->setHTTPServer( _terraRoot->getStringValue("http-server","") ); _workerThread->setHTTPServer( _terraRoot->getStringValue("http-server","automatic") );
_workerThread->setSceneryVersion( _terraRoot->getStringValue("scenery-version","ws20") ); _workerThread->setSceneryVersion( _terraRoot->getStringValue("scenery-version","ws20") );
_workerThread->setProtocol( _terraRoot->getStringValue("protocol","") ); _workerThread->setProtocol( _terraRoot->getStringValue("protocol","") );
#if 1 #if 1