Tom
Tom

Reputation: 53

CloudBlob.CopyState is null after direct account-to-account copy completes

Edit: Extended code sample to show how the destinationBlob is loaded.

We're making use of direct account to account copying to transfer a set of blobs. Because properties are overwritten when the process starts we monitor the destination blobs on an interval then set properties when the copy is complete. For the most part this process works fine.

However, for just a couple of these blobs, there is no copy state on the destination blob (CloudBlob.CopyState is null). These blobs do not exist before hand, they're created as a result of calling CloudBlob.StartCopyAsync().

Here is some simplified code to outline how it works.

// Start copy operation
var operationId = await destinationBlob.StartCopyAsync(new Uri(sourceBlobUrlWithSas));

...

// In a separate process, check the status after a delay, then repeat on an interval
var destinationBlob = await _destinationContainer.GetBlobReferenceFromServerAsync(blobName);

if (destinationBlob.CopyState.Status == CopyStatus.Success) // <-- CopyState is null
{
    // Set properties
}

Microsoft docs indicate CopyState will be null when there is no copy state, but don't outline when that is. From my own experimentation, the destination blob seems to be created immediately, and the copy state seems remain on the blob for some time after an copy operation completes. When the issue occurs it's only a few minutes between starting the copy and checking the CopyState.

What could be the issue? Are there alternate methods of setting properties on the destination blob?

Upvotes: 2

Views: 365

Answers (3)

Tom
Tom

Reputation: 53

This issue ended up being due to a logic error whereby blobs would be 'touched' resulting in the copy state being removed. The documentation around the lifecycle of copy state data could certainly be better, though hopefully this insight helps others who encounter a similar issue.

Upvotes: 2

Ivan Glasenberg
Ivan Glasenberg

Reputation: 29950

I can think of 2 workarounds.

1.check the destination blob, whatever it's copystatus is successful or null, the code like below(here we're using the null-conditional operator, so no worries when the CopyState is null):

if (destinationBlob.CopyState?.Status == CopyStatus.Success || destinationBlob.CopyState?.Status == null)
{
   //codes to set properties
}

2.Another way is that you can create a blob trigger azure function, which targets the destination container. It means that when there is any blob uploaded/copied to destination container, the function will be triggered. So you can write your logic in the function.

Note: you can use CloudBlockBlob instead of Stream for the blob type in the code, so you can take use of CloudBlockBlob to add properites easily.

public static void Run([BlobTrigger("samples-workitems/{name}")] CloudBlockBlob myBlob, string name, ILogger log)
{
   //other code
}

Upvotes: 1

Jim Xu
Jim Xu

Reputation: 23111

If you want to get CopyState, we need to run the method CloudBlob.FetchAttributesAsync at first. The method will return the blob's properties and metadata from server then we can get CopyState. For more details, please refer to here.

For example (I test with package Microsoft.Azure.Storage.Blob)

            var storageAccount = CloudStorageAccount.Parse(connectionString);
            var cloudBlobClient = storageAccount.CreateCloudBlobClient();
            var cloudBlobContainer = cloudBlobClient.GetContainerReference("test");
            CloudBlob destBlob = cloudBlobContainer.GetBlobReference(soureblob.Name);
            string copyId = await destBlob.StartCopyAsync(uri);
            await destBlob.FetchAttributesAsync();

            Console.WriteLine("Status of copy operation: {0}", destBlob.CopyState.Status);
            Console.WriteLine("Completion time: {0}", destBlob.CopyState.CompletionTime);
            Console.WriteLine("Bytes copied: {0}", destBlob.CopyState.BytesCopied.ToString());
            Console.WriteLine("Total bytes: {0}", destBlob.CopyState.TotalBytes.ToString());

enter image description here

Upvotes: 1

Related Questions