aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/modulemanager.lua68
1 files changed, 50 insertions, 18 deletions
diff --git a/core/modulemanager.lua b/core/modulemanager.lua
index e783e9b4..817b5dde 100644
--- a/core/modulemanager.lua
+++ b/core/modulemanager.lua
@@ -32,7 +32,7 @@ local register_actions = require "core.actions".register;
local loadfile, pcall = loadfile, pcall;
local setmetatable, setfenv, getfenv = setmetatable, setfenv, getfenv;
local pairs, ipairs = pairs, ipairs;
-local t_insert = table.insert;
+local t_insert, t_concat = table.insert, table.concat;
local type = type;
local next = next;
local rawget = rawget;
@@ -107,7 +107,7 @@ function load(host, module_name, config)
end
- local mod, err = loadfile(plugin_dir.."mod_"..module_name..".lua");
+ local mod, err = loadfile(get_module_filename(module_name));
if not mod then
log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil");
return nil, err;
@@ -132,18 +132,22 @@ function load(host, module_name, config)
return true;
end
+function get_module(host, name)
+ return modulemap[host] and modulemap[host][name];
+end
+
function is_loaded(host, name)
return modulemap[host] and modulemap[host][name] and true;
end
function unload(host, name, ...)
- local mod = modulemap[host] and modulemap[host][name];
+ local mod = get_module(host, name);
if not mod then return nil, "module-not-loaded"; end
- if type(mod.module.unload) == "function" then
- local ok, err = pcall(mod.module.unload, ...)
+ if module_has_method(mod, "unload") then
+ local ok, err = call_module_method(mod, "unload");
if (not ok) and err then
- log("warn", "Non-fatal error unloading module '%s' from '%s': %s", name, host, err);
+ log("warn", "Non-fatal error unloading module '%s' on '%s': %s", name, host, err);
end
end
modulemap[host][name] = nil;
@@ -161,36 +165,45 @@ function unload(host, name, ...)
end
function reload(host, name, ...)
- local mod = modulemap[host] and modulemap[host][name];
+ local mod = get_module(host, name);
if not mod then return nil, "module-not-loaded"; end
- local _mod, err = loadfile(plugin_dir.."mod_"..name..".lua"); -- checking for syntax errors
+ local _mod, err = loadfile(get_module_filename(name)); -- checking for syntax errors
if not _mod then
log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil");
return nil, err;
end
local saved;
- if type(mod.module.save) == "function" then
- local ok, err = pcall(mod.module.save)
- if (not ok) and err then
- log("warn", "Non-fatal error unloading module '%s' from '%s': %s", name, host, err);
+
+ if module_has_method(mod, "save") then
+ local ok, ret, err = call_module_method(mod, "save");
+ if ok then
+ saved = ret;
else
- saved = err;
+ log("warn", "Error saving module '%s:%s' state: %s", host, module, ret);
+ if not config.get(host, "core", "force_module_reload") then
+ log("warn", "Aborting reload due to error, set force_module_reload to ignore this");
+ return nil, "save-state-failed";
+ else
+ log("warn", "Continuing with reload (using the force)");
+ end
end
end
unload(host, name, ...);
- if load(host, name, ...) then
- mod = modulemap[host] and modulemap[host][name];
- if type(mod.module.restore) == "function" then
- local ok, err = pcall(mod.module.restore, saved or {})
+ local ok, err = load(host, name, ...);
+ if ok then
+ mod = get_module(host, name);
+ if module_has_method(mod, "restore") then
+ local ok, err = call_module_method(mod, "restore", saved or {})
if (not ok) and err then
- log("warn", "Non-fatal error unloading module '%s' from '%s': %s", name, host, err);
+ log("warn", "Error restoring module '%s' from '%s': %s", name, host, err);
end
end
return true;
end
+ return ok, err;
end
function handle_stanza(host, origin, stanza)
@@ -214,6 +227,25 @@ function handle_stanza(host, origin, stanza)
end
end
+function module_has_method(module, method)
+ return type(module.module[method]) == "function";
+end
+
+function call_module_method(module, func, ...)
+ local f = module.module[func];
+ if module_has_method(module, method) then
+ return pcall(f, ...);
+ else
+ return false, "no-such-method";
+ end
+end
+
+local _modulepath = { plugin_dir, "mod_", nil, ".lua"};
+function get_module_filename(name)
+ _modulepath[3] = name;
+ return t_concat(_modulepath);
+end
+
----- API functions exposed to modules -----------
-- Must all be in api.*