Keeping Blob Snapshots For a Specific Amount of Time

February 27, 2013 — 1 Comment

I recently came across the this requirement

  • When content is modified, the editor has the ability to rollback to the original content.
  • The previous version of the content is available for 4 hours.
  • Content cannot be rolled back once the previous version has expired

This got me thinking about the BlobContainerWorker and how I could use it to satisfy these requirements.

I created the BlobSnapshotCleaner  to deleted Blob Snapshots based on their age. It’s also very good at deleting Snapshots that are blocking you from deleting Blobs from Visual Studio.

class Program
{
    static void Main(string[] args)
    {
        var remover = new BlobSnapshotCleaner("StorageConnectionString", 
                                                "documents",
                                                TimeSpan.FromHours(4));
        remover.Start();

        System.Console.ReadLine();
    }
}

This console application is used as a host for the BlobSnapshotCleaner. You can find the source code below. Since the BlobSnapshotCleaner  implements PollingTask<TWorkItem>, it’s used pretty much like the MessageQueueWorker implemented in an earlier post. The BlobSnapshotCleaner  needs a Storage Account Connection String and the name of the Blob container that it will work with and the maximum age for Snapshots.

The code from this Post is part of the Brisebois.WindowsAzure NuGet Package

To install Brisebois.WindowsAzure, run the following command in the Package Manager Console

PM> Install-Package Brisebois.WindowsAzure

Get more details about the Nuget Package.

It BlobSnapshotCleaner implements a BlobContainerWorker, which implements PollingTask<TWorkItem> to read blob snapshots from a container and delete expired Snapshots. If expired snapshots are not found, it uses an exponential back off strategy to reduce the number of transactions made on Windows Azure Blob Storage Service. Without the back off strategy, the service would continuously make requests to check if snapshots needed to be deleted.

public class BlobSnapshotCleaner : BlobContainerWorker
{
    private const int MaxDelayInSeconds = 512;
    private readonly TimeSpan maxAge;

    /// <summary>
    /// Keep Snapshots for a specific amount of time
    /// </summary>
    /// <param name="connectionString">Cloud Connection String</param>
    /// <param name="containerName">Blob Container Name</param>
    /// <param name="maxAge">MAX Age for a Blob Snapshot</param>
    public BlobSnapshotCleaner(string connectionString,
                                string containerName,
                                TimeSpan maxAge)
        : base(connectionString,
                containerName,
                BlobListingDetails.Snapshots,
                false,
                null, 
                MaxDelayInSeconds)
    {
        this.maxAge = maxAge;
    }

    protected override void Report(string message)
    {
        Console.WriteLine(message);
    }

    protected override ICollection<IListBlobItem> GetWork()
    {
        var list = base.GetWork();
        return list.Cast<CloudBlockBlob>()
                    .Where(b => b.SnapshotTime.HasValue && IsExpired(b))
                    .Select(b => (IListBlobItem)b)
                    .ToList();
    }

    private bool IsExpired(CloudBlockBlob cloudBlockBlob)
    {
        var snapshotTime = cloudBlockBlob.SnapshotTime.Value.UtcDateTime;
        return DateTime.UtcNow.Subtract(snapshotTime) < maxAge;
    }

    protected override void OnExecuting(CloudBlockBlob workItem)
    {
        workItem.DeleteIfExists();

        Report(string.Format("DELETED {0} Snapshot Time {1}",
                                workItem.Uri,
                                workItem.SnapshotTime));
    }
}

 

Before executing any of this code be sure to include the PollingTask<TWorkItem> class in your project. Further more be sure to configure the storage connection string in your App.Config or Cloud Configurations.

  <appSettings>
    <add key="StorageConnectionString" value="[Your Storage Connection String]" />
  </appSettings>

Trackbacks and Pingbacks:

  1. Dew Drop – February 28, 2013 (#1,506) | Alvin Ashcraft's Morning Dew - February 28, 2013

    […] Keeping Blob Snapshots For a Specific Amount of Time (Alexandre Brisebois) […]

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.