1
0
Fork 0

Merge branch 'devel' of https://github.com/arangodb/arangodb into devel

This commit is contained in:
Kaveh Vahedipour 2016-08-31 15:24:28 +00:00
commit 6c57f4eb67
25 changed files with 232 additions and 30 deletions

View File

@ -61,10 +61,11 @@ list(APPEND V8_GYP_ARGS
)
if (CROSS_COMPILING)
list(APPEND V8_GYP_ARGS -DGYP_CROSSCOMPILE=1)
list(APPEND V8_GYP_ARGS
-Dhost_arch=${V8_PROC_ARCH}
-DGYP_CROSSCOMPILE=1)
endif()
################################################################################
## ICU EXPORTS
################################################################################

View File

@ -300,6 +300,16 @@ while [ $# -gt 0 ]; do
CLEAN_IT=1
shift
;;
--cxArmV8)
ARMV8=1
CXGCC=1
shift
;;
--cxArmV7)
ARMV7=1
CXGCC=1
shift
;;
*)
echo "Unknown option: $1"
exit 1
@ -330,8 +340,30 @@ elif [ "$CLANG36" == 1 ]; then
CC=/usr/bin/clang-3.6
CXX=/usr/bin/clang++-3.6
CXXFLAGS="${CXXFLAGS} -std=c++11"
elif [ "${CXGCC}" = 1 ]; then
if [ "${ARMV8}" = 1 ]; then
export TOOL_PREFIX=aarch64-linux-gnu
BUILD_DIR="${BUILD_DIR}-ARMV8"
elif [ "${ARMV7}" = 1 ]; then
export TOOL_PREFIX=aarch64-linux-gnu
BUILD_DIR="${BUILD_DIR}-ARMV7"
else
echo "Unknown CX-Compiler!"
exit 1;
fi
export CXX=$TOOL_PREFIX-g++
export AR=$TOOL_PREFIX-ar
export RANLIB=$TOOL_PREFIX-ranlib
export CC=$TOOL_PREFIX-gcc
export LD=$TOOL_PREFIX-g++
export LINK=$TOOL_PREFIX-g++
export STRIP=$TOOL_PREFIX-strip
CONFIGURE_OPTIONS="${CONFIGURE_OPTIONS} -DCROSS_COMPILING=true"
fi
if [ "$SANITIZE" == 1 ]; then
if [ "$GCC5" == 1 ]; then
@ -415,7 +447,7 @@ SOURCE_DIR=`compute_relative ${DST}/ ${SRC}/`
if [ ! -f Makefile -o ! -f CMakeCache.txt ]; then
CFLAGS="${CFLAGS}" CXXFLAGS="${CXXFLAGS}" LDFLAGS="${LDFLAGS}" LIBS="${LIBS}" \
cmake ${SOURCE_DIR} ${CONFIGURE_OPTIONS} -G "${GENERATOR}"
cmake ${SOURCE_DIR} ${CONFIGURE_OPTIONS} -G "${GENERATOR}" || exit 1
fi
${MAKE_CMD_PREFIX} ${MAKE} ${MAKE_PARAMS}

View File

@ -44,6 +44,8 @@ typedef uint64_t term_t;
/// @brief Agent roles
enum role_t {FOLLOWER, CANDIDATE, LEADER};
static const std::string NO_LEADER = "";
/// @brief Duration type
typedef std::chrono::duration<long, std::ratio<1, 1000>> duration_t;

View File

