fix: 🐛 fix plugin reload for multi-file/dir based plugins

Now, it also (un-)loads the whole plugin (sub and master).

This appears to be the most stable option.
Loading behaviour is unchanged from before (load only top level plugin).
However as a precaution, loading tries to unload bad plugins on error.
This helps to not end up in a bad state during reload.
This commit is contained in:
jay 2021-04-29 08:14:40 +05:00
parent e0c477a46f
commit 3686bab167

View File

@ -29,21 +29,22 @@ cfg.botOptions = options
let plugins = {} let plugins = {}
function loadplugin(pluginname, pluginpath) { function loadplugin(pluginname, pluginpath = './plugins/' + pluginname) {
try { try {
plugins[pluginname] = require(pluginpath) plugins[pluginname] = require(pluginpath)
plugins[pluginname].load(cfg) plugins[pluginname].load(cfg)
} catch (error) { } catch (error) {
if (error.code == 'MODULE_NOT_FOUND') { if (error.code == 'MODULE_NOT_FOUND') {
console.warn('plugin not used:', pluginpath) console.warn('plugin not used:', pluginpath)
} else if (plugins[pluginname] && !plugins[pluginname].load) {
unloadplugin(pluginname, pluginpath)
} else { } else {
console.error(error) console.error(error)
} }
} }
} }
function unloadplugin(pluginname, pluginpath) { function unloadplugin(pluginname, pluginpath = './plugins/' + pluginname) {
pluginpath = pluginpath ? pluginpath : './plugins/' + pluginname
const plugin = require.resolve(pluginpath) const plugin = require.resolve(pluginpath)
try { try {
if (plugin && require.cache[plugin]) { if (plugin && require.cache[plugin]) {
@ -58,20 +59,28 @@ function unloadplugin(pluginname, pluginpath) {
} }
} }
function reloadplugin(event, filename, pluginpath) { function reloadplugin(event, filename, pluginpath = './plugins/') {
if (!/\.js$/.test(filename)) { return } if (!/\.js$/.test(filename)) { return }
filename = filename.replace("\\", "/") // windows
if (!cfg.fsTimeout) { if (!cfg.fsTimeout) {
console.info(event, filename) console.info(event, filename)
pluginpath = (pluginpath ? pluginpath : './plugins/') + filename const fullpluginpath = pluginpath + filename
const pluginname = (filename.split(".js")[0]).replace(/\/.+/, "")
pluginpath = pluginpath + pluginname
const hassubplugin = fullpluginpath.replace(/\.js$/, "") !== pluginpath
const check = Object.keys(cfg.plugins) const check = Object.keys(cfg.plugins)
console.info(`reload file: ./lib/${pluginpath}`) console.info(`reload file: ./lib/${fullpluginpath}`)
const plugin = require.resolve(pluginpath) const plugin = require.resolve(fullpluginpath)
if (plugin && require.cache[plugin]) { if (plugin && require.cache[plugin]) {
// console.debug(Object.keys(cfg.plugins)) // console.debug(Object.keys(cfg.plugins))
unloadplugin(filename.split(".js")[0], pluginpath) unloadplugin(pluginname)
console.assert(Object.keys(cfg.plugins).length == check.length - 1, "plugin not removed, potential memory leak") console.assert(Object.keys(cfg.plugins).length == check.length - 1, "plugin not removed, potential memory leak")
if (hassubplugin) {
console.info("reload: also unloading sub")
unloadplugin(pluginname, fullpluginpath)
}
} }
loadplugin(filename.split(".js")[0], pluginpath) loadplugin(pluginname)
if (Object.keys(cfg.plugins).length != check.length) { if (Object.keys(cfg.plugins).length != check.length) {
// If left < right : // If left < right :
// - new plugin that's not registered in cfg.plugins, so added // - new plugin that's not registered in cfg.plugins, so added