diff --git a/src/debugAdapter.ts b/src/debugAdapter.ts index 4b4c48ebbb..8a9184d0c0 100644 --- a/src/debugAdapter.ts +++ b/src/debugAdapter.ts @@ -26,49 +26,107 @@ var debugAdapterLogWriter = // debug server process.stdin.pause(); -// Read the details of the current session to learn -// the connection details for the debug service -let sessionDetails = utils.readSessionFile(); - -// Establish connection before setting up the session -debugAdapterLogWriter.write("Connecting to port: " + sessionDetails.debugServicePort + "\r\n"); -let debugServiceSocket = net.connect(sessionDetails.debugServicePort, '127.0.0.1'); - -// Write any errors to the log file -debugServiceSocket.on( - 'error', - (e) => debugAdapterLogWriter.write("Socket connect ERROR: " + e + "\r\n")); - -// Route any output from the socket through stdout -debugServiceSocket.on( - 'data', - (data: Buffer) => process.stdout.write(data)); - -// Wait for the connection to complete -debugServiceSocket.on( - 'connect', - () => { - debugAdapterLogWriter.write("Connected to socket!\r\n\r\n"); - - // When data comes on stdin, route it through the socket - process.stdin.on( - 'data', - (data: Buffer) => debugServiceSocket.write(data)); - - // Resume the stdin stream - process.stdin.resume(); - }); - -// When the socket closes, end the session -debugServiceSocket.on( - 'close', - () => { - debugAdapterLogWriter.write("Socket closed, shutting down."); - - // Close after a short delay to give the client time - // to finish up - setTimeout(() => { +function startDebugging() { + // Read the details of the current session to learn + // the connection details for the debug service + let sessionDetails = utils.readSessionFile(); + + // Establish connection before setting up the session + debugAdapterLogWriter.write("Connecting to port: " + sessionDetails.debugServicePort + "\r\n"); + + let isConnected = false; + let debugServiceSocket = net.connect(sessionDetails.debugServicePort, '127.0.0.1'); + + // Write any errors to the log file + debugServiceSocket.on( + 'error', + (e) => { + debugAdapterLogWriter.write("Socket ERROR: " + e + "\r\n") + debugAdapterLogWriter.close(); + debugServiceSocket.destroy(); process.exit(0); - }, 1000); + }); + + // Route any output from the socket through stdout + debugServiceSocket.on( + 'data', + (data: Buffer) => process.stdout.write(data)); + + // Wait for the connection to complete + debugServiceSocket.on( + 'connect', + () => { + isConnected = true; + debugAdapterLogWriter.write("Connected to socket!\r\n\r\n"); + + // When data comes on stdin, route it through the socket + process.stdin.on( + 'data', + (data: Buffer) => debugServiceSocket.write(data)); + + // Resume the stdin stream + process.stdin.resume(); + }); + + // When the socket closes, end the session + debugServiceSocket.on( + 'close', + () => { + debugAdapterLogWriter.write("Socket closed, shutting down."); + debugAdapterLogWriter.close(); + isConnected = false; + + // Close after a short delay to give the client time + // to finish up + setTimeout(() => { + process.exit(0); + }, 2000); + } + ) + + process.on( + 'exit', + (e) => { + if (debugAdapterLogWriter) { + debugAdapterLogWriter.write("Debug adapter process is exiting..."); + } + } + ) +} + +var sessionFilePath = utils.getSessionFilePath(); +function waitForSessionFile(triesRemaining: number) { + + debugAdapterLogWriter.write(`Waiting for session file, tries remaining: ${triesRemaining}...\r\n`); + + if (triesRemaining > 0) { + if (utils.checkIfFileExists(sessionFilePath)) { + debugAdapterLogWriter.write(`Session file present, connecting to debug adapter...\r\n\r\n`); + startDebugging(); + } + else { + // Wait for a second and try again + setTimeout( + () => waitForSessionFile(triesRemaining - 1), + 1000); + } + } + else { + debugAdapterLogWriter.write(`Timed out waiting for session file!\r\n`); + var errorJson = + JSON.stringify({ + type: "response", + request_seq: 1, + command: "initialize", + success: false, + message: "Timed out waiting for the PowerShell extension to start." + }); + + process.stdout.write( + `Content-Length: ${Buffer.byteLength(errorJson, 'utf8')}\r\n\r\n${errorJson}`, + 'utf8'); } -) \ No newline at end of file +} + +// Wait for the session file to appear +waitForSessionFile(30); diff --git a/src/main.ts b/src/main.ts index 4d3fe54299..234d8d26c6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5,6 +5,7 @@ 'use strict'; import vscode = require('vscode'); +import utils = require('./utils'); import { Logger, LogLevel } from './logging'; import { IFeature } from './feature'; import { SessionManager } from './session'; @@ -28,6 +29,9 @@ var logger: Logger = undefined; var sessionManager: SessionManager = undefined; var extensionFeatures: IFeature[] = []; +// Clean up the session file just in case one lingers from a previous session +utils.deleteSessionFile(); + export function activate(context: vscode.ExtensionContext): void { vscode.languages.setLanguageConfiguration( diff --git a/src/session.ts b/src/session.ts index 8961e8cf00..4552954e96 100644 --- a/src/session.ts +++ b/src/session.ts @@ -257,11 +257,8 @@ export class SessionManager { if (response["status"] === "started") { let sessionDetails: utils.EditorServicesSessionDetails = response; - // Write out the session configuration file - utils.writeSessionFile(sessionDetails); - // Start the language service client - this.startLanguageClient(sessionDetails.languageServicePort); + this.startLanguageClient(sessionDetails); } else if (response["status"] === "failed") { if (response["reason"] === "unsupported") { @@ -326,12 +323,14 @@ export class SessionManager { .then((answer) => { if (answer === "Yes") { this.restartSession(); }}); } - private startLanguageClient(port: number) { + private startLanguageClient(sessionDetails: utils.EditorServicesSessionDetails) { - this.log.write("Connecting to language service on port " + port + "..." + os.EOL); + var port = sessionDetails.languageServicePort; try { + this.log.write("Connecting to language service on port " + port + "..." + os.EOL); + let connectFunc = () => { return new Promise( (resolve, reject) => { @@ -339,6 +338,9 @@ export class SessionManager { socket.on( 'connect', () => { + // Write out the session configuration file + utils.writeSessionFile(sessionDetails); + this.log.write("Language service connected."); resolve({writer: socket, reader: socket}) });