mirror of https://gitee.com/bigwinds/arangodb
WIP
This commit is contained in:
parent
3d2cc31306
commit
922753ef3d
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "ActionFeature.h"
|
||||
|
||||
#include "Actions/actions.h"
|
||||
#include "ProgramOptions/ProgramOptions.h"
|
||||
#include "ProgramOptions/Section.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
|
@ -34,7 +35,9 @@ using namespace arangodb::options;
|
|||
ActionFeature* ActionFeature::ACTION = nullptr;
|
||||
|
||||
ActionFeature::ActionFeature(application_features::ApplicationServer* server)
|
||||
: ApplicationFeature(server, "Action") {}
|
||||
: ApplicationFeature(server, "Action") {
|
||||
startsAfter("Logger");
|
||||
}
|
||||
|
||||
void ActionFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
|
||||
LOG_TOPIC(TRACE, Logger::STARTUP) << name() << "::collectOptions";
|
||||
|
@ -68,5 +71,7 @@ void ActionFeature::start() {
|
|||
void ActionFeature::stop() {
|
||||
LOG_TOPIC(TRACE, Logger::STARTUP) << name() << "::stop";
|
||||
|
||||
ACTION = this;
|
||||
TRI_CleanupActions();
|
||||
|
||||
ACTION = nullptr;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Kaveh Vahedipour
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "AgencyFeature.h"
|
||||
|
||||
#include "Agency/Agent.h"
|
||||
#include "Logger/Logger.h"
|
||||
#include "ProgramOptions/ProgramOptions.h"
|
||||
#include "ProgramOptions/Section.h"
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::basics;
|
||||
using namespace arangodb::options;
|
||||
using namespace arangodb::rest;
|
||||
|
||||
AgencyFeature::AgencyFeature(application_features::ApplicationServer* server)
|
||||
: ApplicationFeature(server, "Agency"),
|
||||
_size(1),
|
||||
_agentId((std::numeric_limits<uint32_t>::max)()),
|
||||
_minElectionTimeout(0.15),
|
||||
_maxElectionTimeout(1.0),
|
||||
_electionCallRateMultiplier(0.85),
|
||||
_notify(false) {
|
||||
setOptional(false);
|
||||
requiresElevatedPrivileges(false);
|
||||
startsAfter("Database");
|
||||
startsAfter("Dispatcher");
|
||||
startsAfter("Scheduler");
|
||||
startsAfter("Server");
|
||||
}
|
||||
|
||||
AgencyFeature::~AgencyFeature() {}
|
||||
|
||||
void AgencyFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
|
||||
LOG_TOPIC(TRACE, Logger::STARTUP) << name() << "::collectOptions";
|
||||
|
||||
options->addSection("agency", "Configure the agency");
|
||||
|
||||
options->addOption("--agency.size", "number of agents",
|
||||
new UInt64Parameter(&_size));
|
||||
|
||||
options->addOption("--agency.id", "this agent's id",
|
||||
new UInt32Parameter(&_agentId));
|
||||
|
||||
options->addOption(
|
||||
"--agency.election-timeout-min",
|
||||
"minimum timeout before an agent calls for new election [s]",
|
||||
new DoubleParameter(&_minElectionTimeout));
|
||||
|
||||
options->addOption(
|
||||
"--agency.election-timeout-max",
|
||||
"maximum timeout before an agent calls for new election [s]",
|
||||
new DoubleParameter(&_maxElectionTimeout));
|
||||
|
||||
options->addOption("--agency.endpoint", "agency endpoints",
|
||||
new VectorParameter<StringParameter>(&_agencyEndpoints));
|
||||
|
||||
options->addOption("--agency.election-call-rate-multiplier",
|
||||
"Multiplier (<1.0) defining how long the election timeout "
|
||||
"is with respect to the minumum election timeout",
|
||||
new DoubleParameter(&_electionCallRateMultiplier));
|
||||
|
||||
options->addOption("--agency.notify", "notify others",
|
||||
new BooleanParameter(&_notify));
|
||||
}
|
||||
|
||||
void AgencyFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
|
||||
LOG_TOPIC(TRACE, Logger::STARTUP) << name() << "::validateOptions";
|
||||
|
||||
_disabled = (_agentId == (std::numeric_limits<uint32_t>::max)());
|
||||
|
||||
if (_disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_size < 1) {
|
||||
LOG_TOPIC(FATAL, Logger::AGENCY)
|
||||
<< "AGENCY: agency must have size greater 0";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
if (_size % 2 == 0) {
|
||||
LOG_TOPIC(FATAL, Logger::AGENCY)
|
||||
<< "AGENCY: agency must have odd number of members";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
if (_agentId >= _size) {
|
||||
LOG_TOPIC(FATAL, Logger::AGENCY) << "agency.id must not be larger than or "
|
||||
<< "equal to agency.size";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
if (_minElectionTimeout <= 0.) {
|
||||
LOG_TOPIC(FATAL, Logger::AGENCY)
|
||||
<< "agency.election-timeout-min must not be negative!";
|
||||
FATAL_ERROR_EXIT();
|
||||
} else if (_minElectionTimeout < 0.15) {
|
||||
LOG_TOPIC(WARN, Logger::AGENCY)
|
||||
<< "very short agency.election-timeout-min!";
|
||||
}
|
||||
|
||||
if (_maxElectionTimeout <= _minElectionTimeout) {
|
||||
LOG_TOPIC(FATAL, Logger::AGENCY)
|
||||
<< "agency.election-timeout-max must not be shorter than or"
|
||||
<< "equal to agency.election-timeout-min.";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
if (_maxElectionTimeout <= 2 * _minElectionTimeout) {
|
||||
LOG_TOPIC(WARN, Logger::AGENCY)
|
||||
<< "agency.election-timeout-max should probably be chosen longer!";
|
||||
}
|
||||
}
|
||||
|
||||
void AgencyFeature::prepare() {
|
||||
LOG_TOPIC(TRACE, Logger::STARTUP) << name() << "::prepare";
|
||||
|
||||
_agencyEndpoints.resize(_size);
|
||||
}
|
||||
|
||||
void AgencyFeature::start() {
|
||||
LOG_TOPIC(TRACE, Logger::STARTUP) << name() << "::start";
|
||||
|
||||
if (_disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
_agent.reset(new consensus::Agent(
|
||||
consensus::config_t(_agentId, _minElectionTimeout, _maxElectionTimeout,
|
||||
_agencyEndpoints, _notify)));
|
||||
|
||||
_agent->start();
|
||||
}
|
||||
|
||||
void AgencyFeature::stop() {
|
||||
LOG_TOPIC(TRACE, Logger::STARTUP) << name() << "::stop";
|
||||
|
||||
if (_disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
_agent->beginShutdown();
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Kaveh Vahedipour
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGOD_AGENCY_APPLICATION_AGENCY_H
|
||||
#define ARANGOD_AGENCY_APPLICATION_AGENCY_H 1
|
||||
|
||||
#include "ApplicationFeatures/ApplicationFeature.h"
|
||||
|
||||
namespace arangodb {
|
||||
namespace consensus {
|
||||
class Agent;
|
||||
}
|
||||
|
||||
class AgencyFeature : virtual public application_features::ApplicationFeature {
|
||||
AgencyFeature(AgencyFeature const&) = delete;
|
||||
AgencyFeature& operator=(AgencyFeature const&) = delete;
|
||||
|
||||
public:
|
||||
explicit AgencyFeature(application_features::ApplicationServer* server);
|
||||
~AgencyFeature();
|
||||
|
||||
public:
|
||||
void collectOptions(std::shared_ptr<options::ProgramOptions>) override;
|
||||
void validateOptions(std::shared_ptr<options::ProgramOptions>) override;
|
||||
void prepare() override final;
|
||||
void start() override final;
|
||||
void stop() override final;
|
||||
|
||||
private:
|
||||
uint64_t _size; // agency size (default: 5)
|
||||
uint32_t _agentId;
|
||||
double _minElectionTimeout; // min election timeout
|
||||
double _maxElectionTimeout; // max election timeout
|
||||
std::vector<std::string> _agencyEndpoints; // agency adresses
|
||||
double _electionCallRateMultiplier;
|
||||
bool _notify; // interval between retry to slaves
|
||||
|
||||
public:
|
||||
consensus::Agent* agent() const { return _agent.get(); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<consensus::Agent> _agent;
|
||||
bool _disabled;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,169 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Kaveh Vahedipour
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "Basics/win-utils.h"
|
||||
#endif
|
||||
|
||||
#include "Logger/Logger.h"
|
||||
#include "Scheduler/PeriodicTask.h"
|
||||
|
||||
#include "ApplicationAgency.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace arangodb::basics;
|
||||
using namespace arangodb::rest;
|
||||
|
||||
ApplicationAgency::ApplicationAgency()
|
||||
: ApplicationFeature("agency"), _size(1), _min_election_timeout(0.15),
|
||||
_max_election_timeout(1.0), _election_call_rate_mul(0.85), _notify(false),
|
||||
_agent_id((std::numeric_limits<uint32_t>::max)()) {
|
||||
}
|
||||
|
||||
|
||||
ApplicationAgency::~ApplicationAgency() {}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sets the processor affinity
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ApplicationAgency::setupOptions(
|
||||
std::map<std::string, ProgramOptionsDescription>& options) {
|
||||
options["Agency Options:help-agency"]("agency.size", &_size, "Agency size")
|
||||
("agency.id", &_agent_id, "This agent's id")
|
||||
("agency.election-timeout-min", &_min_election_timeout, "Minimum "
|
||||
"timeout before an agent calls for new election [s]")
|
||||
("agency.election-timeout-max", &_max_election_timeout, "Minimum "
|
||||
"timeout before an agent calls for new election [s]")
|
||||
("agency.endpoint", &_agency_endpoints, "Agency endpoints")
|
||||
("agency.election_call_rate_mul [au]", &_election_call_rate_mul,
|
||||
"Multiplier (<1.0) defining how long the election timeout is with respect "
|
||||
"to the minumum election timeout")
|
||||
("agency.notify", &_notify, "Notify others");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool ApplicationAgency::afterOptionParsing (ProgramOptions& opts) {
|
||||
// LOG_TOPIC(WARN, Logger::AGENCY) << "Server endpoint " << opts.has("server.endpoint");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ApplicationAgency::prepare() {
|
||||
|
||||
_disabled = (_agent_id == (std::numeric_limits<uint32_t>::max)());
|
||||
|
||||
if (_disabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_size < 1) {
|
||||
LOG_TOPIC(ERR, Logger::AGENCY) << "AGENCY: agency must have size greater 0";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (_size % 2 == 0) {
|
||||
LOG_TOPIC(ERR, Logger::AGENCY)
|
||||
<< "AGENCY: agency must have odd number of members";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_agent_id == (std::numeric_limits<uint32_t>::max)()) {
|
||||
LOG_TOPIC(ERR, Logger::AGENCY) << "agency.id must be specified";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_agent_id >= _size) {
|
||||
LOG_TOPIC(ERR, Logger::AGENCY) << "agency.id must not be larger than or "
|
||||
<< "equal to agency.size";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_min_election_timeout <= 0.) {
|
||||
LOG_TOPIC(ERR, Logger::AGENCY)
|
||||
<< "agency.election-timeout-min must not be negative!";
|
||||
return false;
|
||||
} else if (_min_election_timeout < .15) {
|
||||
LOG_TOPIC(WARN, Logger::AGENCY)
|
||||
<< "very short agency.election-timeout-min!";
|
||||
}
|
||||
|
||||
if (_max_election_timeout <= _min_election_timeout) {
|
||||
LOG_TOPIC(ERR, Logger::AGENCY)
|
||||
<< "agency.election-timeout-max must not be shorter than or"
|
||||
<< "equal to agency.election-timeout-min.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_max_election_timeout <= 2*_min_election_timeout) {
|
||||
LOG_TOPIC(WARN, Logger::AGENCY)
|
||||
<< "agency.election-timeout-max should probably be chosen longer!";
|
||||
}
|
||||
|
||||
_agency_endpoints.resize(_size);
|
||||
|
||||
_agent = std::unique_ptr<agent_t>(
|
||||
new agent_t(arangodb::consensus::config_t(
|
||||
_agent_id, _min_election_timeout, _max_election_timeout,
|
||||
_agency_endpoints, _notify)));
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool ApplicationAgency::start() {
|
||||
if (_disabled) {
|
||||
return true;
|
||||
}
|
||||
_agent->start();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ApplicationAgency::open() { return true; }
|
||||
|
||||
|
||||
void ApplicationAgency::close() {
|
||||
if (_disabled) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ApplicationAgency::stop() {
|
||||
if (_disabled) {
|
||||
return;
|
||||
}
|
||||
_agent->beginShutdown();
|
||||
}
|
||||
|
||||
agent_t* ApplicationAgency::agent () const {
|
||||
return _agent.get();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Kaveh Vahedipour
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGOD_AGENCY_APPLICATION_AGENCY_H
|
||||
#define ARANGOD_AGENCY_APPLICATION_AGENCY_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
|
||||
#include "ApplicationServer/ApplicationFeature.h"
|
||||
#include "Agency/Agent.h"
|
||||
|
||||
|
||||
namespace arangodb {
|
||||
namespace rest {
|
||||
class Task;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief application server with agency
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
using agent_t = consensus::Agent;
|
||||
|
||||
|
||||
class ApplicationAgency : virtual public arangodb::rest::ApplicationFeature {
|
||||
private:
|
||||
ApplicationAgency(ApplicationAgency const&);
|
||||
ApplicationAgency& operator=(ApplicationAgency const&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
ApplicationAgency();
|
||||
|
||||
|
||||
~ApplicationAgency();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief builds the dispatcher queue
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void buildStandardQueue(size_t nrThreads, size_t maxSize);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief builds the additional AQL dispatcher queue
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void buildAQLQueue(size_t nrThreads, size_t maxSize);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief builds an additional dispatcher queue
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void buildExtraQueue(size_t name, size_t nrThreads, size_t maxSize);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief returns the number of used threads
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
size_t size();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sets the processor affinity
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setProcessorAffinity(std::vector<size_t> const& cores);
|
||||
|
||||
void stop () override;
|
||||
|
||||
|
||||
public:
|
||||
#warning TODO
|
||||
#if 0
|
||||
void setupOptions(std::map<std::string,
|
||||
arangodb::basics::ProgramOptionsDescription>&) override final;
|
||||
bool afterOptionParsing (arangodb::basics::ProgramOptions &) override final;
|
||||
#endif
|
||||
|
||||
bool prepare() override final;
|
||||
bool start() override final;
|
||||
bool open() override final;
|
||||
void close() override final;
|
||||
|
||||
agent_t* agent() const;
|
||||
|
||||
private:
|
||||
|
||||
uint64_t _size; /**< @brief: agency size (default: 5)*/
|
||||
double _min_election_timeout; /**< @brief: min election timeout */
|
||||
double _max_election_timeout; /**< @brief: max election timeout */
|
||||
double _election_call_rate_mul; /**< @brief: */
|
||||
bool _notify;
|
||||
/**< @brief interval between retry to slaves*/
|
||||
std::vector<std::string> _agency_endpoints; /**< @brief agency adresses */
|
||||
std::unique_ptr<agent_t> _agent;
|
||||
uint32_t _agent_id;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
namespace arangodb {
|
||||
extern ConfigFeature CONFIG_FEATURE;
|
||||
extern LoggerFeature LOGGER_FEATURE;
|
||||
extern SslFeature SSL_FEATURE;
|
||||
|
||||
#if 0
|
||||
options["Hidden Options"]
|
||||
#ifdef ARANGODB_HAVE_SETUID
|
||||
("uid", &_uid, "switch to user-id after reading config files")
|
||||
#endif
|
||||
#ifdef ARANGODB_HAVE_SETGID
|
||||
("gid", &_gid, "switch to group-id after reading config files")
|
||||
#endif
|
||||
;
|
||||
|
||||
#if defined(ARANGODB_HAVE_SETUID) || defined(ARANGODB_HAVE_SETGID)
|
||||
|
||||
options["General Options:help-admin"]
|
||||
#ifdef ARANGODB_HAVE_GETPPID
|
||||
("exit-on-parent-death", &_exitOnParentDeath, "exit if parent dies")
|
||||
#endif
|
||||
("watch-process", &_watchParent,
|
||||
"exit if process with given PID dies");
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#warning TODO
|
||||
#if 0
|
||||
// .............................................................................
|
||||
// UID and GID
|
||||
// .............................................................................
|
||||
|
||||
extractPrivileges();
|
||||
dropPrivilegesPermanently();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief checks if the parent is still alive
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool ApplicationServer::checkParent() {
|
||||
// check our parent, if it died given up
|
||||
#ifdef ARANGODB_HAVE_GETPPID
|
||||
if (_exitOnParentDeath && getppid() == 1) {
|
||||
LOG(INFO) << "parent has died";
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// unfortunately even though windows has <signal.h>, there is no
|
||||
// kill method defined. Notice that the kill below is not to terminate
|
||||
// the process.
|
||||
#ifdef TRI_HAVE_SIGNAL_H
|
||||
if (_watchParent != 0) {
|
||||
#ifdef TRI_HAVE_POSIX
|
||||
int res = kill(_watchParent, 0);
|
||||
#else
|
||||
int res = -1;
|
||||
#endif
|
||||
if (res != 0) {
|
||||
LOG(INFO) << "parent " << _watchParent << " has died";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -220,6 +220,7 @@ void Collection::fillIndexes() const {
|
|||
// we rather look at the local indexes.
|
||||
// FIXME: Remove fillIndexesDBServer later, when it is clear that we
|
||||
// will never have to do this.
|
||||
#warning TODO Remove fillIndexesDBServer later, when it is clear that we will never have to do this.
|
||||
#if 0
|
||||
if (arangodb::ServerState::instance()->isDBServer(role) &&
|
||||
documentCollection()->_info._planId > 0) {
|
||||
|
|
|
@ -70,7 +70,7 @@ add_executable(${BIN_ARANGOD}
|
|||
Actions/RestActionHandler.cpp
|
||||
Actions/actions.cpp
|
||||
Agency/Agent.cpp
|
||||
# Agency/ApplicationAgency.cpp
|
||||
Agency/AgencyFeature.cpp
|
||||
Agency/Constituent.cpp
|
||||
Agency/State.cpp
|
||||
Agency/Store.cpp
|
||||
|
@ -139,7 +139,7 @@ add_executable(${BIN_ARANGOD}
|
|||
Aql/grammar.cpp
|
||||
Aql/tokens.cpp
|
||||
Cluster/AgencyComm.cpp
|
||||
# TODO Cluster/ApplicationCluster.cpp
|
||||
Cluster/ClusterFeature.cpp
|
||||
Cluster/ClusterComm.cpp
|
||||
Cluster/ClusterInfo.cpp
|
||||
Cluster/ClusterMethods.cpp
|
||||
|
|
|
@ -1,266 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGOD_CLUSTER_APPLICATION_CLUSTER_H
|
||||
#define ARANGOD_CLUSTER_APPLICATION_CLUSTER_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "ApplicationServer/ApplicationFeature.h"
|
||||
|
||||
struct TRI_server_t;
|
||||
|
||||
namespace arangodb {
|
||||
namespace rest {
|
||||
class ApplicationDispatcher;
|
||||
}
|
||||
|
||||
class ApplicationV8;
|
||||
class HeartbeatThread;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief sharding feature configuration
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ApplicationCluster : public rest::ApplicationFeature {
|
||||
private:
|
||||
ApplicationCluster(ApplicationCluster const&) = delete;
|
||||
ApplicationCluster& operator=(ApplicationCluster const&) = delete;
|
||||
|
||||
public:
|
||||
ApplicationCluster(TRI_server_t*, arangodb::rest::ApplicationDispatcher*,
|
||||
arangodb::ApplicationV8*);
|
||||
|
||||
~ApplicationCluster();
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief disable the heartbeat (used for testing)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void disableHeartbeat() { _disableHeartbeat = true; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not the cluster is enabled
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool enabled() const { return _enableCluster; }
|
||||
|
||||
public:
|
||||
#warning TODO
|
||||
// void setupOptions(std::map<std::string, basics::ProgramOptionsDescription>&) override final;
|
||||
|
||||
bool prepare() override final;
|
||||
|
||||
bool open() override final;
|
||||
|
||||
bool start() override final;
|
||||
|
||||
void close() override final;
|
||||
|
||||
void stop() override final;
|
||||
|
||||
private:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief server
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_server_t* _server;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief dispatcher
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
arangodb::rest::ApplicationDispatcher* _dispatcher;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief v8 dispatcher
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
arangodb::ApplicationV8* _applicationV8;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief thread for heartbeat
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HeartbeatThread* _heartbeat;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief heartbeat interval (in milliseconds)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint64_t _heartbeatInterval;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief was docuBlock clusterAgencyEndpoint
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<std::string> _agencyEndpoints;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief was docuBlock clusterAgencyPrefix
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string _agencyPrefix;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief was docuBlock clusterMyLocalInfo
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string _myLocalInfo;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief was docuBlock clusterMyId
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string _myId;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief was docuBlock clusterMyRole
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string _myRole;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief was docuBlock clusterMyAddress
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string _myAddress;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief was docuBlock clusterUsername
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string _username;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief was docuBlock clusterPassword
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string _password;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief data path for the cluster
|
||||
///
|
||||
/// @CMDOPT{\--cluster.data-path @CA{path}}
|
||||
///
|
||||
/// The default directory where the databases for the cluster processes are
|
||||
/// stored.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string _dataPath;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief log path for the cluster
|
||||
///
|
||||
/// @CMDOPT{\--cluster.log-path @CA{path}}
|
||||
///
|
||||
/// The default directory where the log files for the cluster processes are
|
||||
/// stored.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string _logPath;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief agent path for the cluster
|
||||
///
|
||||
/// @CMDOPT{\--cluster.agent-path @CA{path}}
|
||||
///
|
||||
/// The path to agent executable.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string _agentPath;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief arangod path for the cluster
|
||||
///
|
||||
/// @CMDOPT{\--cluster.arangod-path @CA{path}}
|
||||
///
|
||||
/// The path to arangod executable.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string _arangodPath;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief DBserver config for the cluster
|
||||
///
|
||||
/// @CMDOPT{\--cluster.dbserver-config @CA{path}}
|
||||
///
|
||||
/// The configuration file for the DBserver.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string _dbserverConfig;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief coordinator config for the cluster
|
||||
///
|
||||
/// @CMDOPT{\--cluster.coordinator-config @CA{path}}
|
||||
///
|
||||
/// The configuration file for the coordinator.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string _coordinatorConfig;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief disable the dispatcher frontend
|
||||
///
|
||||
/// @CMDOPT{\--server.disable-dispatcher-interface @CA{flag}}
|
||||
///
|
||||
/// If @LIT{true} the server can be used as dispatcher for a cluster. If you
|
||||
/// enable this option, you should secure access to the dispatcher with a
|
||||
/// password.
|
||||
///
|
||||
/// The default is @LIT{true}.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool _disableDispatcherFrontend;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief disable the dispatcher kickstarter
|
||||
///
|
||||
/// @CMDOPT{\--server.disable-dispatcher-kickstarter @CA{flag}}
|
||||
///
|
||||
/// If @LIT{true} the server can be used as kickstarter to start processes for
|
||||
/// a
|
||||
/// cluster. If you enable this option, you should secure access to the
|
||||
/// dispatcher with a password.
|
||||
///
|
||||
/// The default is @LIT{true}.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool _disableDispatcherKickstarter;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not the cluster feature is enabled
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool _enableCluster;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief flag for turning off heartbeat (used for testing)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool _disableHeartbeat;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -21,7 +21,7 @@
|
|||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "ApplicationCluster.h"
|
||||
#include "ClusterFeature.h"
|
||||
|
||||
#include "Basics/FileUtils.h"
|
||||
#include "Basics/JsonHelper.h"
|
||||
|
@ -31,130 +31,128 @@
|
|||
#include "Cluster/ClusterInfo.h"
|
||||
#include "Cluster/HeartbeatThread.h"
|
||||
#include "Cluster/ServerState.h"
|
||||
#include "Dispatcher/ApplicationDispatcher.h"
|
||||
#include "Endpoint/Endpoint.h"
|
||||
#include "Logger/Logger.h"
|
||||
#include "ProgramOptions/ProgramOptions.h"
|
||||
#include "ProgramOptions/Section.h"
|
||||
#include "SimpleHttpClient/ConnectionManager.h"
|
||||
// #include "V8Server/ApplicationV8.h"
|
||||
#include "VocBase/server.h"
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::basics;
|
||||
using namespace arangodb::options;
|
||||
|
||||
ApplicationCluster::ApplicationCluster(
|
||||
TRI_server_t* server, arangodb::rest::ApplicationDispatcher* dispatcher,
|
||||
ApplicationV8* applicationV8)
|
||||
: ApplicationFeature("Sharding"),
|
||||
_server(server),
|
||||
_dispatcher(dispatcher),
|
||||
_applicationV8(applicationV8),
|
||||
_heartbeat(nullptr),
|
||||
_heartbeatInterval(0),
|
||||
_agencyEndpoints(),
|
||||
_agencyPrefix(),
|
||||
_myId(),
|
||||
_myAddress(),
|
||||
ClusterFeature::ClusterFeature(application_features::ApplicationServer* server)
|
||||
: ApplicationFeature(server, "Cluster"),
|
||||
_username("root"),
|
||||
_password(),
|
||||
_dataPath(),
|
||||
_logPath(),
|
||||
_agentPath(),
|
||||
_arangodPath(),
|
||||
_dbserverConfig(),
|
||||
_coordinatorConfig(),
|
||||
_disableDispatcherFrontend(true),
|
||||
_disableDispatcherKickstarter(true),
|
||||
_dispatcherFrontend(false),
|
||||
_kickstarter(false),
|
||||
_enableCluster(false),
|
||||
_heartbeatThread(nullptr),
|
||||
_heartbeatInterval(0),
|
||||
_disableHeartbeat(false) {
|
||||
TRI_ASSERT(_dispatcher != nullptr);
|
||||
setOptional(false);
|
||||
requiresElevatedPrivileges(false);
|
||||
startsAfter("Database");
|
||||
startsAfter("Dispatcher");
|
||||
startsAfter("Scheduler");
|
||||
}
|
||||
|
||||
ApplicationCluster::~ApplicationCluster() {
|
||||
delete _heartbeat;
|
||||
ClusterFeature::~ClusterFeature() {
|
||||
delete _heartbeatThread;
|
||||
|
||||
// delete connection manager instance
|
||||
auto cm = httpclient::ConnectionManager::instance();
|
||||
delete cm;
|
||||
}
|
||||
|
||||
#warning TODO
|
||||
#if 0
|
||||
void ApplicationCluster::setupOptions(
|
||||
std::map<std::string, basics::ProgramOptionsDescription>& options) {
|
||||
options["Cluster options:help-cluster"]("cluster.agency-endpoint",
|
||||
&_agencyEndpoints,
|
||||
"agency endpoint to connect to")(
|
||||
"cluster.agency-prefix", &_agencyPrefix, "agency prefix")(
|
||||
"cluster.my-local-info", &_myLocalInfo, "this server's local info")(
|
||||
"cluster.my-id", &_myId, "this server's id")(
|
||||
"cluster.my-address", &_myAddress, "this server's endpoint")(
|
||||
"cluster.my-role", &_myRole, "this server's role")(
|
||||
"cluster.username", &_username,
|
||||
"username used for cluster-internal communication")(
|
||||
"cluster.password", &_password,
|
||||
"password used for cluster-internal communication")(
|
||||
"cluster.data-path", &_dataPath, "path to cluster database directory")(
|
||||
"cluster.log-path", &_logPath, "path to log directory for the cluster")(
|
||||
"cluster.agent-path", &_agentPath, "path to the agent for the cluster")(
|
||||
"cluster.arangod-path", &_arangodPath,
|
||||
"path to the arangod for the cluster")(
|
||||
"cluster.dbserver-config", &_dbserverConfig,
|
||||
"path to the DBserver configuration")(
|
||||
"cluster.coordinator-config", &_coordinatorConfig,
|
||||
"path to the coordinator configuration")(
|
||||
"cluster.disable-dispatcher-frontend", &_disableDispatcherFrontend,
|
||||
"do not show the dispatcher interface")(
|
||||
"cluster.disable-dispatcher-kickstarter", &_disableDispatcherKickstarter,
|
||||
"disable the kickstarter functionality");
|
||||
void ClusterFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
|
||||
LOG_TOPIC(TRACE, Logger::STARTUP) << name() << "::collectOptions";
|
||||
|
||||
options->addSection("cluster", "Configure the cluster");
|
||||
|
||||
options->addOption("--cluster.agency-endpoint",
|
||||
"agency endpoint to connect to",
|
||||
new VectorParameter<StringParameter>(&_agencyEndpoints));
|
||||
|
||||
options->addOption("--cluster.agency-prefix", "agency prefix",
|
||||
new StringParameter(&_agencyPrefix));
|
||||
|
||||
options->addOption("--cluster.my-local-info", "this server's local info",
|
||||
new StringParameter(&_myLocalInfo));
|
||||
|
||||
options->addOption("--cluster.my-id", "this server's id",
|
||||
new StringParameter(&_myId));
|
||||
|
||||
options->addOption("--cluster.my-role", "this server's role",
|
||||
new StringParameter(&_myRole));
|
||||
|
||||
options->addOption("--cluster.my-address", "this server's endpoint",
|
||||
new StringParameter(&_myAddress));
|
||||
|
||||
options->addOption("--cluster.username",
|
||||
"username used for cluster-internal communication",
|
||||
new StringParameter(&_username));
|
||||
|
||||
options->addOption("--cluster.password",
|
||||
"password used for cluster-internal communication",
|
||||
new StringParameter(&_password));
|
||||
|
||||
options->addOption("--cluster.data-path",
|
||||
"path to cluster database directory",
|
||||
new StringParameter(&_dataPath));
|
||||
|
||||
options->addOption("--cluster.log-path",
|
||||
"path to log directory for the cluster",
|
||||
new StringParameter(&_logPath));
|
||||
|
||||
options->addOption("--cluster.arangod-path",
|
||||
"path to the arangod for the cluster",
|
||||
new StringParameter(&_arangodPath));
|
||||
|
||||
options->addOption("--cluster.agent-path",
|
||||
"path to the agent for the cluster",
|
||||
new StringParameter(&_agentPath));
|
||||
|
||||
options->addOption("--cluster.dbserver-config",
|
||||
"path to the DBserver configuration",
|
||||
new StringParameter(&_dbserverConfig));
|
||||
|
||||
options->addOption("--cluster.coordinator-config",
|
||||
"path to the coordinator configuration",
|
||||
new StringParameter(&_coordinatorConfig));
|
||||
|
||||
options->addOption("--cluster.dispatcher-frontend",
|
||||
"show the dispatcher interface",
|
||||
new BooleanParameter(&_dispatcherFrontend));
|
||||
|
||||
options->addOption("--cluster.kickstarter", "enable the kickstarter",
|
||||
new BooleanParameter(&_kickstarter));
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ApplicationCluster::prepare() {
|
||||
// set authentication data
|
||||
ServerState::instance()->setAuthentication(_username, _password);
|
||||
void ClusterFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
|
||||
LOG_TOPIC(TRACE, Logger::STARTUP) << name() << "::validateOptions";
|
||||
|
||||
// overwrite memory area
|
||||
_username = _password = "someotherusername";
|
||||
|
||||
ServerState::instance()->setDataPath(_dataPath);
|
||||
ServerState::instance()->setLogPath(_logPath);
|
||||
ServerState::instance()->setAgentPath(_agentPath);
|
||||
ServerState::instance()->setArangodPath(_arangodPath);
|
||||
ServerState::instance()->setDBserverConfig(_dbserverConfig);
|
||||
ServerState::instance()->setCoordinatorConfig(_coordinatorConfig);
|
||||
ServerState::instance()->setDisableDispatcherFrontend(
|
||||
_disableDispatcherFrontend);
|
||||
ServerState::instance()->setDisableDispatcherKickstarter(
|
||||
_disableDispatcherKickstarter);
|
||||
|
||||
// initialize ConnectionManager library
|
||||
httpclient::ConnectionManager::initialize();
|
||||
|
||||
// initialize ClusterComm library
|
||||
// must call initialize while still single-threaded
|
||||
ClusterComm::initialize();
|
||||
|
||||
if (_disabled) {
|
||||
// if ApplicationFeature is disabled
|
||||
_enableCluster = false;
|
||||
ServerState::instance()->setRole(ServerState::ROLE_SINGLE);
|
||||
return true;
|
||||
}
|
||||
|
||||
// check the cluster state
|
||||
// check if the cluster is enabled
|
||||
_enableCluster = !_agencyEndpoints.empty();
|
||||
|
||||
if (!_enableCluster) {
|
||||
ServerState::instance()->setRole(ServerState::ROLE_SINGLE);
|
||||
return;
|
||||
}
|
||||
|
||||
// validate --cluster.agency-endpoint (currently a noop)
|
||||
if (_agencyEndpoints.empty()) {
|
||||
LOG(FATAL)
|
||||
<< "must at least specify one endpoint in --cluster.agency-endpoint";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
// validate
|
||||
if (_agencyPrefix.empty()) {
|
||||
_agencyPrefix = "arango";
|
||||
}
|
||||
|
||||
if (!enabled()) {
|
||||
ServerState::instance()->setRole(ServerState::ROLE_SINGLE);
|
||||
return true;
|
||||
}
|
||||
|
||||
ServerState::instance()->setClusterEnabled();
|
||||
|
||||
// validate --cluster.agency-prefix
|
||||
size_t found = _agencyPrefix.find_first_not_of(
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/");
|
||||
|
@ -164,28 +162,6 @@ bool ApplicationCluster::prepare() {
|
|||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
// register the prefix with the communicator
|
||||
AgencyComm::setPrefix(_agencyPrefix);
|
||||
|
||||
// validate --cluster.agency-endpoint
|
||||
if (_agencyEndpoints.empty()) {
|
||||
LOG(FATAL)
|
||||
<< "must at least specify one endpoint in --cluster.agency-endpoint";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < _agencyEndpoints.size(); ++i) {
|
||||
std::string const unified = Endpoint::unifiedForm(_agencyEndpoints[i]);
|
||||
|
||||
if (unified.empty()) {
|
||||
LOG(FATAL) << "invalid endpoint '" << _agencyEndpoints[i]
|
||||
<< "' specified for --cluster.agency-endpoint";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
AgencyComm::addEndpoint(unified);
|
||||
}
|
||||
|
||||
// validate --cluster.my-id
|
||||
if (_myId.empty()) {
|
||||
if (_myLocalInfo.empty()) {
|
||||
|
@ -208,19 +184,64 @@ bool ApplicationCluster::prepare() {
|
|||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClusterFeature::prepare() {
|
||||
LOG_TOPIC(TRACE, Logger::STARTUP) << name() << "::prepare";
|
||||
|
||||
ServerState::instance()->setAuthentication(_username, _password);
|
||||
ServerState::instance()->setDataPath(_dataPath);
|
||||
ServerState::instance()->setLogPath(_logPath);
|
||||
ServerState::instance()->setAgentPath(_agentPath);
|
||||
ServerState::instance()->setArangodPath(_arangodPath);
|
||||
ServerState::instance()->setDBserverConfig(_dbserverConfig);
|
||||
ServerState::instance()->setCoordinatorConfig(_coordinatorConfig);
|
||||
ServerState::instance()->setDisableDispatcherFrontend(!_dispatcherFrontend);
|
||||
ServerState::instance()->setDisableDispatcherKickstarter(!_kickstarter);
|
||||
|
||||
// initialize ConnectionManager library
|
||||
httpclient::ConnectionManager::initialize();
|
||||
|
||||
// create an instance (this will not yet create a thread)
|
||||
ClusterComm::instance();
|
||||
}
|
||||
|
||||
#warning TODO split into methods
|
||||
|
||||
void ClusterFeature::start() {
|
||||
LOG_TOPIC(TRACE, Logger::STARTUP) << name() << "::start";
|
||||
|
||||
// initialize ClusterComm library, must call initialize only once
|
||||
ClusterComm::initialize();
|
||||
|
||||
// return if cluster is disabled
|
||||
if (!_enableCluster) {
|
||||
return;
|
||||
}
|
||||
|
||||
ServerState::instance()->setClusterEnabled();
|
||||
|
||||
// register the prefix with the communicator
|
||||
AgencyComm::setPrefix(_agencyPrefix);
|
||||
|
||||
for (size_t i = 0; i < _agencyEndpoints.size(); ++i) {
|
||||
std::string const unified = Endpoint::unifiedForm(_agencyEndpoints[i]);
|
||||
|
||||
if (unified.empty()) {
|
||||
LOG(FATAL) << "invalid endpoint '" << _agencyEndpoints[i]
|
||||
<< "' specified for --cluster.agency-endpoint";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
AgencyComm::addEndpoint(unified);
|
||||
}
|
||||
|
||||
// Now either _myId is set properly or _myId is empty and _myLocalInfo and
|
||||
// _myAddress are set.
|
||||
if (!_myAddress.empty()) {
|
||||
ServerState::instance()->setAddress(_myAddress);
|
||||
}
|
||||
|
||||
// initialize ConnectionManager library
|
||||
// httpclient::ConnectionManager::initialize();
|
||||
|
||||
// initialize ClusterComm library
|
||||
// must call initialize while still single-threaded
|
||||
// ClusterComm::initialize();
|
||||
|
||||
// disable error logging for a while
|
||||
ClusterComm::instance()->enableConnectionErrorLogging(false);
|
||||
|
||||
|
@ -233,18 +254,21 @@ bool ApplicationCluster::prepare() {
|
|||
}
|
||||
|
||||
ServerState::instance()->setLocalInfo(_myLocalInfo);
|
||||
|
||||
if (!_myId.empty()) {
|
||||
ServerState::instance()->setId(_myId);
|
||||
}
|
||||
|
||||
if (!_myRole.empty()) {
|
||||
ServerState::RoleEnum role = ServerState::stringToRole(_myRole);
|
||||
|
||||
if (role == ServerState::ROLE_SINGLE ||
|
||||
role == ServerState::ROLE_UNDEFINED) {
|
||||
LOG(FATAL) << "Invalid role provided. Possible values: PRIMARY, "
|
||||
"SECONDARY, COORDINATOR";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
if (!ServerState::instance()->registerWithRole(role)) {
|
||||
LOG(FATAL) << "Couldn't register at agency.";
|
||||
FATAL_ERROR_EXIT();
|
||||
|
@ -260,6 +284,13 @@ bool ApplicationCluster::prepare() {
|
|||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
if (role == ServerState::ROLE_SINGLE) {
|
||||
LOG(FATAL) << "determined single-server role for server '" << _myId
|
||||
<< "'. Please check the configurarion in the agency ("
|
||||
<< endpoints << ")";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
if (_myId.empty()) {
|
||||
_myId = ServerState::instance()->getId(); // has been set by getRole!
|
||||
}
|
||||
|
@ -269,6 +300,7 @@ bool ApplicationCluster::prepare() {
|
|||
// no address given, now ask the agency for our address
|
||||
_myAddress = ServerState::instance()->getAddress();
|
||||
}
|
||||
|
||||
// if nonempty, it has already been set above
|
||||
|
||||
// If we are a coordinator, we wait until at least one DBServer is there,
|
||||
|
@ -276,30 +308,21 @@ bool ApplicationCluster::prepare() {
|
|||
// any collection:
|
||||
if (role == ServerState::ROLE_COORDINATOR) {
|
||||
ClusterInfo* ci = ClusterInfo::instance();
|
||||
do {
|
||||
|
||||
while (true) {
|
||||
LOG(INFO) << "Waiting for a DBserver to show up...";
|
||||
ci->loadCurrentDBServers();
|
||||
std::vector<ServerID> DBServers = ci->getCurrentDBServers();
|
||||
|
||||
if (DBServers.size() > 0) {
|
||||
LOG(INFO) << "Found a DBserver.";
|
||||
break;
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
} while (true);
|
||||
};
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ApplicationCluster::start() {
|
||||
if (!enabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string const endpoints = AgencyComm::getEndpointsString();
|
||||
|
||||
ServerState::RoleEnum role = ServerState::instance()->getRole();
|
||||
|
||||
if (_myAddress.empty()) {
|
||||
LOG(FATAL) << "unable to determine internal address for server '" << _myId
|
||||
<< "'. Please specify --cluster.my-address or configure the "
|
||||
|
@ -360,42 +383,33 @@ bool ApplicationCluster::start() {
|
|||
}
|
||||
|
||||
// start heartbeat thread
|
||||
_heartbeat = new HeartbeatThread(_server, _dispatcher, _applicationV8,
|
||||
_heartbeatInterval * 1000, 5);
|
||||
_heartbeatThread = new HeartbeatThread(_heartbeatInterval * 1000, 5);
|
||||
|
||||
if (_heartbeat == nullptr) {
|
||||
if (_heartbeatThread == nullptr) {
|
||||
LOG(FATAL) << "unable to start cluster heartbeat thread";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
if (!_heartbeat->init() || !_heartbeat->start()) {
|
||||
if (!_heartbeatThread->init() || !_heartbeatThread->start()) {
|
||||
LOG(FATAL) << "heartbeat could not connect to agency endpoints ("
|
||||
<< endpoints << ")";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
while (!_heartbeat->isReady()) {
|
||||
while (!_heartbeatThread->isReady()) {
|
||||
// wait until heartbeat is ready
|
||||
usleep(10000);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ApplicationCluster::open() {
|
||||
if (!enabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
AgencyComm comm;
|
||||
AgencyCommResult result;
|
||||
|
||||
bool success;
|
||||
do {
|
||||
|
||||
while (true) {
|
||||
AgencyCommLocker locker("Current", "WRITE");
|
||||
|
||||
success = locker.successful();
|
||||
|
||||
if (success) {
|
||||
VPackBuilder builder;
|
||||
try {
|
||||
|
@ -421,10 +435,9 @@ bool ApplicationCluster::open() {
|
|||
if (success) {
|
||||
break;
|
||||
}
|
||||
sleep(1);
|
||||
} while (true);
|
||||
|
||||
ServerState::RoleEnum role = ServerState::instance()->getRole();
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
if (role == ServerState::ROLE_COORDINATOR) {
|
||||
ServerState::instance()->setState(ServerState::STATE_SERVING);
|
||||
|
@ -433,28 +446,26 @@ bool ApplicationCluster::open() {
|
|||
} else if (role == ServerState::ROLE_SECONDARY) {
|
||||
ServerState::instance()->setState(ServerState::STATE_SYNCING);
|
||||
}
|
||||
return true;
|
||||
|
||||
DispatcherFeature::DISPATCHER->buildAqlQueue();
|
||||
}
|
||||
|
||||
void ApplicationCluster::close() {
|
||||
if (!enabled()) {
|
||||
return;
|
||||
void ClusterFeature::stop() {
|
||||
if (_enableCluster) {
|
||||
if (_heartbeatThread != nullptr) {
|
||||
_heartbeatThread->beginShutdown();
|
||||
}
|
||||
|
||||
// change into shutdown state
|
||||
ServerState::instance()->setState(ServerState::STATE_SHUTDOWN);
|
||||
|
||||
AgencyComm comm;
|
||||
comm.sendServerState(0.0);
|
||||
}
|
||||
|
||||
if (_heartbeat != nullptr) {
|
||||
_heartbeat->beginShutdown();
|
||||
}
|
||||
|
||||
// change into shutdown state
|
||||
ServerState::instance()->setState(ServerState::STATE_SHUTDOWN);
|
||||
|
||||
AgencyComm comm;
|
||||
comm.sendServerState(0.0);
|
||||
}
|
||||
|
||||
void ApplicationCluster::stop() {
|
||||
ClusterComm::cleanup();
|
||||
if (!enabled()) {
|
||||
|
||||
if (!_enableCluster) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -464,10 +475,6 @@ void ApplicationCluster::stop() {
|
|||
AgencyComm comm;
|
||||
comm.sendServerState(0.0);
|
||||
|
||||
if (_heartbeat != nullptr) {
|
||||
_heartbeat->beginShutdown();
|
||||
}
|
||||
|
||||
{
|
||||
AgencyCommLocker locker("Current", "WRITE");
|
||||
|
||||
|
@ -486,7 +493,7 @@ void ApplicationCluster::stop() {
|
|||
}
|
||||
}
|
||||
|
||||
while (_heartbeat->isRunning()) {
|
||||
while (_heartbeatThread->isRunning()) {
|
||||
usleep(50000);
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGOD_CLUSTER_CLUSTER_FEATURE_H
|
||||
#define ARANGOD_CLUSTER_CLUSTER_FEATURE_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
|
||||
#include "ApplicationFeatures/ApplicationFeature.h"
|
||||
|
||||
namespace arangodb {
|
||||
class HeartbeatThread;
|
||||
|
||||
class ClusterFeature : public application_features::ApplicationFeature {
|
||||
public:
|
||||
ClusterFeature(application_features::ApplicationServer*);
|
||||
~ClusterFeature();
|
||||
|
||||
public:
|
||||
// disable the heartbeat (used for testing)
|
||||
#warning TODO
|
||||
// void disableHeartbeat() { _disableHeartbeat = true; }
|
||||
|
||||
// whether or not the cluster is enabled
|
||||
#warning TODO
|
||||
// inline bool enabled() const { return _enableCluster; }
|
||||
|
||||
public:
|
||||
void collectOptions(std::shared_ptr<options::ProgramOptions>) override;
|
||||
void validateOptions(std::shared_ptr<options::ProgramOptions>) override;
|
||||
void prepare() override;
|
||||
void start() override;
|
||||
void stop() override;
|
||||
|
||||
private:
|
||||
std::vector<std::string> _agencyEndpoints;
|
||||
std::string _agencyPrefix;
|
||||
std::string _myLocalInfo;
|
||||
std::string _myId;
|
||||
std::string _myRole;
|
||||
std::string _myAddress;
|
||||
std::string _username;
|
||||
std::string _password;
|
||||
std::string _dataPath;
|
||||
std::string _logPath;
|
||||
std::string _arangodPath;
|
||||
std::string _agentPath;
|
||||
std::string _dbserverConfig;
|
||||
std::string _coordinatorConfig;
|
||||
bool _dispatcherFrontend;
|
||||
bool _kickstarter;
|
||||
|
||||
|
||||
private:
|
||||
bool _enableCluster;
|
||||
HeartbeatThread* _heartbeatThread;
|
||||
uint64_t _heartbeatInterval;
|
||||
bool _disableHeartbeat;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -22,6 +22,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "HeartbeatThread.h"
|
||||
|
||||
#include "Basics/ConditionLocker.h"
|
||||
#include "Basics/JsonHelper.h"
|
||||
#include "Logger/Logger.h"
|
||||
|
@ -32,10 +33,9 @@
|
|||
#include "Cluster/ClusterMethods.h"
|
||||
#include "Cluster/ServerJob.h"
|
||||
#include "Cluster/ServerState.h"
|
||||
// #include "Dispatcher/ApplicationDispatcher.h"
|
||||
#include "Dispatcher/Dispatcher.h"
|
||||
#include "Dispatcher/DispatcherFeature.h"
|
||||
#include "Dispatcher/Job.h"
|
||||
// #include "V8Server/ApplicationV8.h"
|
||||
#include "V8/v8-globals.h"
|
||||
#include "V8Server/v8-vocbase.h"
|
||||
#include "VocBase/auth.h"
|
||||
|
@ -50,14 +50,9 @@ volatile sig_atomic_t HeartbeatThread::HasRunOnce = 0;
|
|||
/// @brief constructs a heartbeat thread
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HeartbeatThread::HeartbeatThread(
|
||||
TRI_server_t* server, arangodb::rest::ApplicationDispatcher* dispatcher,
|
||||
ApplicationV8* applicationV8, uint64_t interval,
|
||||
uint64_t maxFailsBeforeWarning)
|
||||
HeartbeatThread::HeartbeatThread(uint64_t interval,
|
||||
uint64_t maxFailsBeforeWarning)
|
||||
: Thread("Heartbeat"),
|
||||
_server(server),
|
||||
_dispatcher(dispatcher),
|
||||
_applicationV8(applicationV8),
|
||||
_statusLock(),
|
||||
_agency(),
|
||||
_condition(),
|
||||
|
@ -68,10 +63,8 @@ HeartbeatThread::HeartbeatThread(
|
|||
_numFails(0),
|
||||
_numDispatchedJobs(0),
|
||||
_lastDispatchedJobResult(false),
|
||||
_versionThatTriggeredLastJob(0),
|
||||
_ready(false) {
|
||||
TRI_ASSERT(_dispatcher != nullptr);
|
||||
}
|
||||
_versionThatTriggeredLastJob(0),
|
||||
_ready(false) {}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destroys a heartbeat thread
|
||||
|
@ -376,7 +369,7 @@ void HeartbeatThread::runCoordinator() {
|
|||
uint64_t currentVersion =
|
||||
arangodb::basics::VelocyPackHelper::stringUInt64(
|
||||
it->second._vpack->slice());
|
||||
|
||||
|
||||
if (currentVersion > lastCurrentVersionNoticed) {
|
||||
lastCurrentVersionNoticed = currentVersion;
|
||||
|
||||
|
@ -385,7 +378,6 @@ void HeartbeatThread::runCoordinator() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (shouldSleep) {
|
||||
double remain = interval - (TRI_microtime() - start);
|
||||
|
||||
|
@ -616,19 +608,17 @@ bool HeartbeatThread::handlePlanChangeDBServer(uint64_t currentPlanVersion) {
|
|||
}
|
||||
|
||||
// schedule a job for the change
|
||||
std::unique_ptr<arangodb::rest::Job> job(
|
||||
new ServerJob(this, _server, _applicationV8));
|
||||
std::unique_ptr<arangodb::rest::Job> job(new ServerJob(this));
|
||||
|
||||
#warning TODO
|
||||
#if 0
|
||||
if (_dispatcher->dispatcher()->addJob(job) == TRI_ERROR_NO_ERROR) {
|
||||
auto dispatcher = DispatcherFeature::DISPATCHER;
|
||||
|
||||
if (dispatcher->addJob(job) == TRI_ERROR_NO_ERROR) {
|
||||
++_numDispatchedJobs;
|
||||
_versionThatTriggeredLastJob = currentPlanVersion;
|
||||
|
||||
LOG(TRACE) << "scheduled plan update handler";
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
LOG(ERR) << "could not schedule plan update handler";
|
||||
|
||||
|
|
|
@ -24,12 +24,12 @@
|
|||
#ifndef ARANGOD_CLUSTER_HEARTBEAT_THREAD_H
|
||||
#define ARANGOD_CLUSTER_HEARTBEAT_THREAD_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "Basics/Thread.h"
|
||||
|
||||
#include "Basics/ConditionVariable.h"
|
||||
#include "Basics/Mutex.h"
|
||||
#include "Basics/Thread.h"
|
||||
#include "Logger/Logger.h"
|
||||
#include "Cluster/AgencyComm.h"
|
||||
#include "Logger/Logger.h"
|
||||
|
||||
struct TRI_server_t;
|
||||
struct TRI_vocbase_t;
|
||||
|
@ -42,14 +42,11 @@ class ApplicationDispatcher;
|
|||
class ApplicationV8;
|
||||
|
||||
class HeartbeatThread : public Thread {
|
||||
private:
|
||||
HeartbeatThread(HeartbeatThread const&);
|
||||
HeartbeatThread& operator=(HeartbeatThread const&);
|
||||
HeartbeatThread(HeartbeatThread const&) = delete;
|
||||
HeartbeatThread& operator=(HeartbeatThread const&) = delete;
|
||||
|
||||
public:
|
||||
HeartbeatThread(TRI_server_t*, arangodb::rest::ApplicationDispatcher*,
|
||||
ApplicationV8*, uint64_t, uint64_t);
|
||||
|
||||
HeartbeatThread(uint64_t, uint64_t);
|
||||
~HeartbeatThread();
|
||||
|
||||
public:
|
||||
|
@ -154,18 +151,6 @@ class HeartbeatThread : public Thread {
|
|||
|
||||
TRI_server_t* _server;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Job dispatcher
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
arangodb::rest::ApplicationDispatcher* _dispatcher;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief v8 dispatcher
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ApplicationV8* _applicationV8;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief status lock
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -24,12 +24,13 @@
|
|||
#include "ServerJob.h"
|
||||
|
||||
#include "Basics/MutexLocker.h"
|
||||
#include "Logger/Logger.h"
|
||||
#include "Cluster/HeartbeatThread.h"
|
||||
#include "Cluster/ClusterInfo.h"
|
||||
#include "Cluster/HeartbeatThread.h"
|
||||
#include "Dispatcher/DispatcherQueue.h"
|
||||
#include "Logger/Logger.h"
|
||||
#include "V8/v8-utils.h"
|
||||
// #include "V8Server/ApplicationV8.h"
|
||||
#include "V8Server/V8Context.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
#include "VocBase/server.h"
|
||||
#include "VocBase/vocbase.h"
|
||||
|
||||
|
@ -42,12 +43,9 @@ static arangodb::Mutex ExecutorLock;
|
|||
/// @brief constructs a new db server job
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ServerJob::ServerJob(HeartbeatThread* heartbeat, TRI_server_t* server,
|
||||
ApplicationV8* applicationV8)
|
||||
ServerJob::ServerJob(HeartbeatThread* heartbeat)
|
||||
: Job("HttpServerJob"),
|
||||
_heartbeat(heartbeat),
|
||||
_server(server),
|
||||
_applicationV8(applicationV8),
|
||||
_shutdown(0),
|
||||
_abandon(false) {}
|
||||
|
||||
|
@ -90,10 +88,9 @@ void ServerJob::cleanup(DispatcherQueue* queue) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool ServerJob::execute() {
|
||||
#warning TODO
|
||||
#if 0
|
||||
// default to system database
|
||||
TRI_vocbase_t* const vocbase = TRI_UseDatabaseServer(_server, TRI_VOC_SYSTEM_DATABASE);
|
||||
TRI_vocbase_t* const vocbase =
|
||||
TRI_UseDatabaseServer(_server, TRI_VOC_SYSTEM_DATABASE);
|
||||
|
||||
if (vocbase == nullptr) {
|
||||
// database is gone
|
||||
|
@ -102,15 +99,15 @@ bool ServerJob::execute() {
|
|||
|
||||
TRI_DEFER(TRI_ReleaseVocBase(vocbase));
|
||||
|
||||
ApplicationV8::V8Context* context =
|
||||
_applicationV8->enterContext(vocbase, true);
|
||||
V8Context* context = V8DealerFeature::DEALER->enterContext(vocbase, true);
|
||||
|
||||
if (context == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ok = true;
|
||||
auto isolate = context->isolate;
|
||||
auto isolate = context->_isolate;
|
||||
|
||||
try {
|
||||
v8::HandleScope scope(isolate);
|
||||
|
||||
|
@ -121,7 +118,8 @@ bool ServerJob::execute() {
|
|||
v8::Handle<v8::Value> res = TRI_ExecuteJavaScriptString(
|
||||
isolate, isolate->GetCurrentContext(), content, file, false);
|
||||
if (res->IsBoolean() && res->IsTrue()) {
|
||||
LOG(ERR) << "An error occurred whilst executing the handlePlanChange in JavaScript.";
|
||||
LOG(ERR) << "An error occurred whilst executing the handlePlanChange in "
|
||||
"JavaScript.";
|
||||
ok = false; // The heartbeat thread will notice this!
|
||||
}
|
||||
// invalidate our local cache, even if an error occurred
|
||||
|
@ -129,8 +127,7 @@ bool ServerJob::execute() {
|
|||
} catch (...) {
|
||||
}
|
||||
|
||||
_applicationV8->exitContext(context);
|
||||
V8DealerFeature::DEALER->exitContext(context);
|
||||
|
||||
return ok;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -24,38 +24,22 @@
|
|||
#ifndef ARANGOD_CLUSTER_SERVER_JOB_H
|
||||
#define ARANGOD_CLUSTER_SERVER_JOB_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "Dispatcher/Job.h"
|
||||
|
||||
#include "Basics/Exceptions.h"
|
||||
#include "Basics/Mutex.h"
|
||||
#include "Dispatcher/Job.h"
|
||||
|
||||
struct TRI_server_t;
|
||||
|
||||
namespace arangodb {
|
||||
class HeartbeatThread;
|
||||
class ApplicationV8;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief general server job
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ServerJob : public arangodb::rest::Job {
|
||||
private:
|
||||
ServerJob(ServerJob const&) = delete;
|
||||
ServerJob& operator=(ServerJob const&) = delete;
|
||||
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief constructs a new db server job
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ServerJob(HeartbeatThread* heartbeat, TRI_server_t* server,
|
||||
ApplicationV8* applicationV8);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destructs a db server job
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ServerJob(HeartbeatThread* heartbeat);
|
||||
~ServerJob();
|
||||
|
||||
public:
|
||||
|
@ -104,12 +88,6 @@ class ServerJob : public arangodb::rest::Job {
|
|||
|
||||
TRI_server_t* _server;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief v8 dispatcher
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ApplicationV8* _applicationV8;
|
||||
|
||||
protected:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief shutdown in progress
|
||||
|
|
|
@ -43,10 +43,10 @@ DispatcherFeature::DispatcherFeature(
|
|||
: ApplicationFeature(server, "Dispatcher"),
|
||||
_nrStandardThreads(8),
|
||||
_nrAqlThreads(0),
|
||||
_queueSize(16384),
|
||||
_startAqlQueue(false) {
|
||||
_queueSize(16384) {
|
||||
setOptional(true);
|
||||
requiresElevatedPrivileges(false);
|
||||
startsAfter("FileDescriptorsFeature");
|
||||
startsAfter("Logger");
|
||||
startsAfter("Scheduler");
|
||||
startsAfter("WorkMonitor");
|
||||
|
@ -96,10 +96,6 @@ void DispatcherFeature::start() {
|
|||
buildDispatcher();
|
||||
buildStandardQueue();
|
||||
|
||||
if (_startAqlQueue) {
|
||||
buildAqlQueue();
|
||||
}
|
||||
|
||||
V8DealerFeature* dealer = dynamic_cast<V8DealerFeature*>(
|
||||
ApplicationServer::lookupFeature("V8Dealer"));
|
||||
|
||||
|
@ -143,28 +139,3 @@ void DispatcherFeature::setProcessorAffinity(std::vector<size_t> const& cores) {
|
|||
_dispatcher->setProcessorAffinity(Dispatcher::STANDARD_QUEUE, cores);
|
||||
#endif
|
||||
}
|
||||
|
||||
#warning TODO
|
||||
#if 0
|
||||
|
||||
// now we can create the queues
|
||||
if (startServer) {
|
||||
if (role == ServerState::ROLE_COORDINATOR ||
|
||||
role == ServerState::ROLE_PRIMARY ||
|
||||
role == ServerState::ROLE_SECONDARY) {
|
||||
_applicationDispatcher->buildAQLQueue(_dispatcherThreads,
|
||||
(int)_dispatcherQueueSize);
|
||||
}
|
||||
}
|
||||
|
||||
== == == == == == == == == == == == == == == == == == == == == == == == == == ==
|
||||
== == == == == == == == == == == == ==
|
||||
|
||||
if (!startServer) {
|
||||
_applicationDispatcher->disable();
|
||||
}
|
||||
|
||||
== == == == == == == == == == == == == == == == == == == == == == == == == == ==
|
||||
== == == == == == == == == == == == ==
|
||||
|
||||
#endif
|
||||
|
|
|
@ -63,7 +63,6 @@ class DispatcherFeature final
|
|||
uint64_t _nrStandardThreads;
|
||||
uint64_t _nrAqlThreads;
|
||||
uint64_t _queueSize;
|
||||
bool _startAqlQueue;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "DatabaseFeature.h"
|
||||
|
||||
#include "Aql/QueryCache.h"
|
||||
#include "Aql/QueryRegistry.h"
|
||||
#include "Basics/StringUtils.h"
|
||||
#include "Basics/ThreadPool.h"
|
||||
|
@ -66,6 +67,7 @@ DatabaseFeature::DatabaseFeature(ApplicationServer* server)
|
|||
_upgrade(false) {
|
||||
setOptional(false);
|
||||
requiresElevatedPrivileges(false);
|
||||
startsAfter("FileDescriptorsFeature");
|
||||
startsAfter("Language");
|
||||
startsAfter("Logger");
|
||||
startsAfter("Random");
|
||||
|
@ -122,19 +124,6 @@ void DatabaseFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
|
|||
options->addOption("--query.tracking", "wether to track queries",
|
||||
new BooleanParameter(&_queryTracking));
|
||||
|
||||
#warning TODO
|
||||
#if 0
|
||||
// set global query tracking flag
|
||||
arangodb::aql::Query::DisableQueryTracking(_disableQueryTracking);
|
||||
|
||||
// configure the query cache
|
||||
{
|
||||
std::pair<std::string, size_t> cacheProperties{_queryCacheMode,
|
||||
_queryCacheMaxResults};
|
||||
arangodb::aql::QueryCache::instance()->setProperties(cacheProperties);
|
||||
}
|
||||
#endif
|
||||
|
||||
options->addOption("--query.cache-mode",
|
||||
"mode for the AQL query cache (on, off, demand)",
|
||||
new StringParameter(&_queryCacheMode));
|
||||
|
@ -179,6 +168,18 @@ void DatabaseFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
|
|||
}
|
||||
}
|
||||
|
||||
void DatabaseFeature::prepare() {
|
||||
// set global query tracking flag
|
||||
arangodb::aql::Query::DisableQueryTracking(!_queryTracking);
|
||||
|
||||
// configure the query cache
|
||||
{
|
||||
std::pair<std::string, size_t> cacheProperties{_queryCacheMode,
|
||||
_queryCacheEntries};
|
||||
arangodb::aql::QueryCache::instance()->setProperties(cacheProperties);
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseFeature::start() {
|
||||
LOG_TOPIC(TRACE, Logger::STARTUP) << name() << "::start";
|
||||
|
||||
|
@ -187,7 +188,7 @@ void DatabaseFeature::start() {
|
|||
// sanity check
|
||||
if (_checkVersion && _upgrade) {
|
||||
LOG(FATAL) << "cannot specify both '--database.check-version' and "
|
||||
"'--database.upgrade'";
|
||||
"'--database.upgrade'";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
|
@ -322,14 +323,12 @@ void DatabaseFeature::openDatabases() {
|
|||
_indexPool.reset(new ThreadPool(_indexThreads, "IndexBuilder"));
|
||||
}
|
||||
|
||||
#warning appPath
|
||||
|
||||
bool const iterateMarkersOnOpen =
|
||||
!wal::LogfileManager::instance()->hasFoundLastTick();
|
||||
|
||||
int res = TRI_InitServer(
|
||||
_server.get(), _indexPool.get(), _databasePath.c_str(), nullptr,
|
||||
&defaults, !_replicationApplier, _disableCompactor, iterateMarkersOnOpen);
|
||||
_server.get(), _indexPool.get(), _databasePath.c_str(), &defaults,
|
||||
!_replicationApplier, _disableCompactor, iterateMarkersOnOpen);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
LOG(FATAL) << "cannot create server instance: out of memory";
|
||||
|
@ -353,12 +352,6 @@ void DatabaseFeature::openDatabases() {
|
|||
void DatabaseFeature::closeDatabases() {
|
||||
TRI_ASSERT(_server != nullptr);
|
||||
|
||||
// cleanup actions
|
||||
#warning TODO
|
||||
#if 0
|
||||
TRI_CleanupActions();
|
||||
#endif
|
||||
|
||||
// stop the replication appliers so all replication transactions can end
|
||||
if (_replicationApplier) {
|
||||
TRI_StopReplicationAppliersServer(_server.get());
|
||||
|
@ -368,51 +361,3 @@ void DatabaseFeature::closeDatabases() {
|
|||
// write to the logs
|
||||
wal::LogfileManager::instance()->stop();
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
// and add the feature to the application server
|
||||
_applicationServer->addFeature(wal::LogfileManager::instance());
|
||||
|
||||
// run upgrade script
|
||||
bool performUpgrade = false;
|
||||
|
||||
if (_applicationServer->programOptions().has("upgrade")) {
|
||||
performUpgrade = true;
|
||||
// --upgrade disables all replication appliers
|
||||
_disableReplicationApplier = true;
|
||||
if (_applicationCluster != nullptr) {
|
||||
_applicationCluster->disable(); // TODO
|
||||
}
|
||||
}
|
||||
|
||||
// skip an upgrade even if VERSION is missing
|
||||
|
||||
// .............................................................................
|
||||
// prepare the various parts of the Arango server
|
||||
// .............................................................................
|
||||
|
||||
KeyGenerator::Initialize();
|
||||
|
||||
// open all databases
|
||||
bool const iterateMarkersOnOpen =
|
||||
!wal::LogfileManager::instance()->hasFoundLastTick();
|
||||
|
||||
openDatabases(checkVersion, performUpgraden, iterateMarkersOnOpen);
|
||||
|
||||
if (!checkVersion) {
|
||||
}
|
||||
|
||||
// fetch the system database
|
||||
TRI_vocbase_t* vocbase =
|
||||
TRI_UseDatabaseServer(_server, TRI_VOC_SYSTEM_DATABASE);
|
||||
|
||||
if (vocbase == nullptr) {
|
||||
LOG(FATAL)
|
||||
<< "No _system database found in database directory. Cannot start!";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
TRI_ASSERT(vocbase != nullptr);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -47,6 +47,7 @@ class DatabaseFeature final : public application_features::ApplicationFeature {
|
|||
public:
|
||||
void collectOptions(std::shared_ptr<options::ProgramOptions>) override;
|
||||
void validateOptions(std::shared_ptr<options::ProgramOptions>) override;
|
||||
void prepare() override;
|
||||
void start() override;
|
||||
void stop() override;
|
||||
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
start:
|
||||
// ...........................................................................
|
||||
// init nonces
|
||||
// ...........................................................................
|
||||
|
||||
uint32_t optionNonceHashSize = 0;
|
||||
|
||||
if (optionNonceHashSize > 0) {
|
||||
LOG(DEBUG) << "setting nonce hash size to " << optionNonceHashSize;
|
||||
Nonce::create(optionNonceHashSize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
stop:
|
||||
|
||||
Nonce::destroy();
|
|
@ -82,6 +82,7 @@ ServerFeature::ServerFeature(application_features::ApplicationServer* server,
|
|||
_consoleThread(nullptr) {
|
||||
setOptional(true);
|
||||
requiresElevatedPrivileges(false);
|
||||
startsAfter("Cluster");
|
||||
startsAfter("Database");
|
||||
startsAfter("Dispatcher");
|
||||
startsAfter("Scheduler");
|
||||
|
@ -236,6 +237,8 @@ void ServerFeature::prepare() {
|
|||
|
||||
buildHandlerFactory();
|
||||
HttpHandlerFactory::setMaintenance(true);
|
||||
|
||||
adjustFileDescriptors();
|
||||
}
|
||||
|
||||
void ServerFeature::start() {
|
||||
|
@ -245,6 +248,15 @@ void ServerFeature::start() {
|
|||
V8DealerFeature::DEALER->loadJavascript(vocbase, "server/server.js");
|
||||
_httpOptions._vocbase = vocbase;
|
||||
|
||||
if (_operationMode != OperationMode::MODE_CONSOLE) {
|
||||
auto scheduler = dynamic_cast<SchedulerFeature*>(
|
||||
ApplicationServer::lookupFeature("Scheduler"));
|
||||
|
||||
if (scheduler != nullptr) {
|
||||
scheduler->buildControlCHandler();
|
||||
}
|
||||
}
|
||||
|
||||
defineHandlers();
|
||||
HttpHandlerFactory::setMaintenance(false);
|
||||
|
||||
|
@ -670,6 +682,7 @@ void ServerFeature::defineHandlers() {
|
|||
#endif
|
||||
}
|
||||
|
||||
#warning TODO
|
||||
#if 0
|
||||
|
||||
template <typename T>
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "UpgradeFeature.h"
|
||||
|
||||
#include "Cluster/ClusterFeature.h"
|
||||
#include "ProgramOptions/ProgramOptions.h"
|
||||
#include "ProgramOptions/Section.h"
|
||||
#include "RestServer/DatabaseFeature.h"
|
||||
|
@ -48,6 +49,7 @@ UpgradeFeature::UpgradeFeature(
|
|||
setOptional(false);
|
||||
requiresElevatedPrivileges(false);
|
||||
startsAfter("CheckVersion");
|
||||
startsAfter("Cluser");
|
||||
startsAfter("Database");
|
||||
startsAfter("V8Dealer");
|
||||
}
|
||||
|
@ -88,6 +90,10 @@ void UpgradeFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
|
|||
ApplicationServer::lookupFeature("Database"));
|
||||
database->disableReplicationApplier();
|
||||
database->enableUpgrade();
|
||||
|
||||
ClusterFeature* cluster = dynamic_cast<ClusterFeature*>(
|
||||
ApplicationServer::lookupFeature("Cluster"));
|
||||
cluster->disable();
|
||||
}
|
||||
|
||||
void UpgradeFeature::start() {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "Basics/Common.h"
|
||||
|
||||
#include "Agency/AgencyFeature.h"
|
||||
#include "ApplicationFeatures/ConfigFeature.h"
|
||||
#include "ApplicationFeatures/DaemonFeature.h"
|
||||
#include "ApplicationFeatures/LanguageFeature.h"
|
||||
|
@ -35,6 +36,7 @@
|
|||
#include "ApplicationFeatures/V8PlatformFeature.h"
|
||||
#include "ApplicationFeatures/WorkMonitorFeature.h"
|
||||
#include "Basics/ArangoGlobalContext.h"
|
||||
#include "Cluster/ClusterFeature.h"
|
||||
#include "Dispatcher/DispatcherFeature.h"
|
||||
#include "ProgramOptions/ProgramOptions.h"
|
||||
#include "RestServer/CheckVersionFeature.h"
|
||||
|
@ -90,16 +92,19 @@ int main(int argc, char* argv[]) {
|
|||
application_features::ApplicationServer server(options);
|
||||
|
||||
std::vector<std::string> nonServerFeatures = {
|
||||
"Action", "Daemon", "Dispatcher", "Endpoint",
|
||||
"Server", "Scheduler", "Ssl", "Supervisor"};
|
||||
"Action", "Cluster", "Daemon", "Dispatcher", "Endpoint",
|
||||
"Server", "Scheduler", "Ssl", "Supervisor"};
|
||||
|
||||
int ret = EXIT_FAILURE;
|
||||
|
||||
server.addFeature(new AgencyFeature(&server));
|
||||
server.addFeature(new CheckVersionFeature(&server, &ret, nonServerFeatures));
|
||||
server.addFeature(new ClusterFeature(&server));
|
||||
server.addFeature(new ConfigFeature(&server, name));
|
||||
server.addFeature(new DatabaseFeature(&server));
|
||||
server.addFeature(new DispatcherFeature(&server));
|
||||
server.addFeature(new EndpointFeature(&server));
|
||||
server.addFeature(new FileDescriptorsFeature(&server));
|
||||
server.addFeature(new LanguageFeature(&server));
|
||||
server.addFeature(new LoggerFeature(&server, true));
|
||||
server.addFeature(new RandomFeature(&server));
|
||||
|
|
|
@ -48,10 +48,10 @@ SchedulerFeature::SchedulerFeature(
|
|||
_nrSchedulerThreads(2),
|
||||
_backend(0),
|
||||
_showBackends(false),
|
||||
_scheduler(nullptr),
|
||||
_enableControlCHandler(true) {
|
||||
_scheduler(nullptr) {
|
||||
setOptional(true);
|
||||
requiresElevatedPrivileges(false);
|
||||
startsAfter("FileDescriptorsFeature");
|
||||
startsAfter("Logger");
|
||||
startsAfter("WorkMonitor");
|
||||
}
|
||||
|
@ -293,28 +293,21 @@ void SchedulerFeature::buildScheduler() {
|
|||
}
|
||||
|
||||
void SchedulerFeature::buildControlCHandler() {
|
||||
if (_scheduler == nullptr) {
|
||||
LOG(FATAL) << "no scheduler is known, cannot create control-c handler";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
if (_enableControlCHandler) {
|
||||
#ifdef WIN32
|
||||
int result = SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, true);
|
||||
int result = SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, true);
|
||||
|
||||
if (result == 0) {
|
||||
LOG(WARN) << "unable to install control-c handler";
|
||||
}
|
||||
#else
|
||||
Task* controlC = new ControlCTask(server());
|
||||
|
||||
int res = _scheduler->registerTask(controlC);
|
||||
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
_tasks.emplace_back(controlC);
|
||||
}
|
||||
#endif
|
||||
if (result == 0) {
|
||||
LOG(WARN) << "unable to install control-c handler";
|
||||
}
|
||||
#else
|
||||
Task* controlC = new ControlCTask(server());
|
||||
|
||||
int res = _scheduler->registerTask(controlC);
|
||||
|
||||
if (res == TRI_ERROR_NO_ERROR) {
|
||||
_tasks.emplace_back(controlC);
|
||||
}
|
||||
#endif
|
||||
|
||||
// hangup handler
|
||||
#ifndef WIN32
|
||||
|
@ -328,25 +321,7 @@ void SchedulerFeature::buildControlCHandler() {
|
|||
#endif
|
||||
}
|
||||
|
||||
#warning TODO
|
||||
#if 0
|
||||
|
||||
|
||||
if (mode == OperationMode::MODE_CONSOLE) {
|
||||
_applicationScheduler->disableControlCHandler();
|
||||
}
|
||||
|
||||
|
||||
if (!startServer) {
|
||||
_applicationScheduler->disable();
|
||||
}
|
||||
|
||||
|
||||
|
||||
================================================================================
|
||||
|
||||
void ApplicationScheduler::setProcessorAffinity(
|
||||
std::vector<size_t> const& cores) {
|
||||
void SchedulerFeature::setProcessorAffinity(std::vector<size_t> const& cores) {
|
||||
#ifdef TRI_HAVE_THREAD_AFFINITY
|
||||
size_t j = 0;
|
||||
|
||||
|
@ -365,121 +340,3 @@ void ApplicationScheduler::setProcessorAffinity(
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ApplicationScheduler::disableControlCHandler() {
|
||||
_disableControlCHandler = true;
|
||||
}
|
||||
|
||||
void ApplicationScheduler::setupOptions(
|
||||
std::map<std::string, ProgramOptionsDescription>& options) {
|
||||
// .............................................................................
|
||||
// command line options
|
||||
// .............................................................................
|
||||
|
||||
options["General Options:help-admin"]("show-io-backends",
|
||||
"show available io backends");
|
||||
|
||||
// .............................................................................
|
||||
// application server options
|
||||
// .............................................................................
|
||||
|
||||
options["Server Options:help-admin"]
|
||||
#ifdef _WIN32
|
||||
// ...........................................................................
|
||||
// since we are trying to use libev, then only select is available
|
||||
// no point in allowing this to be configured at this stage. Perhaps if we
|
||||
// eventually write a native libev we can offer something.
|
||||
// ...........................................................................
|
||||
//("scheduler.backend", &_backend, "1: select, 2: poll, 4: epoll")
|
||||
#else
|
||||
("scheduler.backend", &_backend, "1: select, 2: poll, 4: epoll")
|
||||
#endif
|
||||
#ifdef TRI_HAVE_GETRLIMIT
|
||||
("server.descriptors-minimum", &_descriptorMinimum,
|
||||
"minimum number of file descriptors needed to start")
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
bool ApplicationScheduler::afterOptionParsing(
|
||||
arangodb::basics::ProgramOptions& options) {
|
||||
// show io backends
|
||||
if (options.has("show-io-backends")) {
|
||||
std::cout << "available io backends are: "
|
||||
<< SchedulerLibev::availableBackends() << std::endl;
|
||||
TRI_EXIT_FUNCTION(EXIT_SUCCESS, nullptr);
|
||||
}
|
||||
|
||||
// adjust file descriptors
|
||||
adjustFileDescriptors();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ApplicationScheduler::adjustFileDescriptors() {
|
||||
#ifdef TRI_HAVE_GETRLIMIT
|
||||
|
||||
if (0 < _descriptorMinimum) {
|
||||
struct rlimit rlim;
|
||||
int res = getrlimit(RLIMIT_NOFILE, &rlim);
|
||||
|
||||
if (res != 0) {
|
||||
LOG(FATAL) << "cannot get the file descriptor limit: " << strerror(errno); FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
LOG(DEBUG) << "file-descriptors (nofiles) hard limit is " << StringifyLimitValue(rlim.rlim_max)
|
||||
<< ", soft limit is " << StringifyLimitValue(rlim.rlim_cur);
|
||||
|
||||
bool changed = false;
|
||||
|
||||
if (rlim.rlim_max < _descriptorMinimum) {
|
||||
LOG(DEBUG) << "hard limit " << rlim.rlim_max << " is too small, trying to raise";
|
||||
|
||||
rlim.rlim_max = _descriptorMinimum;
|
||||
rlim.rlim_cur = _descriptorMinimum;
|
||||
|
||||
res = setrlimit(RLIMIT_NOFILE, &rlim);
|
||||
|
||||
if (res < 0) {
|
||||
LOG(FATAL) << "cannot raise the file descriptor limit to " << _descriptorMinimum << ": " << strerror(errno); FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
changed = true;
|
||||
} else if (rlim.rlim_cur < _descriptorMinimum) {
|
||||
LOG(DEBUG) << "soft limit " << rlim.rlim_cur << " is too small, trying to raise";
|
||||
|
||||
rlim.rlim_cur = _descriptorMinimum;
|
||||
|
||||
res = setrlimit(RLIMIT_NOFILE, &rlim);
|
||||
|
||||
if (res < 0) {
|
||||
LOG(FATAL) << "cannot raise the file descriptor limit to " << _descriptorMinimum << ": " << strerror(errno); FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
res = getrlimit(RLIMIT_NOFILE, &rlim);
|
||||
|
||||
if (res != 0) {
|
||||
LOG(FATAL) << "cannot get the file descriptor limit: " << strerror(errno); FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
LOG(INFO) << "file-descriptors (nofiles) new hard limit is " << StringifyLimitValue(rlim.rlim_max)
|
||||
<< ", new soft limit is " << ", soft limit is " << StringifyLimitValue(rlim.rlim_cur);
|
||||
}
|
||||
|
||||
// the select backend has more restrictions
|
||||
if (_backend == 1) {
|
||||
if (FD_SETSIZE < _descriptorMinimum) {
|
||||
LOG(FATAL) << "i/o backend 'select' has been selected, which supports only " << FD_SETSIZE << " descriptors, but " << _descriptorMinimum << " are required"; FATAL_ERROR_EXIT();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -59,7 +59,6 @@ class SchedulerFeature final : public application_features::ApplicationFeature {
|
|||
private:
|
||||
rest::Scheduler* _scheduler;
|
||||
std::vector<rest::Task*> _tasks;
|
||||
bool _enableControlCHandler;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -99,9 +99,10 @@ V8DealerFeature::V8DealerFeature(
|
|||
_forceNrContexts(0) {
|
||||
setOptional(false);
|
||||
requiresElevatedPrivileges(false);
|
||||
startsAfter("Action");
|
||||
startsAfter("Database");
|
||||
startsAfter("V8Platform");
|
||||
startsAfter("WorkMonitor");
|
||||
startsAfter("Database");
|
||||
}
|
||||
|
||||
void V8DealerFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
|
||||
|
@ -149,19 +150,6 @@ void V8DealerFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
|
|||
_startupLoader.setDirectory(_startupPath);
|
||||
ServerState::instance()->setJavaScriptPath(_startupPath);
|
||||
|
||||
// dump paths
|
||||
{
|
||||
std::vector<std::string> paths;
|
||||
|
||||
paths.push_back(std::string("startup '" + _startupPath + "'"));
|
||||
|
||||
if (!_appPath.empty()) {
|
||||
paths.push_back(std::string("application '" + _appPath + "'"));
|
||||
}
|
||||
|
||||
LOG(INFO) << "JavaScript using " << StringUtils::join(paths, ", ");
|
||||
}
|
||||
|
||||
// check whether app-path was specified
|
||||
if (_appPath.empty()) {
|
||||
LOG(FATAL) << "no value has been specified for --javascript.app-path.";
|
||||
|
@ -177,6 +165,20 @@ void V8DealerFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
|
|||
void V8DealerFeature::start() {
|
||||
LOG_TOPIC(TRACE, Logger::STARTUP) << name() << "::start";
|
||||
|
||||
// dump paths
|
||||
{
|
||||
std::vector<std::string> paths;
|
||||
|
||||
paths.push_back(std::string("startup '" + _startupPath + "'"));
|
||||
|
||||
if (!_appPath.empty()) {
|
||||
paths.push_back(std::string("application '" + _appPath + "'"));
|
||||
}
|
||||
|
||||
LOG(INFO) << "JavaScript using " << StringUtils::join(paths, ", ");
|
||||
}
|
||||
|
||||
// set singleton
|
||||
DEALER = this;
|
||||
|
||||
// try to guess a suitable number of contexts
|
||||
|
|
|
@ -77,6 +77,8 @@ class V8DealerFeature final : public application_features::ApplicationFeature {
|
|||
|
||||
void shutdownContexts();
|
||||
|
||||
std::string const& appPath() const { return _appPath; }
|
||||
|
||||
private:
|
||||
V8Context* pickFreeContextForGc();
|
||||
void initializeContext(size_t);
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "VocBase/vocbase.h"
|
||||
#include "Wal/LogfileManager.h"
|
||||
#include "Wal/Marker.h"
|
||||
#include "V8Server/V8DealerFeature.h"
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::basics;
|
||||
|
@ -513,7 +514,10 @@ static int OpenDatabases(TRI_server_t* server, bool isUpgrade) {
|
|||
// create app directories
|
||||
// .........................................................................
|
||||
|
||||
res = CreateApplicationDirectory(databaseName.c_str(), server->_appPath);
|
||||
auto appPath = (V8DealerFeature::DEALER == nullptr
|
||||
? std::string()
|
||||
: V8DealerFeature::DEALER->appPath());
|
||||
res = CreateApplicationDirectory(databaseName.c_str(), appPath.c_str());
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
break;
|
||||
|
@ -1040,8 +1044,12 @@ static void DatabaseManager(void* data) {
|
|||
<< "'";
|
||||
|
||||
// remove apps directory for database
|
||||
if (database->_isOwnAppsDirectory && strlen(server->_appPath) > 0) {
|
||||
path = TRI_Concatenate3File(server->_appPath, "_db", database->_name);
|
||||
auto appPath = (V8DealerFeature::DEALER == nullptr
|
||||
? std::string()
|
||||
: V8DealerFeature::DEALER->appPath());
|
||||
|
||||
if (database->_isOwnAppsDirectory && !appPath.empty()) {
|
||||
path = TRI_Concatenate3File(appPath.c_str(), "_db", database->_name);
|
||||
|
||||
if (path != nullptr) {
|
||||
if (TRI_IsDirectory(path)) {
|
||||
|
@ -1119,13 +1127,11 @@ static void DatabaseManager(void* data) {
|
|||
/// @brief initialize a server instance with configuration
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#warning appPath lives in V8DealerFeature - remove here
|
||||
|
||||
int TRI_InitServer(TRI_server_t* server,
|
||||
arangodb::basics::ThreadPool* indexPool,
|
||||
char const* basePath, char const* appPath,
|
||||
TRI_vocbase_defaults_t const* defaults, bool disableAppliers,
|
||||
bool disableCompactor, bool iterateMarkersOnOpen) {
|
||||
char const* basePath, TRI_vocbase_defaults_t const* defaults,
|
||||
bool disableAppliers, bool disableCompactor,
|
||||
bool iterateMarkersOnOpen) {
|
||||
TRI_ASSERT(server != nullptr);
|
||||
TRI_ASSERT(basePath != nullptr);
|
||||
|
||||
|
@ -1171,21 +1177,6 @@ int TRI_InitServer(TRI_server_t* server,
|
|||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (appPath == nullptr) {
|
||||
server->_appPath = nullptr;
|
||||
} else {
|
||||
server->_appPath = TRI_DuplicateString(TRI_CORE_MEM_ZONE, appPath);
|
||||
|
||||
if (server->_appPath == nullptr) {
|
||||
TRI_Free(TRI_CORE_MEM_ZONE, server->_serverIdFilename);
|
||||
TRI_Free(TRI_CORE_MEM_ZONE, server->_lockFilename);
|
||||
TRI_Free(TRI_CORE_MEM_ZONE, server->_databasePath);
|
||||
TRI_Free(TRI_CORE_MEM_ZONE, server->_basePath);
|
||||
|
||||
return TRI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
// ...........................................................................
|
||||
// server defaults
|
||||
// ...........................................................................
|
||||
|
@ -1209,7 +1200,7 @@ int TRI_InitServer(TRI_server_t* server,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_InitServerGlobals() {
|
||||
ServerIdentifier = RandomGenerator::interval((uint16_t) UINT16_MAX);
|
||||
ServerIdentifier = RandomGenerator::interval((uint16_t)UINT16_MAX);
|
||||
PageSize = (size_t)getpagesize();
|
||||
memset(&ServerId, 0, sizeof(TRI_server_id_t));
|
||||
}
|
||||
|
@ -1332,29 +1323,32 @@ int TRI_StartServer(TRI_server_t* server, bool checkVersion,
|
|||
// create shared application directories
|
||||
// ...........................................................................
|
||||
|
||||
if (server->_appPath != nullptr && strlen(server->_appPath) > 0 &&
|
||||
!TRI_IsDirectory(server->_appPath)) {
|
||||
auto appPath =
|
||||
(V8DealerFeature::DEALER == nullptr ? std::string()
|
||||
: V8DealerFeature::DEALER->appPath());
|
||||
|
||||
if (!appPath.empty() && !TRI_IsDirectory(appPath.c_str())) {
|
||||
long systemError;
|
||||
std::string errorMessage;
|
||||
bool res = TRI_CreateRecursiveDirectory(server->_appPath, systemError,
|
||||
bool res = TRI_CreateRecursiveDirectory(appPath.c_str(), systemError,
|
||||
errorMessage);
|
||||
|
||||
if (res) {
|
||||
LOG(INFO) << "created --javascript.app-path directory '"
|
||||
<< server->_appPath << "'.";
|
||||
LOG(INFO) << "created --javascript.app-path directory '" << appPath
|
||||
<< "'.";
|
||||
} else {
|
||||
LOG(ERR) << "unable to create --javascript.app-path directory '"
|
||||
<< server->_appPath << "': " << errorMessage;
|
||||
<< appPath << "': " << errorMessage;
|
||||
return TRI_ERROR_SYS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// create subdirectories if not yet present
|
||||
res = CreateBaseApplicationDirectory(server->_appPath, "_db");
|
||||
res = CreateBaseApplicationDirectory(appPath.c_str(), "_db");
|
||||
|
||||
// system directory is in a read-only location
|
||||
// if (res == TRI_ERROR_NO_ERROR) {
|
||||
// res = CreateBaseApplicationDirectory(server->_appPath, "system");
|
||||
// res = CreateBaseApplicationDirectory(appPath, "system");
|
||||
// }
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
|
@ -1608,11 +1602,11 @@ int TRI_CreateDatabaseServer(TRI_server_t* server, TRI_voc_tick_t databaseId,
|
|||
server->_databasePath, dirname.c_str()));
|
||||
|
||||
if (arangodb::wal::LogfileManager::instance()->isInRecovery()) {
|
||||
LOG(TRACE) << "creating database '" << name << "', directory '"
|
||||
<< path << "'";
|
||||
LOG(TRACE) << "creating database '" << name << "', directory '" << path
|
||||
<< "'";
|
||||
} else {
|
||||
LOG(INFO) << "creating database '" << name << "', directory '"
|
||||
<< path << "'";
|
||||
LOG(INFO) << "creating database '" << name << "', directory '" << path
|
||||
<< "'";
|
||||
}
|
||||
|
||||
vocbase = TRI_OpenVocBase(server, path.c_str(), databaseId, name, defaults,
|
||||
|
@ -1647,7 +1641,10 @@ int TRI_CreateDatabaseServer(TRI_server_t* server, TRI_voc_tick_t databaseId,
|
|||
}
|
||||
|
||||
// create application directories
|
||||
CreateApplicationDirectory(vocbase->_name, server->_appPath);
|
||||
auto appPath = (V8DealerFeature::DEALER == nullptr
|
||||
? std::string()
|
||||
: V8DealerFeature::DEALER->appPath());
|
||||
CreateApplicationDirectory(vocbase->_name, appPath.c_str());
|
||||
|
||||
if (!arangodb::wal::LogfileManager::instance()->isInRecovery()) {
|
||||
TRI_ReloadAuthInfo(vocbase);
|
||||
|
@ -2165,7 +2162,6 @@ TRI_server_t::TRI_server_t()
|
|||
_databasePath(nullptr),
|
||||
_lockFilename(nullptr),
|
||||
_serverIdFilename(nullptr),
|
||||
_appPath(nullptr),
|
||||
_disableReplicationAppliers(false),
|
||||
_iterateMarkersOnOpen(false),
|
||||
_hasCreatedSystemDatabase(false),
|
||||
|
@ -2178,10 +2174,6 @@ TRI_server_t::~TRI_server_t() {
|
|||
auto p = _databasesLists.load();
|
||||
delete p;
|
||||
|
||||
if (_appPath != nullptr) {
|
||||
TRI_Free(TRI_CORE_MEM_ZONE, _appPath);
|
||||
}
|
||||
|
||||
TRI_Free(TRI_CORE_MEM_ZONE, _serverIdFilename);
|
||||
TRI_Free(TRI_CORE_MEM_ZONE, _lockFilename);
|
||||
TRI_Free(TRI_CORE_MEM_ZONE, _databasePath);
|
||||
|
|
|
@ -78,7 +78,6 @@ struct TRI_server_t {
|
|||
char* _databasePath;
|
||||
char* _lockFilename;
|
||||
char* _serverIdFilename;
|
||||
char* _appPath;
|
||||
|
||||
bool _disableReplicationAppliers;
|
||||
bool _disableCompactor;
|
||||
|
@ -98,8 +97,7 @@ extern size_t PageSize;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int TRI_InitServer(TRI_server_t*, arangodb::basics::ThreadPool*, char const*,
|
||||
char const*, TRI_vocbase_defaults_t const*, bool, bool,
|
||||
bool);
|
||||
TRI_vocbase_defaults_t const*, bool, bool, bool);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief initialize globals
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "FileDescriptorsFeature.h"
|
||||
|
||||
using namespace arangodb;
|
||||
using namespace arangodb::basics;
|
||||
using namespace arangodb::options;
|
||||
|
||||
FileDescriptorsFeature::FileDescriptorsFeature(
|
||||
application_features::ApplicationServer* server)
|
||||
: ApplicationFeature(server, "FileDescriptors") {
|
||||
setOptional(false);
|
||||
requiresElevatedPrivileges(false);
|
||||
startsAfter("Logger");
|
||||
}
|
||||
|
||||
void FileDescriptorsFeature::collectOptions(
|
||||
std::shared_ptr<ProgramOptions> options) {
|
||||
LOG_TOPIC(TRACE, Logger::STARTUP) << name() << "::collectOptions";
|
||||
|
||||
#ifdef TRI_HAVE_GETRLIMIT
|
||||
options->addSection("server", "Server features");
|
||||
|
||||
options->addOption("--server.descriptors-minimum",
|
||||
"minimum number of file descriptors needed to start",
|
||||
new UInt64Parameter(&_descriptorMinimum));
|
||||
#endif
|
||||
}
|
||||
|
||||
void FileDescriptorsFeature::prepare() {
|
||||
LOG_TOPIC(TRACE, Logger::STARTUP) << name() << "::prepare";
|
||||
|
||||
adjustFileDescriptors();
|
||||
}
|
||||
|
||||
void FileDescriptors::adjustFileDescriptors() {
|
||||
#ifdef TRI_HAVE_GETRLIMIT
|
||||
|
||||
if (0 < _descriptorMinimum) {
|
||||
struct rlimit rlim;
|
||||
int res = getrlimit(RLIMIT_NOFILE, &rlim);
|
||||
|
||||
if (res != 0) {
|
||||
LOG(FATAL) << "cannot get the file descriptor limit: " << strerror(errno);
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
LOG(DEBUG) << "file-descriptors (nofiles) hard limit is "
|
||||
<< StringifyLimitValue(rlim.rlim_max) << ", soft limit is "
|
||||
<< StringifyLimitValue(rlim.rlim_cur);
|
||||
|
||||
bool changed = false;
|
||||
|
||||
if (rlim.rlim_max < _descriptorMinimum) {
|
||||
LOG(DEBUG) << "hard limit " << rlim.rlim_max
|
||||
<< " is too small, trying to raise";
|
||||
|
||||
rlim.rlim_max = _descriptorMinimum;
|
||||
rlim.rlim_cur = _descriptorMinimum;
|
||||
|
||||
res = setrlimit(RLIMIT_NOFILE, &rlim);
|
||||
|
||||
if (res < 0) {
|
||||
LOG(FATAL) << "cannot raise the file descriptor limit to "
|
||||
<< _descriptorMinimum << ": " << strerror(errno);
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
changed = true;
|
||||
} else if (rlim.rlim_cur < _descriptorMinimum) {
|
||||
LOG(DEBUG) << "soft limit " << rlim.rlim_cur
|
||||
<< " is too small, trying to raise";
|
||||
|
||||
rlim.rlim_cur = _descriptorMinimum;
|
||||
|
||||
res = setrlimit(RLIMIT_NOFILE, &rlim);
|
||||
|
||||
if (res < 0) {
|
||||
LOG(FATAL) << "cannot raise the file descriptor limit to "
|
||||
<< _descriptorMinimum << ": " << strerror(errno);
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
res = getrlimit(RLIMIT_NOFILE, &rlim);
|
||||
|
||||
if (res != 0) {
|
||||
LOG(FATAL) << "cannot get the file descriptor limit: "
|
||||
<< strerror(errno);
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
LOG(INFO) << "file-descriptors (nofiles) new hard limit is "
|
||||
<< StringifyLimitValue(rlim.rlim_max) << ", new soft limit is "
|
||||
<< ", soft limit is " << StringifyLimitValue(rlim.rlim_cur);
|
||||
}
|
||||
|
||||
// the select backend has more restrictions
|
||||
if (_backend == 1) {
|
||||
if (FD_SETSIZE < _descriptorMinimum) {
|
||||
LOG(FATAL)
|
||||
<< "i/o backend 'select' has been selected, which supports only "
|
||||
<< FD_SETSIZE << " descriptors, but " << _descriptorMinimum
|
||||
<< " are required";
|
||||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGOD_CLUSTER_FILE_DESCRIPTORS_FEATURE_H
|
||||
#define ARANGOD_CLUSTER_FILE_DESCRIPTORS_FEATURE_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
|
||||
#include "ApplicationFeatures/ApplicationFeature.h"
|
||||
|
||||
namespace arangodb {
|
||||
class ClusterFeature : public application_features::ApplicationFeature {
|
||||
public:
|
||||
ClusterFeature(application_features::ApplicationServer*);
|
||||
|
||||
public:
|
||||
void collectOptions(std::shared_ptr<options::ProgramOptions>) override;
|
||||
void prepare() override;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -63,6 +63,11 @@ void LanguageFeature::prepare() {
|
|||
FATAL_ERROR_EXIT();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LanguageFeature::start() {
|
||||
LOG_TOPIC(TRACE, Logger::STARTUP) << name() << "::start";
|
||||
|
||||
std::string languageName;
|
||||
|
||||
if (Utf8Helper::DefaultUtf8Helper.getCollatorCountry() != "") {
|
||||
|
|
|
@ -33,6 +33,7 @@ class LanguageFeature final : public application_features::ApplicationFeature {
|
|||
public:
|
||||
void collectOptions(std::shared_ptr<options::ProgramOptions>) override;
|
||||
void prepare() override;
|
||||
void start() override;
|
||||
|
||||
private:
|
||||
std::string _language;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
namespace arangodb {
|
||||
class LoggerFeature final : public application_features::ApplicationFeature {
|
||||
public:
|
||||
explicit LoggerFeature(application_features::ApplicationServer* server, bool threaded);
|
||||
LoggerFeature(application_features::ApplicationServer* server, bool threaded);
|
||||
|
||||
public:
|
||||
void collectOptions(std::shared_ptr<options::ProgramOptions>) override;
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "NonceFeature.h"
|
||||
|
||||
NonceFeature(application_features::ApplicationServer*);
|
||||
|
||||
void NonceFeature::validate() {}
|
||||
|
||||
void NonceFeature::prepare() {
|
||||
uint32_t optionNonceHashSize = 0;
|
||||
|
||||
if (0 < _hashSize) {
|
||||
Nonce::create(_hashSize);
|
||||
}
|
||||
}
|
||||
|
||||
void NonceFeature::start() {
|
||||
LOG(DEBUG) << "setting nonce hash size to " << _hashSize;
|
||||
}
|
||||
|
||||
void NonceFeature::stop() { Nonce::destroy(); }
|
|
@ -0,0 +1,42 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGOD_CLUSTER_FILE_NONCE_FEATURE_H
|
||||
#define ARANGOD_CLUSTER_FILE_NONCE_FEATURE_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
|
||||
#include "ApplicationFeatures/ApplicationFeature.h"
|
||||
|
||||
namespace arangodb {
|
||||
class NonceFeature : public application_features::ApplicationFeature {
|
||||
public:
|
||||
NonceFeature(application_features::ApplicationServer*);
|
||||
|
||||
public:
|
||||
void collectOptions(std::shared_ptr<options::ProgramOptions>) override;
|
||||
void prepare() override;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,3 +1,77 @@
|
|||
#warning TODO
|
||||
|
||||
#if 0
|
||||
options["Hidden Options"]
|
||||
#ifdef ARANGODB_HAVE_SETUID
|
||||
("uid", &_uid, "switch to user-id after reading config files")
|
||||
#endif
|
||||
#ifdef ARANGODB_HAVE_SETGID
|
||||
("gid", &_gid, "switch to group-id after reading config files")
|
||||
#endif
|
||||
;
|
||||
|
||||
#if defined(ARANGODB_HAVE_SETUID) || defined(ARANGODB_HAVE_SETGID)
|
||||
|
||||
options["General Options:help-admin"]
|
||||
#ifdef ARANGODB_HAVE_GETPPID
|
||||
("exit-on-parent-death", &_exitOnParentDeath, "exit if parent dies")
|
||||
#endif
|
||||
("watch-process", &_watchParent,
|
||||
"exit if process with given PID dies");
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#warning TODO
|
||||
#if 0
|
||||
// .............................................................................
|
||||
// UID and GID
|
||||
// .............................................................................
|
||||
|
||||
extractPrivileges();
|
||||
dropPrivilegesPermanently();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief checks if the parent is still alive
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool ApplicationServer::checkParent() {
|
||||
// check our parent, if it died given up
|
||||
#ifdef ARANGODB_HAVE_GETPPID
|
||||
if (_exitOnParentDeath && getppid() == 1) {
|
||||
LOG(INFO) << "parent has died";
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// unfortunately even though windows has <signal.h>, there is no
|
||||
// kill method defined. Notice that the kill below is not to terminate
|
||||
// the process.
|
||||
#ifdef TRI_HAVE_SIGNAL_H
|
||||
if (_watchParent != 0) {
|
||||
#ifdef TRI_HAVE_POSIX
|
||||
int res = kill(_watchParent, 0);
|
||||
#else
|
||||
int res = -1;
|
||||
#endif
|
||||
if (res != 0) {
|
||||
LOG(INFO) << "parent " << _watchParent << " has died";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
void ApplicationServer::extractPrivileges() {
|
||||
#ifdef ARANGODB_HAVE_SETGID
|
||||
if (_gid.empty()) {
|
||||
|
@ -125,3 +199,4 @@ void ApplicationServer::dropPrivilegesPermanently() {
|
|||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -92,6 +92,7 @@ if (MSVC)
|
|||
else ()
|
||||
set(LIB_ARANGO_POSIX
|
||||
ApplicationFeatures/DaemonFeature.cpp
|
||||
ApplicationFeatures/PrivilegeFeature.cpp
|
||||
ApplicationFeatures/SupervisorFeature.cpp
|
||||
Basics/locks-posix.cpp
|
||||
Basics/memory-map-posix.cpp
|
||||
|
@ -139,9 +140,11 @@ add_library(${LIB_ARANGO} STATIC
|
|||
ApplicationFeatures/ClientFeature.cpp
|
||||
ApplicationFeatures/ConfigFeature.cpp
|
||||
ApplicationFeatures/ConsoleFeature.cpp
|
||||
ApplicationFeatures/FileDescriptorsFeature.cpp
|
||||
ApplicationFeatures/LanguageFeature.cpp
|
||||
ApplicationFeatures/LoggerFeature.cpp
|
||||
ApplicationFeatures/RandomFeature.cpp
|
||||
ApplicationFeatures/NonceFeature.cpp
|
||||
ApplicationFeatures/ShutdownFeature.cpp
|
||||
ApplicationFeatures/SslFeature.cpp
|
||||
ApplicationFeatures/TempFeature.cpp
|
||||
|
|
|
@ -1,15 +1,10 @@
|
|||
#!/usr/bin/perl
|
||||
################################################################################
|
||||
### @brief updates preamble of C/C++ files
|
||||
###
|
||||
### @file
|
||||
###
|
||||
### DISCLAIMER
|
||||
###
|
||||
### Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
### Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
###
|
||||
### @author Dr. Frank Celler
|
||||
### @author Copyright 2009-2010, triAGENS GmbH, Cologne, Germany
|
||||
################################################################################
|
||||
|
||||
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
|
||||
|
|
Loading…
Reference in New Issue