1
0
Fork 0

added base class Result and an example FileResult

This commit is contained in:
Frank Celler 2017-03-06 16:12:16 +01:00
parent f7b819579d
commit 4e2a5a13fd
7 changed files with 185 additions and 33 deletions

View File

@ -22,8 +22,8 @@
#include "DaemonFeature.h"
#include <iostream>
#include <fstream>
#include <iostream>
#include "Basics/FileUtils.h"
#include "Logger/Logger.h"
@ -65,13 +65,15 @@ void DaemonFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
if (!_daemon) {
return;
}
if (_pidFile.empty()) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "need --pid-file in --daemon mode";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "need --pid-file in --daemon mode";
FATAL_ERROR_EXIT();
}
LoggerFeature* logger = ApplicationServer::getFeature<LoggerFeature>("Logger");
LoggerFeature* logger =
ApplicationServer::getFeature<LoggerFeature>("Logger");
logger->setBackgrounded(true);
// make the pid filename absolute
@ -79,14 +81,16 @@ void DaemonFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
std::string currentDir = FileUtils::currentDirectory(&err);
char* absoluteFile =
TRI_GetAbsolutePath(_pidFile.c_str(), currentDir.c_str());
TRI_GetAbsolutePath(_pidFile.c_str(), currentDir.c_str());
if (absoluteFile != nullptr) {
_pidFile = std::string(absoluteFile);
TRI_Free(TRI_UNKNOWN_MEM_ZONE, absoluteFile);
LOG_TOPIC(DEBUG, arangodb::Logger::FIXME) << "using absolute pid file '" << _pidFile << "'";
LOG_TOPIC(DEBUG, arangodb::Logger::FIXME) << "using absolute pid file '"
<< _pidFile << "'";
} else {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "cannot determine absolute path";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "cannot determine absolute path";
FATAL_ERROR_EXIT();
}
}
@ -127,7 +131,8 @@ void DaemonFeature::unprepare() {
// remove pid file
if (!FileUtils::remove(_pidFile)) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "cannot remove pid file '" << _pidFile << "'";
LOG_TOPIC(ERR, arangodb::Logger::FIXME) << "cannot remove pid file '"
<< _pidFile << "'";
}
}
@ -135,7 +140,8 @@ void DaemonFeature::checkPidFile() {
// check if the pid-file exists
if (!_pidFile.empty()) {
if (FileUtils::isDirectory(_pidFile)) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "pid-file '" << _pidFile << "' is a directory";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "pid-file '" << _pidFile
<< "' is a directory";
FATAL_ERROR_EXIT();
} else if (FileUtils::exists(_pidFile) && FileUtils::size(_pidFile) > 0) {
LOG_TOPIC(INFO, Logger::STARTUP) << "pid-file '" << _pidFile
@ -150,7 +156,8 @@ void DaemonFeature::checkPidFile() {
f >> oldPid;
if (oldPid == 0) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "pid-file '" << _pidFile << "' is unreadable";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "pid-file '" << _pidFile
<< "' is unreadable";
FATAL_ERROR_EXIT();
}
@ -159,9 +166,9 @@ void DaemonFeature::checkPidFile() {
int r = kill(oldPid, 0);
if (r == 0 || errno == EPERM) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "pid-file '" << _pidFile
<< "' exists and process with pid " << oldPid
<< " is still running, refusing to start twice";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "pid-file '" << _pidFile << "' exists and process with pid "
<< oldPid << " is still running, refusing to start twice";
FATAL_ERROR_EXIT();
} else if (errno == ESRCH) {
LOG_TOPIC(ERR, Logger::STARTUP) << "pid-file '" << _pidFile
@ -169,25 +176,26 @@ void DaemonFeature::checkPidFile() {
<< oldPid << " exists";
if (!FileUtils::remove(_pidFile)) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "pid-file '" << _pidFile
<< "' exists, no process with pid " << oldPid
<< " exists, but pid-file cannot be removed";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "pid-file '" << _pidFile << "' exists, no process with pid "
<< oldPid << " exists, but pid-file cannot be removed";
FATAL_ERROR_EXIT();
}
LOG_TOPIC(INFO, Logger::STARTUP) << "removed stale pid-file '"
<< _pidFile << "'";
} else {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "pid-file '" << _pidFile << "' exists and kill "
<< oldPid << " failed";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "pid-file '" << _pidFile << "' exists and kill " << oldPid
<< " failed";
FATAL_ERROR_EXIT();
}
}
// failed to open file
else {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "pid-file '" << _pidFile
<< "' exists, but cannot be opened";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "pid-file '" << _pidFile << "' exists, but cannot be opened";
FATAL_ERROR_EXIT();
}
}
@ -237,13 +245,17 @@ int DaemonFeature::forkProcess() {
// change the current working directory
if (!_workingDirectory.empty()) {
if (!FileUtils::changeDirectory(_workingDirectory)) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "cannot change into working directory '"
<< _workingDirectory << "'";
FileResult res = FileUtils::changeDirectory(_workingDirectory);
if (!res.ok()) {
LOG_TOPIC(FATAL, arangodb::Logger::STARTUP)
<< "cannot change into working directory '" << _workingDirectory
<< "': " << res.errorMessage();
FATAL_ERROR_EXIT();
} else {
LOG_TOPIC(INFO, arangodb::Logger::FIXME) << "changed working directory for child process to '"
<< _workingDirectory << "'";
LOG_TOPIC(INFO, arangodb::Logger::STARTUP)
<< "changed working directory for child process to '"
<< _workingDirectory << "'";
}
}
@ -257,17 +269,20 @@ int DaemonFeature::forkProcess() {
}
if (dup2(fd, STDIN_FILENO) < 0) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "cannot re-map stdin to /dev/null";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "cannot re-map stdin to /dev/null";
FATAL_ERROR_EXIT();
}
if (dup2(fd, STDOUT_FILENO) < 0) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "cannot re-map stdout to /dev/null";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "cannot re-map stdout to /dev/null";
FATAL_ERROR_EXIT();
}
if (dup2(fd, STDERR_FILENO) < 0) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "cannot re-map stderr to /dev/null";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME)
<< "cannot re-map stderr to /dev/null";
FATAL_ERROR_EXIT();
}
@ -280,7 +295,8 @@ void DaemonFeature::writePidFile(int pid) {
std::ofstream out(_pidFile.c_str(), std::ios::trunc);
if (!out) {
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "cannot write pid-file '" << _pidFile << "'";
LOG_TOPIC(FATAL, arangodb::Logger::FIXME) << "cannot write pid-file '"
<< _pidFile << "'";
FATAL_ERROR_EXIT();
}

32
lib/Basics/FileResult.cpp Normal file
View File

@ -0,0 +1,32 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2017 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 Dr. Frank Celler
////////////////////////////////////////////////////////////////////////////////
#include "FileResult.h"
namespace arangodb {
FileResult::FileResult(bool state)
: Result(), _state(state), _sysErrorNumber(0) {}
FileResult::FileResult(bool state, int sysErrorNumber)
: Result(TRI_ERROR_SYS_ERROR, strerror(sysErrorNumber)),
_state(state), _sysErrorNumber(sysErrorNumber) {}
}

44
lib/Basics/FileResult.h Normal file
View File

@ -0,0 +1,44 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2017 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 Dr. Frank Celler
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGODB_BASICS_FILE_RESULT_H
#define ARANGODB_BASICS_FILE_RESULT_H 1
#include "Basics/Result.h"
namespace arangodb {
class FileResult : public Result {
public:
FileResult(bool state);
FileResult(bool state, int sysErrorNumber);
public:
bool state() const { return _state; }
int sysErrorNumber() const { return _sysErrorNumber; }
private:
bool const _state;
int const _sysErrorNumber;
};
}
#endif

View File

@ -360,7 +360,7 @@ bool copyDirectoryRecursive(std::string const& source,
bool rc = true;
auto isSubDirectory = [](std::string const& name) -> bool {
return isDirectory(name);
return isDirectory(name);
};
#ifdef TRI_HAVE_WIN32_LIST_FILES
struct _finddata_t oneItem;
@ -557,8 +557,14 @@ std::string stripExtension(std::string const& path,
return path;
}
bool changeDirectory(std::string const& path) {
return TRI_CHDIR(path.c_str()) == 0;
FileResult changeDirectory(std::string const& path) {
int res = TRI_CHDIR(path.c_str());
if (res == 0) {
return FileResult(true);
} else {
return FileResult(false, errno);
}
}
std::string currentDirectory(int* errorNumber) {

View File

@ -25,7 +25,9 @@
#define ARANGODB_BASICS_FILE_UTILS_H 1
#include "Basics/Common.h"
#include "Basics/files.h"
#include "Basics/FileResult.h"
namespace arangodb {
namespace basics {
@ -107,7 +109,7 @@ std::string stripExtension(std::string const& path,
std::string const& extension);
// changes into directory
bool changeDirectory(std::string const& path);
FileResult changeDirectory(std::string const& path);
// returns the current directory
std::string currentDirectory(int* errorNumber = 0);

51
lib/Basics/Result.h Normal file
View File

@ -0,0 +1,51 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2017 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 Dr. Frank Celler
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGODB_BASICS_RESULT_H
#define ARANGODB_BASICS_RESULT_H 1
#include "Basics/Common.h"
namespace arangodb {
class Result {
public:
Result() : _errorNumber(TRI_ERROR_NO_ERROR) {}
Result(int errorNumber, std::string errorMessage) {}
virtual ~Result() {}
public:
// the default implementations are const, but subclasses might
// really do more work to compute - for example - the error
// string.
virtual bool ok() { return _errorNumber == TRI_ERROR_NO_ERROR; }
virtual int errorNumber() { return _errorNumber; }
virtual std::string errorMessage() { return _errorMessage; }
protected:
int _errorNumber;
std::string _errorMessage;
};
}
#endif

View File

@ -130,6 +130,7 @@ add_library(${LIB_ARANGO} STATIC
Basics/ConditionVariable.cpp
Basics/DataProtector.cpp
Basics/Exceptions.cpp
Basics/FileResult.cpp
Basics/FileUtils.cpp
Basics/HybridLogicalClock.cpp
Basics/LocalTaskQueue.cpp