private UpdateOutputLogCommand(IStorageBlockBlob outputBlob, Func<string, CancellationToken, Task> uploadCommand) { _outputBlob = outputBlob; _innerWriter = new StringWriter(CultureInfo.InvariantCulture); _synchronizedWriter = TextWriter.Synchronized(_innerWriter); _uploadCommand = uploadCommand; }
public static async Task<UpdateOutputLogCommand> CreateAsync(IStorageBlockBlob outputBlob, string existingContents, Func<string, CancellationToken, Task> uploadCommand, CancellationToken cancellationToken) { if (outputBlob == null) { throw new ArgumentNullException("outputBlob"); } else if (uploadCommand == null) { throw new ArgumentNullException("uploadCommand"); } StringWriter innerWriter = new StringWriter(); if (existingContents != null) { // This can happen if the function was running previously and the // node crashed. Save previous output, could be useful for diagnostics. innerWriter.WriteLine("Previous execution information:"); innerWriter.WriteLine(existingContents); var lastTime = await GetBlobModifiedUtcTimeAsync(outputBlob, cancellationToken); if (lastTime.HasValue) { var delta = DateTime.UtcNow - lastTime.Value; innerWriter.WriteLine("... Last write at {0}, {1} ago", lastTime, delta); } innerWriter.WriteLine("========================"); } return new UpdateOutputLogCommand(innerWriter, uploadCommand); }
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 <DateTime?> LoadLatestScanAsync(string storageAccountName, string containerName) { IStorageBlockBlob scanInfoBlob = GetScanInfoBlobReference(storageAccountName, containerName); DateTime? latestScan = null; try { string scanInfoLine = await scanInfoBlob.DownloadTextAsync(CancellationToken.None); ScanInfo scanInfo; using (StringReader stringReader = new StringReader(scanInfoLine)) { scanInfo = (ScanInfo)_serializer.Deserialize(stringReader, typeof(ScanInfo)); } if (scanInfo != null) { latestScan = scanInfo.LatestScan; } return(latestScan); } catch (StorageException exception) { if (exception.IsNotFound()) { // we haven't saved any scanInfo yet return(null); } throw; } }
public async Task MarkCompletedAsync(IStorageBlockBlob blob, string leaseId, CancellationToken cancellationToken) { BlobReceipt.Complete.ToMetadata(blob.Metadata); try { await blob.SetMetadataAsync( accessCondition : new AccessCondition { LeaseId = leaseId }, options : null, operationContext : null, cancellationToken : cancellationToken); } catch (StorageException exception) { if (exception.IsNotFoundBlobOrContainerNotFound()) { // The user deleted the receipt or its container; nothing to mark complete at this point. } else if (exception.IsPreconditionFailedLeaseLost()) { // The lease expired; don't try to mark complete at this point. } else { throw; } } }
public static async Task <UpdateOutputLogCommand> CreateAsync(IStorageBlockBlob outputBlob, string existingContents, Func <string, CancellationToken, Task> uploadCommand, CancellationToken cancellationToken) { if (outputBlob == null) { throw new ArgumentNullException("outputBlob"); } else if (uploadCommand == null) { throw new ArgumentNullException("uploadCommand"); } StringWriter innerWriter = new StringWriter(); if (existingContents != null) { // This can happen if the function was running previously and the // node crashed. Save previous output, could be useful for diagnostics. innerWriter.WriteLine("Previous execution information:"); innerWriter.WriteLine(existingContents); var lastTime = await GetBlobModifiedUtcTimeAsync(outputBlob, cancellationToken); if (lastTime.HasValue) { var delta = DateTime.UtcNow - lastTime.Value; innerWriter.WriteLine("... Last write at {0}, {1} ago", lastTime, delta); } innerWriter.WriteLine("========================"); } return(new UpdateOutputLogCommand(outputBlob, innerWriter, uploadCommand)); }
private UpdateOutputLogCommand(IStorageBlockBlob outputBlob, Func <string, CancellationToken, Task> uploadCommand) { _outputBlob = outputBlob; _innerWriter = new StringWriter(CultureInfo.InvariantCulture); _synchronizedWriter = TextWriter.Synchronized(_innerWriter); _uploadCommand = uploadCommand; }
public async Task ReleaseLeaseAsync(IStorageBlockBlob blob, string leaseId, CancellationToken cancellationToken) { try { // Note that this call returns without throwing if the lease is expired. See the table at: // http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx await blob.ReleaseLeaseAsync( accessCondition : new AccessCondition { LeaseId = leaseId }, options : null, operationContext : null, cancellationToken : cancellationToken); } catch (StorageException exception) { if (exception.IsNotFoundBlobOrContainerNotFound()) { // The user deleted the receipt or its container; nothing to release at this point. } else if (exception.IsConflictLeaseIdMismatchWithLeaseOperation()) { // Another lease is active; nothing for this lease to release at this point. } else { throw; } } }
/// <inheritdoc /> public async Task DeleteAsync(string messageId, CancellationToken cancellationToken) { try { if (String.IsNullOrEmpty(messageId)) { throw new ArgumentNullException("messageId"); } IStorageBlockBlob blob = _blobContainer.GetBlockBlobReference(messageId); await blob.DeleteAsync(cancellationToken); } catch (StorageException exception) { // Return successfully if the blob has already been deleted. if (exception.IsNotFoundBlobOrContainerNotFound()) { return; } else { throw; } } }
public async Task <IFunctionOutput> CreateOutputAsync(CancellationToken cancellationToken) { IStorageBlockBlob blob = GetBlockBlobReference(_outputBlob); string existingContents = await ReadBlobAsync(blob, cancellationToken); return(await UpdateOutputLogCommand.CreateAsync(blob, existingContents, cancellationToken)); }
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 SingletonLockHandle(string leaseId, string lockId, IStorageBlockBlob blob, TimeSpan leasePeriod) { this.LeaseId = leaseId; this.LockId = lockId; this._leasePeriod = leasePeriod; this.Blob = blob; }
private async Task WriteLeaseBlobMetadata(IStorageBlockBlob blob, string leaseId, string functionInstanceId, CancellationToken cancellationToken) { blob.Metadata.Add(FunctionInstanceMetadataKey, functionInstanceId); try { await blob.SetMetadataAsync( accessCondition : new AccessCondition { LeaseId = leaseId }, options : null, operationContext : null, cancellationToken : cancellationToken); } catch (StorageException exception) { if (exception.IsNotFoundBlobOrContainerNotFound()) { // The user deleted the receipt or its container; } else if (exception.IsPreconditionFailedLeaseLost()) { // The lease expired; } else { throw; } } }
public void BlobTrigger_IfBindingAlwaysFails_MovesToPoisonQueue() { // Arrange IStorageAccount account = CreateFakeStorageAccount(); IStorageBlobContainer container = CreateContainer(account, ContainerName); IStorageBlockBlob blob = container.GetBlockBlobReference(BlobName); CloudBlockBlob expectedBlob = blob.SdkObject; blob.UploadText("ignore"); // Act string result = RunTrigger <string>(account, typeof(PoisonBlobProgram), (s) => PoisonBlobProgram.TaskSource = s, new string[] { typeof(PoisonBlobProgram).FullName + ".PutInPoisonQueue" }); // Assert BlobTriggerMessage message = JsonConvert.DeserializeObject <BlobTriggerMessage>(result); Assert.NotNull(message); Assert.Equal(typeof(PoisonBlobProgram).FullName + ".PutInPoisonQueue", message.FunctionId); Assert.Equal(StorageBlobType.BlockBlob, message.BlobType); Assert.Equal(ContainerName, message.ContainerName); Assert.Equal(BlobName, message.BlobName); Assert.NotEmpty(message.ETag); }
private UpdateOutputLogCommand(IStorageBlockBlob outputBlob, StringWriter innerWriter, Func <string, CancellationToken, Task> uploadCommand) { _outputBlob = outputBlob; _innerWriter = innerWriter; _synchronizedWriter = TextWriter.Synchronized(_innerWriter); _uploadCommand = uploadCommand; }
public RenewLeaseCommand(IStorageBlockBlob leaseBlob, string leaseId, string lockId, IDelayStrategy speedupStrategy, TraceWriter trace) { _leaseBlob = leaseBlob; _leaseId = leaseId; _lockId = lockId; _speedupStrategy = speedupStrategy; _trace = trace; }
private async Task <bool> TryCreateAsync(IStorageBlockBlob blob, CancellationToken cancellationToken) { bool isContainerNotFoundException = false; try { await blob.UploadTextAsync(string.Empty, cancellationToken : cancellationToken); return(true); } catch (StorageException exception) { if (exception.RequestInformation != null) { if (exception.RequestInformation.HttpStatusCode == 404) { isContainerNotFoundException = true; } else if (exception.RequestInformation.HttpStatusCode == 409 || exception.RequestInformation.HttpStatusCode == 412) { // The blob already exists, or is leased by someone else return(false); } else { throw; } } else { throw; } } Debug.Assert(isContainerNotFoundException); await blob.Container.CreateIfNotExistsAsync(cancellationToken); try { await blob.UploadTextAsync(string.Empty, cancellationToken : cancellationToken); return(true); } catch (StorageException exception) { if (exception.RequestInformation != null && (exception.RequestInformation.HttpStatusCode == 409 || exception.RequestInformation.HttpStatusCode == 412)) { // The blob already exists, or is leased by someone else return(false); } else { throw; } } }
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); }
/// <summary> /// Initializes a new instance of the <see cref="HeartbeatCommand"/> class. /// </summary> /// <param name="blob">The heartbeat blob.</param> public HeartbeatCommand(IStorageBlockBlob blob) { if (blob == null) { throw new ArgumentNullException("blob"); } _blob = blob; }
public static void UploadText(this IStorageBlockBlob blob, string content) { if (blob == null) { throw new ArgumentNullException("blob"); } blob.UploadTextAsync(content).GetAwaiter().GetResult(); }
private string CreateAblobAndUploadToContainer(IStorageBlobContainer container, string blobContent = "test") { string blobName = Path.GetRandomFileName().Replace(".", ""); IStorageBlockBlob blob = container.GetBlockBlobReference(blobName); container.CreateIfNotExists(); blob.UploadText(blobContent); return(blobName); }
/// <summary> /// Initializes a new instance of the <see cref="HeartbeatCommand"/> class. /// </summary> /// <param name="blob">The heartbeat blob.</param> public HeartbeatCommand(IStorageBlockBlob blob) { if (blob == null) { throw new ArgumentNullException("blob"); } _blob = blob; }
public async Task<BlobReceipt> TryReadAsync(IStorageBlockBlob blob, CancellationToken cancellationToken) { if (!await blob.TryFetchAttributesAsync(cancellationToken)) { return null; } return BlobReceipt.FromMetadata(blob.Metadata); }
private async Task <string> TryAcquireLeaseAsync(IStorageBlockBlob blob, TimeSpan leasePeriod, CancellationToken cancellationToken) { bool blobDoesNotExist = false; try { // Optimistically try to acquire the lease. The blob may not yet // exist. If it doesn't we handle the 404, create it, and retry below return(await blob.AcquireLeaseAsync(leasePeriod, null, cancellationToken)); } catch (StorageException exception) { if (exception.RequestInformation != null) { if (exception.RequestInformation.HttpStatusCode == 409) { return(null); } else if (exception.RequestInformation.HttpStatusCode == 404) { blobDoesNotExist = true; } else { throw; } } else { throw; } } if (blobDoesNotExist) { await TryCreateAsync(blob, cancellationToken); try { return(await blob.AcquireLeaseAsync(leasePeriod, null, cancellationToken)); } catch (StorageException exception) { if (exception.RequestInformation != null && exception.RequestInformation.HttpStatusCode == 409) { return(null); } else { throw; } } } return(null); }
public async Task <BlobReceipt> TryReadAsync(IStorageBlockBlob blob, CancellationToken cancellationToken) { if (!await blob.TryFetchAttributesAsync(cancellationToken)) { return(null); } return(BlobReceipt.FromMetadata(blob.Metadata)); }
public RenewLeaseCommand(IStorageBlockBlob leaseBlob, string leaseId, string lockId, IDelayStrategy speedupStrategy, TraceWriter trace, TimeSpan leasePeriod) { _lastRenewal = DateTimeOffset.UtcNow; _leaseBlob = leaseBlob; _leaseId = leaseId; _lockId = lockId; _speedupStrategy = speedupStrategy; _trace = trace; _leasePeriod = leasePeriod; }
private static LocalBlobDescriptor CreateDescriptor(IStorageBlobDirectory directory, string name) { IStorageBlockBlob blob = directory.GetBlockBlobReference(name); return(new LocalBlobDescriptor { ContainerName = blob.Container.Name, BlobName = blob.Name }); }
private ITaskSeriesTimer CreateLeaseRenewalTimer(IStorageBlockBlob leaseBlob, string leaseId, string lockId, TimeSpan leasePeriod, IWebJobsExceptionHandler exceptionHandler) { // renew the lease when it is halfway to expiring TimeSpan normalUpdateInterval = new TimeSpan(leasePeriod.Ticks / 2); IDelayStrategy speedupStrategy = new LinearSpeedupStrategy(normalUpdateInterval, MinimumLeaseRenewalInterval); ITaskSeriesCommand command = new RenewLeaseCommand(leaseBlob, leaseId, lockId, speedupStrategy, _trace); return(new TaskSeriesTimer(command, exceptionHandler, Task.Delay(normalUpdateInterval))); }
private static Mock <IBlobReceiptManager> CreateReceiptManagerReferenceMock() { IStorageBlockBlob receiptBlob = CreateAccount().CreateBlobClient() .GetContainerReference("receipts").GetBlockBlobReference("item"); Mock <IBlobReceiptManager> mock = new Mock <IBlobReceiptManager>(MockBehavior.Strict); mock.Setup(m => m.CreateReference(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>())) .Returns(receiptBlob); return(mock); }
private async Task WriteLeaseBlobMetadata(IStorageBlockBlob blob, string leaseId, string functionInstanceId, CancellationToken cancellationToken) { blob.Metadata.Add(FunctionInstanceMetadataKey, functionInstanceId); await blob.SetMetadataAsync( accessCondition : new AccessCondition { LeaseId = leaseId }, options : null, operationContext : null, cancellationToken : cancellationToken); }
public static UpdateOutputLogCommand Create(IStorageBlockBlob outputBlob, Func<string, CancellationToken, Task> uploadCommand) { if (outputBlob == null) { throw new ArgumentNullException("outputBlob"); } else if (uploadCommand == null) { throw new ArgumentNullException("uploadCommand"); } return new UpdateOutputLogCommand(outputBlob, uploadCommand); }
/// <inheritdoc /> public async Task <string> EnqueueAsync(T message, CancellationToken cancellationToken) { await _blobContainer.CreateIfNotExistsAsync(cancellationToken); string blobName = BlobNames.GetConflictFreeDateTimeBasedBlobName(); IStorageBlockBlob blob = _blobContainer.GetBlockBlobReference(blobName); message.AddMetadata(blob.Metadata); string messageBody = JsonConvert.SerializeObject(message, JsonSerialization.Settings); await blob.UploadTextAsync(messageBody, cancellationToken : cancellationToken); return(blobName); }
public static UpdateOutputLogCommand Create(IStorageBlockBlob outputBlob, Func <string, CancellationToken, Task> uploadCommand) { if (outputBlob == null) { throw new ArgumentNullException("outputBlob"); } else if (uploadCommand == null) { throw new ArgumentNullException("uploadCommand"); } return(new UpdateOutputLogCommand(outputBlob, uploadCommand)); }
public UpdateParameterLogCommand(IReadOnlyDictionary <string, IWatcher> watches, IStorageBlockBlob parameterLogBlob, ILogger logger) { if (parameterLogBlob == null) { throw new ArgumentNullException("parameterLogBlob"); } else if (watches == null) { throw new ArgumentNullException("watches"); } _parameterLogBlob = parameterLogBlob; _logger = logger; _watches = watches; }
public CloudBlockBlob Convert(IStorageBlob input) { if (input == null) { return(null); } IStorageBlockBlob blockBlob = input as IStorageBlockBlob; if (blockBlob == null) { throw new InvalidOperationException("The blob is not a block blob."); } return(blockBlob.SdkObject); }
public UpdateParameterLogCommand(IReadOnlyDictionary<string, IWatcher> watches, IStorageBlockBlob parameterLogBlob, TextWriter consoleOutput) { if (parameterLogBlob == null) { throw new ArgumentNullException("parameterLogBlob"); } else if (consoleOutput == null) { throw new ArgumentNullException("consoleOutput"); } else if (watches == null) { throw new ArgumentNullException("watches"); } _parameterLogBlob = parameterLogBlob; _consoleOutput = consoleOutput; _watches = watches; }
public UpdateParameterLogCommand(IReadOnlyDictionary<string, IWatcher> watches, IStorageBlockBlob parameterLogBlob, TraceWriter trace) { if (parameterLogBlob == null) { throw new ArgumentNullException("parameterLogBlob"); } else if (trace == null) { throw new ArgumentNullException("trace"); } else if (watches == null) { throw new ArgumentNullException("watches"); } _parameterLogBlob = parameterLogBlob; _trace = trace; _watches = watches; }
private async Task<bool> TryCreateAsync(IStorageBlockBlob blob, CancellationToken cancellationToken) { bool isContainerNotFoundException = false; try { await blob.UploadTextAsync(string.Empty, cancellationToken: cancellationToken); return true; } catch (StorageException exception) { if (exception.RequestInformation != null) { if (exception.RequestInformation.HttpStatusCode == 404) { isContainerNotFoundException = true; } else if (exception.RequestInformation.HttpStatusCode == 409 || exception.RequestInformation.HttpStatusCode == 412) { // The blob already exists, or is leased by someone else return false; } else { throw; } } else { throw; } } Debug.Assert(isContainerNotFoundException); await blob.Container.CreateIfNotExistsAsync(cancellationToken); try { await blob.UploadTextAsync(string.Empty, cancellationToken: cancellationToken); return true; } catch (StorageException exception) { if (exception.RequestInformation != null && (exception.RequestInformation.HttpStatusCode == 409 || exception.RequestInformation.HttpStatusCode == 412)) { // The blob already exists, or is leased by someone else return false; } else { throw; } } }
private async Task ReleaseLeaseAsync(IStorageBlockBlob blob, string leaseId, CancellationToken cancellationToken) { try { // Note that this call returns without throwing if the lease is expired. See the table at: // http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx await blob.ReleaseLeaseAsync( accessCondition: new AccessCondition { LeaseId = leaseId }, options: null, operationContext: null, cancellationToken: cancellationToken); } catch (StorageException exception) { if (exception.RequestInformation != null) { if (exception.RequestInformation.HttpStatusCode == 404 || exception.RequestInformation.HttpStatusCode == 409) { // if the blob no longer exists, or there is another lease // now active, there is nothing for us to release so we can // ignore } else { throw; } } else { throw; } } }
private async Task ReadLeaseBlobMetadata(IStorageBlockBlob blob, CancellationToken cancellationToken) { try { await blob.FetchAttributesAsync(cancellationToken); } catch (StorageException exception) { if (exception.IsNotFoundBlobOrContainerNotFound()) { // The user deleted the receipt or its container; } else { throw; } } }
private async Task WriteLeaseBlobMetadata(IStorageBlockBlob blob, string leaseId, string functionInstanceId, CancellationToken cancellationToken) { blob.Metadata.Add(FunctionInstanceMetadataKey, functionInstanceId); try { await blob.SetMetadataAsync( accessCondition: new AccessCondition { LeaseId = leaseId }, options: null, operationContext: null, cancellationToken: cancellationToken); } catch (StorageException exception) { if (exception.IsNotFoundBlobOrContainerNotFound()) { // The user deleted the receipt or its container; } else if (exception.IsPreconditionFailedLeaseLost()) { // The lease expired; } else { throw; } } }
private static Task UploadTextAsync(IStorageBlockBlob outputBlob, string contents, CancellationToken cancellationToken) { return outputBlob.UploadTextAsync(contents, cancellationToken: cancellationToken); }
public static Task<UpdateOutputLogCommand> CreateAsync(IStorageBlockBlob outputBlob, string existingContents, CancellationToken cancellationToken) { return CreateAsync(outputBlob, existingContents, (contents, innerToken) => UploadTextAsync( outputBlob, contents, innerToken), cancellationToken); }
private async Task<string> TryAcquireLeaseAsync(IStorageBlockBlob blob, TimeSpan leasePeriod, CancellationToken cancellationToken) { bool blobDoesNotExist = false; try { // Optimistically try to acquire the lease. The blob may not yet // exist. If it doesn't we handle the 404, create it, and retry below return await blob.AcquireLeaseAsync(leasePeriod, null, cancellationToken); } catch (StorageException exception) { if (exception.RequestInformation != null) { if (exception.RequestInformation.HttpStatusCode == 409) { return null; } else if (exception.RequestInformation.HttpStatusCode == 404) { blobDoesNotExist = true; } else { throw; } } else { throw; } } if (blobDoesNotExist) { await TryCreateAsync(blob, cancellationToken); try { return await blob.AcquireLeaseAsync(leasePeriod, null, cancellationToken); } catch (StorageException exception) { if (exception.RequestInformation != null && exception.RequestInformation.HttpStatusCode == 409) { return null; } else { throw; } } } return null; }
private async Task ReleaseLeaseAsync(IStorageBlockBlob blob, string leaseId, CancellationToken cancellationToken) { try { // Note that this call returns without throwing if the lease is expired. See the table at: // http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx await blob.ReleaseLeaseAsync( accessCondition: new AccessCondition { LeaseId = leaseId }, options: null, operationContext: null, cancellationToken: cancellationToken); } catch (StorageException exception) { if (exception.IsNotFoundBlobOrContainerNotFound()) { // The user deleted the receipt or its container; nothing to release at this point. } else if (exception.IsConflictLeaseIdMismatchWithLeaseOperation()) { // Another lease is active; nothing for this lease to release at this point. } else { throw; } } }
private async Task ReadLeaseBlobMetadata(IStorageBlockBlob blob, CancellationToken cancellationToken) { try { await blob.FetchAttributesAsync(cancellationToken); } catch (StorageException exception) { if (exception.RequestInformation != null && exception.RequestInformation.HttpStatusCode == 404) { // the blob no longer exists } else { throw; } } }
private static async Task<string> TryDownloadAsync(IStorageBlockBlob blob, CancellationToken cancellationToken) { try { return await blob.DownloadTextAsync(cancellationToken); } catch (StorageException exception) { if (exception.IsNotFound()) { return null; } else { throw; } } }
private static async Task<Guid?> TryGetExistingIdAsync(IStorageBlockBlob blob, CancellationToken cancellationToken) { string text = await TryDownloadAsync(blob, cancellationToken); if (text == null) { return null; } Guid possibleHostId; if (Guid.TryParseExact(text, "N", out possibleHostId)) { return possibleHostId; } return null; }
public RenewLeaseCommand(IStorageBlockBlob leaseBlob, string leaseId, string lockId, IDelayStrategy speedupStrategy, TraceWriter trace) { _leaseBlob = leaseBlob; _leaseId = leaseId; _lockId = lockId; _speedupStrategy = speedupStrategy; _trace = trace; }
private async Task WriteLeaseBlobMetadata(IStorageBlockBlob blob, string leaseId, string functionInstanceId, CancellationToken cancellationToken) { blob.Metadata.Add(FunctionInstanceMetadataKey, functionInstanceId); await blob.SetMetadataAsync( accessCondition: new AccessCondition { LeaseId = leaseId }, options: null, operationContext: null, cancellationToken: cancellationToken); }
private async Task<string> TryAcquireLeaseAsync(IStorageBlockBlob blob, TimeSpan leasePeriod, CancellationToken cancellationToken) { try { return await blob.AcquireLeaseAsync(leasePeriod, null, cancellationToken); } catch (StorageException exception) { if (exception.IsConflictLeaseAlreadyPresent()) { return null; } else if (exception.IsNotFoundBlobOrContainerNotFound()) { // If someone deleted the receipt, there's no lease to acquire. return null; } else { throw; } } }
private HeartbeatCommand(IStorageBlockBlob blob) { _blob = blob; }
public static UpdateOutputLogCommand Create(IStorageBlockBlob outputBlob) { return Create(outputBlob, (contents, innerToken) => UploadTextAsync(outputBlob, contents, innerToken)); }
private static async Task<bool> TryInitializeIdAsync(IStorageBlockBlob blob, Guid hostId, CancellationToken cancellationToken) { string text = hostId.ToString("N"); AccessCondition accessCondition = new AccessCondition { IfNoneMatchETag = "*" }; bool failedWithContainerNotFoundException = false; try { await blob.UploadTextAsync(text, encoding: null, accessCondition: accessCondition, options: null, operationContext: null, cancellationToken: cancellationToken); return true; } catch (StorageException exception) { if (exception.IsPreconditionFailed() || exception.IsConflict()) { return false; } else if (exception.IsNotFoundContainerNotFound()) { failedWithContainerNotFoundException = true; } else { throw; } } Debug.Assert(failedWithContainerNotFoundException); await blob.Container.CreateIfNotExistsAsync(cancellationToken); try { await blob.UploadTextAsync(text, encoding: null, accessCondition: accessCondition, options: null, operationContext: null, cancellationToken: cancellationToken); return true; } catch (StorageException retryException) { if (retryException.IsPreconditionFailed() || retryException.IsConflict()) { return false; } else { throw; } } }
private async Task<bool> TryCreateAsync(IStorageBlockBlob blob, CancellationToken cancellationToken) { AccessCondition accessCondition = new AccessCondition { IfNoneMatchETag = "*" }; bool isContainerNotFoundException = false; try { await blob.UploadTextAsync(String.Empty, encoding: null, accessCondition: accessCondition, options: null, operationContext: null, cancellationToken: cancellationToken); return true; } catch (StorageException exception) { if (exception.IsNotFoundContainerNotFound()) { isContainerNotFoundException = true; } else if (exception.IsConflictBlobAlreadyExists()) { return false; } else if (exception.IsPreconditionFailedLeaseIdMissing()) { return false; } else { throw; } } Debug.Assert(isContainerNotFoundException); await blob.Container.CreateIfNotExistsAsync(cancellationToken); try { await blob.UploadTextAsync(String.Empty, encoding: null, accessCondition: accessCondition, options: null, operationContext: null, cancellationToken: cancellationToken); return true; } catch (StorageException exception) { if (exception.IsConflictBlobAlreadyExists()) { return false; } else if (exception.IsPreconditionFailedLeaseIdMissing()) { return false; } else { throw; } } }
private ITaskSeriesTimer CreateLeaseRenewalTimer(IStorageBlockBlob leaseBlob, string leaseId, string lockId, TimeSpan leasePeriod, IBackgroundExceptionDispatcher backgroundExceptionDispatcher) { // renew the lease when it is halfway to expiring TimeSpan normalUpdateInterval = new TimeSpan(leasePeriod.Ticks / 2); IDelayStrategy speedupStrategy = new LinearSpeedupStrategy(normalUpdateInterval, MinimumLeaseRenewalInterval); ITaskSeriesCommand command = new RenewLeaseCommand(leaseBlob, leaseId, lockId, speedupStrategy, _trace); return new TaskSeriesTimer(command, backgroundExceptionDispatcher, Task.Delay(normalUpdateInterval)); }
public async Task MarkCompletedAsync(IStorageBlockBlob blob, string leaseId, CancellationToken cancellationToken) { BlobReceipt.Complete.ToMetadata(blob.Metadata); try { await blob.SetMetadataAsync( accessCondition: new AccessCondition { LeaseId = leaseId }, options: null, operationContext: null, cancellationToken: cancellationToken); } catch (StorageException exception) { if (exception.IsNotFoundBlobOrContainerNotFound()) { // The user deleted the receipt or its container; nothing to mark complete at this point. } else if (exception.IsPreconditionFailedLeaseLost()) { // The lease expired; don't try to mark complete at this point. } else { throw; } } }