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 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); }
public async Task <string> GetHostIdAsync(CancellationToken cancellationToken) { IStorageAccount account; try { account = await _storageAccountProvider.GetStorageAccountAsync(cancellationToken); } catch (InvalidOperationException exception) { throw new InvalidOperationException( "A host ID is required. Either set JobHostConfiguration.HostId or provide a valid storage " + "connection string.", exception); } IFunctionIndex index = await _getFunctionIndexProvider.Invoke().GetAsync(cancellationToken); IEnumerable <MethodInfo> indexedMethods = index.ReadAllMethods(); string sharedHostName = GetSharedHostName(indexedMethods, account); IStorageBlobDirectory directory = account.CreateBlobClient().GetContainerReference( HostContainerNames.Hosts).GetDirectoryReference(HostDirectoryNames.Ids); return(await GetOrCreateHostIdAsync(sharedHostName, directory, cancellationToken)); }
public SingletonManager(IStorageBlobClient blobClient, IBackgroundExceptionDispatcher backgroundExceptionDispatcher, SingletonConfiguration config, TraceWriter trace) { _backgroundExceptionDispatcher = backgroundExceptionDispatcher; _directory = blobClient.GetContainerReference(HostContainerNames.Hosts) .GetDirectoryReference(HostDirectoryNames.SingletonLocks); _config = config; _trace = trace; }
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); }
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 void GetLockDirectory_HandlesMultipleAccounts() { IStorageBlobDirectory directory = _core.GetLockDirectory(ConnectionStringNames.Storage); Assert.Same(_mockBlobDirectory.Object, directory); directory = _core.GetLockDirectory(null); Assert.Same(_mockBlobDirectory.Object, directory); directory = _core.GetLockDirectory(Secondary); Assert.Same(_mockSecondaryBlobDirectory.Object, directory); }
internal IStorageBlobDirectory GetLockDirectory(string accountName) { if (string.IsNullOrEmpty(accountName)) { accountName = ConnectionStringNames.Storage; } IStorageBlobDirectory storageDirectory = null; if (!_lockDirectoryMap.TryGetValue(accountName, out storageDirectory)) { IStorageBlobContainer container = this.GetContainer(accountName); storageDirectory = container.GetDirectoryReference(HostDirectoryNames.SingletonLocks); _lockDirectoryMap[accountName] = storageDirectory; } return(storageDirectory); }
internal IStorageBlobDirectory GetLockDirectory(string accountName) { if (string.IsNullOrEmpty(accountName)) { accountName = ConnectionStringNames.Storage; } IStorageBlobDirectory storageDirectory = null; if (!_lockDirectoryMap.TryGetValue(accountName, out storageDirectory)) { Task <IStorageAccount> task = _accountProvider.GetAccountAsync(accountName, CancellationToken.None); IStorageAccount storageAccount = task.Result; IStorageBlobClient blobClient = storageAccount.CreateBlobClient(); storageDirectory = blobClient.GetContainerReference(HostContainerNames.Hosts) .GetDirectoryReference(HostDirectoryNames.SingletonLocks); _lockDirectoryMap[accountName] = storageDirectory; } return(storageDirectory); }
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); }
public StorageBlobScanInfoManager(string hostId, IStorageBlobClient blobClient) { if (string.IsNullOrEmpty(hostId)) { throw new ArgumentNullException("hostId"); } if (blobClient == null) { throw new ArgumentNullException("blobClient"); } _hostId = hostId; JsonSerializerSettings settings = new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.IsoDateFormat }; _serializer = JsonSerializer.Create(settings); string blobScanInfoDirectoryPath = string.Format(CultureInfo.InvariantCulture, "blobscaninfo/{0}", _hostId); _blobScanInfoDirectory = blobClient.GetContainerReference(HostContainerNames.Hosts).GetDirectoryReference(blobScanInfoDirectoryPath); }
internal IStorageBlobDirectory GetLockDirectory(string accountName) { if (string.IsNullOrEmpty(accountName)) { accountName = ConnectionStringNames.Storage; } IStorageBlobDirectory storageDirectory = null; if (!_lockDirectoryMap.TryGetValue(accountName, out storageDirectory)) { Task <IStorageAccount> task = _accountProvider.GetStorageAccountAsync(accountName, CancellationToken.None); IStorageAccount storageAccount = task.Result; // singleton requires block blobs, cannot be premium storageAccount.AssertTypeOneOf(StorageAccountType.GeneralPurpose, StorageAccountType.BlobOnly); IStorageBlobClient blobClient = storageAccount.CreateBlobClient(); storageDirectory = blobClient.GetContainerReference(HostContainerNames.Hosts) .GetDirectoryReference(HostDirectoryNames.SingletonLocks); _lockDirectoryMap[accountName] = storageDirectory; } return(storageDirectory); }
private BlobReceiptManager(IStorageBlobDirectory directory) { _directory = directory; }
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 BlobFunctionOutputLogger(IStorageBlobDirectory outputLogDirectory) { _outputLogDirectory = outputLogDirectory; }