use local tsserverForkStart
This commit is contained in:
parent
6af7cf518a
commit
7563b04482
2 changed files with 162 additions and 1 deletions
161
bin/tsserverForkStart.js
Normal file
161
bin/tsserverForkStart.js
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
let net = require('net');
|
||||
let fs = require('fs');
|
||||
let ENABLE_LOGGING = false;
|
||||
let log = (function () {
|
||||
if (!ENABLE_LOGGING) {
|
||||
return function () { }; // tslint:disable-line
|
||||
}
|
||||
let isFirst = true;
|
||||
let LOG_LOCATION = 'C:\\stdFork.log';
|
||||
return function log(str) {
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
fs.writeFileSync(LOG_LOCATION, str + '\n');
|
||||
return;
|
||||
}
|
||||
fs.appendFileSync(LOG_LOCATION, str + '\n');
|
||||
};
|
||||
})();
|
||||
let stdInPipeName = process.env['STDIN_PIPE_NAME']; // tslint:disable-line
|
||||
let stdOutPipeName = process.env['STDOUT_PIPE_NAME']; // tslint:disable-line
|
||||
let stdErrPipeName = process.env['STDERR_PIPE_NAME']; // tslint:disable-line
|
||||
log('STDIN_PIPE_NAME: ' + stdInPipeName);
|
||||
log('STDOUT_PIPE_NAME: ' + stdOutPipeName);
|
||||
log('STDERR_PIPE_NAME: ' + stdErrPipeName);
|
||||
(function () {
|
||||
log('Beginning stdout redirection...');
|
||||
// Create a writing stream to the stdout pipe
|
||||
let stdOutStream = net.connect(stdOutPipeName);
|
||||
// unref stdOutStream to behave like a normal standard out
|
||||
stdOutStream.unref();
|
||||
process.__defineGetter__('stdout', function () {
|
||||
return stdOutStream;
|
||||
});
|
||||
// Create a writing stream to the stderr pipe
|
||||
let stdErrStream = net.connect(stdErrPipeName);
|
||||
// unref stdErrStream to behave like a normal standard out
|
||||
stdErrStream.unref();
|
||||
process.__defineGetter__('stderr', function () {
|
||||
return stdErrStream;
|
||||
});
|
||||
let fsWriteSyncString = function (// tslint:disable-line
|
||||
fd, str, _position, encoding) {
|
||||
// fs.writeSync(fd, string[, position[, encoding]])
|
||||
let buf = Buffer.from(str, encoding || 'utf8');
|
||||
return fsWriteSyncBuffer(fd, buf, 0, buf.length); // tslint:disable-line
|
||||
};
|
||||
let fsWriteSyncBuffer = function (// tslint:disable-line
|
||||
fd, buffer, off, len) {
|
||||
off = Math.abs(off | 0);
|
||||
len = Math.abs(len | 0);
|
||||
// fs.writeSync(fd, buffer, offset, length[, position])
|
||||
let buffer_length = buffer.length;
|
||||
if (off > buffer_length) {
|
||||
throw new Error('offset out of bounds');
|
||||
}
|
||||
if (len > buffer_length) {
|
||||
throw new Error('length out of bounds');
|
||||
}
|
||||
if (((off + len) | 0) < off) {
|
||||
throw new Error('off + len overflow');
|
||||
}
|
||||
if (buffer_length - off < len) {
|
||||
// Asking for more than is left over in the buffer
|
||||
throw new Error('off + len > buffer.length');
|
||||
}
|
||||
let slicedBuffer = buffer;
|
||||
if (off !== 0 || len !== buffer_length) {
|
||||
slicedBuffer = buffer.slice(off, off + len);
|
||||
}
|
||||
if (fd === 1) {
|
||||
stdOutStream.write(slicedBuffer);
|
||||
}
|
||||
else {
|
||||
stdErrStream.write(slicedBuffer);
|
||||
}
|
||||
return slicedBuffer.length;
|
||||
};
|
||||
// handle fs.writeSync(1, ...)
|
||||
let originalWriteSync = fs.writeSync;
|
||||
fs.writeSync = function (// tslint:disable-line
|
||||
fd, data, _position, _encoding) {
|
||||
if (fd !== 1 && fd !== 2) {
|
||||
return originalWriteSync.apply(fs, arguments);
|
||||
}
|
||||
// usage:
|
||||
// fs.writeSync(fd, buffer, offset, length[, position])
|
||||
// OR
|
||||
// fs.writeSync(fd, string[, position[, encoding]])
|
||||
if (data instanceof Buffer) {
|
||||
return fsWriteSyncBuffer.apply(null, arguments);
|
||||
}
|
||||
// For compatibility reasons with fs.writeSync, writing null will write "null", etc
|
||||
if (typeof data !== 'string') {
|
||||
data += '';
|
||||
}
|
||||
return fsWriteSyncString.apply(null, arguments);
|
||||
};
|
||||
log('Finished defining process.stdout, process.stderr and fs.writeSync');
|
||||
})();
|
||||
(function () {
|
||||
// Begin listening to stdin pipe
|
||||
let server = net.createServer(function (stream) {
|
||||
// Stop accepting new connections, keep the existing one alive
|
||||
server.close();
|
||||
log('Parent process has connected to my stdin. All should be good now.');
|
||||
process.__defineGetter__('stdin', function () {
|
||||
return stream;
|
||||
});
|
||||
// Remove myself from process.argv
|
||||
process.argv.splice(1, 1);
|
||||
// Load the actual program
|
||||
let program = process.argv[1];
|
||||
log('Loading program: ' + program);
|
||||
// Unset the custom environmental variables that should not get inherited
|
||||
delete process.env['STDIN_PIPE_NAME']; // tslint:disable-line
|
||||
delete process.env['STDOUT_PIPE_NAME']; // tslint:disable-line
|
||||
delete process.env['STDERR_PIPE_NAME']; // tslint:disable-line
|
||||
require(program);
|
||||
log('Finished loading program.');
|
||||
let stdinIsReferenced = true;
|
||||
let timer = setInterval(function () {
|
||||
let listenerCount = stream.listeners('data').length +
|
||||
stream.listeners('end').length +
|
||||
stream.listeners('close').length +
|
||||
stream.listeners('error').length;
|
||||
// log('listenerCount: ' + listenerCount)
|
||||
if (listenerCount <= 1) {
|
||||
// No more "actual" listeners, only internal node
|
||||
if (stdinIsReferenced) {
|
||||
stdinIsReferenced = false;
|
||||
// log('unreferencing stream!!!')
|
||||
stream.unref();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// There are "actual" listeners
|
||||
if (!stdinIsReferenced) {
|
||||
stdinIsReferenced = true;
|
||||
stream.ref();
|
||||
}
|
||||
}
|
||||
// log(
|
||||
// '' + stream.listeners('data').length +
|
||||
// ' ' + stream.listeners('end').length +
|
||||
// ' ' + stream.listeners('close').length +
|
||||
// ' ' + stream.listeners('error').length
|
||||
// )
|
||||
}, 1000);
|
||||
if (timer.unref) { // tslint:disable-line
|
||||
timer.unref(); // tslint:disable-line
|
||||
}
|
||||
});
|
||||
server.listen(stdInPipeName, function () {
|
||||
// signal via stdout that the parent process can now begin writing to stdin pipe
|
||||
process.stdout.write('ready');
|
||||
});
|
||||
})();
|
|
@ -135,7 +135,7 @@ export function fork(
|
|||
// Create the process
|
||||
logger.info('Forking TSServer', `PATH: ${newEnv['PATH']} `)
|
||||
|
||||
const bootstrapperPath = path.join(workspace.pluginRoot, 'bin/tsserverForkStart')
|
||||
const bootstrapperPath = path.resolve(__dirname, '../../../bin/tsserverForkStart')
|
||||
childProcess = cp.fork(bootstrapperPath, [modulePath].concat(args), {
|
||||
silent: true,
|
||||
env: newEnv,
|
||||
|
|
Loading…
Reference in a new issue