mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of https://github.com/arangodb/arangodb into devel
This commit is contained in:
commit
6c57f4eb67
|
@ -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
|
||||
################################################################################
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -142,6 +142,7 @@ struct config_t {
|
|||
|
||||
/// @brief of active agents
|
||||
query_t activeToBuilder () const;
|
||||
query_t activeAgentsToBuilder () const;
|
||||
query_t poolToBuilder () const;
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -54,6 +54,9 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
void activeAgency();
|
||||
void gossip();
|
||||
|
||||
Agent* _agent;
|
||||
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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*/{
|
||||
|
|
|
@ -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 \
|
||||
|
|
Loading…
Reference in New Issue