More error reporting from TerraSync/HTTP

- raise more errors when requests fail, and report/catch these.
This commit is contained in:
James Turner
2016-02-25 21:20:33 +02:00
parent 6cef1f9091
commit 0b4f416ddc
2 changed files with 73 additions and 20 deletions
+57 -18
View File
@@ -133,7 +133,9 @@ public:
std::string computeHashForPath(const SGPath& p); std::string computeHashForPath(const SGPath& p);
void writeHashCache(); void writeHashCache();
void failedToGetRootIndex(); void failedToGetRootIndex(AbstractRepository::ResultCode st);
void failedToUpdateChild(const SGPath& relativePath,
AbstractRepository::ResultCode fileStatus);
typedef std::vector<HTTP::Request_ptr> RequestVector; typedef std::vector<HTTP::Request_ptr> RequestVector;
RequestVector requests; RequestVector requests;
@@ -200,7 +202,7 @@ public:
if (p.exists()) { if (p.exists()) {
try { try {
// already exists on disk // already exists on disk
parseDirIndex(children); bool ok = parseDirIndex(children);
std::sort(children.begin(), children.end()); std::sort(children.begin(), children.end());
} catch (sg_exception& e) { } catch (sg_exception& e) {
// parsing cache failed // parsing cache failed
@@ -234,13 +236,14 @@ public:
std::sort(children.begin(), children.end()); std::sort(children.begin(), children.end());
} }
void failedToUpdate() void failedToUpdate(AbstractRepository::ResultCode status)
{ {
if (_relativePath.isNull()) { if (_relativePath.isNull()) {
// root dir failed // root dir failed
_repository->failedToGetRootIndex(); _repository->failedToGetRootIndex(status);
} else { } else {
SG_LOG(SG_TERRASYNC, SG_WARN, "failed to update dir:" << _relativePath); SG_LOG(SG_TERRASYNC, SG_WARN, "failed to update dir:" << _relativePath);
_repository->failedToUpdateChild(_relativePath, status);
} }
} }
@@ -277,8 +280,6 @@ public:
p.append(c->name); p.append(c->name);
HTTPDirectory* childDir = _repository->getOrCreateDirectory(p.str()); HTTPDirectory* childDir = _repository->getOrCreateDirectory(p.str());
childDir->updateChildrenBasedOnHash(); childDir->updateChildrenBasedOnHash();
} else {
SG_LOG(SG_TERRASYNC, SG_INFO, "existing file is ok:" << c->name);
} }
} }
@@ -357,11 +358,13 @@ public:
SG_LOG(SG_TERRASYNC, SG_INFO, "did update:" << fpath); SG_LOG(SG_TERRASYNC, SG_INFO, "did update:" << fpath);
} }
void didFailToUpdateFile(const std::string& file) void didFailToUpdateFile(const std::string& file,
AbstractRepository::ResultCode status)
{ {
SGPath fpath(_relativePath); SGPath fpath(_relativePath);
fpath.append(file); fpath.append(file);
SG_LOG(SG_TERRASYNC, SG_WARN, "failed to update:" << fpath); SG_LOG(SG_TERRASYNC, SG_WARN, "failed to update:" << fpath);
_repository->failedToUpdateChild(fpath, status);
} }
private: private:
@@ -379,10 +382,14 @@ private:
return std::find_if(children.begin(), children.end(), ChildWithName(name)); return std::find_if(children.begin(), children.end(), ChildWithName(name));
} }
void parseDirIndex(ChildInfoList& children) bool parseDirIndex(ChildInfoList& children)
{ {
SGPath p(absolutePath()); SGPath p(absolutePath());
p.append(".dirindex"); p.append(".dirindex");
if (!p.exists()) {
return false;
}
std::ifstream indexStream( p.c_str(), std::ios::in ); std::ifstream indexStream( p.c_str(), std::ios::in );
if ( !indexStream.is_open() ) { if ( !indexStream.is_open() ) {
@@ -427,6 +434,8 @@ private:
children.back().setSize(sizeData); children.back().setSize(sizeData);
} }
} }
return true;
} }
void removeChild(const std::string& name) void removeChild(const std::string& name)
@@ -448,6 +457,7 @@ private:
if (!ok) { if (!ok) {
SG_LOG(SG_TERRASYNC, SG_WARN, "removal failed for:" << p); SG_LOG(SG_TERRASYNC, SG_WARN, "removal failed for:" << p);
throw sg_io_exception("Failed to remove existing file/dir:", p);
} }
} }
@@ -561,12 +571,21 @@ HTTPRepository::failure() const
directory->didUpdateFile(fileName, hash); directory->didUpdateFile(fileName, hash);
SG_LOG(SG_TERRASYNC, SG_DEBUG, "got file " << fileName << " in " << directory->absolutePath()); SG_LOG(SG_TERRASYNC, SG_DEBUG, "got file " << fileName << " in " << directory->absolutePath());
} else if (responseCode() == 404) {
directory->didFailToUpdateFile(fileName, AbstractRepository::REPO_ERROR_FILE_NOT_FOUND);
} else { } else {
directory->didFailToUpdateFile(fileName); directory->didFailToUpdateFile(fileName, AbstractRepository::REPO_ERROR_HTTP);
} }
directory->repository()->finishedRequest(this); directory->repository()->finishedRequest(this);
} }
virtual void onFail()
{
file.reset();
directory->didFailToUpdateFile(fileName, AbstractRepository::REPO_ERROR_SOCKET);
directory->repository()->finishedRequest(this);
}
private: private:
static std::string makeUrl(HTTPDirectory* d, const std::string& file) static std::string makeUrl(HTTPDirectory* d, const std::string& file)
{ {
@@ -645,15 +664,27 @@ HTTPRepository::failure() const
} }
// either way we've confirmed the index is valid so update try {
// children now // either way we've confirmed the index is valid so update
directory->updateChildrenBasedOnHash(); // children now
directory->updateChildrenBasedOnHash();
} catch (sg_exception& e) {
directory->failedToUpdate(AbstractRepository::REPO_ERROR_IO);
}
} else if (responseCode() == 404) {
directory->failedToUpdate(AbstractRepository::REPO_ERROR_FILE_NOT_FOUND);
} else { } else {
directory->failedToUpdate(); directory->failedToUpdate(AbstractRepository::REPO_ERROR_HTTP);
} }
directory->repository()->finishedRequest(this); directory->repository()->finishedRequest(this);
} }
virtual void onFail()
{
directory->failedToUpdate(AbstractRepository::REPO_ERROR_SOCKET);
directory->repository()->finishedRequest(this);
}
private: private:
static std::string makeUrl(HTTPDirectory* d) static std::string makeUrl(HTTPDirectory* d)
{ {
@@ -677,16 +708,16 @@ HTTPRepository::failure() const
HTTP::Request_ptr HTTPRepoPrivate::updateFile(HTTPDirectory* dir, const std::string& name) HTTP::Request_ptr HTTPRepoPrivate::updateFile(HTTPDirectory* dir, const std::string& name)
{ {
HTTP::Request_ptr r(new FileGetRequest(dir, name)); HTTP::Request_ptr r(new FileGetRequest(dir, name));
http->makeRequest(r);
requests.push_back(r); requests.push_back(r);
http->makeRequest(r);
return r; return r;
} }
HTTP::Request_ptr HTTPRepoPrivate::updateDir(HTTPDirectory* dir) HTTP::Request_ptr HTTPRepoPrivate::updateDir(HTTPDirectory* dir)
{ {
HTTP::Request_ptr r(new DirGetRequest(dir)); HTTP::Request_ptr r(new DirGetRequest(dir));
http->makeRequest(r);
requests.push_back(r); requests.push_back(r);
http->makeRequest(r);
return r; return r;
} }
@@ -863,7 +894,7 @@ HTTPRepository::failure() const
{ {
RequestVector::iterator it = std::find(requests.begin(), requests.end(), req); RequestVector::iterator it = std::find(requests.begin(), requests.end(), req);
if (it == requests.end()) { if (it == requests.end()) {
throw sg_exception("lost request somehow"); throw sg_exception("lost request somehow", req->url());
} }
requests.erase(it); requests.erase(it);
if (requests.empty()) { if (requests.empty()) {
@@ -871,11 +902,19 @@ HTTPRepository::failure() const
} }
} }
void HTTPRepoPrivate::failedToGetRootIndex() void HTTPRepoPrivate::failedToGetRootIndex(AbstractRepository::ResultCode st)
{ {
SG_LOG(SG_TERRASYNC, SG_WARN, "Failed to get root of repo:" << baseUrl); SG_LOG(SG_TERRASYNC, SG_WARN, "Failed to get root of repo:" << baseUrl);
status = AbstractRepository::REPO_ERROR_NOT_FOUND; status = st;
}
void HTTPRepoPrivate::failedToUpdateChild(const SGPath& relativePath,
AbstractRepository::ResultCode fileStatus)
{
// this means we only record the last error, should this be improved?
status = fileStatus;
} }
} // of namespace simgear } // of namespace simgear
+16 -2
View File
@@ -664,7 +664,16 @@ void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
} }
slot.repository->setBaseUrl(serverUrl + "/" + slot.currentItem._dir); slot.repository->setBaseUrl(serverUrl + "/" + slot.currentItem._dir);
slot.repository->update(); try {
slot.repository->update();
} catch (sg_exception& e) {
SG_LOG(SG_TERRASYNC, SG_INFO, "sync of " << slot.repository->baseUrl() << " failed to start with error:"
<< e.getFormattedMessage());
fail(slot.currentItem);
slot.busy = false;
slot.repository.reset();
return;
}
slot.nextWarnTimeout = 20000; slot.nextWarnTimeout = 20000;
slot.stamp.stamp(); slot.stamp.stamp();
@@ -676,7 +685,12 @@ void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
void SGTerraSync::SvnThread::runInternal() void SGTerraSync::SvnThread::runInternal()
{ {
while (!_stop) { while (!_stop) {
_http.update(100); try {
_http.update(100);
} catch (sg_exception& e) {
SG_LOG(SG_TERRASYNC, SG_WARN, "failure doing HTTP update" << e.getFormattedMessage());
}
_transfer_rate = _http.transferRateBytesPerSec(); _transfer_rate = _http.transferRateBytesPerSec();
// convert from bytes to kbytes // convert from bytes to kbytes
_total_kb_downloaded = static_cast<int>(_http.totalBytesDownloaded() / 1024); _total_kb_downloaded = static_cast<int>(_http.totalBytesDownloaded() / 1024);