зеркало из 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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expectingLength != null)
|
if (expectingLength != null && expectingLength.Value >= 0)
|
||||||
{
|
{
|
||||||
stream.Value.Stream.SetLength(expectingLength.Value);
|
stream.Value.Stream.SetLength(expectingLength.Value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
// Copyright (c) Microsoft Corporation.
|
// Copyright (c) Microsoft Corporation.
|
||||||
// Licensed under the MIT License.
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
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.Extensions;
|
||||||
using BuildXL.Cache.ContentStore.Interfaces.FileSystem;
|
|
||||||
|
|
||||||
namespace BuildXL.Cache.ContentStore.Extensions
|
namespace BuildXL.Cache.ContentStore.Extensions
|
||||||
{
|
{
|
||||||
|
@ -35,35 +31,5 @@ namespace BuildXL.Cache.ContentStore.Extensions
|
||||||
return content.ToArray();
|
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;
|
||||||
using System.Diagnostics.ContractsLight;
|
using System.Diagnostics.ContractsLight;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using BuildXL.Cache.ContentStore.Extensions;
|
using BuildXL.Cache.ContentStore.Extensions;
|
||||||
using BuildXL.Cache.ContentStore.Interfaces.FileSystem;
|
using BuildXL.Cache.ContentStore.Interfaces.FileSystem;
|
||||||
using BuildXL.Cache.ContentStore.Interfaces.Tracing;
|
using BuildXL.Cache.ContentStore.Interfaces.Tracing;
|
||||||
using BuildXL.Cache.ContentStore.Tracing;
|
using BuildXL.Cache.ContentStore.Tracing;
|
||||||
|
using BuildXL.Cache.ContentStore.Tracing.Internal;
|
||||||
using BuildXL.Utilities.Core;
|
using BuildXL.Utilities.Core;
|
||||||
|
|
||||||
namespace BuildXL.Cache.ContentStore.FileSystem
|
namespace BuildXL.Cache.ContentStore.FileSystem
|
||||||
|
@ -41,20 +43,34 @@ namespace BuildXL.Cache.ContentStore.FileSystem
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new instance from content in the given input stream.
|
/// Create a new instance from content in the given input stream.
|
||||||
/// </summary>
|
/// </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();
|
var path = _directory.CreateRandomFileName();
|
||||||
|
|
||||||
try
|
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(
|
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)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
|
|
|
@ -324,7 +324,7 @@ namespace BuildXL.Cache.ContentStore.Sessions
|
||||||
Stream? disposableStream = null;
|
Stream? disposableStream = null;
|
||||||
if (!stream.CanSeek)
|
if (!stream.CanSeek)
|
||||||
{
|
{
|
||||||
putStream = TempFileStreamFactory.Create(operationContext, stream);
|
putStream = await TempFileStreamFactory.CreateAsync(operationContext, stream);
|
||||||
disposableStream = putStream;
|
disposableStream = putStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче