| File: Commands\BuildServer\Shutdown\BuildServerShutdownCommand.cs | Web Access |
| Project: src\sdk\src\Cli\dotnet\dotnet.csproj (dotnet) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.CommandLine; using Microsoft.DotNet.Cli.BuildServer; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Cli.Utils.Extensions; namespace Microsoft.DotNet.Cli.Commands.BuildServer.Shutdown; internal sealed class BuildServerShutdownCommand : CommandBase<BuildServerShutdownCommandDefinition> { private readonly ServerEnumerationFlags _enumerationFlags; private readonly IBuildServerProvider _serverProvider; private readonly bool _useOrderedWait; private readonly IReporter _reporter; public BuildServerShutdownCommand( ParseResult result, IBuildServerProvider? serverProvider = null, bool useOrderedWait = false, IReporter? reporter = null) : base(result) { bool msbuild = result.GetValue(Definition.MSBuildOption); bool vbcscompiler = result.GetValue(Definition.VbcsOption); bool razor = result.GetValue(Definition.RazorOption); bool all = !msbuild && !vbcscompiler && !razor; _enumerationFlags = ServerEnumerationFlags.None; if (msbuild || all) { _enumerationFlags |= ServerEnumerationFlags.MSBuild; } if (vbcscompiler || all) { _enumerationFlags |= ServerEnumerationFlags.VBCSCompiler; } if (razor || all) { _enumerationFlags |= ServerEnumerationFlags.Razor; } _serverProvider = serverProvider ?? new BuildServerProvider(); _useOrderedWait = useOrderedWait; _reporter = reporter ?? Reporter.Output; } public override int Execute() { var tasks = StartShutdown(); if (tasks.Count == 0) { _reporter.WriteLine(CliCommandStrings.NoServersToShutdown.Green()); return 0; } bool success = true; while (tasks.Count > 0) { var index = WaitForResult([.. tasks.Select(t => t.Item2)]); var (server, task) = tasks[index]; if (task.IsFaulted) { success = false; WriteFailureMessage(server, task.Exception); } else { WriteSuccessMessage(server); } tasks.RemoveAt(index); } return success ? 0 : 1; } private List<(IBuildServer, Task)> StartShutdown() { var tasks = new List<(IBuildServer, Task)>(); foreach (var server in _serverProvider.EnumerateBuildServers(_enumerationFlags)) { WriteShutdownMessage(server); tasks.Add((server, Task.Run(() => server.Shutdown()))); } return tasks; } private int WaitForResult(Task[] tasks) { if (_useOrderedWait) { return Task.WaitAny(tasks.First()); } return Task.WaitAny(tasks); } private void WriteShutdownMessage(IBuildServer server) { if (server.ProcessId != 0) { _reporter.WriteLine( string.Format( CliCommandStrings.ShuttingDownServerWithPid, server.Name, server.ProcessId)); } else { _reporter.WriteLine( string.Format( CliCommandStrings.ShuttingDownServer, server.Name)); } } private void WriteFailureMessage(IBuildServer server, AggregateException exception) { if (server.ProcessId != 0) { _reporter.WriteLine( string.Format( CliCommandStrings.ShutDownFailedWithPid, server.Name, server.ProcessId, exception.InnerException?.Message).Red()); } else { _reporter.WriteLine( string.Format( CliCommandStrings.ShutDownFailed, server.Name, exception.InnerException?.Message).Red()); } if (CommandLoggingContext.IsVerbose) { Reporter.Verbose.WriteLine(exception.ToString().Red()); } } private void WriteSuccessMessage(IBuildServer server) { if (server.ProcessId != 0) { _reporter.WriteLine( string.Format( CliCommandStrings.ShutDownSucceededWithPid, server.Name, server.ProcessId).Green()); } else { _reporter.WriteLine( string.Format( CliCommandStrings.ShutDownSucceeded, server.Name).Green()); } } }