refactor(server): use TSS_DEBUG & TSS_DEBUG_BRK for debug port
This commit is contained in:
parent
f0820d2357
commit
65e1f75be5
6 changed files with 82 additions and 56 deletions
|
@ -116,7 +116,6 @@ for guide of coc.nvim's configuration.
|
|||
- `tsserver.log`:Log level of tsserver, default: `"off"`
|
||||
- `tsserver.trace.server`:Trace level of tsserver, default: `"off"`
|
||||
- `tsserver.pluginPaths`:Folders contains tsserver plugins, default: `[]`
|
||||
- `tsserver.debugPort`:Debug port number of tsserver
|
||||
- `tsserver.watchOptions`:Configure which watching strategies should be used to
|
||||
keep track of files and directories. Requires using TypeScript 3.8+ in the
|
||||
workspace, default: `undefined`
|
||||
|
|
|
@ -238,10 +238,6 @@
|
|||
},
|
||||
"description": "Folders contains tsserver plugins"
|
||||
},
|
||||
"tsserver.debugPort": {
|
||||
"type": "number",
|
||||
"description": "Debug port number of tsserver"
|
||||
},
|
||||
"tsserver.reportStyleChecksAsWarnings": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
|
|
|
@ -25,22 +25,22 @@ import Tracer from './utils/tracer'
|
|||
import { inferredProjectConfig } from './utils/tsconfig'
|
||||
import { TypeScriptVersion, TypeScriptVersionProvider } from './utils/versionProvider'
|
||||
import VersionStatus from './utils/versionStatus'
|
||||
import { ICallback, Reader } from './utils/wireProtocol'
|
||||
import { Reader } from './utils/wireProtocol'
|
||||
|
||||
interface ToCancelOnResourceChanged {
|
||||
readonly resource: string
|
||||
cancel(): void
|
||||
}
|
||||
|
||||
class ForkedTsServerProcess {
|
||||
constructor(private childProcess: cp.ChildProcess) {}
|
||||
class ForkedTsServerProcess implements Disposable {
|
||||
private readonly _reader: Reader<Proto.Response>
|
||||
|
||||
constructor(private childProcess: cp.ChildProcess) {
|
||||
this._reader = new Reader<Proto.Response>(this.childProcess.stdout)
|
||||
}
|
||||
|
||||
public readonly toCancelOnResourceChange = new Set<ToCancelOnResourceChanged>()
|
||||
|
||||
public onError(cb: (err: Error) => void): void {
|
||||
this.childProcess.on('error', cb)
|
||||
}
|
||||
|
||||
public onExit(cb: (err: any) => void): void {
|
||||
this.childProcess.on('exit', cb)
|
||||
}
|
||||
|
@ -52,16 +52,22 @@ class ForkedTsServerProcess {
|
|||
)
|
||||
}
|
||||
|
||||
public createReader(
|
||||
callback: ICallback<Proto.Response>,
|
||||
onError: (error: any) => void
|
||||
): void {
|
||||
// tslint:disable-next-line:no-unused-expression
|
||||
new Reader<Proto.Response>(this.childProcess.stdout, callback, onError)
|
||||
public onData(handler: (data: Proto.Response) => void): void {
|
||||
this._reader.onData(handler)
|
||||
}
|
||||
|
||||
public onError(handler: (err: Error) => void): void {
|
||||
this.childProcess.on('error', handler)
|
||||
this._reader.onError(handler)
|
||||
}
|
||||
|
||||
public kill(): void {
|
||||
this.childProcess.kill()
|
||||
this._reader.dispose()
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._reader.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -296,19 +302,26 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
|
|||
this.versionStatus.onDidChangeTypeScriptVersion(currentVersion)
|
||||
this.lastError = null
|
||||
const tsServerForkArgs = await this.getTsServerArgs(currentVersion)
|
||||
const debugPort = this._configuration.debugPort
|
||||
const maxTsServerMemory = this._configuration.maxTsServerMemory
|
||||
const options = {
|
||||
execArgv: [
|
||||
...(debugPort ? [`--inspect=${debugPort}`] : []), // [`--debug-brk=5859`]
|
||||
...(maxTsServerMemory ? [`--max-old-space-size=${maxTsServerMemory}`] : []),
|
||||
],
|
||||
cwd: workspace.root
|
||||
}
|
||||
const options = { execArgv: this.getExecArgv() }
|
||||
this.servicePromise = this.startProcess(currentVersion, tsServerForkArgs, options, resendModels)
|
||||
return this.servicePromise
|
||||
}
|
||||
|
||||
private getExecArgv(): string[] {
|
||||
const args: string[] = []
|
||||
const debugPort = getDebugPort()
|
||||
if (debugPort) {
|
||||
const isBreak = process.env[process.env.remoteName ? 'TSS_REMOTE_DEBUG_BRK' : 'TSS_DEBUG_BRK'] !== undefined
|
||||
const inspectFlag = isBreak ? '--inspect-brk' : '--inspect'
|
||||
args.push(`${inspectFlag}=${debugPort}`)
|
||||
}
|
||||
const maxTsServerMemory = this._configuration.maxTsServerMemory
|
||||
if (maxTsServerMemory) {
|
||||
args.push(`--max-old-space-size=${maxTsServerMemory}`)
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
private startProcess(currentVersion: TypeScriptVersion, args: string[], options: IForkOptions, resendModels: boolean): Promise<ForkedTsServerProcess> {
|
||||
this.state = ServiceStat.Starting
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -347,16 +360,11 @@ export default class TypeScriptServiceClient implements ITypeScriptServiceClient
|
|||
this.info(`TSServer log file: ${this.tsServerLogFile || ''}`)
|
||||
this.serviceExited(!this.isRestarting)
|
||||
this.isRestarting = false
|
||||
handle.dispose()
|
||||
})
|
||||
|
||||
handle.createReader(
|
||||
msg => {
|
||||
handle.onData(msg => {
|
||||
this.dispatchMessage(msg)
|
||||
},
|
||||
error => {
|
||||
this.error('ReaderError', error)
|
||||
}
|
||||
)
|
||||
})
|
||||
resolve(handle)
|
||||
this.serviceStarted(resendModels)
|
||||
this._onTsServerStarted.fire(currentVersion.version)
|
||||
|
@ -1013,3 +1021,15 @@ function getQueueingType(
|
|||
}
|
||||
return lowPriority ? RequestQueueingType.LowPriority : RequestQueueingType.Normal
|
||||
}
|
||||
|
||||
function getDebugPort(): number | undefined {
|
||||
let debugBrk = process.env[process.env.remoteName ? 'TSS_REMOTE_DEBUG_BRK' : 'TSS_DEBUG_BRK']
|
||||
let value = debugBrk || process.env[process.env.remoteName ? 'TSS_REMOTE_DEBUG_BRK' : 'TSS_DEBUG_BRK']
|
||||
if (value) {
|
||||
const port = parseInt(value)
|
||||
if (!isNaN(port)) {
|
||||
return port
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
|
|
@ -108,10 +108,6 @@ export class TypeScriptServiceConfiguration {
|
|||
return this._configuration.get<number>('maxTsServerMemory', 0)
|
||||
}
|
||||
|
||||
public get debugPort(): number | null {
|
||||
return this._configuration.get<number>('debugPort', parseInt(process.env['TSS_DEBUG'], 10))
|
||||
}
|
||||
|
||||
public get npmLocation(): string | null {
|
||||
let path = this._configuration.get<string>('npm', '')
|
||||
if (path) return workspace.expand(path)
|
||||
|
|
|
@ -98,16 +98,12 @@ export function fork(
|
|||
): void {
|
||||
let callbackCalled = false
|
||||
const resolve = (result: cp.ChildProcess) => {
|
||||
if (callbackCalled) {
|
||||
return
|
||||
}
|
||||
if (callbackCalled) return
|
||||
callbackCalled = true
|
||||
callback(null, result)
|
||||
}
|
||||
const reject = (err: any) => {
|
||||
if (callbackCalled) {
|
||||
return
|
||||
}
|
||||
if (callbackCalled) return
|
||||
callbackCalled = true
|
||||
callback(err, null)
|
||||
}
|
||||
|
@ -123,7 +119,7 @@ export function fork(
|
|||
stdOutPipeName,
|
||||
stdErrPipeName
|
||||
)
|
||||
newEnv['NODE_PATH'] = path.join(modulePath, '..', '..', '..') // tslint:disable-line
|
||||
newEnv['NODE_PATH'] = path.join(modulePath, '..', '..', '..')
|
||||
|
||||
let childProcess: cp.ChildProcess
|
||||
// Begin listening to stderr pipe
|
||||
|
@ -165,6 +161,7 @@ export function fork(
|
|||
const bootstrapperPath = path.resolve(__dirname, '../bin/tsserverForkStart')
|
||||
childProcess = cp.fork(bootstrapperPath, [modulePath].concat(args), {
|
||||
silent: true,
|
||||
cwd: undefined,
|
||||
env: newEnv,
|
||||
execArgv: options.execArgv
|
||||
})
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { disposeAll } from 'coc.nvim'
|
||||
import stream from 'stream'
|
||||
import { Disposable, Emitter } from 'vscode-languageserver-protocol'
|
||||
|
||||
const DefaultSize = 8192
|
||||
const ContentLength = 'Content-Length: '
|
||||
|
@ -99,18 +101,30 @@ export interface ICallback<T> {
|
|||
(data: T): void // tslint:disable-line
|
||||
}
|
||||
|
||||
export class Reader<T> {
|
||||
export class Reader<T> implements Disposable {
|
||||
private readonly buffer: ProtocolBuffer = new ProtocolBuffer()
|
||||
private nextMessageLength = -1
|
||||
private disposables: Disposable[] = []
|
||||
|
||||
public constructor(
|
||||
private readonly readable: stream.Readable,
|
||||
private readonly callback: ICallback<T>,
|
||||
private readonly onError: (error: any) => void
|
||||
) {
|
||||
this.readable.on('data', (data: Buffer) => {
|
||||
private readonly _onError = new Emitter<Error>()
|
||||
public readonly onError = this._onError.event
|
||||
|
||||
private readonly _onData = new Emitter<T>()
|
||||
public readonly onData = this._onData.event
|
||||
|
||||
public constructor(readable: stream.Readable) {
|
||||
const onData = (data: Buffer) => {
|
||||
this.onLengthData(data)
|
||||
}
|
||||
readable.on('data', onData)
|
||||
|
||||
this.disposables.push({
|
||||
dispose: () => {
|
||||
readable.off('data', onData)
|
||||
}
|
||||
})
|
||||
this.disposables.push(this._onError)
|
||||
this.disposables.push(this._onData)
|
||||
}
|
||||
|
||||
private onLengthData(data: Buffer): void {
|
||||
|
@ -129,10 +143,14 @@ export class Reader<T> {
|
|||
}
|
||||
this.nextMessageLength = -1
|
||||
const json = JSON.parse(msg)
|
||||
this.callback(json)
|
||||
this._onData.fire(json)
|
||||
}
|
||||
} catch (e) {
|
||||
this.onError(e)
|
||||
this._onError.fire(e)
|
||||
}
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
disposeAll(this.disposables)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue