1
0
Fork 0

agency bug in precondition and log handling fixed

This commit is contained in:
Kaveh Vahedipour 2017-01-18 11:07:30 +01:00
parent 4426929cb7
commit ea7e16979a
8 changed files with 111 additions and 16 deletions

View File

@ -682,7 +682,7 @@ inquire_ret_t Agent::inquire(query_t const& query) {
}
}
ret.result = builder;
ret = inquire_ret_t(true, id(), builder);
return ret;
}

View File

@ -461,14 +461,20 @@ inline RestStatus RestAgencyHandler::handleInquire() {
std::this_thread::sleep_for(duration_t(100));
}
inquire_ret_t ret = _agent->inquire(query);
inquire_ret_t ret;
try {
ret = _agent->inquire(query);
} catch (std::exception const& e) {
generateError(
rest::ResponseCode::SERVER_ERROR, TRI_ERROR_INTERNAL, e.what());
}
if (ret.accepted) { // I am leading
generateResult(rest::ResponseCode::OK, ret.result->slice());
generateResult(rest::ResponseCode::OK, ret.result->slice());
} else { // Redirect to leader
if (_agent->leaderID() == NO_LEADER) {
Builder body;
body.openObject();
@ -613,6 +619,8 @@ RestStatus RestAgencyHandler::execute() {
return handleWrite();
} else if (suffixes[0] == "read") {
return handleRead();
} else if (suffixes[0] == "inquire") {
return handleInquire();
} else if (suffixes[0] == "transact") {
return handleTransact();
} else if (suffixes[0] == "config") {

View File

@ -135,7 +135,7 @@ std::vector<arangodb::consensus::index_t> State::log(
std::shared_ptr<Buffer<uint8_t>> buf =
std::make_shared<Buffer<uint8_t>>();
buf->append((char const*)i[0].begin(), i[0].byteSize());
LOG(WARN) << i.length();
if (i.length()==3) {
clientId = i[2].copyString();
}
@ -145,8 +145,8 @@ std::vector<arangodb::consensus::index_t> State::log(
_clientIdLookupTable.emplace(
std::pair<std::string, arangodb::consensus::index_t>(clientId, idx[j]));
persist(idx[j], term, i[0], clientId); // log to disk
++j;
}
++j;
}
return idx;
@ -845,25 +845,34 @@ std::vector<log_t> State::inquire(query_t const& query) const {
MUTEX_LOCKER(mutexLocker, _logLock); // Cannot be read lock (Compaction)
if (!query->slice().isArray()) {
LOG_TOPIC(WARN, Logger::AGENCY)
<< "Inquire interface handles [<clientIds>]. We got " << query->toJson();
THROW_ARANGO_EXCEPTION_MESSAGE(
210002,
std::string("Inquiry handles a list of string clientIds: [<clientId>] ")
+ ". We got " + query->toJson());
return result;
}
size_t pos = 0;
for (auto const& i : VPackArrayIterator(query->slice())) {
if (!i.isString()) {
LOG_TOPIC(WARN, Logger::AGENCY)
<< "ClientIds must be strings. We got " << i.toJson();
continue;
THROW_ARANGO_EXCEPTION_MESSAGE(
210002, std::string("ClientIds must be strings. On position ")
+ std::to_string(pos) + " we got " + i.toJson());
}
auto ret = _clientIdLookupTable.equal_range(i.copyString());
for (auto it = ret.first; it != ret.second; ++it) {
if (it->second < _log[0].index) {
continue;
}
result.push_back(_log.at(it->second-_cur));
}
pos++;
}
return result;
}

View File

@ -294,7 +294,70 @@ function agencyTestSuite () {
////////////////////////////////////////////////////////////////////////////////
testClientIds : function () {
writeAndCheck([[{"a":12},{},guid()]]);
var res;
var id0 = guid();
var query0 = {"a":12};
var pre0 = {};
writeAndCheck([[query0, pre0, id0]]);
res = accessAgency("inquire",[id0]).bodyParsed;
assertEqual(res.length, 1);
assertEqual(res[0].query, query0);
var query1 = {"a":13};
var pre1 = {"a":12}
writeAndCheck([[query1, pre1, id0]]);
res = accessAgency("inquire",[id0]).bodyParsed;
assertEqual(res.length, 2);
assertEqual(res[0].query, query0);
assertEqual(res[1].query, query1);
var query2 = {"a":13};
var pre2 = {"a":12}
var id2 = guid();
res = accessAgency("write",[[query1, pre1, id2]]);
assertEqual(res.statusCode,412);
res = accessAgency("inquire",[id2]).bodyParsed;
assertEqual(res.length, 0);
var id3 = guid();
res = accessAgency("write",[[query0, pre0, id3],[query1, pre1, id3]]);
assertEqual(res.statusCode,200);
res = accessAgency("inquire",[id3]).bodyParsed;
assertEqual(res.length, 2);
assertEqual(res[0].query, query0);
assertEqual(res[1].query, query1);
var id4 = guid();
res = accessAgency("write",[[query0, pre0, id4],
[query1, pre1, id4],
[query2, pre2, id4]]);
assertEqual(res.statusCode,412);
res = accessAgency("inquire",[id4]).bodyParsed;
assertEqual(res.length, 2);
assertEqual(res[0].query, query0);
assertEqual(res[1].query, query1);
var id5 = guid();
res = accessAgency("write",[[query0, pre0, id5],
[query2, pre2, id5],
[query1, pre1, id5]]);
assertEqual(res.statusCode,412);
res = accessAgency("inquire",[id5]).bodyParsed;
assertEqual(res.length, 2);
assertEqual(res[0].query, query0);
assertEqual(res[1].query, query1);
var id6 = guid();
res = accessAgency("write",[[query2, pre2, id6],
[query0, pre0, id6],
[query1, pre1, id6]]);
assertEqual(res.statusCode,412);
res = accessAgency("inquire",[id6]).bodyParsed;
assertEqual(res.length, 2);
assertEqual(res[0].query, query0);
assertEqual(res[1].query, query1);
},

View File

@ -278,6 +278,7 @@
"ERROR_AGENCY_INFORM_MUST_CONTAIN_ID" : { "code" : 20013, "message" : "Inform message must contain string parameter 'id'" },
"ERROR_AGENCY_INFORM_MUST_CONTAIN_ACTIVE" : { "code" : 20014, "message" : "Inform message must contain array 'active'" },
"ERROR_AGENCY_INFORM_MUST_CONTAIN_POOL" : { "code" : 20015, "message" : "Inform message must contain object 'pool'" },
"ERROR_AGENCY_INQUIRE_CLIENT_ID_MUST_BE_STRING" : { "code" : 20020, "message" : "Inquiry failed" },
"ERROR_DISPATCHER_IS_STOPPING" : { "code" : 21001, "message" : "dispatcher stopped" },
"ERROR_QUEUE_UNKNOWN" : { "code" : 21002, "message" : "named queue does not exist" },
"ERROR_QUEUE_FULL" : { "code" : 21003, "message" : "named queue is full" }

View File

@ -395,6 +395,7 @@ ERROR_AGENCY_INFORM_MUST_CONTAIN_TERM,20012,"Inform message must contain uint pa
ERROR_AGENCY_INFORM_MUST_CONTAIN_ID,20013,"Inform message must contain string parameter 'id'","The inform message in the agency must contain a string parameter 'id'."
ERROR_AGENCY_INFORM_MUST_CONTAIN_ACTIVE,20014,"Inform message must contain array 'active'","The inform message in the agency must contain an array 'active'."
ERROR_AGENCY_INFORM_MUST_CONTAIN_POOL,20015,"Inform message must contain object 'pool'","The inform message in the agency must contain an object 'pool'."
ERROR_AGENCY_INQUIRE_CLIENT_ID_MUST_BE_STRING,20020,"Inquiry failed","Inquiry by clientId failed"
################################################################################
## Dispatcher errors

View File

@ -274,6 +274,7 @@ void TRI_InitializeErrorMessages () {
REG_ERROR(ERROR_AGENCY_INFORM_MUST_CONTAIN_ID, "Inform message must contain string parameter 'id'");
REG_ERROR(ERROR_AGENCY_INFORM_MUST_CONTAIN_ACTIVE, "Inform message must contain array 'active'");
REG_ERROR(ERROR_AGENCY_INFORM_MUST_CONTAIN_POOL, "Inform message must contain object 'pool'");
REG_ERROR(ERROR_AGENCY_INQUIRE_CLIENT_ID_MUST_BE_STRING, "Inquiry failed");
REG_ERROR(ERROR_DISPATCHER_IS_STOPPING, "dispatcher stopped");
REG_ERROR(ERROR_QUEUE_UNKNOWN, "named queue does not exist");
REG_ERROR(ERROR_QUEUE_FULL, "named queue is full");

View File

@ -652,6 +652,8 @@
/// The inform message in the agency must contain an array 'active'.
/// - 20015: @LIT{Inform message must contain object 'pool'}
/// The inform message in the agency must contain an object 'pool'.
/// - 20020: @LIT{Inquiry failed}
/// Inquiry by clientId failed
/// - 21001: @LIT{dispatcher stopped}
/// Will be returned if a shutdown is in progress.
/// - 21002: @LIT{named queue does not exist}
@ -3449,6 +3451,16 @@ void TRI_InitializeErrorMessages ();
#define TRI_ERROR_AGENCY_INFORM_MUST_CONTAIN_POOL (20015)
////////////////////////////////////////////////////////////////////////////////
/// @brief 20020: ERROR_AGENCY_INQUIRE_CLIENT_ID_MUST_BE_STRING
///
/// Inquiry failed
///
/// Inquiry by clientId failed
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_AGENCY_INQUIRE_CLIENT_ID_MUST_BE_STRING (20020)
////////////////////////////////////////////////////////////////////////////////
/// @brief 21001: ERROR_DISPATCHER_IS_STOPPING
///