server/state, testmodules/__loader: Don't automate module reload, instead implement it in __loader

This commit is contained in:
Perttu Ahola 2014-09-18 17:52:44 +03:00
parent 479968f229
commit ed921ebf4b
4 changed files with 48 additions and 10 deletions

View File

@ -49,9 +49,10 @@ files. They cannot export any internally defined functions directly, but they
can provide convenience wrappers for event-based interfaces. can provide convenience wrappers for event-based interfaces.
Startup sequence and what the module should do: Startup sequence and what the module should do:
- constructor : Initialize everything you can here - constructor : Don't access other modules. Throw on fatal errors.
- init() : Subscribe to events - init() : Subscribe to events; access other external things.
- "core:start" event : Start doing whatever the module wants to actively do - "core:start" : Start doing whatever the module wants to actively do.
- "core:continue" : Continue doing stuff after a reload.
Network protocol Network protocol
---------------- ----------------

View File

@ -17,12 +17,20 @@ namespace interface
SocketEvent(int fd): fd(fd){} SocketEvent(int fd): fd(fd){}
}; };
struct ModuleModifiedEvent: public interface::Event::Private {
ss_ name;
ss_ path;
ModuleModifiedEvent(const ss_ &name, const ss_ &path):
name(name), path(path){}
};
struct Server struct Server
{ {
virtual ~Server(){} virtual ~Server(){}
virtual void load_module(const ss_ &module_name, const ss_ &path) = 0; virtual void 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 ss_ get_modules_path() = 0; virtual ss_ get_modules_path() = 0;
virtual ss_ get_builtin_modules_path() = 0; virtual ss_ get_builtin_modules_path() = 0;
virtual bool has_module(const ss_ &module_name) = 0; virtual bool has_module(const ss_ &module_name) = 0;

View File

@ -88,9 +88,11 @@ struct CState: public State, public interface::Server
interface::createFileWatch({init_cpp_path}, interface::createFileWatch({init_cpp_path},
[this, module_name, path]() [this, module_name, path]()
{ {
log_i(MODULE, "Module modified: %s; reloading", cs(module_name)); log_i(MODULE, "Module modified: %s: %s",
unload_module_u(module_name); cs(module_name), cs(path));
load_module(module_name, path); emit_event(Event("core:module_modified",
new interface::ModuleModifiedEvent(module_name, path)));
handle_events();
})); }));
} }
@ -130,7 +132,7 @@ struct CState: public State, public interface::Server
m_modules_path = path; m_modules_path = path;
ss_ first_module_path = path+"/__loader"; ss_ first_module_path = path+"/__loader";
load_module("__loader", first_module_path); load_module("__loader", first_module_path);
// Allow loader load other modules // Allow loader to load other modules
emit_event(Event("core:load_modules")); emit_event(Event("core:load_modules"));
handle_events(); handle_events();
// Now that everyone is listening, we can fire the start event // Now that everyone is listening, we can fire the start event
@ -148,6 +150,26 @@ struct CState: public State, public interface::Server
m_unloads_requested.insert(module_name); m_unloads_requested.insert(module_name);
} }
void reload_module(const ss_ &module_name, const ss_ &path)
{
log_i(MODULE, "reload_module(%s)", cs(module_name));
unload_module_u(module_name);
load_module(module_name, path);
// Send core::continue directly to module
{
interface::MutexScope ms(m_modules_mutex);
auto it = m_modules.find(module_name);
if(it == m_modules.end()){
log_w(MODULE, "reload_module: Module not found: %s",
cs(module_name));
return;
}
ModuleContainer *mc = &it->second;
interface::MutexScope mc_ms(mc->mutex);
mc->module->event(Event::t("core:continue"), nullptr);
}
}
// Direct version; internal and unsafe // Direct version; internal and unsafe
void unload_module_u(const ss_ &module_name) void unload_module_u(const ss_ &module_name)
{ {

View File

@ -28,13 +28,14 @@ struct Module: public interface::Module
{ {
log_v(MODULE, "__loader init"); log_v(MODULE, "__loader init");
m_server->sub_event(this, Event::t("core:load_modules")); m_server->sub_event(this, Event::t("core:load_modules"));
m_server->sub_event(this, Event::t("core:module_modified"));
} }
void event(const Event::Type &type, const Event::Private *p) void event(const Event::Type &type, const Event::Private *p)
{ {
if(type == Event::t("core:load_modules")){ EVENT_VOIDN("core:load_modules", on_load_modules)
on_load_modules(); EVENT_TYPEN("core:module_modified", on_module_modified,
} interface::ModuleModifiedEvent)
} }
void on_load_modules() void on_load_modules()
@ -55,6 +56,12 @@ struct Module: public interface::Module
m_server->load_module(n.name, m_server->get_modules_path()+"/"+n.name); m_server->load_module(n.name, m_server->get_modules_path()+"/"+n.name);
}*/ }*/
} }
void on_module_modified(const interface::ModuleModifiedEvent &event)
{
log_v(MODULE, "__loader::on_module_modified()");
m_server->reload_module(event.name, event.path);
}
}; };
extern "C" { extern "C" {