Example #1
0
        /// <summary>
        /// Main entry point for the process. Initialize the server dispatcher
        /// and wait for connections.
        /// </summary>
        public static int Main(string[] args)
        {
            CompilerServerLogger.Initialize("SRV");
            CompilerServerLogger.Log("Process started");

            TimeSpan?keepAliveTimeout = null;

            // VBCSCompiler is installed in the same directory as csc.exe and vbc.exe which is also the
            // location of the response files.
            var compilerExeDirectory = AppDomain.CurrentDomain.BaseDirectory;

            // Pipename should be passed as the first and only argument to the server process
            // and it must have the form "-pipename:name". Otherwise, exit with a non-zero
            // exit code
            const string pipeArgPrefix = "-pipename:";

            if (args.Length != 1 ||
                args[0].Length <= pipeArgPrefix.Length ||
                !args[0].StartsWith(pipeArgPrefix))
            {
                return(CommonCompiler.Failed);
            }

            var pipeName = args[0].Substring(pipeArgPrefix.Length);

            try
            {
                int    keepAliveValue;
                string keepAliveStr = ConfigurationManager.AppSettings["keepalive"];
                if (int.TryParse(keepAliveStr, NumberStyles.Integer, CultureInfo.InvariantCulture, out keepAliveValue) &&
                    keepAliveValue >= 0)
                {
                    if (keepAliveValue == 0)
                    {
                        // This is a one time server entry.
                        keepAliveTimeout = null;
                    }
                    else
                    {
                        keepAliveTimeout = TimeSpan.FromSeconds(keepAliveValue);
                    }
                }
                else
                {
                    keepAliveTimeout = s_defaultServerKeepAlive;
                }
            }
            catch (ConfigurationErrorsException e)
            {
                keepAliveTimeout = s_defaultServerKeepAlive;
                CompilerServerLogger.LogException(e, "Could not read AppSettings");
            }

            CompilerServerLogger.Log("Keep alive timeout is: {0} milliseconds.", keepAliveTimeout?.TotalMilliseconds ?? 0);
            FatalError.Handler = FailFast.OnFatalException;

            var dispatcher = new ServerDispatcher(new CompilerRequestHandler(compilerExeDirectory), new EmptyDiagnosticListener());

            dispatcher.ListenAndDispatchConnections(
                pipeName,
                keepAliveTimeout,
                watchAnalyzerFiles: true);
            return(CommonCompiler.Succeeded);
        }
Example #2
0
 private void LogException(Exception e, string description)
 {
     CompilerServerLogger.LogException(e, string.Format(LogFormat, LoggingIdentifier, description));
 }
Example #3
0
        internal async Task <CompletionData> ProcessAsync(
            Task <IClientConnection> clientConnectionTask,
            bool allowCompilationRequests       = true,
            CancellationToken cancellationToken = default)
        {
            try
            {
                return(await ProcessCore().ConfigureAwait(false));
            }
            catch (Exception ex)
            {
                CompilerServerLogger.LogException(ex, $"Error processing request for client");
                return(CompletionData.RequestError);
            }

            async Task <CompletionData> ProcessCore()
            {
                using var clientConnection = await clientConnectionTask.ConfigureAwait(false);

                var request = await clientConnection.ReadBuildRequestAsync(cancellationToken).ConfigureAwait(false);

                if (request.ProtocolVersion != BuildProtocolConstants.ProtocolVersion)
                {
                    return(await WriteBuildResponseAsync(
                               clientConnection,
                               new MismatchedVersionBuildResponse(),
                               CompletionData.RequestError,
                               cancellationToken).ConfigureAwait(false));
                }

                if (!string.Equals(request.CompilerHash, BuildProtocolConstants.GetCommitHash(), StringComparison.OrdinalIgnoreCase))
                {
                    return(await WriteBuildResponseAsync(
                               clientConnection,
                               new IncorrectHashBuildResponse(),
                               CompletionData.RequestError,
                               cancellationToken).ConfigureAwait(false));
                }

                if (request.Arguments.Count == 1 && request.Arguments[0].ArgumentId == BuildProtocolConstants.ArgumentId.Shutdown)
                {
                    return(await WriteBuildResponseAsync(
                               clientConnection,
                               new ShutdownBuildResponse(Process.GetCurrentProcess().Id),
                               new CompletionData(CompletionReason.RequestCompleted, shutdownRequested : true),
                               cancellationToken).ConfigureAwait(false));
                }

                if (!allowCompilationRequests)
                {
                    return(await WriteBuildResponseAsync(
                               clientConnection,
                               new RejectedBuildResponse("Compilation not allowed at this time"),
                               CompletionData.RequestCompleted,
                               cancellationToken).ConfigureAwait(false));
                }

                if (!Environment.Is64BitProcess && !MemoryHelper.IsMemoryAvailable())
                {
                    return(await WriteBuildResponseAsync(
                               clientConnection,
                               new RejectedBuildResponse("Not enough resources to accept connection"),
                               CompletionData.RequestError,
                               cancellationToken).ConfigureAwait(false));
                }

                return(await ProcessCompilationRequestAsync(clientConnection, request, cancellationToken).ConfigureAwait(false));
            }
        }
Example #4
0
 private static void LogException(FileNotFoundException e)
 {
     CompilerServerLogger.LogException(e, "File not found");
 }
 private void LogException(Exception e, string message)
 {
     CompilerServerLogger.LogException(e, string.Format("Client {0}: {1}", _loggingIdentifier, message));
 }