Skip to content

Commit

Permalink
repl: disable blocking completions by default
Browse files Browse the repository at this point in the history
It’s not okay for the REPL to be blocked for multiple seconds after
entering `require('` because the completion is performing blocking
fs operations on potentially huge directories. Turning the REPL
completion function asynchronous would be the right thing to do here,
but unfortunately the way the code is structured doesn’t play well
with that (in particular, it breaks the preview feature).
Therefore, disable these blocking calls by default.

Refs: #33282 (comment)

PR-URL: #36564
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
  • Loading branch information
addaleax committed Dec 21, 2020
1 parent ab895bd commit 82dd23f
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 3 deletions.
7 changes: 5 additions & 2 deletions lib/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ function REPLServer(prompt,
configurable: true
});

this.allowBlockingCompletions = !!options.allowBlockingCompletions;
this.useColors = !!options.useColors;
this._domain = options.domain || domain.create();
this.useGlobal = !!useGlobal;
Expand Down Expand Up @@ -1204,7 +1205,8 @@ function complete(line, callback) {
if (completeOn.length) {
filter = completeOn;
}
} else if (RegExpPrototypeTest(requireRE, line)) {
} else if (RegExpPrototypeTest(requireRE, line) &&
this.allowBlockingCompletions) {
// require('...<Tab>')
const extensions = ObjectKeys(this.context.require.extensions);
const indexes = ArrayPrototypeMap(extensions,
Expand Down Expand Up @@ -1265,7 +1267,8 @@ function complete(line, callback) {
if (!subdir) {
ArrayPrototypePush(completionGroups, _builtinLibs);
}
} else if (RegExpPrototypeTest(fsAutoCompleteRE, line)) {
} else if (RegExpPrototypeTest(fsAutoCompleteRE, line) &&
this.allowBlockingCompletions) {
[completionGroups, completeOn] = completeFSFunctions(line);
// Handle variable member lookup.
// We support simple chained expressions like the following (no function
Expand Down
7 changes: 6 additions & 1 deletion test/parallel/test-repl-tab-complete.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ function getNoResultsFunction() {

const works = [['inner.one'], 'inner.o'];
const putIn = new ArrayStream();
const testMe = repl.start('', putIn);
const testMe = repl.start({
prompt: '',
input: putIn,
output: process.stdout,
allowBlockingCompletions: true
});

// Some errors are passed to the domain, but do not callback
testMe._domain.on('error', assert.ifError);
Expand Down

0 comments on commit 82dd23f

Please sign in to comment.