public GetChunkRequestResponseAsync ( UploadChunkRequest request, byte readBuffer, ICollection |
||
request | UploadChunkRequest | |
readBuffer | byte | |
exceptionTrackingList | ICollection |
|
return | Task |
public virtual async Task<UploadChunkResult> GetChunkRequestResponseAsync(UploadChunkRequest request, byte[] readBuffer, ICollection<Exception> exceptionTrackingList)
{
var firstAttempt = true;
this.uploadStream.Seek(request.RangeBegin, SeekOrigin.Begin);
await this.uploadStream.ReadAsync(readBuffer, 0, request.RangeLength).ConfigureAwait(false);
while (true)
{
using (var requestBodyStream = new MemoryStream(request.RangeLength))
{
await requestBodyStream.WriteAsync(readBuffer, 0, request.RangeLength).ConfigureAwait(false);
requestBodyStream.Seek(0, SeekOrigin.Begin);
try
{
return await request.PutAsync(requestBodyStream).ConfigureAwait(false);
}
catch (ServiceException exception)
{
if (exception.IsMatch("generalException") || exception.IsMatch("timeout"))
{
if (firstAttempt)
{
firstAttempt = false;
exceptionTrackingList.Add(exception);
}
else
{
throw;
}
}
else if (exception.IsMatch("invalidRange"))
{
// Succeeded previously, but nothing to return right now
return new UploadChunkResult();
}
else
{
throw;
}
}
}
}
}
private UploadChunkResult SetupGetChunkResponseTest(ServiceException serviceException = null, bool failsOnce = true, bool verifyTrackedExceptions = true) { var chunkSize = 320 * 1024; var bytesToUpload = new byte[] { 4, 8, 15, 16 }; var trackedExceptions = new List<Exception>(); this.uploadSession.Object.NextExpectedRanges = new[] { "0-" }; var stream = new MemoryStream(bytesToUpload.Length); stream.Write(bytesToUpload, 0, bytesToUpload.Length); stream.Seek(0, SeekOrigin.Begin); var provider = new ChunkedUploadProvider( this.uploadSession.Object, this.client.Object, stream, chunkSize); var mockRequest = new Mock<UploadChunkRequest>( this.uploadSession.Object.UploadUrl, this.client.Object, null, 0, bytesToUpload.Length - 1, bytesToUpload.Length); if (serviceException != null && failsOnce) { mockRequest.SetupSequence(r => r.PutAsync( It.IsAny<Stream>(), It.IsAny<CancellationToken>())) .Throws(serviceException) .Returns(Task.FromResult(new UploadChunkResult() { ItemResponse = new Item()})); } else if (serviceException != null) { mockRequest.Setup(r => r.PutAsync( It.IsAny<Stream>(), It.IsAny<CancellationToken>())) .Throws(serviceException); } else { mockRequest.Setup(r => r.PutAsync( It.IsAny<Stream>(), It.IsAny<CancellationToken>())) .Returns(Task.FromResult(new UploadChunkResult { ItemResponse = new Item()})); } var task = provider.GetChunkRequestResponseAsync(mockRequest.Object, bytesToUpload, trackedExceptions); try { task.Wait(); } catch (AggregateException exception) { throw exception.InnerException; } if (verifyTrackedExceptions) { Assert.IsTrue(trackedExceptions.Contains(serviceException), "Expected ServiceException in TrackedException list"); } return task.Result; }