зеркало из https://github.com/microsoft/BuildXL.git
Merged PR 785202: Make TempFileStreamFactory async
Make TempFileStreamFactory async
This commit is contained in:
Родитель
8e7874240d
Коммит
78684e203e
|
@ -206,7 +206,7 @@ namespace BuildXL.Cache.ContentStore.Interfaces.FileSystem
|
|||
return null;
|
||||
}
|
||||
|
||||
if (expectingLength != null)
|
||||
if (expectingLength != null && expectingLength.Value >= 0)
|
||||
{
|
||||
stream.Value.Stream.SetLength(expectingLength.Value);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using BuildXL.Cache.ContentStore.Exceptions;
|
||||
using BuildXL.Cache.ContentStore.Hashing;
|
||||
using BuildXL.Cache.ContentStore.Interfaces.Extensions;
|
||||
using BuildXL.Cache.ContentStore.Interfaces.FileSystem;
|
||||
|
||||
namespace BuildXL.Cache.ContentStore.Extensions
|
||||
{
|
||||
|
@ -35,35 +31,5 @@ namespace BuildXL.Cache.ContentStore.Extensions
|
|||
return content.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy all or some bytes from one stream to another.
|
||||
/// </summary>
|
||||
public static void CopyTo(this Stream sourceStream, Stream destinationStream, int bufferSize, long size)
|
||||
{
|
||||
if (size < 0)
|
||||
{
|
||||
sourceStream.CopyTo(destinationStream, bufferSize);
|
||||
return;
|
||||
}
|
||||
|
||||
var buffer = new byte[bufferSize];
|
||||
var bytesLeft = size;
|
||||
|
||||
while (bytesLeft > 0)
|
||||
{
|
||||
var bytesToRead = (int)Math.Min(bytesLeft, bufferSize);
|
||||
var bytesRead = sourceStream.Read(buffer, 0, bytesToRead);
|
||||
|
||||
if (bytesRead == 0)
|
||||
{
|
||||
throw new CacheException($"Read {bytesRead} bytes from ClientStream, but expected to read {bytesToRead} bytes");
|
||||
}
|
||||
|
||||
destinationStream.Write(buffer, 0, bytesRead);
|
||||
|
||||
bytesLeft -= bytesRead;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
using System;
|
||||
using System.Diagnostics.ContractsLight;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using BuildXL.Cache.ContentStore.Extensions;
|
||||
using BuildXL.Cache.ContentStore.Interfaces.FileSystem;
|
||||
using BuildXL.Cache.ContentStore.Interfaces.Tracing;
|
||||
using BuildXL.Cache.ContentStore.Tracing;
|
||||
using BuildXL.Cache.ContentStore.Tracing.Internal;
|
||||
using BuildXL.Utilities.Core;
|
||||
|
||||
namespace BuildXL.Cache.ContentStore.FileSystem
|
||||
|
@ -41,20 +43,34 @@ namespace BuildXL.Cache.ContentStore.FileSystem
|
|||
/// <summary>
|
||||
/// Create a new instance from content in the given input stream.
|
||||
/// </summary>
|
||||
public FileStream Create(Context context, Stream stream, long size = -1)
|
||||
public async Task<FileStream> CreateAsync(OperationContext context, Stream stream, long? size = null)
|
||||
{
|
||||
const int bufSize = FileSystemConstants.FileIOBufferSize;
|
||||
Contract.RequiresNotNull(stream);
|
||||
var path = _directory.CreateRandomFileName();
|
||||
|
||||
try
|
||||
{
|
||||
using (var fileStream = new FileStream(path.Path, FileMode.Create, FileAccess.Write, FileShare.None, bufSize))
|
||||
using (var fileStream = _fileSystem.TryOpenForWrite(
|
||||
path,
|
||||
size,
|
||||
FileMode.Create,
|
||||
FileShare.None,
|
||||
FileOptions.SequentialScan | FileOptions.Asynchronous,
|
||||
AbsFileSystemExtension.DefaultFileStreamBufferSize))
|
||||
{
|
||||
stream.CopyTo(fileStream, bufSize, size);
|
||||
Contract.AssertNotNull(fileStream);
|
||||
await stream.CopyToAsync(fileStream.Value.Stream, AbsFileSystemExtension.DefaultFileStreamBufferSize, context.Token);
|
||||
}
|
||||
|
||||
// Please note, this temporary file will be deleted once it's closed (i.e., even if the program
|
||||
// crashes!)
|
||||
return new FileStream(
|
||||
path.Path, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete, bufSize, FileOptions.DeleteOnClose);
|
||||
path.Path,
|
||||
FileMode.Open,
|
||||
FileAccess.Read,
|
||||
FileShare.Read | FileShare.Delete,
|
||||
AbsFileSystemExtension.DefaultFileStreamBufferSize,
|
||||
FileOptions.DeleteOnClose);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
|
|
|
@ -324,7 +324,7 @@ namespace BuildXL.Cache.ContentStore.Sessions
|
|||
Stream? disposableStream = null;
|
||||
if (!stream.CanSeek)
|
||||
{
|
||||
putStream = TempFileStreamFactory.Create(operationContext, stream);
|
||||
putStream = await TempFileStreamFactory.CreateAsync(operationContext, stream);
|
||||
disposableStream = putStream;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче