Merged PR 785202: Make TempFileStreamFactory async

Make TempFileStreamFactory async
This commit is contained in:
Julian Bayardo 2024-05-15 21:55:38 +00:00
Родитель 8e7874240d
Коммит 78684e203e
4 изменённых файлов: 23 добавлений и 41 удалений

Просмотреть файл

@ -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;
}