locked
Pseudo-transactional CloudBlobs RRS feed

  • Question

  • I'm using SQL Azure for Blob Meta Data Storage and Azure Blob Storage for the actual blobs. Blob Creation/Deletion is implemented by enlisting those operation in the ambient TransactionScope. Everything works fine so far but I'm wondering if anyone can recommend optimizations to the Delete-Operation (see source code below) that might get-rid of the requirement to download the blob contents in order to rollback.

    public class CloudBlobDeletionEnlistment : CloudBlobBaseEnlistment,
     IEnlistmentNotification,
     IDisposable
    {
     public CloudBlobDeletionEnlistment(Guid ownerId, string blobId, CloudBlobContainer container, Logger logger, IUserUploadActivity currentUploadActivity)
     {
      ctx = new Context { OwnerId = ownerId, BlobId = blobId, Container = container, Logger = logger, CurrentUploadActivity = currentUploadActivity };
     }
    
     public class Context
     {
      public Guid OwnerId;
      public string BlobId;
      public string ContentFileName;
      public string MimeType;
      public bool IsCompressed;
      public CloudBlobContainer Container;
      public Logger Logger;
      public IUserUploadActivity CurrentUploadActivity;
     }
    
     private readonly Context ctx;
     private CloudBlob blob;
    
     public void Prepare(PreparingEnlistment preparingEnlistment)
     {
      blob = ctx.Container.GetBlobReference(ctx.BlobId);
    
      // save backup information
      ctx.ContentFileName = Path.GetTempFileName();
      blob.DownloadToFile(ctx.ContentFileName);
      blob.FetchAttributes();
      ctx.MimeType = blob.Metadata[Constants.BlobMetaAttributeContentType];
      ctx.IsCompressed = bool.Parse(blob.Metadata[Constants.BlobMetaAttributeCompressed]);
    
      // delete it
      blob.DeleteIfExists();
    
      // update activity
      if (ctx.Logger.IsDebugEnabled)
       ctx.Logger.Debug("Subtracting {0} bytes to the monthly upload activity for {1}/{2} of user {3}", blob.Properties.Length, ctx.CurrentUploadActivity.Month, ctx.CurrentUploadActivity.Year, ctx.OwnerId);
      ctx.CurrentUploadActivity.AccumulatedSize -= blob.Properties.Length;
      ctx.CurrentUploadActivity.LastUpdate = DateTime.UtcNow;
    
      // done
      preparingEnlistment.Prepared();
     }
    
     public void Commit(Enlistment enlistment)
     {
      Cleanup();
       
      // done
      enlistment.Done();
     }
    
     public void Rollback(Enlistment enlistment)
     {
      if (blob != null)
      {
       try
       {
        blob.UploadFile(ctx.ContentFileName);
        blob.Metadata[Constants.BlobMetaAttributeContentType] = ctx.MimeType;
        blob.Metadata[Constants.BlobMetaAttributeCompressed] = ctx.IsCompressed.ToString();
        blob.SetMetadata();
       }
    
       finally
       {
        Cleanup();
       }
      }
    
      else Cleanup();
    
      // done
      enlistment.Done();
     }
    
     public void InDoubt(Enlistment enlistment)
     {
      Cleanup();
      
      enlistment.Done();
     }
    
     void Cleanup()
     {
      // delete the temporary file holding the blob content
      if (!string.IsNullOrEmpty(ctx.ContentFileName) && File.Exists(ctx.ContentFileName))
      {
       File.Delete(ctx.ContentFileName);
       ctx.ContentFileName = null;
      }
     }
    
     public void Dispose()
     {
      Dispose(true);
      GC.SuppressFinalize(this);
     }
    
     protected virtual void Dispose(bool disposing)
     {
      if (disposing)
      {
       // free managed resources
      }
    
      // free native resources if there are any.
      Cleanup();
     }
     #endregion
    }
    
    



    weichhold.com
    Thursday, July 28, 2011 7:51 PM

Answers

  • Hi Oliver,

    > get-rid of the requirement to download the blob contents in order to rollback.

    Instead of downloading the blob, I'd suggest copying the blob to a backup blob (with a special prefix in the blob name) and deleting the original blob. Copying the blob will be much more faster. And then you delete the backup blob in Cleanup method. Please check CloudBlob.CopyFromBlob Method (CloudBlob) for more information.

    Thanks.


    Wenchao Zeng
    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework
    • Marked as answer by Wenchao Zeng Friday, August 5, 2011 6:47 AM
    Friday, July 29, 2011 8:41 AM

All replies

  • Hi Oliver,

    > get-rid of the requirement to download the blob contents in order to rollback.

    Instead of downloading the blob, I'd suggest copying the blob to a backup blob (with a special prefix in the blob name) and deleting the original blob. Copying the blob will be much more faster. And then you delete the backup blob in Cleanup method. Please check CloudBlob.CopyFromBlob Method (CloudBlob) for more information.

    Thanks.


    Wenchao Zeng
    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework
    • Marked as answer by Wenchao Zeng Friday, August 5, 2011 6:47 AM
    Friday, July 29, 2011 8:41 AM
  • Sounds good. Thanks!
    weichhold.com
    Friday, July 29, 2011 8:42 AM
  • Hi,

    I will mark the reply as answer. If you find it no help, please feel free to unmark it and follow up.

    Thanks.


    Wenchao Zeng
    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework
    Friday, August 5, 2011 6:47 AM