コード例 #1
0
        internal int RunServer(
            string pipeName,
            ICompilerServerHost?compilerServerHost     = null,
            IClientConnectionHost?clientConnectionHost = null,
            IDiagnosticListener?listener        = null,
            TimeSpan?keepAlive                  = null,
            CancellationToken cancellationToken = default)
        {
            keepAlive ??= GetKeepAliveTimeout();
            listener ??= new EmptyDiagnosticListener();
            compilerServerHost ??= CreateCompilerServerHost(_logger);
            clientConnectionHost ??= CreateClientConnectionHost(pipeName, _logger);

            // Grab the server mutex to prevent multiple servers from starting with the same
            // pipename and consuming excess resources. If someone else holds the mutex
            // exit immediately with a non-zero exit code
            var  mutexName = BuildServerConnection.GetServerMutexName(pipeName);
            bool createdNew;

            using (var serverMutex = BuildServerConnection.OpenOrCreateMutex(name: mutexName,
                                                                             createdNew: out createdNew))
            {
                if (!createdNew)
                {
                    return(CommonCompiler.Failed);
                }

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

                var dispatcher = new ServerDispatcher(compilerServerHost, clientConnectionHost, listener);
                dispatcher.ListenAndDispatchConnections(keepAlive, cancellationToken);
                return(CommonCompiler.Succeeded);
            }
        }
コード例 #2
0
        public void MutexStopsServerStarting()
        {
            var pipeName  = Guid.NewGuid().ToString("N");
            var mutexName = BuildServerConnection.GetServerMutexName(pipeName);

            bool holdsMutex;

            using (var mutex = BuildServerConnection.OpenOrCreateMutex(
                       name: mutexName,
                       createdNew: out holdsMutex))
            {
                Assert.True(holdsMutex);
                try
                {
                    var host   = new Mock <IClientConnectionHost>(MockBehavior.Strict);
                    var result = BuildServerController.CreateAndRunServer(
                        pipeName,
                        clientConnectionHost: host.Object,
                        keepAlive: null);
                    Assert.Equal(CommonCompiler.Failed, result);
                }
                finally
                {
                    mutex.Dispose();
                }
            }
        }
コード例 #3
0
            public void ConnectToServerFails()
            {
                // Create and grab the mutex for the server. This should make
                // the client believe that a server is active and it will try
                // to connect. When it fails it should fall back to in-proc
                // compilation.
                bool holdsMutex;

                using (var serverMutex = BuildServerConnection.OpenOrCreateMutex(
                           name: BuildServerConnection.GetServerMutexName(_pipeName),
                           createdNew: out holdsMutex))
                {
                    Assert.True(holdsMutex);
                    var ranLocal = false;
                    // Note: Connecting to a server can take up to a second to time out
                    var client = CreateClient(
                        compileFunc: delegate
                    {
                        ranLocal = true;
                        return(0);
                    });
                    var exitCode = client.RunCompilation(new[] { "/shared" }, _buildPaths, pipeName: _pipeName).ExitCode;
                    Assert.Equal(0, exitCode);
                    Assert.True(ranLocal);
                }
            }
コード例 #4
0
            public async Task ServerShutdownsDuringProcessing()
            {
                using (var readyMre = new ManualResetEvent(initialState: false))
                    using (var doneMre = new ManualResetEvent(initialState: false))
                    {
                        var  pipeName  = Guid.NewGuid().ToString();
                        var  mutexName = BuildServerConnection.GetServerMutexName(pipeName);
                        bool created   = false;
                        bool connected = false;

                        var thread = new Thread(() =>
                        {
                            using (var stream = NamedPipeUtil.CreateServer(pipeName))
                            {
                                var mutex = BuildServerConnection.OpenOrCreateMutex(name: mutexName, createdNew: out created);
                                readyMre.Set();

                                stream.WaitForConnection();
                                connected = true;

                                // Client is waiting for a response.  Close the mutex now.  Then close the connection
                                // so the client gets an error.
                                mutex.Dispose();
                                stream.Close();

                                doneMre.WaitOne();
                            }
                        });

                        // Block until the mutex and named pipe is setup.
                        thread.Start();
                        readyMre.WaitOne();

                        var exitCode = await RunShutdownAsync(pipeName, waitForProcess : false);

                        // Let the fake server exit.
                        doneMre.Set();
                        thread.Join();

                        Assert.Equal(CommonCompiler.Succeeded, exitCode);
                        Assert.True(connected);
                        Assert.True(created);
                    }
            }
コード例 #5
0
        protected override int RunServerCore(string pipeName, IClientConnectionHost connectionHost, IDiagnosticListener listener, TimeSpan?keepAlive, CancellationToken cancellationToken)
        {
            // Grab the server mutex to prevent multiple servers from starting with the same
            // pipename and consuming excess resources. If someone else holds the mutex
            // exit immediately with a non-zero exit code
            var  mutexName = BuildServerConnection.GetServerMutexName(pipeName);
            bool createdNew;

            using (var serverMutex = BuildServerConnection.OpenOrCreateMutex(name: mutexName,
                                                                             createdNew: out createdNew))
            {
                if (!createdNew)
                {
                    return(CommonCompiler.Failed);
                }

                return(base.RunServerCore(pipeName, connectionHost, listener, keepAlive, cancellationToken));
            }
        }
コード例 #6
0
            public async Task NoServerConnection()
            {
                using (var readyMre = new ManualResetEvent(initialState: false))
                    using (var doneMre = new ManualResetEvent(initialState: false))
                    {
                        var  pipeName  = Guid.NewGuid().ToString();
                        var  mutexName = BuildServerConnection.GetServerMutexName(pipeName);
                        bool created   = false;
                        bool connected = false;

                        var thread = new Thread(() =>
                        {
                            using (var mutex = BuildServerConnection.OpenOrCreateMutex(name: mutexName, createdNew: out created))
                                using (var stream = NamedPipeUtil.CreateServer(pipeName))
                                {
                                    readyMre.Set();

                                    // Get a client connection and then immediately close it.  Don't give any response.
                                    stream.WaitForConnection();
                                    connected = true;
                                    stream.Close();

                                    doneMre.WaitOne();
                                    mutex.Dispose();
                                }
                        });

                        // Block until the mutex and named pipe is setup.
                        thread.Start();
                        readyMre.WaitOne();

                        var exitCode = await RunShutdownAsync(pipeName, waitForProcess : false);

                        // Let the fake server exit.
                        doneMre.Set();
                        thread.Join();

                        Assert.Equal(CommonCompiler.Failed, exitCode);
                        Assert.True(connected);
                        Assert.True(created);
                    }
            }