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.
Startup sequence and what the module should do:
- constructor : Initialize everything you can here
- init() : Subscribe to events
- "core:start" event : Start doing whatever the module wants to actively do
- constructor : Don't access other modules. Throw on fatal errors.
- init() : Subscribe to events; access other external things.
- "core:start" : Start doing whatever the module wants to actively do.
- "core:continue" : Continue doing stuff after a reload.
Network protocol
----------------

View File

@ -17,12 +17,20 @@ namespace interface
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
{
virtual ~Server(){}
virtual void 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;
virtual ss_ get_builtin_modules_path() = 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},
[this, module_name, path]()
{
log_i(MODULE, "Module modified: %s; reloading", cs(module_name));
unload_module_u(module_name);
load_module(module_name, path);
log_i(MODULE, "Module modified: %s: %s",
cs(module_name), cs(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;
ss_ first_module_path = path+"/__loader";
load_module("__loader", first_module_path);
// Allow loader load other modules
// Allow loader to load other modules
emit_event(Event("core:load_modules"));
handle_events();
// 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);
}
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
void unload_module_u(const ss_ &module_name)
{

View File

@ -28,13 +28,14 @@ struct Module: public interface::Module
{
log_v(MODULE, "__loader init");
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)
{
if(type == Event::t("core:load_modules")){
on_load_modules();
}
EVENT_VOIDN("core:load_modules", on_load_modules)
EVENT_TYPEN("core:module_modified", on_module_modified,
interface::ModuleModifiedEvent)
}
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);
}*/
}
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" {