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 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 reload_module(const ss_ &module_name, const ss_ &path) = 0;
|
||||
virtual ss_ get_modules_path() = 0;
|
||||
|
@ -112,9 +112,11 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
up_<server::State> state(server::createState());
|
||||
|
||||
state->load_modules(module_path);
|
||||
|
||||
// Main loop
|
||||
int exit_status = 0;
|
||||
uint64_t next_tick_us = get_timeofday_us();
|
||||
uint64_t t_per_tick = 1000 * 100;
|
||||
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);
|
||||
if(r == -1){
|
||||
if(errno == EINTR && g_sigint_received){
|
||||
// Fine, we're quitting
|
||||
break;
|
||||
}
|
||||
// Error
|
||||
num_consequent_valid_selects = 0;
|
||||
log_w("main", "select() returned -1: %s (fds: %s)",
|
||||
@ -207,8 +213,11 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
state->handle_events();
|
||||
|
||||
if(state->is_shutdown_requested(&exit_status))
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return exit_status;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
using interface::Event;
|
||||
|
||||
extern server::Config g_server_config;
|
||||
extern bool g_sigint_received;
|
||||
|
||||
namespace server {
|
||||
|
||||
@ -104,6 +105,9 @@ struct CState: public State, public interface::Server
|
||||
Event::Type event_type;
|
||||
};
|
||||
|
||||
bool m_shutdown_requested = false;
|
||||
int m_shutdown_exit_status = 0;
|
||||
|
||||
up_<rccpp::Compiler> m_compiler;
|
||||
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);
|
||||
|
||||
@ -162,7 +184,7 @@ struct CState: public State, public interface::Server
|
||||
sv_<ss_> include_dirs = m_compiler->include_directories;
|
||||
include_dirs.push_back(m_modules_path);
|
||||
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());
|
||||
|
||||
if(m_module_file_watches.count(module_name) == 0){
|
||||
@ -189,8 +211,8 @@ struct CState: public State, public interface::Server
|
||||
if(dep.type == "ldflags")
|
||||
extra_ldflags += dep.value+" ";
|
||||
}
|
||||
log_i(MODULE, "extra_cxxflags: %s", cs(extra_cxxflags));
|
||||
log_i(MODULE, "extra_ldflags: %s", cs(extra_ldflags));
|
||||
log_v(MODULE, "extra_cxxflags: %s", cs(extra_cxxflags));
|
||||
log_v(MODULE, "extra_ldflags: %s", cs(extra_ldflags));
|
||||
|
||||
m_compiler->include_directories.push_back(m_modules_path);
|
||||
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){
|
||||
log_w(MODULE, "Failed to build module %s", cs(module_name));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Construct instance
|
||||
@ -209,7 +231,7 @@ struct CState: public State, public interface::Server
|
||||
if(m == nullptr){
|
||||
log_w(MODULE, "Failed to construct module %s instance",
|
||||
cs(module_name));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
m_modules[module_name] = ModuleContainer(m);
|
||||
m_modules[module_name].path = path;
|
||||
@ -224,6 +246,7 @@ struct CState: public State, public interface::Server
|
||||
|
||||
emit_event(Event("core:module_loaded",
|
||||
new interface::ModuleLoadedEvent(module_name)));
|
||||
return true;
|
||||
}
|
||||
|
||||
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
|
||||
// only by this same thread.
|
||||
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_<sv_<ModuleContainer*>> event_subs_snapshot;
|
||||
{
|
||||
|
@ -11,6 +11,11 @@ namespace interface
|
||||
|
||||
namespace server
|
||||
{
|
||||
struct ServerShutdownRequest: public Exception {
|
||||
ss_ msg;
|
||||
ServerShutdownRequest(const ss_ &msg): Exception(msg){}
|
||||
};
|
||||
|
||||
struct ModuleNotFoundException: public Exception {
|
||||
ss_ msg;
|
||||
ModuleNotFoundException(const ss_ &msg): Exception(msg){}
|
||||
@ -19,7 +24,9 @@ namespace server
|
||||
struct 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 interface::Module* get_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()
|
||||
{
|
||||
ss_ builtin = m_server->get_builtin_modules_path();
|
||||
m_server->load_module("network", builtin+"/network");
|
||||
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");
|
||||
ss_ current = m_server->get_modules_path();
|
||||
|
||||
sv_<ss_> load_list = {
|
||||
"test1",
|
||||
//"test2",
|
||||
//"minigame",
|
||||
sv_<std::pair<ss_, ss_>> load_list = {
|
||||
{builtin, "network"},
|
||||
{builtin, "client_file"},
|
||||
{builtin, "client_lua"},
|
||||
{builtin, "client_data"},
|
||||
{current, "test1"},
|
||||
//{current, "test2"},
|
||||
//{current, "minigame"},
|
||||
};
|
||||
for(const ss_ &name : load_list){
|
||||
m_server->load_module(name, m_server->get_modules_path()+"/"+name);
|
||||
for(auto &pair : load_list){
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user