public async Task ServerRequest_WriteRead_RoundtripsProperly() { // Arrange var request = new ServerRequest( ServerProtocol.ProtocolVersion, ImmutableArray.Create( new RequestArgument(RequestArgument.ArgumentId.CurrentDirectory, argumentIndex: 0, value: "directory"), new RequestArgument(RequestArgument.ArgumentId.CommandLineArgument, argumentIndex: 1, value: "file"))); var memoryStream = new MemoryStream(); // Act await request.WriteAsync(memoryStream, CancellationToken.None); // Assert Assert.True(memoryStream.Position > 0); memoryStream.Position = 0; var read = await ServerRequest.ReadAsync(memoryStream, CancellationToken.None); Assert.Equal(ServerProtocol.ProtocolVersion, read.ProtocolVersion); Assert.Equal(2, read.Arguments.Count); Assert.Equal(RequestArgument.ArgumentId.CurrentDirectory, read.Arguments[0].Id); Assert.Equal(0, read.Arguments[0].ArgumentIndex); Assert.Equal("directory", read.Arguments[0].Value); Assert.Equal(RequestArgument.ArgumentId.CommandLineArgument, read.Arguments[1].Id); Assert.Equal(1, read.Arguments[1].ArgumentIndex); Assert.Equal("file", read.Arguments[1].Value); }
/// <summary> /// Try to process the request using the server. Returns a null-containing Task if a response /// from the server cannot be retrieved. /// </summary> private static async Task <ServerResponse> TryProcessRequest( Client client, ServerRequest request, CancellationToken cancellationToken) { ServerResponse response; using (client) { // Write the request try { ServerLogger.Log("Begin writing request"); await request.WriteAsync(client.Stream, cancellationToken).ConfigureAwait(false); ServerLogger.Log("End writing request"); } catch (Exception e) { ServerLogger.LogException(e, "Error writing build request."); return(new RejectedServerResponse()); } // Wait for the compilation and a monitor to detect if the server disconnects var serverCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); ServerLogger.Log("Begin reading response"); var responseTask = ServerResponse.ReadAsync(client.Stream, serverCts.Token); var monitorTask = client.WaitForDisconnectAsync(serverCts.Token); await Task.WhenAny(new[] { responseTask, monitorTask }).ConfigureAwait(false); ServerLogger.Log("End reading response"); if (responseTask.IsCompleted) { // await the task to log any exceptions try { response = await responseTask.ConfigureAwait(false); } catch (Exception e) { ServerLogger.LogException(e, "Error reading response"); response = new RejectedServerResponse(); } } else { ServerLogger.Log("Server disconnect"); response = new RejectedServerResponse(); } // Cancel whatever task is still around serverCts.Cancel(); Debug.Assert(response != null); return(response); } }
internal static async Task <ServerResponse> Send(string pipeName, ServerRequest request) { using (var client = await Client.ConnectAsync(pipeName, timeout: null, cancellationToken: default).ConfigureAwait(false)) { await request.WriteAsync(client.Stream).ConfigureAwait(false); return(await ServerResponse.ReadAsync(client.Stream).ConfigureAwait(false)); } }