Remove old terraysnc backend methods.
Only in-process HTTP access is supported now, SVN and rsync and removed. This is to allow changes for better use of the HTTP API.
This commit is contained in:
parent
2b15b6b8ad
commit
9d2df12ab8
@ -59,23 +59,14 @@
|
|||||||
#include <simgear/debug/BufferedLogCallback.hxx>
|
#include <simgear/debug/BufferedLogCallback.hxx>
|
||||||
#include <simgear/props/props_io.hxx>
|
#include <simgear/props/props_io.hxx>
|
||||||
#include <simgear/io/HTTPClient.hxx>
|
#include <simgear/io/HTTPClient.hxx>
|
||||||
#include <simgear/io/SVNRepository.hxx>
|
|
||||||
#include <simgear/io/HTTPRepository.hxx>
|
#include <simgear/io/HTTPRepository.hxx>
|
||||||
#include <simgear/io/DNSClient.hxx>
|
#include <simgear/io/DNSClient.hxx>
|
||||||
#include <simgear/structure/exception.hxx>
|
#include <simgear/structure/exception.hxx>
|
||||||
#include <simgear/math/sg_random.h>
|
#include <simgear/math/sg_random.h>
|
||||||
|
|
||||||
static const bool svn_built_in_available = true;
|
|
||||||
|
|
||||||
using namespace simgear;
|
using namespace simgear;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
const char* rsync_cmd =
|
|
||||||
"rsync --verbose --archive --delete --perms --owner --group";
|
|
||||||
|
|
||||||
const char* svn_options =
|
|
||||||
"checkout -q";
|
|
||||||
|
|
||||||
namespace UpdateInterval
|
namespace UpdateInterval
|
||||||
{
|
{
|
||||||
// interval in seconds to allow an update to repeat after a successful update (=daily)
|
// interval in seconds to allow an update to repeat after a successful update (=daily)
|
||||||
@ -89,6 +80,7 @@ typedef map<string,time_t> TileAgeCache;
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// helper functions ///////////////////////////////////////////////////////////
|
// helper functions ///////////////////////////////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
string stripPath(string path)
|
string stripPath(string path)
|
||||||
{
|
{
|
||||||
// svn doesn't like trailing white-spaces or path separators - strip them!
|
// svn doesn't like trailing white-spaces or path separators - strip them!
|
||||||
@ -199,52 +191,15 @@ static unsigned int syncSlotForType(SyncItem::Type ty)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Base server query
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class ServerSelectQuery : public HTTP::Request
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// SGTerraSync::WorkerThread //////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
class SGTerraSync::WorkerThread : public SGThread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ServerSelectQuery() :
|
WorkerThread();
|
||||||
HTTP::Request("http://scenery.flightgear.org/svn-server", "GET")
|
virtual ~WorkerThread( ) { stop(); }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string svnUrl() const
|
|
||||||
{
|
|
||||||
std::string s = simgear::strutils::strip(m_url);
|
|
||||||
if (s.at(s.length() - 1) == '/') {
|
|
||||||
s = s.substr(0, s.length() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
protected:
|
|
||||||
virtual void gotBodyData(const char* s, int n)
|
|
||||||
{
|
|
||||||
m_url.append(std::string(s, n));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void onFail()
|
|
||||||
{
|
|
||||||
SG_LOG(SG_TERRASYNC, SG_ALERT, "Failed to query TerraSync SVN server");
|
|
||||||
HTTP::Request::onFail();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_url;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// SGTerraSync::SvnThread /////////////////////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
class SGTerraSync::SvnThread : public SGThread
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SvnThread();
|
|
||||||
virtual ~SvnThread( ) { stop(); }
|
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
bool start();
|
bool start();
|
||||||
@ -255,23 +210,17 @@ public:
|
|||||||
bool hasNewTiles() { return !_freshTiles.empty();}
|
bool hasNewTiles() { return !_freshTiles.empty();}
|
||||||
SyncItem getNewTile() { return _freshTiles.pop_front();}
|
SyncItem getNewTile() { return _freshTiles.pop_front();}
|
||||||
|
|
||||||
void setSvnServer(string server) { _svn_server = stripPath(server);}
|
|
||||||
void setSvnDataServer(string server) { _svn_data_server = stripPath(server);}
|
|
||||||
void setHTTPServer(const std::string& server)
|
void setHTTPServer(const std::string& server)
|
||||||
{
|
{
|
||||||
_httpServer = stripPath(server);
|
_httpServer = stripPath(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setExtSvnUtility(string svn_util) { _svn_command = simgear::strutils::strip(svn_util);}
|
|
||||||
void setRsyncServer(string server) { _rsync_server = simgear::strutils::strip(server);}
|
|
||||||
void setLocalDir(string dir) { _local_dir = stripPath(dir);}
|
void setLocalDir(string dir) { _local_dir = stripPath(dir);}
|
||||||
string getLocalDir() { return _local_dir;}
|
string getLocalDir() { return _local_dir;}
|
||||||
void setUseSvn(bool use_svn) { _use_svn = use_svn;}
|
|
||||||
void setAllowedErrorCount(int errors) {_allowed_errors = errors;}
|
void setAllowedErrorCount(int errors) {_allowed_errors = errors;}
|
||||||
|
|
||||||
void setCachePath(const SGPath& p) {_persistentCachePath = p;}
|
void setCachePath(const SGPath& p) {_persistentCachePath = p;}
|
||||||
void setCacheHits(unsigned int hits) {_cache_hits = hits;}
|
void setCacheHits(unsigned int hits) {_cache_hits = hits;}
|
||||||
void setUseBuiltin(bool built_in) { _use_built_in = built_in;}
|
|
||||||
|
|
||||||
volatile bool _active;
|
volatile bool _active;
|
||||||
volatile bool _running;
|
volatile bool _running;
|
||||||
@ -290,11 +239,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
virtual void run();
|
virtual void run();
|
||||||
|
|
||||||
// external model run and helpers
|
|
||||||
void runExternal();
|
|
||||||
void syncPathExternal(const SyncItem& next);
|
|
||||||
bool runExternalSyncCommand(const char* dir);
|
|
||||||
|
|
||||||
// internal mode run and helpers
|
// internal mode run and helpers
|
||||||
void runInternal();
|
void runInternal();
|
||||||
void updateSyncSlot(SyncSlot& slot);
|
void updateSyncSlot(SyncSlot& slot);
|
||||||
@ -308,7 +252,6 @@ private:
|
|||||||
void fail(SyncItem failedItem);
|
void fail(SyncItem failedItem);
|
||||||
void notFound(SyncItem notFoundItem);
|
void notFound(SyncItem notFoundItem);
|
||||||
|
|
||||||
bool _use_built_in;
|
|
||||||
HTTP::Client _http;
|
HTTP::Client _http;
|
||||||
SyncSlot _syncSlots[NUM_SYNC_SLOTS];
|
SyncSlot _syncSlots[NUM_SYNC_SLOTS];
|
||||||
|
|
||||||
@ -320,17 +263,12 @@ private:
|
|||||||
TileAgeCache _notFoundItems;
|
TileAgeCache _notFoundItems;
|
||||||
|
|
||||||
SGBlockingDeque <SyncItem> _freshTiles;
|
SGBlockingDeque <SyncItem> _freshTiles;
|
||||||
bool _use_svn;
|
|
||||||
string _svn_server;
|
|
||||||
string _svn_data_server;
|
|
||||||
string _svn_command;
|
|
||||||
string _rsync_server;
|
|
||||||
string _local_dir;
|
string _local_dir;
|
||||||
SGPath _persistentCachePath;
|
SGPath _persistentCachePath;
|
||||||
string _httpServer;
|
string _httpServer;
|
||||||
};
|
};
|
||||||
|
|
||||||
SGTerraSync::SvnThread::SvnThread() :
|
SGTerraSync::WorkerThread::WorkerThread() :
|
||||||
_active(false),
|
_active(false),
|
||||||
_running(false),
|
_running(false),
|
||||||
_busy(false),
|
_busy(false),
|
||||||
@ -343,15 +281,13 @@ SGTerraSync::SvnThread::SvnThread() :
|
|||||||
_cache_hits(0),
|
_cache_hits(0),
|
||||||
_transfer_rate(0),
|
_transfer_rate(0),
|
||||||
_total_kb_downloaded(0),
|
_total_kb_downloaded(0),
|
||||||
_use_built_in(true),
|
|
||||||
_is_dirty(false),
|
_is_dirty(false),
|
||||||
_stop(false),
|
_stop(false)
|
||||||
_use_svn(true)
|
|
||||||
{
|
{
|
||||||
_http.setUserAgent("terrascenery-" SG_STRINGIZE(SIMGEAR_VERSION));
|
_http.setUserAgent("terrascenery-" SG_STRINGIZE(SIMGEAR_VERSION));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SGTerraSync::SvnThread::stop()
|
void SGTerraSync::WorkerThread::stop()
|
||||||
{
|
{
|
||||||
// drop any pending requests
|
// drop any pending requests
|
||||||
waitingTiles.clear();
|
waitingTiles.clear();
|
||||||
@ -367,7 +303,7 @@ void SGTerraSync::SvnThread::stop()
|
|||||||
_running = false;
|
_running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SGTerraSync::SvnThread::start()
|
bool SGTerraSync::WorkerThread::start()
|
||||||
{
|
{
|
||||||
if (_running)
|
if (_running)
|
||||||
return false;
|
return false;
|
||||||
@ -403,18 +339,6 @@ bool SGTerraSync::SvnThread::start()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_use_svn |= _use_built_in;
|
|
||||||
|
|
||||||
|
|
||||||
if ((!_use_svn)&&(_rsync_server==""))
|
|
||||||
{
|
|
||||||
SG_LOG(SG_TERRASYNC,SG_ALERT,
|
|
||||||
"Cannot start scenery download. Rsync scenery server is undefined.");
|
|
||||||
_fail_count++;
|
|
||||||
_stalled = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_fail_count = 0;
|
_fail_count = 0;
|
||||||
_updated_tile_count = 0;
|
_updated_tile_count = 0;
|
||||||
_success_count = 0;
|
_success_count = 0;
|
||||||
@ -423,20 +347,7 @@ bool SGTerraSync::SvnThread::start()
|
|||||||
_stalled = false;
|
_stalled = false;
|
||||||
_running = true;
|
_running = true;
|
||||||
|
|
||||||
string status;
|
string status = "Using built-in HTTP support.";
|
||||||
|
|
||||||
if (_use_svn && _use_built_in)
|
|
||||||
status = "Using built-in SVN support. ";
|
|
||||||
else if (_use_svn)
|
|
||||||
{
|
|
||||||
status = "Using external SVN utility '";
|
|
||||||
status += _svn_command;
|
|
||||||
status += "'. ";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status = "Using RSYNC. ";
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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).
|
||||||
@ -449,61 +360,7 @@ bool SGTerraSync::SvnThread::start()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SGTerraSync::SvnThread::runExternalSyncCommand(const char* dir)
|
void SGTerraSync::WorkerThread::run()
|
||||||
{
|
|
||||||
ostringstream buf;
|
|
||||||
SGPath localPath( _local_dir );
|
|
||||||
localPath.append( dir );
|
|
||||||
|
|
||||||
if (_use_svn)
|
|
||||||
{
|
|
||||||
buf << "\"" << _svn_command << "\" "
|
|
||||||
<< svn_options << " "
|
|
||||||
<< "\"" << _svn_server << "/" << dir << "\" "
|
|
||||||
<< "\"" << localPath.str_native() << "\"";
|
|
||||||
} else {
|
|
||||||
buf << rsync_cmd << " "
|
|
||||||
<< "\"" << _rsync_server << "/" << dir << "/\" "
|
|
||||||
<< "\"" << localPath.str_native() << "/\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
string command;
|
|
||||||
#ifdef SG_WINDOWS
|
|
||||||
// windows command line parsing is just lovely...
|
|
||||||
// to allow white spaces, the system call needs this:
|
|
||||||
// ""C:\Program Files\something.exe" somearg "some other arg""
|
|
||||||
// Note: whitespace strings quoted by a pair of "" _and_ the
|
|
||||||
// entire string needs to be wrapped by "" too.
|
|
||||||
// The svn url needs forward slashes (/) as a path separator while
|
|
||||||
// the local path needs windows-native backslash as a path separator.
|
|
||||||
command = "\"" + buf.str() + "\"";
|
|
||||||
#else
|
|
||||||
command = buf.str();
|
|
||||||
#endif
|
|
||||||
SG_LOG(SG_TERRASYNC,SG_DEBUG, "sync command '" << command << "'");
|
|
||||||
|
|
||||||
#ifdef SG_WINDOWS
|
|
||||||
// tbd: does Windows support "popen"?
|
|
||||||
int rc = system( command.c_str() );
|
|
||||||
#else
|
|
||||||
FILE* pipe = popen( command.c_str(), "r");
|
|
||||||
int rc=-1;
|
|
||||||
// wait for external process to finish
|
|
||||||
if (pipe)
|
|
||||||
rc = pclose(pipe);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (rc)
|
|
||||||
{
|
|
||||||
SG_LOG(SG_TERRASYNC,SG_ALERT,
|
|
||||||
"Failed to synchronize directory '" << dir << "', " <<
|
|
||||||
"error code= " << rc);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SGTerraSync::SvnThread::run()
|
|
||||||
{
|
{
|
||||||
_active = true;
|
_active = true;
|
||||||
initCompletedTilesPersistentCache();
|
initCompletedTilesPersistentCache();
|
||||||
@ -566,106 +423,15 @@ void SGTerraSync::SvnThread::run()
|
|||||||
SG_LOG(SG_TERRASYNC,SG_INFO, "picking entry # " << idx << ", server is " << _httpServer );
|
SG_LOG(SG_TERRASYNC,SG_INFO, "picking entry # " << idx << ", server is " << _httpServer );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( _httpServer.empty() ) { // don't resolve SVN server is HTTP server is set
|
|
||||||
if ( _svn_server.empty()) {
|
|
||||||
SG_LOG(SG_TERRASYNC,SG_INFO, "Querying closest TerraSync server");
|
|
||||||
ServerSelectQuery* ssq = new ServerSelectQuery;
|
|
||||||
HTTP::Request_ptr req = ssq;
|
|
||||||
_http.makeRequest(req);
|
|
||||||
while (!req->isComplete()) {
|
|
||||||
_http.update(20);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req->readyState() == HTTP::Request::DONE) {
|
runInternal();
|
||||||
_svn_server = ssq->svnUrl();
|
|
||||||
SG_LOG(SG_TERRASYNC,SG_INFO, "Closest TerraSync server:" << _svn_server);
|
|
||||||
} else {
|
|
||||||
SG_LOG(SG_TERRASYNC,SG_WARN, "Failed to query closest TerraSync server");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SG_LOG(SG_TERRASYNC,SG_INFO, "Explicit: TerraSync server:" << _svn_server);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_svn_server.empty()) {
|
|
||||||
#if WE_HAVE_A_DEFAULT_SERVER_BUT_WE_DONT_THIS_URL_IS_NO_LONGER_VALID
|
|
||||||
// default value
|
|
||||||
_svn_server = "http://foxtrot.mgras.net:8080/terrascenery/trunk/data/Scenery";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_use_built_in) {
|
|
||||||
runInternal();
|
|
||||||
} else {
|
|
||||||
runExternal();
|
|
||||||
}
|
|
||||||
|
|
||||||
_active = false;
|
_active = false;
|
||||||
_running = false;
|
_running = false;
|
||||||
_is_dirty = true;
|
_is_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SGTerraSync::SvnThread::runExternal()
|
void SGTerraSync::WorkerThread::updateSyncSlot(SyncSlot &slot)
|
||||||
{
|
|
||||||
while (!_stop)
|
|
||||||
{
|
|
||||||
SyncItem next = waitingTiles.pop_front();
|
|
||||||
if (_stop)
|
|
||||||
break;
|
|
||||||
|
|
||||||
SyncItem::Status cacheStatus = isPathCached(next);
|
|
||||||
if (cacheStatus != SyncItem::Invalid) {
|
|
||||||
_cache_hits++;
|
|
||||||
SG_LOG(SG_TERRASYNC, SG_DEBUG,
|
|
||||||
"Cache hit for: '" << next._dir << "'");
|
|
||||||
next._status = cacheStatus;
|
|
||||||
_freshTiles.push_back(next);
|
|
||||||
_is_dirty = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
syncPathExternal(next);
|
|
||||||
|
|
||||||
if ((_allowed_errors >= 0)&&
|
|
||||||
(_consecutive_errors >= _allowed_errors))
|
|
||||||
{
|
|
||||||
_stalled = true;
|
|
||||||
_stop = true;
|
|
||||||
}
|
|
||||||
} // of thread running loop
|
|
||||||
}
|
|
||||||
|
|
||||||
void SGTerraSync::SvnThread::syncPathExternal(const SyncItem& next)
|
|
||||||
{
|
|
||||||
_busy = true;
|
|
||||||
SGPath path( _local_dir );
|
|
||||||
path.append( next._dir );
|
|
||||||
bool isNewDirectory = !path.exists();
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (isNewDirectory) {
|
|
||||||
int rc = path.create_dir( 0755 );
|
|
||||||
if (rc) {
|
|
||||||
SG_LOG(SG_TERRASYNC,SG_ALERT,
|
|
||||||
"Cannot create directory '" << path << "', return code = " << rc );
|
|
||||||
throw sg_exception("Cannot create directory for terrasync", path.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!runExternalSyncCommand(next._dir.c_str())) {
|
|
||||||
throw sg_exception("Running external sync command failed");
|
|
||||||
}
|
|
||||||
} catch (sg_exception& e) {
|
|
||||||
fail(next);
|
|
||||||
_busy = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
updated(next, isNewDirectory);
|
|
||||||
_busy = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
|
|
||||||
{
|
{
|
||||||
if (slot.repository.get()) {
|
if (slot.repository.get()) {
|
||||||
if (slot.repository->isDoingSync()) {
|
if (slot.repository->isDoingSync()) {
|
||||||
@ -680,7 +446,7 @@ void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check result
|
// check result
|
||||||
SVNRepository::ResultCode res = slot.repository->failure();
|
AbstractRepository::ResultCode res = slot.repository->failure();
|
||||||
if (res == AbstractRepository::REPO_ERROR_NOT_FOUND) {
|
if (res == AbstractRepository::REPO_ERROR_NOT_FOUND) {
|
||||||
notFound(slot.currentItem);
|
notFound(slot.currentItem);
|
||||||
} else if (res != AbstractRepository::REPO_NO_ERROR) {
|
} else if (res != AbstractRepository::REPO_NO_ERROR) {
|
||||||
@ -714,18 +480,9 @@ void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
|
|||||||
}
|
}
|
||||||
} // of creating directory step
|
} // of creating directory step
|
||||||
|
|
||||||
string serverUrl(_svn_server);
|
slot.repository.reset(new HTTPRepository(path, &_http));
|
||||||
if (!_httpServer.empty()) {
|
slot.repository->setBaseUrl(_httpServer + "/" + slot.currentItem._dir);
|
||||||
slot.repository.reset(new HTTPRepository(path, &_http));
|
|
||||||
serverUrl = _httpServer;
|
|
||||||
} else {
|
|
||||||
if (slot.currentItem._type == SyncItem::AIData) {
|
|
||||||
serverUrl = _svn_data_server;
|
|
||||||
}
|
|
||||||
slot.repository.reset(new SVNRepository(path, &_http));
|
|
||||||
}
|
|
||||||
|
|
||||||
slot.repository->setBaseUrl(serverUrl + "/" + slot.currentItem._dir);
|
|
||||||
try {
|
try {
|
||||||
slot.repository->update();
|
slot.repository->update();
|
||||||
} catch (sg_exception& e) {
|
} catch (sg_exception& e) {
|
||||||
@ -744,7 +501,7 @@ void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SGTerraSync::SvnThread::runInternal()
|
void SGTerraSync::WorkerThread::runInternal()
|
||||||
{
|
{
|
||||||
while (!_stop) {
|
while (!_stop) {
|
||||||
try {
|
try {
|
||||||
@ -794,7 +551,7 @@ void SGTerraSync::SvnThread::runInternal()
|
|||||||
} // of thread running loop
|
} // of thread running loop
|
||||||
}
|
}
|
||||||
|
|
||||||
SyncItem::Status SGTerraSync::SvnThread::isPathCached(const SyncItem& next) const
|
SyncItem::Status SGTerraSync::WorkerThread::isPathCached(const SyncItem& next) const
|
||||||
{
|
{
|
||||||
TileAgeCache::const_iterator ii = _completedTiles.find( next._dir );
|
TileAgeCache::const_iterator ii = _completedTiles.find( next._dir );
|
||||||
if (ii == _completedTiles.end()) {
|
if (ii == _completedTiles.end()) {
|
||||||
@ -816,7 +573,7 @@ SyncItem::Status SGTerraSync::SvnThread::isPathCached(const SyncItem& next) cons
|
|||||||
return (ii->second > now) ? SyncItem::Cached : SyncItem::Invalid;
|
return (ii->second > now) ? SyncItem::Cached : SyncItem::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SGTerraSync::SvnThread::fail(SyncItem failedItem)
|
void SGTerraSync::WorkerThread::fail(SyncItem failedItem)
|
||||||
{
|
{
|
||||||
time_t now = time(0);
|
time_t now = time(0);
|
||||||
_consecutive_errors++;
|
_consecutive_errors++;
|
||||||
@ -829,7 +586,7 @@ void SGTerraSync::SvnThread::fail(SyncItem failedItem)
|
|||||||
_is_dirty = true;
|
_is_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SGTerraSync::SvnThread::notFound(SyncItem item)
|
void SGTerraSync::WorkerThread::notFound(SyncItem item)
|
||||||
{
|
{
|
||||||
// treat not found as authorative, so use the same cache expiry
|
// treat not found as authorative, so use the same cache expiry
|
||||||
// as succesful download. Important for MP models and similar so
|
// as succesful download. Important for MP models and similar so
|
||||||
@ -844,7 +601,7 @@ void SGTerraSync::SvnThread::notFound(SyncItem item)
|
|||||||
writeCompletedTilesPersistentCache();
|
writeCompletedTilesPersistentCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SGTerraSync::SvnThread::updated(SyncItem item, bool isNewDirectory)
|
void SGTerraSync::WorkerThread::updated(SyncItem item, bool isNewDirectory)
|
||||||
{
|
{
|
||||||
time_t now = time(0);
|
time_t now = time(0);
|
||||||
_consecutive_errors = 0;
|
_consecutive_errors = 0;
|
||||||
@ -863,7 +620,7 @@ void SGTerraSync::SvnThread::updated(SyncItem item, bool isNewDirectory)
|
|||||||
writeCompletedTilesPersistentCache();
|
writeCompletedTilesPersistentCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SGTerraSync::SvnThread::initCompletedTilesPersistentCache()
|
void SGTerraSync::WorkerThread::initCompletedTilesPersistentCache()
|
||||||
{
|
{
|
||||||
if (!_persistentCachePath.exists()) {
|
if (!_persistentCachePath.exists()) {
|
||||||
return;
|
return;
|
||||||
@ -896,7 +653,7 @@ void SGTerraSync::SvnThread::initCompletedTilesPersistentCache()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SGTerraSync::SvnThread::writeCompletedTilesPersistentCache() const
|
void SGTerraSync::WorkerThread::writeCompletedTilesPersistentCache() const
|
||||||
{
|
{
|
||||||
// cache is disabled
|
// cache is disabled
|
||||||
if (_persistentCachePath.isNull()) {
|
if (_persistentCachePath.isNull()) {
|
||||||
@ -931,11 +688,11 @@ void SGTerraSync::SvnThread::writeCompletedTilesPersistentCache() const
|
|||||||
// SGTerraSync ////////////////////////////////////////////////////////////////
|
// SGTerraSync ////////////////////////////////////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
SGTerraSync::SGTerraSync() :
|
SGTerraSync::SGTerraSync() :
|
||||||
_svnThread(NULL),
|
_workerThread(NULL),
|
||||||
_bound(false),
|
_bound(false),
|
||||||
_inited(false)
|
_inited(false)
|
||||||
{
|
{
|
||||||
_svnThread = new SvnThread();
|
_workerThread = new WorkerThread();
|
||||||
_log = new BufferedLogCallback(SG_TERRASYNC, SG_INFO);
|
_log = new BufferedLogCallback(SG_TERRASYNC, SG_INFO);
|
||||||
_log->truncateAt(255);
|
_log->truncateAt(255);
|
||||||
|
|
||||||
@ -944,8 +701,8 @@ SGTerraSync::SGTerraSync() :
|
|||||||
|
|
||||||
SGTerraSync::~SGTerraSync()
|
SGTerraSync::~SGTerraSync()
|
||||||
{
|
{
|
||||||
delete _svnThread;
|
delete _workerThread;
|
||||||
_svnThread = NULL;
|
_workerThread = NULL;
|
||||||
sglog().removeCallback(_log);
|
sglog().removeCallback(_log);
|
||||||
delete _log;
|
delete _log;
|
||||||
_tiedProperties.Untie();
|
_tiedProperties.Untie();
|
||||||
@ -965,56 +722,42 @@ void SGTerraSync::init()
|
|||||||
_inited = true;
|
_inited = true;
|
||||||
|
|
||||||
assert(_terraRoot);
|
assert(_terraRoot);
|
||||||
_terraRoot->setBoolValue("built-in-svn-available",svn_built_in_available);
|
_terraRoot->setBoolValue("built-in-svn-available", true);
|
||||||
|
|
||||||
reinit();
|
reinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SGTerraSync::shutdown()
|
void SGTerraSync::shutdown()
|
||||||
{
|
{
|
||||||
_svnThread->stop();
|
_workerThread->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SGTerraSync::reinit()
|
void SGTerraSync::reinit()
|
||||||
{
|
{
|
||||||
// do not reinit when enabled and we're already up and running
|
// do not reinit when enabled and we're already up and running
|
||||||
if ((_terraRoot->getBoolValue("enabled",false))&&
|
if ((_terraRoot->getBoolValue("enabled",false))&&
|
||||||
(_svnThread->_active && _svnThread->_running))
|
(_workerThread->_active && _workerThread->_running))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_svnThread->stop();
|
_workerThread->stop();
|
||||||
|
|
||||||
if (_terraRoot->getBoolValue("enabled",false))
|
if (_terraRoot->getBoolValue("enabled",false))
|
||||||
{
|
{
|
||||||
_svnThread->setSvnServer(_terraRoot->getStringValue("svn-server",""));
|
|
||||||
std::string httpServer(_terraRoot->getStringValue("http-server",""));
|
std::string httpServer(_terraRoot->getStringValue("http-server",""));
|
||||||
_svnThread->setHTTPServer(httpServer);
|
_workerThread->setHTTPServer(httpServer);
|
||||||
_svnThread->setSvnDataServer(_terraRoot->getStringValue("svn-data-server",""));
|
_workerThread->setLocalDir(_terraRoot->getStringValue("scenery-dir",""));
|
||||||
_svnThread->setRsyncServer(_terraRoot->getStringValue("rsync-server",""));
|
_workerThread->setAllowedErrorCount(_terraRoot->getIntValue("max-errors",5));
|
||||||
_svnThread->setLocalDir(_terraRoot->getStringValue("scenery-dir",""));
|
_workerThread->setCacheHits(_terraRoot->getIntValue("cache-hit", 0));
|
||||||
_svnThread->setAllowedErrorCount(_terraRoot->getIntValue("max-errors",5));
|
|
||||||
_svnThread->setUseBuiltin(_terraRoot->getBoolValue("use-built-in-svn",true));
|
|
||||||
|
|
||||||
if (httpServer.empty()) {
|
if (_workerThread->start())
|
||||||
// HTTP doesn't benefit from using the persistent cache
|
|
||||||
_svnThread->setCachePath(SGPath(_terraRoot->getStringValue("cache-path","")));
|
|
||||||
} else {
|
|
||||||
SG_LOG(SG_TERRASYNC, SG_INFO, "HTTP repository selected, disabling persistent cache");
|
|
||||||
}
|
|
||||||
|
|
||||||
_svnThread->setCacheHits(_terraRoot->getIntValue("cache-hit", 0));
|
|
||||||
_svnThread->setUseSvn(_terraRoot->getBoolValue("use-svn",true));
|
|
||||||
_svnThread->setExtSvnUtility(_terraRoot->getStringValue("ext-svn-utility","svn"));
|
|
||||||
|
|
||||||
if (_svnThread->start())
|
|
||||||
{
|
{
|
||||||
syncAirportsModels();
|
syncAirportsModels();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_stalledNode->setBoolValue(_svnThread->_stalled);
|
_stalledNode->setBoolValue(_workerThread->_stalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SGTerraSync::bind()
|
void SGTerraSync::bind()
|
||||||
@ -1024,17 +767,17 @@ void SGTerraSync::bind()
|
|||||||
}
|
}
|
||||||
|
|
||||||
_bound = true;
|
_bound = true;
|
||||||
_tiedProperties.Tie( _terraRoot->getNode("busy", true), (bool*) &_svnThread->_busy );
|
_tiedProperties.Tie( _terraRoot->getNode("busy", true), (bool*) &_workerThread->_busy );
|
||||||
_tiedProperties.Tie( _terraRoot->getNode("active", true), (bool*) &_svnThread->_active );
|
_tiedProperties.Tie( _terraRoot->getNode("active", true), (bool*) &_workerThread->_active );
|
||||||
_tiedProperties.Tie( _terraRoot->getNode("update-count", true), (int*) &_svnThread->_success_count );
|
_tiedProperties.Tie( _terraRoot->getNode("update-count", true), (int*) &_workerThread->_success_count );
|
||||||
_tiedProperties.Tie( _terraRoot->getNode("error-count", true), (int*) &_svnThread->_fail_count );
|
_tiedProperties.Tie( _terraRoot->getNode("error-count", true), (int*) &_workerThread->_fail_count );
|
||||||
_tiedProperties.Tie( _terraRoot->getNode("tile-count", true), (int*) &_svnThread->_updated_tile_count );
|
_tiedProperties.Tie( _terraRoot->getNode("tile-count", true), (int*) &_workerThread->_updated_tile_count );
|
||||||
_tiedProperties.Tie( _terraRoot->getNode("cache-hits", true), (int*) &_svnThread->_cache_hits );
|
_tiedProperties.Tie( _terraRoot->getNode("cache-hits", true), (int*) &_workerThread->_cache_hits );
|
||||||
_tiedProperties.Tie( _terraRoot->getNode("transfer-rate-bytes-sec", true), (int*) &_svnThread->_transfer_rate );
|
_tiedProperties.Tie( _terraRoot->getNode("transfer-rate-bytes-sec", true), (int*) &_workerThread->_transfer_rate );
|
||||||
|
|
||||||
// use kbytes here because propety doesn't support 64-bit and we might conceivably
|
// use kbytes here because propety doesn't support 64-bit and we might conceivably
|
||||||
// download more than 2G in a single session
|
// download more than 2G in a single session
|
||||||
_tiedProperties.Tie( _terraRoot->getNode("downloaded-kbytes", true), (int*) &_svnThread->_total_kb_downloaded );
|
_tiedProperties.Tie( _terraRoot->getNode("downloaded-kbytes", true), (int*) &_workerThread->_total_kb_downloaded );
|
||||||
|
|
||||||
_terraRoot->getNode("busy", true)->setAttribute(SGPropertyNode::WRITE,false);
|
_terraRoot->getNode("busy", true)->setAttribute(SGPropertyNode::WRITE,false);
|
||||||
_terraRoot->getNode("active", true)->setAttribute(SGPropertyNode::WRITE,false);
|
_terraRoot->getNode("active", true)->setAttribute(SGPropertyNode::WRITE,false);
|
||||||
@ -1045,13 +788,13 @@ void SGTerraSync::bind()
|
|||||||
_terraRoot->getNode("use-svn", true)->setAttribute(SGPropertyNode::USERARCHIVE,false);
|
_terraRoot->getNode("use-svn", true)->setAttribute(SGPropertyNode::USERARCHIVE,false);
|
||||||
// stalled is used as a signal handler (to connect listeners triggering GUI pop-ups)
|
// stalled is used as a signal handler (to connect listeners triggering GUI pop-ups)
|
||||||
_stalledNode = _terraRoot->getNode("stalled", true);
|
_stalledNode = _terraRoot->getNode("stalled", true);
|
||||||
_stalledNode->setBoolValue(_svnThread->_stalled);
|
_stalledNode->setBoolValue(_workerThread->_stalled);
|
||||||
_stalledNode->setAttribute(SGPropertyNode::PRESERVE,true);
|
_stalledNode->setAttribute(SGPropertyNode::PRESERVE,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SGTerraSync::unbind()
|
void SGTerraSync::unbind()
|
||||||
{
|
{
|
||||||
_svnThread->stop();
|
_workerThread->stop();
|
||||||
_tiedProperties.Untie();
|
_tiedProperties.Untie();
|
||||||
_bound = false;
|
_bound = false;
|
||||||
_inited = false;
|
_inited = false;
|
||||||
@ -1064,11 +807,11 @@ void SGTerraSync::unbind()
|
|||||||
void SGTerraSync::update(double)
|
void SGTerraSync::update(double)
|
||||||
{
|
{
|
||||||
static SGBucket bucket;
|
static SGBucket bucket;
|
||||||
if (_svnThread->isDirty())
|
if (_workerThread->isDirty())
|
||||||
{
|
{
|
||||||
if (!_svnThread->_active)
|
if (!_workerThread->_active)
|
||||||
{
|
{
|
||||||
if (_svnThread->_stalled)
|
if (_workerThread->_stalled)
|
||||||
{
|
{
|
||||||
SG_LOG(SG_TERRASYNC,SG_ALERT,
|
SG_LOG(SG_TERRASYNC,SG_ALERT,
|
||||||
"Automatic scenery download/synchronization stalled. Too many errors.");
|
"Automatic scenery download/synchronization stalled. Too many errors.");
|
||||||
@ -1079,12 +822,12 @@ void SGTerraSync::update(double)
|
|||||||
SG_LOG(SG_TERRASYNC,SG_ALERT,
|
SG_LOG(SG_TERRASYNC,SG_ALERT,
|
||||||
"Automatic scenery download/synchronization has stopped.");
|
"Automatic scenery download/synchronization has stopped.");
|
||||||
}
|
}
|
||||||
_stalledNode->setBoolValue(_svnThread->_stalled);
|
_stalledNode->setBoolValue(_workerThread->_stalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (_svnThread->hasNewTiles())
|
while (_workerThread->hasNewTiles())
|
||||||
{
|
{
|
||||||
SyncItem next = _svnThread->getNewTile();
|
SyncItem next = _workerThread->getNewTile();
|
||||||
|
|
||||||
if ((next._type == SyncItem::Tile) || (next._type == SyncItem::AIData)) {
|
if ((next._type == SyncItem::Tile) || (next._type == SyncItem::AIData)) {
|
||||||
_activeTileDirs.erase(next._dir);
|
_activeTileDirs.erase(next._dir);
|
||||||
@ -1093,7 +836,7 @@ void SGTerraSync::update(double)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SGTerraSync::isIdle() {return _svnThread->isIdle();}
|
bool SGTerraSync::isIdle() {return _workerThread->isIdle();}
|
||||||
|
|
||||||
void SGTerraSync::syncAirportsModels()
|
void SGTerraSync::syncAirportsModels()
|
||||||
{
|
{
|
||||||
@ -1106,12 +849,12 @@ void SGTerraSync::syncAirportsModels()
|
|||||||
ostringstream dir;
|
ostringstream dir;
|
||||||
dir << "Airports/" << synced_other;
|
dir << "Airports/" << synced_other;
|
||||||
SyncItem w(dir.str(), SyncItem::AirportData);
|
SyncItem w(dir.str(), SyncItem::AirportData);
|
||||||
_svnThread->request( w );
|
_workerThread->request( w );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SyncItem w("Models", SyncItem::SharedModels);
|
SyncItem w("Models", SyncItem::SharedModels);
|
||||||
_svnThread->request( w );
|
_workerThread->request( w );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SGTerraSync::syncAreaByPath(const std::string& aPath)
|
void SGTerraSync::syncAreaByPath(const std::string& aPath)
|
||||||
@ -1126,7 +869,7 @@ void SGTerraSync::syncAreaByPath(const std::string& aPath)
|
|||||||
|
|
||||||
_activeTileDirs.insert(dir);
|
_activeTileDirs.insert(dir);
|
||||||
SyncItem w(dir, SyncItem::Tile);
|
SyncItem w(dir, SyncItem::Tile);
|
||||||
_svnThread->request( w );
|
_workerThread->request( w );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1139,7 +882,7 @@ bool SGTerraSync::scheduleTile(const SGBucket& bucket)
|
|||||||
|
|
||||||
bool SGTerraSync::isTileDirPending(const std::string& sceneryDir) const
|
bool SGTerraSync::isTileDirPending(const std::string& sceneryDir) const
|
||||||
{
|
{
|
||||||
if (!_svnThread->_running) {
|
if (!_workerThread->_running) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1162,13 +905,13 @@ void SGTerraSync::scheduleDataDir(const std::string& dataDir)
|
|||||||
|
|
||||||
_activeTileDirs.insert(dataDir);
|
_activeTileDirs.insert(dataDir);
|
||||||
SyncItem w(dataDir, SyncItem::AIData);
|
SyncItem w(dataDir, SyncItem::AIData);
|
||||||
_svnThread->request( w );
|
_workerThread->request( w );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SGTerraSync::isDataDirPending(const std::string& dataDir) const
|
bool SGTerraSync::isDataDirPending(const std::string& dataDir) const
|
||||||
{
|
{
|
||||||
if (!_svnThread->_running) {
|
if (!_workerThread->_running) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,10 +84,10 @@ protected:
|
|||||||
void syncAirportsModels();
|
void syncAirportsModels();
|
||||||
|
|
||||||
|
|
||||||
class SvnThread;
|
class WorkerThread;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SvnThread* _svnThread;
|
WorkerThread* _workerThread;
|
||||||
SGPropertyNode_ptr _terraRoot;
|
SGPropertyNode_ptr _terraRoot;
|
||||||
SGPropertyNode_ptr _stalledNode;
|
SGPropertyNode_ptr _stalledNode;
|
||||||
SGPropertyNode_ptr _cacheHits;
|
SGPropertyNode_ptr _cacheHits;
|
||||||
|
Loading…
Reference in New Issue
Block a user