Right now I\'m making a HTTP serverless function with Azure Functions and with that I need to make my incoming requests synchronous when accessing a single Blob Storage Item
The error (probably a code=409) what you are received is correct when you acquired a lease blob. This is a perfect behavior for serverless distributed model, where more functions (jobs, workers, etc.) want to have an exclusive access on the lease blob.
Only one of them can be a winner and the others must periodically asking again for their acquire lease. It is recommended during this acquiring period use a random waiting time.
The following code snippet shows an example of this "loop logic" in the azure function:
// Acquireing a Lease blob
public async static Task<string> LockingEntity(dynamic entity, int leaseTimeInSec = 60, string leaseId = null)
{
while (true)
{
try
{
string lid = await entity.AcquireLeaseAsync(TimeSpan.FromSeconds(leaseTimeInSec), leaseId);
if (string.IsNullOrEmpty(lid))
await Task.Delay(TimeSpan.FromMilliseconds(new Random(Guid.NewGuid().GetHashCode()).Next(250, 1000)));
else
return lid;
}
catch (StorageException ex)
{
if (ex.RequestInformation.HttpStatusCode != 409)
throw;
}
}
}
the usage of the above method in the azure function:
string leaseId = await LockingEntity(blockBlob);
if (string.IsNullOrEmpty(leaseId) == false)
{
try
{
string esp = await blockBlob.DownloadTextAsync(Encoding.UTF8, AccessCondition.GenerateLeaseCondition(leaseId), null, null);
state = JsonConvert.DeserializeObject<State>(esp);
// …
}
finally
{
await blockBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId));
}
}
Also, have a look at my article Using Azure Lease Blob for more patterns, etc. in the serverless event driven distributed architecture.