Beispiel #1
0
        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);
        }
Beispiel #2
0
 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();
 }
Beispiel #3
0
        public async Task ShutdownRequestWriteRead()
        {
            var memoryStream = new MemoryStream();
            var request      = BuildRequest.CreateShutdown();
            await request.WriteAsync(memoryStream, CancellationToken.None);

            memoryStream.Position = 0;
            var read = await BuildRequest.ReadAsync(memoryStream, CancellationToken.None);

            VerifyShutdownRequest(read);
        }
Beispiel #4
0
        public async Task <ConnectionData> HandleConnection(bool allowCompilationRequests = true, CancellationToken cancellationToken = default(CancellationToken))
        {
            try
            {
                BuildRequest request;
                try
                {
                    Log("Begin reading request.");
                    request = await BuildRequest.ReadAsync(_stream, cancellationToken).ConfigureAwait(false);

                    ValidateBuildRequest(request);
                    Log("End reading request.");
                }
                catch (Exception e)
                {
                    LogException(e, "Error reading build request.");
                    return(new ConnectionData(CompletionReason.CompilationNotStarted));
                }

                if (request.ProtocolVersion != BuildProtocolConstants.ProtocolVersion)
                {
                    return(await HandleMismatchedVersionRequest(cancellationToken).ConfigureAwait(false));
                }
                else if (!string.Equals(request.CompilerHash, BuildProtocolConstants.GetCommitHash(), StringComparison.OrdinalIgnoreCase))
                {
                    return(await HandleIncorrectHashRequest(cancellationToken).ConfigureAwait(false));
                }
                else if (IsShutdownRequest(request))
                {
                    return(await HandleShutdownRequest(cancellationToken).ConfigureAwait(false));
                }
                else if (!allowCompilationRequests)
                {
                    return(await HandleRejectedRequest(cancellationToken).ConfigureAwait(false));
                }
                else
                {
                    return(await HandleCompilationRequest(request, cancellationToken).ConfigureAwait(false));
                }
            }
            finally
            {
                Close();
            }
        }
Beispiel #5
0
            internal async Task <ConnectionResult> AcceptConnection(Task <Connection> task, bool accept, CancellationToken cancellationToken)
            {
                Connection connection;

                try
                {
                    connection = await task;
                }
                catch (Exception ex)
                {
                    // Unable to establish a connection with the client.  The client is responsible for
                    // handling this case.  Nothing else for us to do here.
                    CompilerServerLogger.LogException(ex, "Error creating client named pipe");
                    return(new ConnectionResult(ConnectionResult.Reason.CompilationNotStarted));
                }

                try
                {
                    using (connection)
                    {
                        BuildRequest request;
                        try
                        {
                            CompilerServerLogger.Log("Begin reading request.");
                            request = await BuildRequest.ReadAsync(connection.Stream, cancellationToken).ConfigureAwait(false);

                            CompilerServerLogger.Log("End reading request.");
                        }
                        catch (Exception e)
                        {
                            CompilerServerLogger.LogException(e, "Error reading build request.");
                            return(new ConnectionResult(ConnectionResult.Reason.CompilationNotStarted));
                        }

                        if (request.IsShutdownRequest())
                        {
                            // Reply with the PID of this process so that the client can wait for it to exit.
                            var response = new ShutdownBuildResponse(Process.GetCurrentProcess().Id);
                            await response.WriteAsync(connection.Stream, cancellationToken);

                            // We can safely disconnect the client, then when this connection gets cleaned up by the event loop
                            // the server will go to a shutdown state.
                            return(new ConnectionResult(ConnectionResult.Reason.ClientShutdownRequest));
                        }
                        else if (!accept)
                        {
                            // We're already in shutdown mode, respond gracefully so the client can run in-process.
                            var response = new RejectedBuildResponse();
                            await response.WriteAsync(connection.Stream, cancellationToken).ConfigureAwait(false);

                            return(new ConnectionResult(ConnectionResult.Reason.CompilationNotStarted));
                        }
                        else
                        {
                            // If we get here then this is a real request that we will accept and process.
                            //
                            // Kick off both the compilation and a task to monitor the pipe for closing.
                            var buildCancelled = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

                            var watcher = connection.WaitForDisconnectAsync(buildCancelled.Token);
                            var worker  = ExecuteRequestAsync(request, buildCancelled.Token);

                            // await will end when either the work is complete or the connection is closed.
                            await Task.WhenAny(worker, watcher);

                            // Do an 'await' on the completed task, preference being compilation, to force
                            // any exceptions to be realized in this method for logging.
                            ConnectionResult.Reason reason;
                            if (worker.IsCompleted)
                            {
                                var response = await worker;

                                try
                                {
                                    CompilerServerLogger.Log("Begin writing response.");
                                    await response.WriteAsync(connection.Stream, cancellationToken);

                                    CompilerServerLogger.Log("End writing response.");

                                    reason = ConnectionResult.Reason.CompilationCompleted;
                                }
                                catch
                                {
                                    reason = ConnectionResult.Reason.ClientDisconnect;
                                }
                            }
                            else
                            {
                                await watcher;
                                reason = ConnectionResult.Reason.ClientDisconnect;
                            }

                            // Begin the tear down of the Task which didn't complete.
                            buildCancelled.Cancel();

                            return(new ConnectionResult(reason, request.KeepAlive));
                        }
                    }
                }
                catch (Exception ex)
                {
                    CompilerServerLogger.LogException(ex, "Error handling connection");
                    return(new ConnectionResult(ConnectionResult.Reason.ClientException));
                }
            }