Quick fixes: Make `dotnet-getdocument` more reliable (#8716)
- use `WaitAny(...)` in inside man - call `Process.WaitForExit()` twice - `Flush()` all output `FileStream`s before disposal - catch `UnauthorizedAccessException` when calling `File.Delete(...)` in case file's in use - add `/nr:false` to `dotnet msbuild` command line
This commit is contained in:
parent
195a22d92c
commit
8308d94e39
|
|
@ -109,8 +109,8 @@ namespace Microsoft.Extensions.ApiDescription.Tool.Commands
|
|||
return false;
|
||||
}
|
||||
|
||||
var finished = Task.WhenAny(resultTask, Task.Delay(TimeSpan.FromMinutes(1)));
|
||||
if (!ReferenceEquals(resultTask, finished))
|
||||
var finishedIndex = Task.WaitAny(resultTask, Task.Delay(TimeSpan.FromMinutes(1)));
|
||||
if (finishedIndex != 0)
|
||||
{
|
||||
Reporter.WriteWarning(Resources.FormatMethodTimedOut(methodName, serviceName, 1));
|
||||
return false;
|
||||
|
|
@ -121,6 +121,8 @@ namespace Microsoft.Extensions.ApiDescription.Tool.Commands
|
|||
using (var outStream = File.Create(context.OutputPath))
|
||||
{
|
||||
stream.CopyTo(outStream);
|
||||
|
||||
outStream.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -177,6 +177,8 @@ namespace Microsoft.Extensions.ApiDescription.Tasks
|
|||
using (var outStream = File.Create(destinationPath))
|
||||
{
|
||||
await responseStream.CopyToAsync(outStream);
|
||||
|
||||
await outStream.FlushAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,8 +186,22 @@ namespace Microsoft.Extensions.ApiDescription.Tool.Commands
|
|||
{
|
||||
if (cleanupExecutable && !string.IsNullOrEmpty(executable))
|
||||
{
|
||||
File.Delete(executable);
|
||||
File.Delete(executable + ".config");
|
||||
// Ignore errors about in-use files. Should still be marked for delete after process cleanup.
|
||||
try
|
||||
{
|
||||
File.Delete(executable);
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File.Delete(executable + ".config");
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
|
@ -31,20 +32,32 @@ namespace Microsoft.Extensions.ApiDescription.Tool
|
|||
startInfo.WorkingDirectory = workingDirectory;
|
||||
}
|
||||
|
||||
var process = Process.Start(startInfo);
|
||||
|
||||
if (interceptOutput)
|
||||
using (var process = Process.Start(startInfo))
|
||||
{
|
||||
string line;
|
||||
while ((line = process.StandardOutput.ReadLine()) != null)
|
||||
if (interceptOutput)
|
||||
{
|
||||
Reporter.WriteVerbose(line);
|
||||
string line;
|
||||
while ((line = process.StandardOutput.ReadLine()) != null)
|
||||
{
|
||||
Reporter.WriteVerbose(line);
|
||||
}
|
||||
}
|
||||
|
||||
// Follow precedent set in Razor integration tests and ensure process events and output are complete.
|
||||
// https://github.com/aspnet/Razor/blob/d719920fdcc7d1db3a6f74cd5404d66fa098f057/test/Microsoft.NET.Sdk.Razor.Test/IntegrationTests/MSBuildProcessManager.cs#L91-L102
|
||||
// Timeout is double how long the inside man waits for the IDocumentProcessor to wrap up.
|
||||
if (!process.WaitForExit((int)(TimeSpan.FromMinutes(2).TotalMilliseconds)))
|
||||
{
|
||||
process.Kill();
|
||||
|
||||
// Should be unreachable in almost every case.
|
||||
throw new TimeoutException($"Process {executable} timed out after 2 minutes.");
|
||||
}
|
||||
|
||||
process.WaitForExit();
|
||||
|
||||
return process.ExitCode;
|
||||
}
|
||||
|
||||
process.WaitForExit();
|
||||
|
||||
return process.ExitCode;
|
||||
}
|
||||
|
||||
private static string ToArguments(IReadOnlyList<string> args)
|
||||
|
|
|
|||
|
|
@ -89,6 +89,8 @@ namespace Microsoft.Extensions.ApiDescription.Tool
|
|||
// NB: Copy always in case it changes
|
||||
Reporter.WriteVerbose(Resources.FormatWritingFile(targetsPath));
|
||||
input.CopyTo(output);
|
||||
|
||||
output.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -102,6 +104,7 @@ namespace Microsoft.Extensions.ApiDescription.Tool
|
|||
"/target:WriteServiceProjectReferenceMetadata",
|
||||
"/verbosity:quiet",
|
||||
"/nologo",
|
||||
"/nodeReuse:false",
|
||||
$"/property:ServiceProjectReferenceMetadataPath={metadataPath}",
|
||||
projectFile,
|
||||
};
|
||||
|
|
@ -134,8 +137,22 @@ namespace Microsoft.Extensions.ApiDescription.Tool
|
|||
}
|
||||
finally
|
||||
{
|
||||
File.Delete(metadataPath);
|
||||
File.Delete(targetsPath);
|
||||
// Ignore errors about in-use files. Should still be marked for delete after process cleanup.
|
||||
try
|
||||
{
|
||||
File.Delete(metadataPath);
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File.Delete(targetsPath);
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
var project = new Project
|
||||
|
|
|
|||
Loading…
Reference in New Issue