server: Respond quickly to SIGINT and stop startup if some module fails to compile
This commit is contained in:
parent
4f93467716
commit
abc39ba044
@ -40,7 +40,9 @@ namespace interface
|
|||||||
{
|
{
|
||||||
virtual ~Server(){}
|
virtual ~Server(){}
|
||||||
|
|
||||||
virtual void load_module(const ss_ &module_name, const ss_ &path) = 0;
|
virtual void shutdown(int exit_status=0) = 0;
|
||||||
|
|
||||||
|
virtual bool load_module(const ss_ &module_name, const ss_ &path) = 0;
|
||||||
virtual void unload_module(const ss_ &module_name) = 0;
|
virtual void unload_module(const ss_ &module_name) = 0;
|
||||||
virtual void reload_module(const ss_ &module_name, const ss_ &path) = 0;
|
virtual void reload_module(const ss_ &module_name, const ss_ &path) = 0;
|
||||||
virtual ss_ get_modules_path() = 0;
|
virtual ss_ get_modules_path() = 0;
|
||||||
|
@ -112,9 +112,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
up_<server::State> state(server::createState());
|
up_<server::State> state(server::createState());
|
||||||
|
|
||||||
state->load_modules(module_path);
|
state->load_modules(module_path);
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
|
int exit_status = 0;
|
||||||
uint64_t next_tick_us = get_timeofday_us();
|
uint64_t next_tick_us = get_timeofday_us();
|
||||||
uint64_t t_per_tick = 1000 * 100;
|
uint64_t t_per_tick = 1000 * 100;
|
||||||
set_<int> attempt_bad_fds;
|
set_<int> attempt_bad_fds;
|
||||||
@ -150,6 +152,10 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
int r = select(fd_max + 1, &rfds, NULL, NULL, &tv);
|
int r = select(fd_max + 1, &rfds, NULL, NULL, &tv);
|
||||||
if(r == -1){
|
if(r == -1){
|
||||||
|
if(errno == EINTR && g_sigint_received){
|
||||||
|
// Fine, we're quitting
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Error
|
// Error
|
||||||
num_consequent_valid_selects = 0;
|
num_consequent_valid_selects = 0;
|
||||||
log_w("main", "select() returned -1: %s (fds: %s)",
|
log_w("main", "select() returned -1: %s (fds: %s)",
|
||||||
@ -207,8 +213,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
state->handle_events();
|
state->handle_events();
|
||||||
|
|
||||||
|
if(state->is_shutdown_requested(&exit_status))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return exit_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
using interface::Event;
|
using interface::Event;
|
||||||
|
|
||||||
extern server::Config g_server_config;
|
extern server::Config g_server_config;
|
||||||
|
extern bool g_sigint_received;
|
||||||
|
|
||||||
namespace server {
|
namespace server {
|
||||||
|
|
||||||
@ -104,6 +105,9 @@ struct CState: public State, public interface::Server
|
|||||||
Event::Type event_type;
|
Event::Type event_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool m_shutdown_requested = false;
|
||||||
|
int m_shutdown_exit_status = 0;
|
||||||
|
|
||||||
up_<rccpp::Compiler> m_compiler;
|
up_<rccpp::Compiler> m_compiler;
|
||||||
ss_ m_modules_path;
|
ss_ m_modules_path;
|
||||||
|
|
||||||
@ -146,7 +150,25 @@ struct CState: public State, public interface::Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_module(const ss_ &module_name, const ss_ &path)
|
void shutdown(int exit_status)
|
||||||
|
{
|
||||||
|
if(m_shutdown_requested && exit_status == 0){
|
||||||
|
// Only reset these values for exit values indicating failure
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log_i(MODULE, "Server shutdown requested; exit_status=%i", exit_status);
|
||||||
|
m_shutdown_requested = true;
|
||||||
|
m_shutdown_exit_status = exit_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_shutdown_requested(int *exit_status=nullptr)
|
||||||
|
{
|
||||||
|
if(m_shutdown_requested && exit_status)
|
||||||
|
*exit_status = m_shutdown_exit_status;
|
||||||
|
return m_shutdown_requested;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool load_module(const ss_ &module_name, const ss_ &path)
|
||||||
{
|
{
|
||||||
interface::MutexScope ms(m_modules_mutex);
|
interface::MutexScope ms(m_modules_mutex);
|
||||||
|
|
||||||
@ -162,7 +184,7 @@ struct CState: public State, public interface::Server
|
|||||||
sv_<ss_> include_dirs = m_compiler->include_directories;
|
sv_<ss_> include_dirs = m_compiler->include_directories;
|
||||||
include_dirs.push_back(m_modules_path);
|
include_dirs.push_back(m_modules_path);
|
||||||
sv_<ss_> includes = list_includes(init_cpp_path, include_dirs);
|
sv_<ss_> includes = list_includes(init_cpp_path, include_dirs);
|
||||||
log_i(MODULE, "Includes: %s", cs(dump(includes)));
|
log_v(MODULE, "Includes: %s", cs(dump(includes)));
|
||||||
files_to_watch.insert(files_to_watch.end(), includes.begin(), includes.end());
|
files_to_watch.insert(files_to_watch.end(), includes.begin(), includes.end());
|
||||||
|
|
||||||
if(m_module_file_watches.count(module_name) == 0){
|
if(m_module_file_watches.count(module_name) == 0){
|
||||||
@ -189,8 +211,8 @@ struct CState: public State, public interface::Server
|
|||||||
if(dep.type == "ldflags")
|
if(dep.type == "ldflags")
|
||||||
extra_ldflags += dep.value+" ";
|
extra_ldflags += dep.value+" ";
|
||||||
}
|
}
|
||||||
log_i(MODULE, "extra_cxxflags: %s", cs(extra_cxxflags));
|
log_v(MODULE, "extra_cxxflags: %s", cs(extra_cxxflags));
|
||||||
log_i(MODULE, "extra_ldflags: %s", cs(extra_ldflags));
|
log_v(MODULE, "extra_ldflags: %s", cs(extra_ldflags));
|
||||||
|
|
||||||
m_compiler->include_directories.push_back(m_modules_path);
|
m_compiler->include_directories.push_back(m_modules_path);
|
||||||
bool build_ok = m_compiler->build(module_name, init_cpp_path, build_dst,
|
bool build_ok = m_compiler->build(module_name, init_cpp_path, build_dst,
|
||||||
@ -199,7 +221,7 @@ struct CState: public State, public interface::Server
|
|||||||
|
|
||||||
if(!build_ok){
|
if(!build_ok){
|
||||||
log_w(MODULE, "Failed to build module %s", cs(module_name));
|
log_w(MODULE, "Failed to build module %s", cs(module_name));
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct instance
|
// Construct instance
|
||||||
@ -209,7 +231,7 @@ struct CState: public State, public interface::Server
|
|||||||
if(m == nullptr){
|
if(m == nullptr){
|
||||||
log_w(MODULE, "Failed to construct module %s instance",
|
log_w(MODULE, "Failed to construct module %s instance",
|
||||||
cs(module_name));
|
cs(module_name));
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
m_modules[module_name] = ModuleContainer(m);
|
m_modules[module_name] = ModuleContainer(m);
|
||||||
m_modules[module_name].path = path;
|
m_modules[module_name].path = path;
|
||||||
@ -224,6 +246,7 @@ struct CState: public State, public interface::Server
|
|||||||
|
|
||||||
emit_event(Event("core:module_loaded",
|
emit_event(Event("core:module_loaded",
|
||||||
new interface::ModuleLoadedEvent(module_name)));
|
new interface::ModuleLoadedEvent(module_name)));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_modules(const ss_ &path)
|
void load_modules(const ss_ &path)
|
||||||
@ -429,6 +452,10 @@ struct CState: public State, public interface::Server
|
|||||||
// can be deleted while this is running, because modules are deleted
|
// can be deleted while this is running, because modules are deleted
|
||||||
// only by this same thread.
|
// only by this same thread.
|
||||||
for(size_t loop_i = 0;; loop_i++){
|
for(size_t loop_i = 0;; loop_i++){
|
||||||
|
if(g_sigint_received){
|
||||||
|
// Get out fast
|
||||||
|
throw ServerShutdownRequest("Server shutdown requested via SIGINT");
|
||||||
|
}
|
||||||
sv_<Event> event_queue_snapshot;
|
sv_<Event> event_queue_snapshot;
|
||||||
sv_<sv_<ModuleContainer*>> event_subs_snapshot;
|
sv_<sv_<ModuleContainer*>> event_subs_snapshot;
|
||||||
{
|
{
|
||||||
|
@ -11,6 +11,11 @@ namespace interface
|
|||||||
|
|
||||||
namespace server
|
namespace server
|
||||||
{
|
{
|
||||||
|
struct ServerShutdownRequest: public Exception {
|
||||||
|
ss_ msg;
|
||||||
|
ServerShutdownRequest(const ss_ &msg): Exception(msg){}
|
||||||
|
};
|
||||||
|
|
||||||
struct ModuleNotFoundException: public Exception {
|
struct ModuleNotFoundException: public Exception {
|
||||||
ss_ msg;
|
ss_ msg;
|
||||||
ModuleNotFoundException(const ss_ &msg): Exception(msg){}
|
ModuleNotFoundException(const ss_ &msg): Exception(msg){}
|
||||||
@ -19,7 +24,9 @@ namespace server
|
|||||||
struct State
|
struct State
|
||||||
{
|
{
|
||||||
virtual ~State(){}
|
virtual ~State(){}
|
||||||
virtual void load_module(const ss_ &module_name, const ss_ &path) = 0;
|
virtual void shutdown(int exit_status=0) = 0;
|
||||||
|
virtual bool is_shutdown_requested(int *exit_status=nullptr) = 0;
|
||||||
|
virtual bool load_module(const ss_ &module_name, const ss_ &path) = 0;
|
||||||
virtual void load_modules(const ss_ &path) = 0;
|
virtual void load_modules(const ss_ &path) = 0;
|
||||||
virtual interface::Module* get_module(const ss_ &module_name) = 0;
|
virtual interface::Module* get_module(const ss_ &module_name) = 0;
|
||||||
virtual interface::Module* check_module(const ss_ &module_name) = 0;
|
virtual interface::Module* check_module(const ss_ &module_name) = 0;
|
||||||
|
@ -41,18 +41,25 @@ struct Module: public interface::Module
|
|||||||
void on_load_modules()
|
void on_load_modules()
|
||||||
{
|
{
|
||||||
ss_ builtin = m_server->get_builtin_modules_path();
|
ss_ builtin = m_server->get_builtin_modules_path();
|
||||||
m_server->load_module("network", builtin+"/network");
|
ss_ current = m_server->get_modules_path();
|
||||||
m_server->load_module("client_file", builtin+"/client_file");
|
|
||||||
m_server->load_module("client_lua", builtin+"/client_lua");
|
|
||||||
m_server->load_module("client_data", builtin+"/client_data");
|
|
||||||
|
|
||||||
sv_<ss_> load_list = {
|
sv_<std::pair<ss_, ss_>> load_list = {
|
||||||
"test1",
|
{builtin, "network"},
|
||||||
//"test2",
|
{builtin, "client_file"},
|
||||||
//"minigame",
|
{builtin, "client_lua"},
|
||||||
|
{builtin, "client_data"},
|
||||||
|
{current, "test1"},
|
||||||
|
//{current, "test2"},
|
||||||
|
//{current, "minigame"},
|
||||||
};
|
};
|
||||||
for(const ss_ &name : load_list){
|
for(auto &pair : load_list){
|
||||||
m_server->load_module(name, m_server->get_modules_path()+"/"+name);
|
const ss_ &name = pair.second;
|
||||||
|
const ss_ &path = pair.first+"/"+pair.second;
|
||||||
|
bool ok = m_server->load_module(name, path);
|
||||||
|
if(!ok){
|
||||||
|
m_server->shutdown(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*// TODO: Dependencies
|
/*// TODO: Dependencies
|
||||||
|
Loading…
x
Reference in New Issue
Block a user