1
0
Fork 0

Bugfix 3.3: Import would not report communication errors (#9501)

* arangoimport was neither reporting not stopping on communications errors.  Add reporting of impacted lines for CSV imports.

* correct lines missing from initial backport
This commit is contained in:
Matthew Von-Maszewski 2019-07-18 15:34:42 +02:00 committed by GitHub
parent 9a0bd3222e
commit 9ff3aeacfa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 95 additions and 54 deletions

View File

@ -1,6 +1,9 @@
v3.3.24 (XXXX-XX-XX)
--------------------
* arangoimport would not stop, much less report, communications errors. Add CSV reporting
of line numbers that are impacted during such errors
* changed several internal VelocyPack comparisons in the cluster to not check for bytewise identity,
but for logical intentity of objects

View File

@ -452,8 +452,7 @@ void ImportFeature::start() {
std::cout << std::endl;
// give information about import
if (ok) {
// give information about import (even if errors occur)
std::cout << "created: " << ih.getNumberCreated() << std::endl;
std::cout << "warnings/errors: " << ih.getNumberErrors() << std::endl;
std::cout << "updated/replaced: " << ih.getNumberUpdated() << std::endl;
@ -463,12 +462,16 @@ void ImportFeature::start() {
std::cout << "lines read: " << ih.getReadLines() << std::endl;
}
} else {
if (!ok) {
auto const& msgs = ih.getErrorMessages();
if (!msgs.empty()) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "error message(s):";
for (std::string const& msg : ih.getErrorMessages()) {
for (std::string const& msg : msgs) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << msg;
}
}
}
} catch (std::exception const& ex) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "Caught exception " << ex.what() << " during import";

View File

@ -815,7 +815,7 @@ void ImportHelper::sendCsvBuffer() {
SenderThread* t = findIdleSender();
if (t != nullptr) {
uint64_t tmp_length = _outputBuffer.length();
t->sendData(url, &_outputBuffer);
t->sendData(url, &_outputBuffer, _rowOffset +1, _rowsRead);
addPeriodByteCount(tmp_length + url.length());
}

View File

@ -47,6 +47,8 @@ SenderThread::SenderThread(std::unique_ptr<httpclient::SimpleHttpClient>&& clien
_hasError(false),
_idle(true),
_ready(false),
_lowLineNumber(0),
_highLineNumber(0),
_stats(stats) {}
SenderThread::~SenderThread() {
@ -62,7 +64,8 @@ void SenderThread::beginShutdown() {
guard.broadcast();
}
void SenderThread::sendData(std::string const& url, arangodb::basics::StringBuffer* data) {
void SenderThread::sendData(std::string const& url, arangodb::basics::StringBuffer* data,
size_t lowLine, size_t highLine) {
TRI_ASSERT(_idle && !_hasError);
_url = url;
_data.swap(data);
@ -70,12 +73,25 @@ void SenderThread::sendData(std::string const& url, arangodb::basics::StringBuff
// wake up the thread that may be waiting in run()
CONDITION_LOCKER(guard, _condition);
_idle = false;
_lowLineNumber = lowLine;
_highLineNumber = highLine;
guard.broadcast();
}
bool SenderThread::hasError() {
bool retFlag = false;
{
// flag reset after read to prevent multiple reporting
// of errors in ImportHelper
CONDITION_LOCKER(guard, _condition);
return _hasError;
retFlag = _hasError;
_hasError = false;
}
if (retFlag) {
beginShutdown();
}
return retFlag;
}
bool SenderThread::isReady() {
@ -134,6 +150,8 @@ void SenderThread::run() {
}
void SenderThread::handleResult(httpclient::SimpleHttpResult* result) {
bool haveBody = false;
if (result == nullptr) {
return;
}
@ -141,10 +159,12 @@ void SenderThread::handleResult(httpclient::SimpleHttpResult* result) {
std::shared_ptr<VPackBuilder> parsedBody;
try {
parsedBody = result->getBodyVelocyPack();
haveBody = true;
} catch (...) {
// No action required
return;
// no body, likely error situation
}
if (haveBody) {
VPackSlice const body = parsedBody->slice();
// error details
@ -193,4 +213,16 @@ void SenderThread::handleResult(httpclient::SimpleHttpResult* result) {
// will trigger the waiting ImportHelper thread to cancel the import
_hasError = true;
}
} // if
if (!_hasError && !result->getHttpReturnMessage().empty() && !result->isComplete()) {
_errorMessage = result->getHttpReturnMessage();
if (0 != _lowLineNumber || 0 != _highLineNumber) {
LOG_TOPIC(WARN, arangodb::Logger::FIXME) << "Error left import lines "
<< _lowLineNumber << " through "
<< _highLineNumber
<< " in unknown state";
} // if
_hasError = true;
} // if
}

View File

@ -55,7 +55,8 @@ class SenderThread : public arangodb::Thread {
/// @brief imports a delimited file
//////////////////////////////////////////////////////////////////////////////
void sendData(std::string const& url, basics::StringBuffer* sender);
void sendData(std::string const& url, basics::StringBuffer* sender,
size_t lowLine = 0, size_t highLine = 0);
bool hasError();
/// Ready to start sending
@ -80,6 +81,8 @@ class SenderThread : public arangodb::Thread {
bool _hasError;
bool _idle;
bool _ready;
size_t _lowLineNumber;
size_t _highLineNumber;
ImportStatistics* _stats;
std::string _errorMessage;