private async Task <CompletionData> ProcessCompilationRequestAsync(IClientConnection clientConnection, BuildRequest request, CancellationToken cancellationToken)
        {
            // Need to wait for the compilation and client disconnection in parallel. If the client
            // suddenly disconnects we need to cancel the compilation that is occurring. It could be the
            // client hit Ctrl-C due to a run away analyzer.
            var buildCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
            var compilationTask = ProcessCompilationRequestCore(CompilerServerHost, request, buildCancellationTokenSource.Token);
            await Task.WhenAny(compilationTask, clientConnection.DisconnectTask).ConfigureAwait(false);

            try
            {
                if (compilationTask.IsCompleted)
                {
                    BuildResponse  response;
                    CompletionData completionData;
                    try
                    {
                        response = await compilationTask.ConfigureAwait(false);

                        completionData = response switch
                        {
                            // Once there is an analyzer inconsistency the assembly load space is polluted. The
                            // request is an error.
                            AnalyzerInconsistencyBuildResponse _ => CompletionData.RequestError,
                                                               _ => new CompletionData(CompletionReason.RequestCompleted, newKeepAlive: CheckForNewKeepAlive(request))
                        };
                    }
                    catch (Exception ex)
                    {
                        // The compilation task should never throw. If it does we need to assume that the compiler is
                        // in a bad state and need to issue a RequestError
                        Logger.LogException(ex, $"Exception running compilation for {request.RequestId}");
                        response       = new RejectedBuildResponse($"Exception during compilation: {ex.Message}");
                        completionData = CompletionData.RequestError;
                    }

                    return(await WriteBuildResponseAsync(
                               clientConnection,
                               request.RequestId,
                               response,
                               completionData,
                               cancellationToken).ConfigureAwait(false));
                }
                else
                {
                    return(CompletionData.RequestError);
                }
            }
            finally
            {
                buildCancellationTokenSource.Cancel();
            }
示例#2
0
        private async Task <CompletionData> ProcessCompilationRequestAsync(IClientConnection clientConnection, BuildRequest request, CancellationToken cancellationToken)
        {
            // Need to wait for the compilation and client disconnection in parallel. If the client
            // suddenly disconnects we need to cancel the compilation that is occuring. It could be the
            // client hit Ctrl-C due to a run away analyzer.
            var buildCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
            var compilationTask = ProcessCompilationRequestCore(CompilerServerHost, request, buildCancellationTokenSource.Token);
            await Task.WhenAny(compilationTask, clientConnection.DisconnectTask).ConfigureAwait(false);

            try
            {
                if (compilationTask.IsCompleted)
                {
                    BuildResponse response;
                    try
                    {
                        response = await compilationTask.ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        CompilerServerLogger.LogException(ex, $"Exception running compilation for {clientConnection.LoggingIdentifier}");
                        response = new RejectedBuildResponse($"Exception during compilation: {ex.Message}");
                    }

                    await clientConnection.WriteBuildResponseAsync(response, cancellationToken).ConfigureAwait(false);

                    var newKeepAlive     = CheckForNewKeepAlive(request);
                    var completionReason = response switch
                    {
                        AnalyzerInconsistencyBuildResponse _ => CompletionReason.RequestError,
                        RejectedBuildResponse _ => CompletionReason.RequestError,
                        _ => CompletionReason.RequestCompleted
                    };
                    return(new CompletionData(completionReason, newKeepAlive));
                }
                else
                {
                    return(CompletionData.RequestError);
                }
            }
            finally
            {
                buildCancellationTokenSource.Cancel();
            }