1
0
Fork 0

issue #1054: add info whether server is running in service or user mode?

This commit is contained in:
Jan Steemann 2015-03-27 16:49:47 +01:00
parent a0420101e2
commit 960b464c57
9 changed files with 180 additions and 65 deletions

View File

@ -1,6 +1,15 @@
v2.6.0 (XXXX-XX-XX) v2.6.0 (XXXX-XX-XX)
------------------- -------------------
* issue #1051: add info whether server is running in service or user mode?
This will add a "mode" attribute to the result of the result of HTTP GET `/_api/version?details=true`
"mode" can have the following values:
- `standalone`: server was started manually (e.g. on command-line)
- `service`: service is running as Windows service, in daemon mode or under the supervisor
* increased default value of `--server.request-timeout` from 300 to 1200 seconds for client tools * increased default value of `--server.request-timeout` from 300 to 1200 seconds for client tools
(arangosh, arangoimp, arangodump, arangorestore) (arangosh, arangoimp, arangodump, arangorestore)

View File

@ -28,15 +28,14 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include "Basics/Common.h" #include "Basics/Common.h"
#include "Basics/messages.h" #include "Basics/messages.h"
#include "Basics/logging.h" #include "Basics/logging.h"
#include "Basics/tri-strings.h" #include "Basics/tri-strings.h"
#include "Rest/InitialiseRest.h" #include "Rest/InitialiseRest.h"
#include "Basics/files.h" #include "Basics/files.h"
#include "RestServer/ArangoServer.h" #include "RestServer/ArangoServer.h"
#include <signal.h>
#include <signal.h>
using namespace triagens; using namespace triagens;
using namespace triagens::rest; using namespace triagens::rest;
@ -81,7 +80,6 @@ static SERVICE_STATUS_HANDLE ServiceStatus;
void TRI_GlobalEntryFunction (); void TRI_GlobalEntryFunction ();
void TRI_GlobalExitFunction (int, void*); void TRI_GlobalExitFunction (int, void*);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief installs arangod as service with command-line /// @brief installs arangod as service with command-line
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -135,7 +133,7 @@ static void InstallServiceCommand (std::string command) {
static void InstallService (int argc, char* argv[]) { static void InstallService (int argc, char* argv[]) {
CHAR path[MAX_PATH]; CHAR path[MAX_PATH];
if(! GetModuleFileNameA(NULL, path, MAX_PATH)) { if (! GetModuleFileNameA(NULL, path, MAX_PATH)) {
std::cerr << "FATAL: GetModuleFileNameA failed" << std::endl; std::cerr << "FATAL: GetModuleFileNameA failed" << std::endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -160,7 +158,7 @@ static void InstallService (int argc, char* argv[]) {
static void DeleteService (int argc, char* argv[], bool force) { static void DeleteService (int argc, char* argv[], bool force) {
CHAR path[MAX_PATH] = ""; CHAR path[MAX_PATH] = "";
if(! GetModuleFileNameA(NULL, path, MAX_PATH)) { if (! GetModuleFileNameA(NULL, path, MAX_PATH)) {
std::cerr << "FATAL: GetModuleFileNameA failed" << std::endl; std::cerr << "FATAL: GetModuleFileNameA failed" << std::endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -189,7 +187,7 @@ static void DeleteService (int argc, char* argv[], bool force) {
std::string command = std::string("\"") + std::string(path) + std::string("\" --start-service"); std::string command = std::string("\"") + std::string(path) + std::string("\" --start-service");
if (strcmp(cfg->lpBinaryPathName, command.c_str())) { if (strcmp(cfg->lpBinaryPathName, command.c_str())) {
if (!force) { if (! force) {
std::cerr << "NOT removing service of other installation: " << std::cerr << "NOT removing service of other installation: " <<
cfg->lpBinaryPathName << cfg->lpBinaryPathName <<
" Our path is: " << " Our path is: " <<
@ -272,7 +270,7 @@ static void StartArangoService (bool WaitForRunning) {
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
if (!StartService(arangoService, 0, NULL) ) { if (! StartService(arangoService, 0, NULL) ) {
TRI_SYSTEM_ERROR(); TRI_SYSTEM_ERROR();
std::cout << "StartService failed " << windowsErrorBuf << std::endl; std::cout << "StartService failed " << windowsErrorBuf << std::endl;
CloseServiceHandle(arangoService); CloseServiceHandle(arangoService);
@ -289,11 +287,11 @@ static void StartArangoService (bool WaitForRunning) {
// Check the status again. // Check the status again.
if (!QueryServiceStatusEx(arangoService, if (! QueryServiceStatusEx(arangoService,
SC_STATUS_PROCESS_INFO, // info level SC_STATUS_PROCESS_INFO, // info level
(LPBYTE) &ssp, // address of structure (LPBYTE) &ssp, // address of structure
sizeof(SERVICE_STATUS_PROCESS), // size of structure sizeof(SERVICE_STATUS_PROCESS), // size of structure
&bytesNeeded ) ) { &bytesNeeded ) ) {
TRI_SYSTEM_ERROR(); TRI_SYSTEM_ERROR();
std::cerr << "INFO: QueryServiceStatusEx failed with " << windowsErrorBuf << std::endl; std::cerr << "INFO: QueryServiceStatusEx failed with " << windowsErrorBuf << std::endl;
break; break;
@ -354,7 +352,7 @@ static void StopArangoService (bool WaitForShutdown) {
} }
// Send a stop code to the service. // Send a stop code to the service.
if ( !ControlService(arangoService, if (! ControlService(arangoService,
SERVICE_CONTROL_STOP, SERVICE_CONTROL_STOP,
(LPSERVICE_STATUS) &ssp ) ) { (LPSERVICE_STATUS) &ssp ) ) {
TRI_SYSTEM_ERROR(); TRI_SYSTEM_ERROR();
@ -380,6 +378,7 @@ static void StopArangoService (bool WaitForShutdown) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
CloseServiceHandle(arangoService); CloseServiceHandle(arangoService);
CloseServiceHandle(schSCManager); CloseServiceHandle(schSCManager);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
@ -570,8 +569,6 @@ void TRI_GlobalEntryFunction () {
TRI_Application_Exit_SetExit(TRI_GlobalExitFunction); TRI_Application_Exit_SetExit(TRI_GlobalExitFunction);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief global exit function /// @brief global exit function
/// ///
@ -579,7 +576,6 @@ void TRI_GlobalEntryFunction () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void TRI_GlobalExitFunction (int exitCode, void* data) { void TRI_GlobalExitFunction (int exitCode, void* data) {
// ........................................................................... // ...........................................................................
// TODO: need a terminate function for windows to be called and cleanup // TODO: need a terminate function for windows to be called and cleanup
// any windows specific stuff. // any windows specific stuff.
@ -609,7 +605,7 @@ protected:
/// @brief wrap ArangoDB server so we can properly emmit a status once we're /// @brief wrap ArangoDB server so we can properly emmit a status once we're
/// really up and running. /// really up and running.
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
virtual void startupProgress () { virtual void startupProgress () override final {
SetServiceStatus(SERVICE_START_PENDING, NO_ERROR, _progress++, 20000); SetServiceStatus(SERVICE_START_PENDING, NO_ERROR, _progress++, 20000);
} }
@ -617,7 +613,7 @@ protected:
/// @brief wrap ArangoDB server so we can properly emmit a status once we're /// @brief wrap ArangoDB server so we can properly emmit a status once we're
/// really up and running. /// really up and running.
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
virtual void startupFinished () { virtual void startupFinished () override final {
// startup finished - signalize we're running. // startup finished - signalize we're running.
SetServiceStatus(SERVICE_RUNNING, NO_ERROR, 0, 0); SetServiceStatus(SERVICE_RUNNING, NO_ERROR, 0, 0);
} }
@ -626,16 +622,18 @@ protected:
/// @brief wrap ArangoDB server so we can properly emmit a status on shutdown /// @brief wrap ArangoDB server so we can properly emmit a status on shutdown
/// starting /// starting
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
virtual void shutDownBegins () { virtual void shutDownBegins () override final {
// startup finished - signalize we're running. // startup finished - signalize we're running.
SetServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0, 0); SetServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0, 0);
} }
public: public:
WindowsArangoServer (int argc, char ** argv) : WindowsArangoServer (int argc, char ** argv)
ArangoServer(argc, argv) { : ArangoServer(argc, argv) {
_progress = 2;
_progress = 2;
} }
}; };
static int ARGC; static int ARGC;
@ -650,6 +648,7 @@ static void WINAPI ServiceMain (DWORD dwArgc, LPSTR *lpszArgv) {
IsRunning = true; IsRunning = true;
ArangoInstance = new WindowsArangoServer(ARGC, ARGV); ArangoInstance = new WindowsArangoServer(ARGC, ARGV);
ArangoInstance->setMode(ServerMode::MODE_SERVICE);
ArangoInstance->start(); ArangoInstance->start();
IsRunning = false; IsRunning = false;
@ -661,8 +660,7 @@ static void WINAPI ServiceMain (DWORD dwArgc, LPSTR *lpszArgv) {
/// @brief parse windows specific commandline options /// @brief parse windows specific commandline options
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool TRI_ParseMoreArgs (int argc, char* argv[]) bool TRI_ParseMoreArgs (int argc, char* argv[]) {
{
SetUnhandledExceptionFilter(unhandledExceptionHandler); SetUnhandledExceptionFilter(unhandledExceptionHandler);
if (1 < argc) { if (1 < argc) {
@ -702,8 +700,7 @@ bool TRI_ParseMoreArgs (int argc, char* argv[])
/// @brief start the windows service /// @brief start the windows service
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void TRI_StartService (int argc, char* argv[]) void TRI_StartService (int argc, char* argv[]) {
{
// create and start an ArangoDB server // create and start an ArangoDB server
SERVICE_TABLE_ENTRY ste[] = { SERVICE_TABLE_ENTRY ste[] = {

View File

@ -37,7 +37,6 @@
#include "RestServer/ArangoServer.h" #include "RestServer/ArangoServer.h"
#include <signal.h> #include <signal.h>
using namespace triagens; using namespace triagens;
using namespace triagens::rest; using namespace triagens::rest;
using namespace triagens::arango; using namespace triagens::arango;
@ -50,8 +49,7 @@ using namespace triagens::arango;
/// @brief ArangoDB server /// @brief ArangoDB server
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
ArangoServer* ArangoInstance = nullptr; AnyServer* ArangoInstance = nullptr;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- private functions // --SECTION-- private functions
@ -77,17 +75,17 @@ void TRI_StartService(int argc, char* argv[]) { }
/// @brief handle fatal SIGNALs; print backtrace, /// @brief handle fatal SIGNALs; print backtrace,
/// and rethrow signal for coredumps. /// and rethrow signal for coredumps.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void abortHandler(int signum) { void abortHandler(int signum) {
TRI_PrintBacktrace(); TRI_PrintBacktrace();
#ifdef _WIN32 #ifdef _WIN32
exit(255 + signum); exit(255 + signum);
#else #else
signal(signum, SIG_DFL); signal(signum, SIG_DFL);
kill(getpid(), signum); kill(getpid(), signum);
#endif #endif
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- public functions // --SECTION-- public functions
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -101,7 +99,11 @@ int main (int argc, char* argv[]) {
signal(SIGSEGV, abortHandler); signal(SIGSEGV, abortHandler);
bool startAsService = TRI_ParseMoreArgs(argc, argv); #if _WIN32
bool const startAsService = TRI_ParseMoreArgs(argc, argv);
#else
bool const startAsService = false;
#endif
// initialise sub-systems // initialise sub-systems
TRI_GlobalEntryFunction(); TRI_GlobalEntryFunction();

View File

@ -92,7 +92,7 @@ V8ClientConnection::V8ClientConnection (Endpoint* endpoint,
// connect to server and get version number // connect to server and get version number
map<string, string> headerFields; map<string, string> headerFields;
SimpleHttpResult* result = _client->request(HttpRequest::HTTP_REQUEST_GET, "/_api/version", 0, 0, headerFields); SimpleHttpResult* result = _client->request(HttpRequest::HTTP_REQUEST_GET, "/_api/version?details=true", nullptr, 0, headerFields);
if (! result || ! result->isComplete()) { if (! result || ! result->isComplete()) {
// save error message // save error message
@ -105,22 +105,29 @@ V8ClientConnection::V8ClientConnection (Endpoint* endpoint,
if (result->getHttpReturnCode() == HttpResponse::OK) { if (result->getHttpReturnCode() == HttpResponse::OK) {
// default value // default value
_version = "arango"; _version = "arango";
_mode = "unknown mode";
// convert response body to json // convert response body to json
TRI_json_t* json = TRI_JsonString(TRI_UNKNOWN_MEM_ZONE, std::unique_ptr<TRI_json_t> json(TRI_JsonString(TRI_UNKNOWN_MEM_ZONE, result->getBody().c_str()));
result->getBody().c_str());
if (json != nullptr) { if (json != nullptr) {
// look up "server" value // look up "server" value
const string server = JsonHelper::getStringValue(json, "server", ""); const string server = JsonHelper::getStringValue(json.get(), "server", "");
// "server" value is a string and content is "arango" // "server" value is a string and content is "arango"
if (server == "arango") { if (server == "arango") {
// look up "version" value // look up "version" value
_version = JsonHelper::getStringValue(json, "version", ""); _version = JsonHelper::getStringValue(json.get(), "version", "");
} auto const* details = TRI_LookupObjectJson(json.get(), "details");
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json); if (TRI_IsObjectJson(details)) {
auto const* mode = TRI_LookupObjectJson(details, "mode");
if (TRI_IsStringJson(mode)) {
_mode = std::string(mode->_value._string.data, mode->_value._string.length - 1);
}
}
}
} }
} }
else { else {
@ -224,6 +231,14 @@ const string& V8ClientConnection::getVersion () {
return _version; return _version;
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the server mode
////////////////////////////////////////////////////////////////////////////////
const string& V8ClientConnection::getMode () {
return _mode;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief get the last http return code /// @brief get the last http return code
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -130,6 +130,12 @@ namespace triagens {
const std::string& getVersion (); const std::string& getVersion ();
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the server mode
////////////////////////////////////////////////////////////////////////////////
const std::string& getMode ();
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief get the last http return code /// @brief get the last http return code
/// ///
@ -348,6 +354,12 @@ namespace triagens {
std::string _version; std::string _version;
////////////////////////////////////////////////////////////////////////////////
/// @brief mode
////////////////////////////////////////////////////////////////////////////////
std::string _mode;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief last http return code /// @brief last http return code
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -675,7 +675,7 @@ static void ClientConnection_ConstructorCallback (const v8::FunctionCallbackInfo
if (connection->isConnected() && connection->getLastHttpReturnCode() == HttpResponse::OK) { if (connection->isConnected() && connection->getLastHttpReturnCode() == HttpResponse::OK) {
ostringstream s; ostringstream s;
s << "Connected to ArangoDB '" << BaseClient.endpointServer()->getSpecification() s << "Connected to ArangoDB '" << BaseClient.endpointServer()->getSpecification()
<< "', version " << connection->getVersion() << ", database '" << BaseClient.databaseName() << "', version " << connection->getVersion() << " [" << connection->getMode() << "], database '" << BaseClient.databaseName()
<< "', username: '" << BaseClient.username() << "'"; << "', username: '" << BaseClient.username() << "'";
BaseClient.printLine(s.str()); BaseClient.printLine(s.str());
} }
@ -769,7 +769,7 @@ static void ClientConnection_reconnect (const v8::FunctionCallbackInfo<v8::Value
if (newConnection->isConnected() && newConnection->getLastHttpReturnCode() == HttpResponse::OK) { if (newConnection->isConnected() && newConnection->getLastHttpReturnCode() == HttpResponse::OK) {
ostringstream s; ostringstream s;
s << "Connected to ArangoDB '" << BaseClient.endpointServer()->getSpecification() s << "Connected to ArangoDB '" << BaseClient.endpointServer()->getSpecification()
<< "' version: " << newConnection->getVersion() << ", database: '" << BaseClient.databaseName() << "' version: " << newConnection->getVersion() << " [" << newConnection->getMode() << "], database: '" << BaseClient.databaseName()
<< "', username: '" << BaseClient.username() << "'"; << "', username: '" << BaseClient.username() << "'";
BaseClient.printLine(s.str()); BaseClient.printLine(s.str());
@ -1371,6 +1371,29 @@ static void ClientConnection_getVersion (const v8::FunctionCallbackInfo<v8::Valu
TRI_V8_RETURN_STD_STRING(connection->getVersion()); TRI_V8_RETURN_STD_STRING(connection->getVersion());
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief ClientConnection method "getMode"
////////////////////////////////////////////////////////////////////////////////
static void ClientConnection_getMode (const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
v8::HandleScope scope(isolate);
// get the connection
V8ClientConnection* connection = TRI_UnwrapClass<V8ClientConnection>(args.Holder(), WRAP_TYPE_CONNECTION);
if (connection == nullptr) {
TRI_V8_THROW_EXCEPTION_INTERNAL("connection class corrupted");
}
if (args.Length() != 0) {
TRI_V8_THROW_EXCEPTION_USAGE("getMode()");
}
TRI_V8_RETURN_STD_STRING(connection->getMode());
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief ClientConnection method "getDatabaseName" /// @brief ClientConnection method "getDatabaseName"
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -2070,7 +2093,8 @@ static bool printHelo(bool useServer, bool promptError) {
if (ClientConnection->isConnected() && ClientConnection->getLastHttpReturnCode() == HttpResponse::OK) { if (ClientConnection->isConnected() && ClientConnection->getLastHttpReturnCode() == HttpResponse::OK) {
ostringstream is; ostringstream is;
is << "Connected to ArangoDB '" << BaseClient.endpointString() is << "Connected to ArangoDB '" << BaseClient.endpointString()
<< "' version: " << ClientConnection->getVersion() << ", database: '" << BaseClient.databaseName() << "' version: " << ClientConnection->getVersion()
<< " [" << ClientConnection->getMode() << "], database: '" << BaseClient.databaseName()
<< "', username: '" << BaseClient.username() << "'"; << "', username: '" << BaseClient.username() << "'";
BaseClient.printLine(is.str(), true); BaseClient.printLine(is.str(), true);
@ -2147,6 +2171,7 @@ void InitCallbacks (v8::Isolate *isolate,
connection_proto->Set(isolate, "reconnect", v8::FunctionTemplate::New(isolate, ClientConnection_reconnect)); connection_proto->Set(isolate, "reconnect", v8::FunctionTemplate::New(isolate, ClientConnection_reconnect));
connection_proto->Set(isolate, "toString", v8::FunctionTemplate::New(isolate, ClientConnection_toString)); connection_proto->Set(isolate, "toString", v8::FunctionTemplate::New(isolate, ClientConnection_toString));
connection_proto->Set(isolate, "getVersion", v8::FunctionTemplate::New(isolate, ClientConnection_getVersion)); connection_proto->Set(isolate, "getVersion", v8::FunctionTemplate::New(isolate, ClientConnection_getVersion));
connection_proto->Set(isolate, "getMode", v8::FunctionTemplate::New(isolate, ClientConnection_getMode));
connection_proto->Set(isolate, "getDatabaseName", v8::FunctionTemplate::New(isolate, ClientConnection_getDatabaseName)); connection_proto->Set(isolate, "getDatabaseName", v8::FunctionTemplate::New(isolate, ClientConnection_getDatabaseName));
connection_proto->Set(isolate, "setDatabaseName", v8::FunctionTemplate::New(isolate, ClientConnection_setDatabaseName)); connection_proto->Set(isolate, "setDatabaseName", v8::FunctionTemplate::New(isolate, ClientConnection_setDatabaseName));
connection_proto->SetCallAsFunctionHandler(ClientConnection_ConstructorCallback); connection_proto->SetCallAsFunctionHandler(ClientConnection_ConstructorCallback);

View File

@ -32,6 +32,7 @@
#include "Basics/json.h" #include "Basics/json.h"
#include "Basics/tri-strings.h" #include "Basics/tri-strings.h"
#include "Basics/conversions.h" #include "Basics/conversions.h"
#include "Rest/AnyServer.h"
#include "Rest/HttpRequest.h" #include "Rest/HttpRequest.h"
#include "Rest/Version.h" #include "Rest/Version.h"
@ -40,6 +41,12 @@ using namespace triagens::rest;
using namespace triagens::admin; using namespace triagens::admin;
using namespace std; using namespace std;
////////////////////////////////////////////////////////////////////////////////
/// @brief ArangoDB server
////////////////////////////////////////////////////////////////////////////////
extern AnyServer* ArangoInstance;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief name of the queue /// @brief name of the queue
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -140,15 +147,15 @@ HttpHandler::status_t RestVersionHandler::execute () {
RequestStatisticsAgentSetIgnore(this); RequestStatisticsAgentSetIgnore(this);
TRI_InitObjectJson(TRI_CORE_MEM_ZONE, &result, 3); TRI_InitObjectJson(TRI_UNKNOWN_MEM_ZONE, &result, 3);
TRI_json_t server; TRI_json_t server;
TRI_InitStringJson(&server, TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, "arango"), strlen("arango")); TRI_InitStringJson(&server, TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, "arango"), strlen("arango"));
TRI_Insert2ObjectJson(TRI_CORE_MEM_ZONE, &result, "server", &server); TRI_Insert2ObjectJson(TRI_UNKNOWN_MEM_ZONE, &result, "server", &server);
TRI_json_t version; TRI_json_t version;
TRI_InitStringJson(&version, TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, TRI_VERSION), strlen(TRI_VERSION)); TRI_InitStringJson(&version, TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, TRI_VERSION), strlen(TRI_VERSION));
TRI_Insert2ObjectJson(TRI_CORE_MEM_ZONE, &result, "version", &version); TRI_Insert2ObjectJson(TRI_UNKNOWN_MEM_ZONE, &result, "version", &version);
bool found; bool found;
char const* detailsStr = _request->value("details", found); char const* detailsStr = _request->value("details", found);
@ -156,14 +163,20 @@ HttpHandler::status_t RestVersionHandler::execute () {
if (found && StringUtils::boolean(detailsStr)) { if (found && StringUtils::boolean(detailsStr)) {
TRI_json_t details; TRI_json_t details;
TRI_InitObjectJson(TRI_CORE_MEM_ZONE, &details); TRI_InitObjectJson(TRI_UNKNOWN_MEM_ZONE, &details);
Version::getJson(TRI_CORE_MEM_ZONE, &details); Version::getJson(TRI_UNKNOWN_MEM_ZONE, &details);
TRI_Insert2ObjectJson(TRI_CORE_MEM_ZONE, &result, "details", &details);
if (ArangoInstance != nullptr) {
std::string mode = ArangoInstance->modeString();
TRI_Insert2ObjectJson(TRI_UNKNOWN_MEM_ZONE, &details, "mode", TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, mode.c_str(), mode.size()));
}
TRI_Insert2ObjectJson(TRI_UNKNOWN_MEM_ZONE, &result, "details", &details);
} }
generateResult(&result); generateResult(&result);
TRI_DestroyJson(TRI_CORE_MEM_ZONE, &result); TRI_DestroyJson(TRI_UNKNOWN_MEM_ZONE, &result);
return status_t(HANDLER_DONE); return status_t(HANDLER_DONE);
} }

View File

@ -136,7 +136,7 @@ static void CheckPidFile (string const& pidFile) {
#ifdef TRI_HAVE_FORK #ifdef TRI_HAVE_FORK
static int forkProcess (string const& workingDirectory, string& current) { static int ForkProcess (string const& workingDirectory, string& current) {
// fork off the parent process // fork off the parent process
TRI_pid_t pid = fork(); TRI_pid_t pid = fork();
@ -213,7 +213,7 @@ static int forkProcess (string const& workingDirectory, string& current) {
// TODO: use windows API CreateProcess & CreateThread to minic fork() // TODO: use windows API CreateProcess & CreateThread to minic fork()
// .............................................................................. // ..............................................................................
static int forkProcess (string const& workingDirectory, string& current) { static int ForkProcess (string const& workingDirectory, string& current) {
// fork off the parent process // fork off the parent process
TRI_pid_t pid = -1; // fork(); TRI_pid_t pid = -1; // fork();
@ -236,7 +236,7 @@ static int forkProcess (string const& workingDirectory, string& current) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
AnyServer::AnyServer () AnyServer::AnyServer ()
: _daemonMode(false), : _mode(ServerMode::MODE_STANDALONE),
_supervisorMode(false), _supervisorMode(false),
_pidFile(""), _pidFile(""),
_workingDirectory(""), _workingDirectory(""),
@ -248,9 +248,7 @@ AnyServer::AnyServer ()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
AnyServer::~AnyServer () { AnyServer::~AnyServer () {
if (_applicationServer != nullptr) { delete _applicationServer;
delete _applicationServer;
}
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -262,7 +260,6 @@ AnyServer::~AnyServer () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int AnyServer::start () { int AnyServer::start () {
startupProgress(); startupProgress();
if (_applicationServer == nullptr) { if (_applicationServer == nullptr) {
@ -343,7 +340,7 @@ int AnyServer::startupSupervisor () {
_applicationServer->setupLogging(false, true, false); _applicationServer->setupLogging(false, true, false);
string current; string current;
int result = forkProcess(_workingDirectory, current); int result = ForkProcess(_workingDirectory, current);
// main process // main process
if (result != 0) { if (result != 0) {
@ -352,6 +349,8 @@ int AnyServer::startupSupervisor () {
// child process // child process
else { else {
setMode(ServerMode::MODE_SERVICE);
time_t startTime = time(0); time_t startTime = time(0);
time_t t; time_t t;
bool done = false; bool done = false;
@ -481,7 +480,7 @@ int AnyServer::startupDaemon () {
_applicationServer->setupLogging(false, true, false); _applicationServer->setupLogging(false, true, false);
string current; string current;
int result = forkProcess(_workingDirectory, current); int result = ForkProcess(_workingDirectory, current);
// main process // main process
if (result != 0) { if (result != 0) {
@ -494,6 +493,7 @@ int AnyServer::startupDaemon () {
// child process // child process
else { else {
setMode(ServerMode::MODE_SERVICE);
_applicationServer->setupLogging(true, false, true); _applicationServer->setupLogging(true, false, true);
LOG_DEBUG("daemon mode: within child"); LOG_DEBUG("daemon mode: within child");

View File

@ -50,8 +50,8 @@ namespace triagens {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class AnyServer { class AnyServer {
AnyServer (AnyServer const&); AnyServer (AnyServer const&) = delete;
AnyServer& operator= (AnyServer const&); AnyServer& operator= (AnyServer const&) = delete;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors // --SECTION-- constructors and destructors
@ -71,6 +71,21 @@ namespace triagens {
virtual ~AnyServer (); virtual ~AnyServer ();
// -----------------------------------------------------------------------------
// --SECTION-- public types
// -----------------------------------------------------------------------------
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief enumeration for server modes
////////////////////////////////////////////////////////////////////////////////
enum class ServerMode {
MODE_STANDALONE,
MODE_SERVICE
};
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- public methods // --SECTION-- public methods
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -89,6 +104,27 @@ namespace triagens {
void beginShutdown (); void beginShutdown ();
////////////////////////////////////////////////////////////////////////////////
/// @brief set the server mode
////////////////////////////////////////////////////////////////////////////////
void setMode (ServerMode mode) {
_mode = mode;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief get the server mode as a string
////////////////////////////////////////////////////////////////////////////////
char const* modeString () const {
if (_mode == ServerMode::MODE_STANDALONE) {
return "standalone";
}
TRI_ASSERT(_mode == ServerMode::MODE_SERVICE) {
return "service";
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- protected methods // --SECTION-- protected methods
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -137,6 +173,12 @@ namespace triagens {
protected: protected:
////////////////////////////////////////////////////////////////////////////////
/// @brief the server mode
////////////////////////////////////////////////////////////////////////////////
ServerMode _mode;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief running in daemon mode /// @brief running in daemon mode
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////