@ -200,6 +200,8 @@ void Agent::reportIn(std::string const& id, index_t index) {
MUTEX_LOCKER(mutexLocker, _ioLock);
_lastAcked[id] = std::chrono::system_clock::now();
if (index > _confirmed[id]) { // progress this follower?
_confirmed[id] = index;
}
@ -486,11 +488,27 @@ write_ret_t Agent::write(query_t const& query) {
/// Read from store
read_ret_t Agent::read(query_t const& query) {
MUTEX_LOCKER(mutexLocker, _ioLock);
// Only leader else redirect
if (!_constituent.leading()) {
return read_ret_t(false, _constituent.leaderID());
}
// Still leading?
size_t good = 0;
for (auto const& i : _lastAcked) {
std::chrono::duration<double> m =
std::chrono::system_clock::now() - i.second;
if(0.9*_config.minPing() > m.count()) {
++good;
}
}
if (good < size() / 2) {
_constituent.candidate();
}
// Retrieve data from readDB
auto result = std::make_shared<arangodb::velocypack::Builder>();
std::vector<bool> success = _readDB.read(query, result);
@ -568,6 +586,26 @@ bool Agent::lead() {
guard.broadcast();
}
for (auto const& i : _config.active()) {
_lastAcked[i] = std::chrono::system_clock::now();
}
// Agency configuration
auto agency = std::make_shared<Builder>();
agency->openArray();
agency->openArray();
agency->openObject();
agency->add(".agency", VPackValue(VPackValueType::Object));
agency->add("term", VPackValue(term()));
agency->add("id", VPackValue(id()));
agency->add("active", _config.activeToBuilder()->slice());
agency->add("pool", _config.poolToBuilder()->slice());
agency->close();
agency->close();
agency->close();
agency->close();
write(agency);
// Wake up supervision
_supervision.wakeUp();

View File

@ -224,6 +224,7 @@ class Agent : public arangodb::Thread {
std::map<std::string, index_t> _confirmed;
std::map<std::string, index_t> _lastHighest;
std::map<std::string, TimePoint> _lastAcked;
std::map<std::string, TimePoint> _lastSent;
arangodb::Mutex _ioLock; /**< @brief Read/Write lock */

View File

@ -243,6 +243,19 @@ query_t config_t::activeToBuilder () const {
return ret;
}
query_t config_t::activeAgentsToBuilder () const {
query_t ret = std::make_shared<arangodb::velocypack::Builder>();
ret->openObject();
{
READ_LOCKER(readLocker, _lock);
for (auto const& i : _active) {
ret->add(i, VPackValue(_pool.at(i)));
}
}
ret->close();
return ret;
}
query_t config_t::poolToBuilder () const {
query_t ret = std::make_shared<arangodb::velocypack::Builder>();
ret->openObject();

View File

@ -142,6 +142,7 @@ struct config_t {
/// @brief of active agents
query_t activeToBuilder () const;
query_t activeAgentsToBuilder () const;
query_t poolToBuilder () const;

View File

@ -49,7 +49,6 @@ using namespace arangodb::rest;
using namespace arangodb::velocypack;
using namespace arangodb;
static const std::string NO_LEADER = "";
// (std::numeric_limits<std::string>::max)();
/// Raft role names for display purposes

View File

@ -51,14 +51,13 @@ bool Inception::start() { return Thread::start(); }
/// - Get snapshot of gossip peers and agent pool
/// - Create outgoing gossip.
/// - Send to all peers
void Inception::run() {
TRI_ASSERT(_agent != nullptr);
void Inception::gossip() {
auto s = std::chrono::system_clock::now();
std::chrono::seconds timeout(120);
size_t i = 0;
//bool cs = false;
while (!this->isStopping()) {
config_t config = _agent->config(); // get a copy of conf
@ -113,16 +112,63 @@ void Inception::run() {
}
if (config.poolComplete()) {
//if(!cs) {
_agent->startConstituent();
break;
//cs = true;
//}
}
}
}
void Inception::activeAgency() { // Do we have an active agency?
/*
config_t config = _agent->config(); // get a copy of conf
size_t i = 0;
std::string const path = "/_api/agency/activeAgents";
for (auto const& endpoint : config.gossipPeers()) { // gossip peers
if (endpoint != config.endpoint()) {
std::string clientid = config.id() + std::to_string(i++);
auto hf = std::make_unique<std::unordered_map<std::string, std::string>>();
arangodb::ClusterComm::instance()->asyncRequest(
clientid, 1, endpoint, GeneralRequest::RequestType::POST, path,
std::make_shared<std::string>(out->toJson()), hf,
std::make_shared<GossipCallback>(_agent), 1.0, true);
}
}
for (auto const& pair : config.pool()) { // pool entries
if (pair.second != config.endpoint()) {
std::string clientid = config.id() + std::to_string(i++);
auto hf = std::make_unique<std::unordered_map<std::string, std::string>>();
arangodb::ClusterComm::instance()->asyncRequest(
clientid, 1, pair.second, GeneralRequest::RequestType::POST, path,
std::make_shared<std::string>(out->toJson()), hf,
std::make_shared<GossipCallback>(_agent), 1.0, true);
}
}
*/
// start in pool/gossi peers start check if active agency
// if not if i have persisted agency
// if member
// contact other agents.
// if agreement raft
// complete pool?
}
void Inception::run() {
//activeAgency();
config_t config = _agent->config();
if (!config.poolComplete()) {
gossip();
}
}

View File

@ -54,6 +54,9 @@ public:
private:
void activeAgency();
void gossip();
Agent* _agent;
};

View File

@ -130,6 +130,9 @@ RestHandler::status RestAgencyPrivHandler::execute() {
return reportBadQuery(); // bad query
}
} else if (_request->suffix()[0] == "gossip") {
if (_request->requestType() != GeneralRequest::RequestType::POST) {
return reportMethodNotAllowed();
}
arangodb::velocypack::Options options;
query_t query = _request->toVelocyPackBuilderPtr(&options);
try {
@ -140,6 +143,13 @@ RestHandler::status RestAgencyPrivHandler::execute() {
} catch (std::exception const& e) {
return reportBadQuery(e.what());
}
} else if (_request->suffix()[0] == "activeAgents") {
if (_request->requestType() != GeneralRequest::RequestType::GET) {
return reportMethodNotAllowed();
}
if (_agent->leaderID() != NO_LEADER) {
result.add("active", _agent->config().activeAgentsToBuilder()->slice());
}
} else if (_request->suffix()[0] == "inform") {
arangodb::velocypack::Options options;
query_t query = _request->toVelocyPackBuilderPtr(&options);

View File

@ -316,7 +316,9 @@ bool Supervision::updateSnapshot() {
if (_agent == nullptr || this->isStopping()) {
return false;
}
try {
_snapshot = _agent->readDB().get(_agencyPrefix);
} catch (...) {}
return true;
}
@ -339,7 +341,7 @@ void Supervision::run() {
// make sense at all without other ArangoDB servers, we wait pretty
// long here before giving up:
if (!updateAgencyPrefix(1000, 1)) {
LOG_TOPIC(ERR, Logger::AGENCY)
LOG_TOPIC(DEBUG, Logger::AGENCY)
<< "Cannot get prefix from Agency. Stopping supervision for good.";
return;
}

View File

@ -1357,6 +1357,11 @@ size_t ClusterComm::performSingleRequest(
THROW_ARANGO_EXCEPTION(TRI_ERROR_CLUSTER_BACKEND_UNAVAILABLE);
}
if (req.result.status == CL_COMM_ERROR && req.result.result != nullptr
&& req.result.result->getHttpReturnCode() == 503) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_CLUSTER_BACKEND_UNAVAILABLE);
}
// Add correct recognition of content type later.
basics::StringBuffer& buffer = req.result.result->getBody();
const char* body = buffer.c_str();

View File

@ -159,6 +159,9 @@ bool GeneralServer::handleRequestAsync(GeneralCommTask* task,
if (res != TRI_ERROR_DISPATCHER_IS_STOPPING) {
LOG(WARN) << "unable to add job to the job queue: "
<< TRI_errno_string(res);
} else {
task->handleSimpleError(GeneralResponse::ResponseCode::SERVICE_UNAVAILABLE);
return true;
}
// todo send info to async work manager?
return false;
@ -194,6 +197,11 @@ bool GeneralServer::handleRequest(GeneralCommTask* task,
// add the job to the dispatcher
int res = DispatcherFeature::DISPATCHER->addJob(job, startThread);
if (res == TRI_ERROR_DISPATCHER_IS_STOPPING) {
task->handleSimpleError(GeneralResponse::ResponseCode::SERVICE_UNAVAILABLE);
return true;
}
// job is in queue now
return res == TRI_ERROR_NO_ERROR;
}

View File

@ -164,6 +164,10 @@ static int runServer(int argc, char** argv) {
try {
server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
}
} catch (std::exception const& ex) {
LOG(ERR) << "arangod terminated because of an unhandled exception: "
<< ex.what();

View File

@ -64,6 +64,10 @@ int main(int argc, char* argv[]) {
try {
server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
}
} catch (std::exception const& ex) {
LOG(ERR) << "arangobench terminated because of an unhandled exception: "
<< ex.what();

View File

@ -60,6 +60,10 @@ int main(int argc, char* argv[]) {
try {
server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
}
} catch (std::exception const& ex) {
LOG(ERR) << "arangodump terminated because of an unhandled exception: "
<< ex.what();

View File

@ -62,6 +62,10 @@ int main(int argc, char* argv[]) {
try {
server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
}
} catch (std::exception const& ex) {
LOG(ERR) << "arangoimp terminated because of an unhandled exception: "
<< ex.what();

View File

@ -62,6 +62,10 @@ int main(int argc, char* argv[]) {
try {
server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
}
} catch (std::exception const& ex) {
LOG(ERR) << "arangorestore terminated because of an unhandled exception: "
<< ex.what();

View File

@ -72,6 +72,10 @@ int main(int argc, char* argv[]) {
try {
server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
}
} catch (std::exception const& ex) {
LOG(ERR) << "arangosh terminated because of an unhandled exception: "
<< ex.what();

View File

@ -56,6 +56,10 @@ int main(int argc, char* argv[]) {
try {
server.run(argc, argv);
if (server.helpShown()) {
// --help was displayed
ret = EXIT_SUCCESS;
}
} catch (std::exception const& ex) {
LOG(ERR) << "arangovpack terminated because of an unhandled exception: "
<< ex.what();

View File

@ -166,6 +166,11 @@ void ApplicationServer::run(int argc, char* argv[]) {
// file(s)
parseOptions(argc, argv);
if (!_helpSection.empty()) {
// help shown. we can exit early
return;
}
// seal the options
_options->seal();
@ -285,17 +290,17 @@ void ApplicationServer::collectOptions() {
void ApplicationServer::parseOptions(int argc, char* argv[]) {
ArgumentParser parser(_options.get());
std::string helpSection = parser.helpSection(argc, argv);
_helpSection = parser.helpSection(argc, argv);
if (!helpSection.empty()) {
if (!_helpSection.empty()) {
// user asked for "--help"
// translate "all" to "*"
if (helpSection == "all") {
helpSection = "*";
if (_helpSection == "all") {
_helpSection = "*";
}
_options->printHelp(helpSection);
exit(EXIT_SUCCESS);
_options->printHelp(_helpSection);
return;
}
if (!parser.parse(argc, argv)) {

View File

@ -166,6 +166,9 @@ class ApplicationServer {
~ApplicationServer();
std::string helpSection() const { return _helpSection; }
bool helpShown() const { return !_helpSection.empty(); }
// adds a feature to the application server. the application server
// will take ownership of the feature object and destroy it in its
// destructor
@ -297,6 +300,9 @@ class ApplicationServer {
// reporter for progress
std::vector<ProgressHandler> _progressReports;
// help section displayed
std::string _helpSection;
};
}
}

View File

@ -49,7 +49,9 @@ VPackSlice FakeRequest::payload(arangodb::velocypack::Options const* options) {
if( _contentType == ContentType::JSON) {
VPackParser parser(options);
if (_contentLength > 0) {
parser.parse(_body, static_cast<size_t>(_contentLength));
}
_vpackBuilder = parser.steal();
return VPackSlice(_vpackBuilder->slice());
} else /*VPACK*/{

View File

@ -69,7 +69,7 @@ for aid in `seq 0 $(( $NRAGENTS - 1 ))`; do
--agency.pool-size $NRAGENTS \
--agency.supervision true \
--agency.supervision-frequency $SFRE \
--agency.wait-for-sync true \
--agency.wait-for-sync false \
--agency.election-timeout-min $MINP \
--agency.election-timeout-max $MAXP \
--database.directory cluster/data$port \