public void ReadWriteRequest() { Task.Run(async () => { var request = new BuildRequest( BuildProtocolConstants.ProtocolVersion, BuildProtocolConstants.RequestLanguage.VisualBasicCompile, ImmutableArray.Create( new BuildRequest.Argument(BuildProtocolConstants.ArgumentId.CurrentDirectory, argumentIndex: 0, value: "directory"), new BuildRequest.Argument(BuildProtocolConstants.ArgumentId.CommandLineArgument, argumentIndex: 1, value: "file"))); var memoryStream = new MemoryStream(); await request.WriteAsync(memoryStream, default(CancellationToken)).ConfigureAwait(false); Assert.True(memoryStream.Position > 0); memoryStream.Position = 0; var read = await BuildRequest.ReadAsync(memoryStream, default(CancellationToken)).ConfigureAwait(false); Assert.Equal(BuildProtocolConstants.ProtocolVersion, read.ProtocolVersion); Assert.Equal(BuildProtocolConstants.RequestLanguage.VisualBasicCompile, read.Language); Assert.Equal(2, read.Arguments.Length); Assert.Equal(BuildProtocolConstants.ArgumentId.CurrentDirectory, read.Arguments[0].ArgumentId); Assert.Equal(0, read.Arguments[0].ArgumentIndex); Assert.Equal("directory", read.Arguments[0].Value); Assert.Equal(BuildProtocolConstants.ArgumentId.CommandLineArgument, read.Arguments[1].ArgumentId); Assert.Equal(1, read.Arguments[1].ArgumentIndex); Assert.Equal("file", read.Arguments[1].Value); }).Wait(); }
public async Task ClientDisconnectDuringBuild() { using var buildStartedMre = new ManualResetEvent(initialState: false); using var clientClosedMre = new ManualResetEvent(initialState: false); var host = new TestableCompilerServerHost(runCompilation: (request, cancellationToken) => { buildStartedMre.Set(); clientClosedMre.WaitOne(); return(new CompletedBuildResponse(0, utf8output: false, "")); }); using var serverData = await ServerUtil.CreateServer(compilerServerHost : host).ConfigureAwait(false); // Create a short lived client that send a request but does not wait for the using (var client = await BuildServerConnection.TryConnectToServerAsync(serverData.PipeName, Timeout.Infinite, cancellationToken: default).ConfigureAwait(false)) { await s_emptyCSharpBuildRequest.WriteAsync(client).ConfigureAwait(false); await buildStartedMre.WaitOneAsync().ConfigureAwait(false); } clientClosedMre.Set(); var reason = await serverData.ConnectionCompletionCollection.TakeAsync().ConfigureAwait(false); Assert.Equal(CompletionReason.ClientDisconnect, reason); }
public async Task ReadWriteRequest() { var request = new BuildRequest( BuildProtocolConstants.ProtocolVersion, RequestLanguage.VisualBasicCompile, "HashValue", ImmutableArray.Create( new BuildRequest.Argument(BuildProtocolConstants.ArgumentId.CurrentDirectory, argumentIndex: 0, value: "directory"), new BuildRequest.Argument(BuildProtocolConstants.ArgumentId.CommandLineArgument, argumentIndex: 1, value: "file"))); var memoryStream = new MemoryStream(); await request.WriteAsync(memoryStream, default(CancellationToken)); Assert.True(memoryStream.Position > 0); memoryStream.Position = 0; var read = await BuildRequest.ReadAsync(memoryStream, default(CancellationToken)); Assert.Equal(BuildProtocolConstants.ProtocolVersion, read.ProtocolVersion); Assert.Equal(RequestLanguage.VisualBasicCompile, read.Language); Assert.Equal("HashValue", read.CompilerHash); Assert.Equal(2, read.Arguments.Count); Assert.Equal(BuildProtocolConstants.ArgumentId.CurrentDirectory, read.Arguments[0].ArgumentId); Assert.Equal(0, read.Arguments[0].ArgumentIndex); Assert.Equal("directory", read.Arguments[0].Value); Assert.Equal(BuildProtocolConstants.ArgumentId.CommandLineArgument, read.Arguments[1].ArgumentId); Assert.Equal(1, read.Arguments[1].ArgumentIndex); Assert.Equal("file", read.Arguments[1].Value); }
public void ReadWriteRequest() { Task.Run(async() => { var request = new BuildRequest( BuildProtocolConstants.ProtocolVersion, BuildProtocolConstants.RequestLanguage.VisualBasicCompile, ImmutableArray.Create( new BuildRequest.Argument(BuildProtocolConstants.ArgumentId.CurrentDirectory, argumentIndex: 0, value: "directory"), new BuildRequest.Argument(BuildProtocolConstants.ArgumentId.CommandLineArgument, argumentIndex: 1, value: "file"))); var memoryStream = new MemoryStream(); await request.WriteAsync(memoryStream, default(CancellationToken)).ConfigureAwait(false); Assert.True(memoryStream.Position > 0); memoryStream.Position = 0; var read = await BuildRequest.ReadAsync(memoryStream, default(CancellationToken)).ConfigureAwait(false); Assert.Equal(BuildProtocolConstants.ProtocolVersion, read.ProtocolVersion); Assert.Equal(BuildProtocolConstants.RequestLanguage.VisualBasicCompile, read.Language); Assert.Equal(2, read.Arguments.Length); Assert.Equal(BuildProtocolConstants.ArgumentId.CurrentDirectory, read.Arguments[0].ArgumentId); Assert.Equal(0u, read.Arguments[0].ArgumentIndex); Assert.Equal("directory", read.Arguments[0].Value); Assert.Equal(BuildProtocolConstants.ArgumentId.CommandLineArgument, read.Arguments[1].ArgumentId); Assert.Equal(1u, read.Arguments[1].ArgumentIndex); Assert.Equal("file", read.Arguments[1].Value); }).Wait(); }
internal async Task <BuildResponse> SendAsync(BuildRequest request, CancellationToken cancellationToken = default) { using var client = await BuildServerConnection.TryConnectToServerAsync(PipeName, Timeout.Infinite, cancellationToken).ConfigureAwait(false); await request.WriteAsync(client).ConfigureAwait(false); return(await BuildResponse.ReadAsync(client).ConfigureAwait(false)); }
internal static async Task <BuildResponse> Send(string pipeName, BuildRequest request) { using (var client = await BuildServerConnection.TryConnectToServerAsync(pipeName, Timeout.Infinite, cancellationToken: default).ConfigureAwait(false)) { await request.WriteAsync(client).ConfigureAwait(false); return(await BuildResponse.ReadAsync(client).ConfigureAwait(false)); } }
/// <summary> /// Try to compile using the server. Returns null if a response from the /// server cannot be retrieved. /// </summary> private static async Task <BuildResponse> TryCompile(NamedPipeClientStream pipeStream, BuildRequest request, CancellationToken cancellationToken) { BuildResponse response; using (pipeStream) { // Write the request try { Log("Begin writing request"); await request.WriteAsync(pipeStream, cancellationToken).ConfigureAwait(false); Log("End writing request"); } catch (Exception e) { LogException(e, "Error writing build request."); return(null); } // Wait for the compilation and a monitor to dectect if the server disconnects var serverCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); Log("Begin reading response"); var responseTask = BuildResponse.ReadAsync(pipeStream, serverCts.Token); var monitorTask = CreateMonitorDisconnectTask(pipeStream, serverCts.Token); await Task.WhenAny(responseTask, monitorTask).ConfigureAwait(false); Log("End reading response"); if (responseTask.IsCompleted) { // await the task to log any exceptions try { response = await responseTask.ConfigureAwait(false); } catch (Exception e) { LogException(e, "Error reading response"); response = null; } } else { Log("Server disconnect"); response = null; } // Cancel whatever task is still around serverCts.Cancel(); return(response); } }
internal static async Task <BuildResponse> Send(string pipeName, BuildRequest request) { using (var client = new NamedPipeClientStream(pipeName)) { await client.ConnectAsync(); await request.WriteAsync(client); return(await BuildResponse.ReadAsync(client)); } }
public async Task WriteError() { var realStream = new MemoryStream(); await s_emptyCSharpBuildRequest.WriteAsync(realStream, CancellationToken.None).ConfigureAwait(true); realStream.Position = 0; var stream = new Mock <Stream>(MockBehavior.Strict); stream .Setup(x => x.ReadAsync(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>(), It.IsAny <CancellationToken>())) .Returns((byte[] array, int start, int length, CancellationToken ct) => Task.FromResult(realStream.Read(array, start, length))); var connection = CreateConnection(stream.Object); connection.ServeBuildRequestFunc = delegate { return(Task.FromResult(s_emptyBuildResponse)); }; var connectionData = await connection.HandleConnection().ConfigureAwait(true); Assert.Equal(CompletionReason.ClientDisconnect, connectionData.CompletionReason); Assert.Null(connectionData.KeepAlive); }
public async Task WriteError() { using var compileMre = new ManualResetEvent(initialState: false); using var closedStreamMre = new ManualResetEvent(initialState: false); var host = new TestableCompilerServerHost(runCompilation: delegate { compileMre.Set(); closedStreamMre.WaitOne(); return(s_emptyBuildResponse); }); var(clientStream, serverStream) = await CreateNamedPipePair().ConfigureAwait(false); try { var connection = new NamedPipeClientConnection(host, "identifier", serverStream); await s_emptyCSharpBuildRequest.WriteAsync(clientStream).ConfigureAwait(false); var connectionTask = connection.HandleConnection(); await compileMre.WaitOneAsync().ConfigureAwait(false); clientStream.Close(); closedStreamMre.Set(); var connectionData = await connectionTask.ConfigureAwait(false); Assert.Equal(CompletionReason.ClientDisconnect, connectionData.CompletionReason); Assert.Null(connectionData.KeepAlive); } finally { clientStream.Close(); serverStream.Close(); } }
private async Task <BuildResponse> DoCompilationAsync(NamedPipeClientStream pipeStream, BuildRequest req, CancellationToken cancellationToken) { using (pipeStream) { try { // Start a monitor that cancels if the pipe closes on us var monitorCancellation = new CancellationTokenSource(); Task disconnectMonitor = MonitorPipeForDisconnectionAsync(pipeStream, monitorCancellation.Token); // Write the request. CompilerServerLogger.Log("Writing request"); await req.WriteAsync(pipeStream, cancellationToken).ConfigureAwait(false); // Read the response. CompilerServerLogger.Log("Reading response"); BuildResponse response = await BuildResponse.ReadAsync(pipeStream, cancellationToken).ConfigureAwait(false); // Stop monitoring pipe monitorCancellation.Cancel(throwOnFirstException: true); await disconnectMonitor.ConfigureAwait(false); Debug.Assert(response != null); CompilerServerLogger.Log("BuildResponse received; exit code={0}", response.ReturnCode); return(response); } catch (PipeBrokenException e) { CompilerServerLogger.LogException(e, "Server process died; pipe broken."); return(null); } catch (ObjectDisposedException e) { CompilerServerLogger.LogException(e, "Pipe stream unexpectedly disposed"); return(null); } } }