public async Task <IDistributedLock> TryLockAsync( string account, string lockId, string lockOwnerId, string proposedLeaseId, TimeSpan lockPeriod, CancellationToken cancellationToken) { IStorageBlobDirectory lockDirectory = GetLockDirectory(account); IStorageBlockBlob lockBlob = lockDirectory.GetBlockBlobReference(lockId); string leaseId = await TryAcquireLeaseAsync(lockBlob, lockPeriod, proposedLeaseId, cancellationToken); if (string.IsNullOrEmpty(leaseId)) { return(null); } if (!string.IsNullOrEmpty(lockOwnerId)) { await WriteLeaseBlobMetadata(lockBlob, leaseId, lockOwnerId, cancellationToken); } SingletonLockHandle lockHandle = new SingletonLockHandle(leaseId, lockId, lockBlob, lockPeriod); return(lockHandle); }
private static async Task<string> GetOrCreateHostIdAsync(string sharedHostName, IStorageBlobDirectory directory, CancellationToken cancellationToken) { Debug.Assert(directory != null); IStorageBlockBlob blob = directory.GetBlockBlobReference(sharedHostName); Guid? possibleHostId = await TryGetExistingIdAsync(blob, cancellationToken); if (possibleHostId.HasValue) { return possibleHostId.Value.ToString("N"); } Guid newHostId = Guid.NewGuid(); if (await TryInitializeIdAsync(blob, newHostId, cancellationToken)) { return newHostId.ToString("N"); } possibleHostId = await TryGetExistingIdAsync(blob, cancellationToken); if (possibleHostId.HasValue) { return possibleHostId.Value.ToString("N"); } // Not expected - valid host ID didn't exist before, couldn't be created, and still didn't exist after. throw new InvalidOperationException("Unable to determine host ID."); }
private static async Task <string> GetOrCreateHostIdAsync(string sharedHostName, IStorageBlobDirectory directory, CancellationToken cancellationToken) { Debug.Assert(directory != null); IStorageBlockBlob blob = directory.GetBlockBlobReference(sharedHostName); Guid?possibleHostId = await TryGetExistingIdAsync(blob, cancellationToken); if (possibleHostId.HasValue) { return(possibleHostId.Value.ToString("N")); } Guid newHostId = Guid.NewGuid(); if (await TryInitializeIdAsync(blob, newHostId, cancellationToken)) { return(newHostId.ToString("N")); } possibleHostId = await TryGetExistingIdAsync(blob, cancellationToken); if (possibleHostId.HasValue) { return(possibleHostId.Value.ToString("N")); } // Not expected - valid host ID didn't exist before, couldn't be created, and still didn't exist after. throw new InvalidOperationException("Unable to determine host ID."); }
public async virtual Task <object> TryLockAsync(string lockId, string functionInstanceId, SingletonAttribute attribute, CancellationToken cancellationToken, bool retry = true) { IStorageBlobDirectory lockDirectory = GetLockDirectory(attribute.Account); IStorageBlockBlob lockBlob = lockDirectory.GetBlockBlobReference(lockId); await TryCreateAsync(lockBlob, cancellationToken); _trace.Verbose(string.Format(CultureInfo.InvariantCulture, "Waiting for Singleton lock ({0})", lockId), source: TraceSource.Execution); TimeSpan lockPeriod = GetLockPeriod(attribute, _config); string leaseId = await TryAcquireLeaseAsync(lockBlob, lockPeriod, cancellationToken); if (string.IsNullOrEmpty(leaseId) && retry) { // Someone else has the lease. Continue trying to periodically get the lease for // a period of time TimeSpan acquisitionTimeout = attribute.LockAcquisitionTimeout != null ? TimeSpan.FromSeconds(attribute.LockAcquisitionTimeout.Value) : _config.LockAcquisitionTimeout; double remainingWaitTime = acquisitionTimeout.TotalMilliseconds; while (string.IsNullOrEmpty(leaseId) && remainingWaitTime > 0) { await Task.Delay(_config.LockAcquisitionPollingInterval); leaseId = await TryAcquireLeaseAsync(lockBlob, lockPeriod, cancellationToken); remainingWaitTime -= _config.LockAcquisitionPollingInterval.TotalMilliseconds; } } if (string.IsNullOrEmpty(leaseId)) { _trace.Verbose(string.Format(CultureInfo.InvariantCulture, "Unable to acquire Singleton lock ({0}).", lockId), source: TraceSource.Execution); return(null); } _trace.Verbose(string.Format(CultureInfo.InvariantCulture, "Singleton lock acquired ({0})", lockId), source: TraceSource.Execution); if (!string.IsNullOrEmpty(functionInstanceId)) { await WriteLeaseBlobMetadata(lockBlob, leaseId, functionInstanceId, cancellationToken); } SingletonLockHandle lockHandle = new SingletonLockHandle { LeaseId = leaseId, LockId = lockId, Blob = lockBlob, LeaseRenewalTimer = CreateLeaseRenewalTimer(lockBlob, leaseId, lockId, lockPeriod, _backgroundExceptionDispatcher) }; // start the renewal timer, which ensures that we maintain our lease until // the lock is released lockHandle.LeaseRenewalTimer.Start(); return(lockHandle); }
public IStorageBlockBlob CreateReference(string hostId, string functionId, string containerName, string blobName, string eTag) { // Put the ETag before the blob name to prevent ambiguity since the blob name can contain embedded slashes. string receiptName = String.Format(CultureInfo.InvariantCulture, "{0}/{1}/{2}/{3}/{4}", hostId, functionId, eTag, containerName, blobName); return(_directory.GetBlockBlobReference(receiptName)); }
private static LocalBlobDescriptor CreateDescriptor(IStorageBlobDirectory directory, string name) { IStorageBlockBlob blob = directory.GetBlockBlobReference(name); return(new LocalBlobDescriptor { ContainerName = blob.Container.Name, BlobName = blob.Name }); }
private static LocalBlobDescriptor CreateDescriptor(IStorageBlobDirectory directory, string name) { IStorageBlockBlob blob = directory.GetBlockBlobReference(name); return new LocalBlobDescriptor { ContainerName = blob.Container.Name, BlobName = blob.Name }; }
public async virtual Task <string> GetLockOwnerAsync(SingletonAttribute attribute, string lockId, CancellationToken cancellationToken) { IStorageBlobDirectory lockDirectory = GetLockDirectory(attribute.Account); IStorageBlockBlob lockBlob = lockDirectory.GetBlockBlobReference(lockId); await ReadLeaseBlobMetadata(lockBlob, cancellationToken); // if the lease is Available, then there is no current owner // (any existing owner value is the last owner that held the lease) if (lockBlob.Properties.LeaseState == LeaseState.Available && lockBlob.Properties.LeaseStatus == LeaseStatus.Unlocked) { return(null); } string owner = string.Empty; lockBlob.Metadata.TryGetValue(FunctionInstanceMetadataKey, out owner); return(owner); }