Software /
code /
prosody
Comparison
core/modulemanager.lua @ 745:5a343599cd3e
core.modulemanager: Some refactoring to make upcoming changes a little easier
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Sat, 24 Jan 2009 01:15:40 +0000 |
parent | 733:b1aedec00661 |
child | 746:7027de4c039d |
comparison
equal
deleted
inserted
replaced
744:328b702fb80c | 745:5a343599cd3e |
---|---|
30 local register_actions = require "core.actions".register; | 30 local register_actions = require "core.actions".register; |
31 | 31 |
32 local loadfile, pcall = loadfile, pcall; | 32 local loadfile, pcall = loadfile, pcall; |
33 local setmetatable, setfenv, getfenv = setmetatable, setfenv, getfenv; | 33 local setmetatable, setfenv, getfenv = setmetatable, setfenv, getfenv; |
34 local pairs, ipairs = pairs, ipairs; | 34 local pairs, ipairs = pairs, ipairs; |
35 local t_insert = table.insert; | 35 local t_insert, t_concat = table.insert, table.concat; |
36 local type = type; | 36 local type = type; |
37 local next = next; | 37 local next = next; |
38 local rawget = rawget; | 38 local rawget = rawget; |
39 | 39 |
40 local tostring, print = tostring, print; | 40 local tostring, print = tostring, print; |
105 elseif modulemap["*"][module_name] then | 105 elseif modulemap["*"][module_name] then |
106 return nil, "global-module-already-loaded"; | 106 return nil, "global-module-already-loaded"; |
107 end | 107 end |
108 | 108 |
109 | 109 |
110 local mod, err = loadfile(plugin_dir.."mod_"..module_name..".lua"); | 110 local mod, err = loadfile(get_module_filename(module_name)); |
111 if not mod then | 111 if not mod then |
112 log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil"); | 112 log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil"); |
113 return nil, err; | 113 return nil, err; |
114 end | 114 end |
115 | 115 |
130 modulemap[api_instance.host][module_name] = pluginenv; | 130 modulemap[api_instance.host][module_name] = pluginenv; |
131 | 131 |
132 return true; | 132 return true; |
133 end | 133 end |
134 | 134 |
135 function get_module(host, name) | |
136 return modulemap[host] and modulemap[host][name]; | |
137 end | |
138 | |
135 function is_loaded(host, name) | 139 function is_loaded(host, name) |
136 return modulemap[host] and modulemap[host][name] and true; | 140 return modulemap[host] and modulemap[host][name] and true; |
137 end | 141 end |
138 | 142 |
139 function unload(host, name, ...) | 143 function unload(host, name, ...) |
140 local mod = modulemap[host] and modulemap[host][name]; | 144 local mod = get_module(host, name); |
141 if not mod then return nil, "module-not-loaded"; end | 145 if not mod then return nil, "module-not-loaded"; end |
142 | 146 |
143 if type(mod.module.unload) == "function" then | 147 if module_has_method(mod, "unload") then |
144 local ok, err = pcall(mod.module.unload, ...) | 148 local ok, err = call_module_method(mod, "unload"); |
145 if (not ok) and err then | 149 if (not ok) and err then |
146 log("warn", "Non-fatal error unloading module '%s' from '%s': %s", name, host, err); | 150 log("warn", "Non-fatal error unloading module '%s' on '%s': %s", name, host, err); |
147 end | 151 end |
148 end | 152 end |
149 modulemap[host][name] = nil; | 153 modulemap[host][name] = nil; |
150 features_table:remove(host, name); | 154 features_table:remove(host, name); |
151 local params = handler_table:get(host, name); -- , {module.host, origin_type, tag, xmlns} | 155 local params = handler_table:get(host, name); -- , {module.host, origin_type, tag, xmlns} |
159 event_hooks:remove(host, name); | 163 event_hooks:remove(host, name); |
160 return true; | 164 return true; |
161 end | 165 end |
162 | 166 |
163 function reload(host, name, ...) | 167 function reload(host, name, ...) |
164 local mod = modulemap[host] and modulemap[host][name]; | 168 local mod = get_module(host, name); |
165 if not mod then return nil, "module-not-loaded"; end | 169 if not mod then return nil, "module-not-loaded"; end |
166 | 170 |
167 local _mod, err = loadfile(plugin_dir.."mod_"..name..".lua"); -- checking for syntax errors | 171 local _mod, err = loadfile(get_module_filename(name)); -- checking for syntax errors |
168 if not _mod then | 172 if not _mod then |
169 log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil"); | 173 log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil"); |
170 return nil, err; | 174 return nil, err; |
171 end | 175 end |
172 | 176 |
173 local saved; | 177 local saved; |
174 if type(mod.module.save) == "function" then | 178 |
175 local ok, err = pcall(mod.module.save) | 179 if module_has_method(mod, "save") then |
176 if (not ok) and err then | 180 local ok, ret, err = call_module_method(mod, "save"); |
177 log("warn", "Non-fatal error unloading module '%s' from '%s': %s", name, host, err); | 181 if ok then |
182 saved = ret; | |
178 else | 183 else |
179 saved = err; | 184 log("warn", "Error saving module '%s:%s' state: %s", host, module, ret); |
185 if not config.get(host, "core", "force_module_reload") then | |
186 log("warn", "Aborting reload due to error, set force_module_reload to ignore this"); | |
187 return nil, "save-state-failed"; | |
188 else | |
189 log("warn", "Continuing with reload (using the force)"); | |
190 end | |
180 end | 191 end |
181 end | 192 end |
182 | 193 |
183 unload(host, name, ...); | 194 unload(host, name, ...); |
184 if load(host, name, ...) then | 195 local ok, err = load(host, name, ...); |
185 mod = modulemap[host] and modulemap[host][name]; | 196 if ok then |
186 if type(mod.module.restore) == "function" then | 197 mod = get_module(host, name); |
187 local ok, err = pcall(mod.module.restore, saved or {}) | 198 if module_has_method(mod, "restore") then |
199 local ok, err = call_module_method(mod, "restore", saved or {}) | |
188 if (not ok) and err then | 200 if (not ok) and err then |
189 log("warn", "Non-fatal error unloading module '%s' from '%s': %s", name, host, err); | 201 log("warn", "Error restoring module '%s' from '%s': %s", name, host, err); |
190 end | 202 end |
191 end | 203 end |
192 return true; | 204 return true; |
193 end | 205 end |
206 return ok, err; | |
194 end | 207 end |
195 | 208 |
196 function handle_stanza(host, origin, stanza) | 209 function handle_stanza(host, origin, stanza) |
197 local name, xmlns, origin_type = stanza.name, stanza.attr.xmlns, origin.type; | 210 local name, xmlns, origin_type = stanza.name, stanza.attr.xmlns, origin.type; |
198 if name == "iq" and xmlns == "jabber:client" then | 211 if name == "iq" and xmlns == "jabber:client" then |
210 (handlers[1])(origin, stanza); | 223 (handlers[1])(origin, stanza); |
211 return true; | 224 return true; |
212 else | 225 else |
213 log("debug", "Stanza unhandled by any modules, xmlns: %s", stanza.attr.xmlns); -- we didn't handle it | 226 log("debug", "Stanza unhandled by any modules, xmlns: %s", stanza.attr.xmlns); -- we didn't handle it |
214 end | 227 end |
228 end | |
229 | |
230 function module_has_method(module, method) | |
231 return type(module.module[method]) == "function"; | |
232 end | |
233 | |
234 function call_module_method(module, func, ...) | |
235 local f = module.module[func]; | |
236 if module_has_method(module, method) then | |
237 return pcall(f, ...); | |
238 else | |
239 return false, "no-such-method"; | |
240 end | |
241 end | |
242 | |
243 local _modulepath = { plugin_dir, "mod_", nil, ".lua"}; | |
244 function get_module_filename(name) | |
245 _modulepath[3] = name; | |
246 return t_concat(_modulepath); | |
215 end | 247 end |
216 | 248 |
217 ----- API functions exposed to modules ----------- | 249 ----- API functions exposed to modules ----------- |
218 -- Must all be in api.* | 250 -- Must all be in api.* |
219 | 251 |