Skip to content

Commit

Permalink
Daemonize nebula-graphd (vesoft-inc#54)
Browse files Browse the repository at this point in the history
  • Loading branch information
dutor authored Jan 2, 2019
1 parent 65dd18b commit e7c87b9
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 14 deletions.
4 changes: 4 additions & 0 deletions etc/nebula-graphd.conf.default
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
########## basics ##########
# Whether run as a daemon process
--daemonize=true

########## logging ##########
# Directory to host logging files, which must already exist
--log_dir=logs
Expand Down
20 changes: 20 additions & 0 deletions src/common/process/ProcessUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,26 @@ Status ProcessUtils::makePidFile(const std::string &pidFile, uint32_t pid) {
}


Status ProcessUtils::daemonize(const std::string &pidFile) {
auto pid = ::fork();
if (pid == -1) {
return Status::Error("fork: %s", ::strerror(errno));
}
if (pid > 0) { // parent process
::exit(0);
}

// Make the child process as the session leader and detach with the controlling terminal
::setsid();
// Set `/dev/null' as standard input
auto fd = ::open("/dev/null", O_RDWR);
::dup2(fd, 0);
::close(fd);

return makePidFile(pidFile);
}


StatusOr<std::string> ProcessUtils::getExePath(uint32_t pid) {
if (pid == 0) {
pid = ::getpid();
Expand Down
7 changes: 7 additions & 0 deletions src/common/process/ProcessUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@ class ProcessUtils final {
* The pidFile contains a valid pid and no such process exists.
*/
static Status isPidAvailable(const std::string &pidFile);
/**
* Write pid into file, create if not exist.
*/
static Status makePidFile(const std::string &path, uint32_t pid = 0);
/**
* Make current process a daemon and write the daemon's pid into pidFile
*/
static Status daemonize(const std::string &pidFile);
/**
* Get the absolute path to the target process's executable.
* Use the current process if pid == 0.
Expand Down
25 changes: 16 additions & 9 deletions src/common/time/Duration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,28 @@ uint64_t calibrateTicksPerUSec() {
}


static void launchTickTockThread();

volatile std::atomic<uint64_t> ticksPerUSec{
[]() -> uint64_t {
thread::NamedThread t("tick-tock",
[]() {
while (true) {
sleep(3);
ticksPerUSec.store(calibrateTicksPerUSec());
} // while
});
t.detach();

launchTickTockThread();
// re-launch tick-tock thread after forking
::pthread_atfork(nullptr, nullptr, &launchTickTockThread);
return calibrateTicksPerUSec();
}()
};

void launchTickTockThread() {
thread::NamedThread t("tick-tock",
[]() {
while (true) {
sleep(3);
ticksPerUSec.store(calibrateTicksPerUSec());
} // while
});
t.detach();
}

} // namespace detail


Expand Down
57 changes: 52 additions & 5 deletions src/daemons/GraphDaemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,31 @@ static std::unique_ptr<apache::thrift::ThriftServer> gServer;
static void signalHandler(int sig);
static Status setupSignalHandler();
static Status setupLogging();
static void printHelp(const char *prog);
static void printVersion();

DECLARE_string(flagfile);

int main(int argc, char *argv[]) {
if (argc == 1) {
printHelp(argv[0]);
return EXIT_FAILURE;
}
if (argc == 2) {
if (::strcmp(argv[1], "-h") == 0) {
printHelp(argv[0]);
return EXIT_SUCCESS;
}
if (::strcmp(argv[1], "-v") == 0) {
printVersion();
return EXIT_SUCCESS;
}
}
if (FLAGS_flagfile.empty()) {
printHelp(argv[0]);
return EXIT_FAILURE;
}

folly::init(&argc, &argv, true);

// Setup logging
Expand All @@ -43,11 +66,19 @@ int main(int argc, char *argv[]) {
return EXIT_FAILURE;
}

// Write the current pid into the pid file
status = ProcessUtils::makePidFile(pidPath);
if (!status.ok()) {
LOG(ERROR) << status;
return EXIT_FAILURE;
if (FLAGS_daemonize) {
status = ProcessUtils::daemonize(pidPath);
if (!status.ok()) {
LOG(ERROR) << status;
return EXIT_FAILURE;
}
} else {
// Write the current pid into the pid file
status = ProcessUtils::makePidFile(pidPath);
if (!status.ok()) {
LOG(ERROR) << status;
return EXIT_FAILURE;
}
}

// Setup the signal handlers
Expand Down Expand Up @@ -123,6 +154,10 @@ void signalHandler(int sig) {


Status setupLogging() {
if (!FLAGS_redirect_stdout) {
return Status::OK();
}

auto dup = [] (const std::string &filename, FILE *stream) -> Status {
auto path = FLAGS_log_dir + "/" + filename;
auto fd = ::open(path.c_str(), O_WRONLY | O_APPEND | O_CREAT, 0644);
Expand Down Expand Up @@ -152,3 +187,15 @@ Status setupLogging() {

return status;
}


void printHelp(const char *prog) {
fprintf(stderr, "%s -flagfile config_file\n", prog);
fprintf(stderr, "%s -h\n", prog);
fprintf(stderr, "%s -v\n", prog);
}


void printVersion() {
// TODO(dutor)
}
1 change: 1 addition & 0 deletions src/graph/GraphFlags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ DEFINE_string(pid_file, "nebula-graphd.pid", "File to hold the process id");
DEFINE_bool(redirect_stdout, true, "Whether to redirect stdout and stderr to separate files");
DEFINE_string(stdout_log_file, "graphd-stdout.log", "Destination filename of stdout");
DEFINE_string(stderr_log_file, "graphd-stderr.log", "Destination filename of stderr");
DEFINE_bool(daemonize, true, "Whether run as a daemon process");
1 change: 1 addition & 0 deletions src/graph/GraphFlags.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ DECLARE_string(pid_file);
DECLARE_bool(redirect_stdout);
DECLARE_string(stdout_log_file);
DECLARE_string(stderr_log_file);
DECLARE_bool(daemonize);


#endif // GRAPH_GRAPHFLAGS_H_

0 comments on commit e7c87b9

Please sign in to comment.