Skip to content

Commit

Permalink
fix #5756: use decache to unload plugin modules
Browse files Browse the repository at this point in the history
- don't touch exports!
- traverse only modules loaded by the plugin, not the entire require cache

Signed-off-by: Anton Kosyakov <anton.kosyakov@typefox.io>
  • Loading branch information
akosyakov committed Jul 19, 2019
1 parent 3587c23 commit a9a112d
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 35 deletions.
1 change: 1 addition & 0 deletions packages/plugin-ext/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@theia/search-in-workspace": "^0.8.0",
"@theia/task": "^0.8.0",
"@theia/workspace": "^0.8.0",
"decache": "^4.5.1",
"decompress": "^4.2.0",
"getmac": "^1.4.6",
"jsonc-parser": "^2.0.2",
Expand Down
37 changes: 2 additions & 35 deletions packages/plugin-ext/src/hosted/node/plugin-host-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { EditorsAndDocumentsExtImpl } from '../../plugin/editors-and-documents';
import { WorkspaceExtImpl } from '../../plugin/workspace';
import { MessageRegistryExt } from '../../plugin/message-registry';
import { EnvNodeExtImpl } from '../../plugin/node/env-node-ext';
import decache from 'decache';

/**
* Handle the RPC calls.
Expand Down Expand Up @@ -95,41 +96,7 @@ export class PluginHostRPC {
loadPlugin(plugin: Plugin): void {
console.log('PLUGIN_HOST(' + process.pid + '): PluginManagerExtImpl/loadPlugin(' + plugin.pluginPath + ')');
try {
// cleaning the cache for all files of that plug-in.
Object.keys(require.cache).forEach(function (key) {
const mod: NodeJS.Module = require.cache[key];

// attempting to reload a native module will throw an error, so skip them
if (mod.id.endsWith('.node')) {
return;
}

// remove children that are part of the plug-in
let i = mod.children.length;
while (i--) {
const childMod: NodeJS.Module = mod.children[i];
// ensure the child module is not null, is in the plug-in folder, and is not a native module (see above)
if (childMod && childMod.id.startsWith(plugin.pluginFolder) && !childMod.id.endsWith('.node')) {
// cleanup exports - note that some modules (e.g. ansi-styles) define their
// exports in an immutable manner, so overwriting the exports throws an error
delete childMod.exports;
mod.children.splice(i, 1);
for (let j = 0; j < childMod.children.length; j++) {
delete childMod.children[j];
}
}
}

if (key.startsWith(plugin.pluginFolder)) {
// delete entry
delete require.cache[key];
const ix = mod.parent!.children.indexOf(mod);
if (ix >= 0) {
mod.parent!.children.splice(ix, 1);
}
}

});
decache(plugin.pluginPath);
return require(plugin.pluginPath);
} catch (e) {
console.error(e);
Expand Down
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1978,6 +1978,11 @@ caller-id@^0.1.0:
dependencies:
stack-trace "~0.0.7"

callsite@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20"
integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA=

camelcase-keys@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
Expand Down Expand Up @@ -3059,6 +3064,13 @@ debug@~0.8.0:
version "0.8.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-0.8.1.tgz#20ff4d26f5e422cb68a1bacbbb61039ad8c1c130"

decache@^4.5.1:
version "4.5.1"
resolved "https://registry.yarnpkg.com/decache/-/decache-4.5.1.tgz#94a977a88a4188672c96550ec4889582ceecdf49"
integrity sha512-5J37nATc6FmOTLbcsr9qx7Nm28qQyg1SK4xyEHqM0IBkNhWFp0Sm+vKoWYHD8wq+OUEb9jLyaKFfzzd1A9hcoA==
dependencies:
callsite "^1.0.0"

decamelize-keys@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9"
Expand Down

0 comments on commit a9a112d

Please sign in to comment.