From 3686bab167ca72d99888c3b74520d69dac800074 Mon Sep 17 00:00:00 2001 From: jay Date: Thu, 29 Apr 2021 08:14:40 +0500 Subject: [PATCH] fix: :bug: 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. --- lib/index.js | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/lib/index.js b/lib/index.js index ec205ec..bc66301 100644 --- a/lib/index.js +++ b/lib/index.js @@ -29,21 +29,22 @@ cfg.botOptions = options let plugins = {} -function loadplugin(pluginname, pluginpath) { +function loadplugin(pluginname, pluginpath = './plugins/' + pluginname) { try { plugins[pluginname] = require(pluginpath) plugins[pluginname].load(cfg) } catch (error) { if (error.code == 'MODULE_NOT_FOUND') { console.warn('plugin not used:', pluginpath) + } else if (plugins[pluginname] && !plugins[pluginname].load) { + unloadplugin(pluginname, pluginpath) } else { console.error(error) } } } -function unloadplugin(pluginname, pluginpath) { - pluginpath = pluginpath ? pluginpath : './plugins/' + pluginname +function unloadplugin(pluginname, pluginpath = './plugins/' + pluginname) { const plugin = require.resolve(pluginpath) try { 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 } + filename = filename.replace("\\", "/") // windows if (!cfg.fsTimeout) { 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) - console.info(`reload file: ./lib/${pluginpath}`) - const plugin = require.resolve(pluginpath) + console.info(`reload file: ./lib/${fullpluginpath}`) + const plugin = require.resolve(fullpluginpath) if (plugin && require.cache[plugin]) { // 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") + 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 left < right : // - new plugin that's not registered in cfg.plugins, so added