Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.NodejsTools.Logging;
using Microsoft.VisualStudioTools;
using Microsoft.VisualStudioTools.Project;
using Newtonsoft.Json;

Expand Down Expand Up @@ -112,10 +113,49 @@ public Version NodeVersion {
/// <param name="uri">URI identifying the endpoint to connect to.</param>
public void Connect(Uri uri) {
Utilities.ArgumentNotNull("uri", uri);
LiveLogger.WriteLine("Debugger connecting to URI: {0}", uri);

Close();
lock (_networkClientLock) {
_networkClient = _networkClientFactory.CreateNetworkClient(uri);
int connection_attempts = 0;
const int MAX_ATTEMPTS = 5;
while (true) {
connection_attempts++;
try {
// TODO: This currently results in a call to the synchronous TcpClient
// constructor, which is a blocking call, and can take a couple of seconds
// to connect (with timeouts and retries). This code is running on the UI
// thread. Ideally this should be connecting async, or moved off the UI thread.
_networkClient = _networkClientFactory.CreateNetworkClient(uri);

// Unclear if the above can succeed and not be connected, but check for safety.
// The code needs to either break out the while loop, or hit the retry logic
// in the exception handler.
if (_networkClient.Connected) {
LiveLogger.WriteLine("Debugger connected successfully");
break;
}
else {
throw new SocketException();
}
}
catch (Exception ex) {
if (ex.IsCriticalException()) {
throw;
}
LiveLogger.WriteLine("Connection attempt {0} failed with: {1}", connection_attempts, ex);
if (connection_attempts >= MAX_ATTEMPTS) {
throw;
}
else {
// See above TODO. This should be moved off the UI thread or posted to retry
// without blocking in the meantime. For now, this seems the lesser of two
// evils. (The other being the debugger failing to attach on launch if the
// debuggee socket wasn't open quickly enough).
System.Threading.Thread.Sleep(200);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine taking this for RC2, but let's file an issue on this since we really shouldn't be blocking.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but as noted above, just the existing TCP connection call blocks for 2 to 3 seconds already trying to connect. Getting this whole logic off the UI thread, or moving to async, seems desirable, but that's a much more invasive change at this point. (My point being the whole refactor should be the opened issue, not just this 200ms delay)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gotcha, makes sense

}
}
}
}

Task.Factory.StartNew(ReceiveAndDispatchMessagesWorker);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,22 @@ private static NodeRemoteDebugProcess Connect(NodeRemoteDebugPort port, INetwork
} catch (OperationCanceledException) {
LiveLogger.WriteLine("NodeRemoteEnumDebugProcesses ping timed out.");
} catch (DebuggerAlreadyAttachedException ex) {
LiveLogger.WriteLine("DebuggerAlreadyAttachedException connecting to remote debugger");
exception = ex;
} catch (AggregateException ex) {
LiveLogger.WriteLine("AggregateException connecting to remote debugger");
exception = ex;
} catch (IOException ex) {
LiveLogger.WriteLine("IOException connecting to remote debugger");
exception = ex;
} catch (SocketException ex) {
LiveLogger.WriteLine("SocketException connecting to remote debugger");
exception = ex;
} catch (WebSocketException ex) {
LiveLogger.WriteLine("WebSocketException connecting to remote debugger");
exception = ex;
} catch (PlatformNotSupportedException) {
LiveLogger.WriteLine("PlatformNotSupportedException connecting to remote debugger");
MessageBox.Show(
"Remote debugging of node.js Microsoft Azure applications is only supported on Windows 8 and above.",
null, MessageBoxButtons.OK, MessageBoxIcon.Error);
Expand Down