Skip to content

Commit

Permalink
Merged PR 739783: [Blob cache] Use DownloadStreamingAsync instead of …
Browse files Browse the repository at this point in the history
…DownloadContentAsync for TouchAsync

Replace DownloadContentAsync  with DownloadStreamingAsync in the implementation of TouchAsync. Considering this blog post Azure/azure-sdk-for-net#22022 and browsing the implementation of both operations, DownloadStreamingAsync is slightly more lightweight. Disclaimer: network operations are handled in the same way, DownloadStreamingAsync just avoids some stream copying which DownloadContentAsync performs - and content is something we don't actually interact with when doing a touch operation.
  • Loading branch information
smera committed Sep 20, 2023
1 parent 5c10fb0 commit f4e297f
Showing 1 changed file with 16 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ public class BlobStorageClientAdapter

private const string ETagAll = "*";

// Some commonly used options just to avoid unnecesary allocations for every request
private static readonly BlobRequestConditions RequestConditionsWithEtagAll = new() { IfMatch = ETag.All, };
private static readonly BlobRequestConditions RequestConditionsWithNoneMatchEtagAll = new() { IfNoneMatch = ETag.All, };
private static readonly BlobDownloadOptions BlobDownloadOptionsWithETagAll = new() { Conditions = RequestConditionsWithEtagAll };
private static readonly BlobDownloadOptions BlobDownloadOptionsWithETagAllAndRange01 = new() { Conditions = RequestConditionsWithEtagAll, Range = new HttpRange(0, 1) };

public BlobStorageClientAdapter(
Tracer tracer,
BlobFolderStorageConfiguration configuration)
Expand Down Expand Up @@ -326,7 +332,7 @@ public Task<Result<bool>> CompareUpdateContentAsync(
if (etag is null)
{
// Perform the operation only if the the blob doesn't exist
accessCondition = new BlobRequestConditions() { IfNoneMatch = ETag.All };
accessCondition = RequestConditionsWithNoneMatchEtagAll;
}
else if (etag == ETagAll)
{
Expand Down Expand Up @@ -407,26 +413,23 @@ async Task<Result<bool>> uploadAsync()
// This updates the last access time in blob storage when last access time tracking is enabled. Please note,
// we're not downloading anything here because we're doing a 0-length download.
// See: https://learn.microsoft.com/en-us/azure/storage/blobs/lifecycle-management-overview?tabs=azure-portal#move-data-based-on-last-accessed-time
// For the choice about using DownloadStreamingAsync, please check https://github.com/Azure/azure-sdk-for-net/issues/22022
try
{
var response = await blob.DownloadContentAsync(
new BlobDownloadOptions()
{
Range = new HttpRange(0, 1),
Conditions = new BlobRequestConditions() { IfMatch = ETag.All, }
},
using BlobDownloadStreamingResult response = await blob.DownloadStreamingAsync(
BlobDownloadOptionsWithETagAllAndRange01,
cancellationToken: context.Token);
return Result.Success<(DateTimeOffset?, long?)>((response.Value.Details.LastAccessed, response.Value.Details.ContentLength), isNullAllowed: true);
return Result.Success<(DateTimeOffset?, long?)>((response.Details.LastAccessed, response.Details.ContentLength), isNullAllowed: true);
}
catch (RequestFailedException ex) when (ex.ErrorCode == BlobErrorCode.InvalidRange)
{
// We are dealing with a zero-size piece of content. Use unbounded download API to touch the file.
var response = await blob.DownloadContentAsync(
conditions: new BlobRequestConditions() { IfMatch = ETag.All, },
using BlobDownloadStreamingResult response = await blob.DownloadStreamingAsync(
BlobDownloadOptionsWithETagAll,
cancellationToken: context.Token);
return Result.Success<(DateTimeOffset?, long?)>((response.Value.Details.LastAccessed, response.Value.Details.ContentLength), isNullAllowed: true);
return Result.Success<(DateTimeOffset?, long?)>((response.Details.LastAccessed, response.Details.ContentLength), isNullAllowed: true);
}
},
traceOperationStarted: false,
Expand All @@ -445,7 +448,7 @@ public Task<Result<bool>> UpdateMetadataAsync(OperationContext context, BlobClie
{
var response = await blob.SetMetadataAsync(
metadata,
conditions: new BlobRequestConditions() { IfMatch = ETag.All, },
conditions: RequestConditionsWithEtagAll,
cancellationToken: context.Token);
return Result.Success<bool>(true);
Expand Down

0 comments on commit f4e297f

Please sign in to comment.