Created
February 13, 2013 20:02
-
-
Save codingoutloud/4947695 to your computer and use it in GitHub Desktop.
Use Windows Azure Blob to create a semaphore spanning the cloud.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// intended to be called only ONCE in real installations - or for a clean test run when no Jobs container exists | |
public static void GloballyInitializeJobManager(bool quiet) | |
{ | |
var blobContainer = AzureStorageAccess.GetBlobContainer(JobContainerName); | |
bool didNotExistCreated = blobContainer.CreateIfNotExist(); | |
if (!quiet) System.Diagnostics.Debug.Assert(didNotExistCreated); // else, we probably should not be calling this method | |
var blob = blobContainer.GetBlobReference(JobGlobalJobIdSequencePath); | |
if (!blob.Exists()) | |
{ | |
blob.UploadText(JobGlobalJobIdSequenceStartingValue); | |
blob.Properties.ContentType = "text/plain"; | |
blob.SetProperties(); | |
} | |
} | |
public static string GetUniqueJobId() | |
{ | |
// Nod to http://blog.smarx.com/posts/leasing-windows-azure-blobs-using-the-storage-client-library | |
var blobContainer = AzureStorageAccess.GetBlobContainer(JobContainerName); | |
bool didNotExistCreated = blobContainer.CreateIfNotExist(); | |
var blob = blobContainer.GetBlobReference(JobGlobalJobIdSequencePath); | |
if (!blob.Exists()) | |
{ | |
blob.UploadText(JobGlobalJobIdSequenceStartingValue); | |
} | |
// TODO: ??? needs to handle case where it cannot initially Acquire Lease due to resource contention | |
string leaseId = null; | |
int retryCount = 0; | |
var random = new Random((int)DateTime.Now.Ticks); | |
var timeBeforeRetries = DateTime.UtcNow; | |
while (leaseId == null && retryCount < 100 && (DateTime.UtcNow < timeBeforeRetries.AddMinutes(2))) | |
{ | |
try | |
{ | |
leaseId = blob.AcquireLease(); // lease is for 60 seconds and is renewable | |
} | |
catch (System.Net.WebException wex) | |
{ | |
retryCount++; | |
int sleepMilliseconds = random.Next(50, 1000); | |
System.Threading.Thread.Sleep(sleepMilliseconds); | |
System.Diagnostics.Trace.WriteLine(String.Format( | |
"About to attempt retry {0} after sleeping {1} ms [exception status: {2}; exception message: {3}]", | |
retryCount, sleepMilliseconds, wex.Status, wex.Message)); | |
} | |
} | |
try { var leaseId2 = blob.AcquireLease(); } | |
catch { } | |
var blobContent = blob.DownloadText(); | |
// increment string to next one | |
long jobId = Convert.ToInt64(blobContent); | |
jobId++; | |
string jobIdString = jobId.ToString(); | |
blob.UploadText(jobIdString, leaseId); // extension method | |
// that writing new data to the blob turns this to application/octet-stream: | |
blob.Properties.ContentType = "text/plain"; | |
blob.SetProperties(); // TODO: extension for passing leaseid | |
blob.ReleaseLease(leaseId); | |
return jobIdString; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment