Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add daemonization support. #42

Merged
merged 2 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions linux/server/Main.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,32 @@
#include <format>
#include <iostream>

#include <microsoft/net/remote/NetRemoteServerConfiguration.hxx>
#include <microsoft/net/remote/NetRemoteServer.hxx>
#include <unistd.h>

using namespace Microsoft::Net::Remote;

int
main(int argc, char* argv[])
{
NetRemoteServer server{ argc, argv };
const auto configuration = NetRemoteServerConfiguration::FromCommandLineArguments(argc, argv);

NetRemoteServer server{ configuration.ServerAddress };
server.Run();
server.GetGrpcServer()->Wait();

if (configuration.RunInBackground)
{
constexpr int nochdir = 0; // Change current working directory to /
constexpr int noclose = 0; // Don't redirect stdin, stdout to /dev/null

if (daemon(nochdir, noclose) != 0) {
const int error = errno;
const auto what = std::format("failed to daemonize (error={})", error);
std::cerr << what << std::endl;
throw std::runtime_error(what);
}
}

return 0;
}
11 changes: 11 additions & 0 deletions src/server/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ set(NET_REMOTE_SERVER_PUBLIC_INCLUDE_PREFIX ${NET_REMOTE_SERVER_PUBLIC_INCLUDE}/
target_sources(netremote-server
PRIVATE
NetRemoteServer.cxx
NetRemoteServerConfiguration.cxx
PUBLIC
${NET_REMOTE_SERVER_PUBLIC_INCLUDE_PREFIX}/NetRemoteServer.hxx
${NET_REMOTE_SERVER_PUBLIC_INCLUDE_PREFIX}/NetRemoteServerConfiguration.hxx
)

target_include_directories(netremote-server
Expand All @@ -23,6 +25,15 @@ target_link_libraries(netremote-server
CLI11::CLI11
)

list(APPEND NET_REMOTE_SERVER_PUBLIC_HEADERS
${NET_REMOTE_SERVER_PUBLIC_INCLUDE_PREFIX}/NetRemoteServer.hxx
${NET_REMOTE_SERVER_PUBLIC_INCLUDE_PREFIX}/NetRemoteServerConfiguration.hxx
)

set_target_properties(netremote-server PROPERTIES
PUBLIC_HEADER "${NET_REMOTE_SERVER_PUBLIC_HEADERS}"
)

install(
TARGETS netremote-server
EXPORT netremote
Expand Down
30 changes: 3 additions & 27 deletions src/server/NetRemoteServer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,9 @@

using namespace Microsoft::Net::Remote;

NetRemoteServer::NetRemoteServer(int argc, char* argv[])
{
try
{
m_cliParser->parse(argc, argv);
}
catch (const CLI::ParseError& e)
{
const auto failureMessage = std::format("Failed to parse command-line arguments ({}).", e.what());
std::cerr << std::format("{}\n{}", failureMessage, m_cliParser->help()) << std::endl;
throw std::runtime_error{ failureMessage };
}

// At this point, all supported command line arguments have been parsed.
// However, there are no command-line arguments currently supported, so
// there is nothing to do here. This should be updated to tease out the
// command line arguments from m_cliParser and save them to member variables
// if/when some arguments are supported.
}

/* static */
std::unique_ptr<CLI::App> NetRemoteServer::CreateCliParser()
{
auto app = std::make_unique<CLI::App>("NetRemoteServer");
// TODO: configure CLI11 app with supported options. Currently none.
return app;
}
NetRemoteServer::NetRemoteServer(std::string_view serverAddress) :
m_serverAddress{ serverAddress }
{}

std::unique_ptr<grpc::Server>& NetRemoteServer::GetGrpcServer() noexcept
{
Expand Down
64 changes: 64 additions & 0 deletions src/server/NetRemoteServerConfiguration.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@

#include <utility>

#include <CLI/CLI.hpp>
#include <microsoft/net/remote/NetRemoteServerConfiguration.hxx>

using namespace Microsoft::Net::Remote;

namespace details
{
CLI::App&
ConfigureCliAppOptions(CLI::App& app, NetRemoteServerConfiguration& config)
{
app.add_flag(
"-d",
config.RunInBackground,
"Run the service as a daemon in the background");

app.add_option(
"-a,--address",
config.ServerAddress,
"The address to listen on for incoming connections.");

return app;
}

template <typename... Args>
NetRemoteServerConfiguration
ParseCliAppOptions(bool throwOnParseError, Args&&... args)
{
CLI::App app{};
NetRemoteServerConfiguration configuration{};
ConfigureCliAppOptions(app, configuration);

try
{
app.parse(std::forward<Args>(args)...);
}
catch (const CLI::ParseError& parseError)
{
if (throwOnParseError)
{
throw parseError;
}
}

return configuration;
}

} // namespace details

/* static */
NetRemoteServerConfiguration
NetRemoteServerConfiguration::FromCommandLineArguments(int argc, char* argv[], bool throwOnParseError)
{
return details::ParseCliAppOptions(throwOnParseError, argc, argv);
}

/* static */
NetRemoteServerConfiguration
NetRemoteServerConfiguration::FromCommandLineArguments(std::vector<std::string>& args, bool throwOnParseError)
{
return details::ParseCliAppOptions(throwOnParseError, args);
}
25 changes: 4 additions & 21 deletions src/server/include/microsoft/net/remote/NetRemoteServer.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include <string_view>
#include <string>

#include <CLI/CLI.hpp>
#include <grpcpp/server.h>
#include <microsoft/net/remote/NetRemoteService.hxx>

Expand All @@ -18,17 +17,11 @@ namespace Microsoft::Net::Remote
struct NetRemoteServer
{
/**
* @brief Default address for the server to listen on.
*/
static constexpr auto ServerAddressDefault = "0.0.0.0:5047";

/**
* @brief Construct a new NetRemoteServer object from command-line arguments.
* @brief Construct a new NetRemoteServer object.
*
* @param argc The number of arguments.
* @param argv An array of 'argc' arguments.
* @param serverAddress
*/
NetRemoteServer(int argc, char* argv[]);
NetRemoteServer(std::string_view serverAddress);

/**
* @brief Get the GrpcServer object.
Expand All @@ -48,18 +41,8 @@ struct NetRemoteServer
void Stop();

private:
/**
* @brief Create a CLI11 parser object configured with the supported CLI
* arguments.
*
* @return std::unique_ptr<CLI::App>
*/
static std::unique_ptr<CLI::App> CreateCliParser();

private:
std::string m_serverAddress{ ServerAddressDefault };
std::string m_serverAddress;
std::unique_ptr<grpc::Server> m_server;
std::unique_ptr<CLI::App> m_cliParser;
Service::NetRemoteService m_service{};
};
} // namespace Microsoft::Net::Remote
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

#ifndef NET_REMOTE_SERVER_CONFIGURATION_HXX
#define NET_REMOTE_SERVER_CONFIGURATION_HXX

#include <string>
#include <vector>

namespace Microsoft::Net::Remote
{
struct NetRemoteServerConfiguration
{
/**
* @brief Default address for the server to listen on.
*/
static constexpr auto ServerAddressDefault = "0.0.0.0:5047";

/**
* @brief Create a NetRemoteServerConfiguration object from command-line
* arguments.
*
* @param argc
* @param argv
* @param throwOnParseError
* @return NetRemoteServerConfiguration
*/
static NetRemoteServerConfiguration
FromCommandLineArguments(int argc, char* argv[], bool throwOnParseError = false);

/**
* @brief Create a NetRemoteServerConfiguration object from command-line
* arguments.
*
* @param args
* @param throwOnParseError
* @return NetRemoteServerConfiguration
*/
static NetRemoteServerConfiguration
FromCommandLineArguments(std::vector<std::string>& args, bool throwOnParseError = false);

/**
* @brief Default address for the server to listen on.
*/
std::string ServerAddress{ ServerAddressDefault };

/**
* @brief Run the service in the background.
*/
bool RunInBackground{ true };
};

} // namespace Microsoft::Net::Remote

#endif // NET_REMOTE_SERVER_CONFIGURATION_HXX