Azure Blob Storage | AcquireLeaseAsync, synchronously wait until lock is released

前端 未结 1 2029
醉话见心
醉话见心 2021-01-14 00:17

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

1条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-01-14 00:47

    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 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(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.

    0 讨论(0)
提交回复
热议问题