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);
        }
示例#3
0
        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);
        }
示例#4
0
        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;
            }
        }
示例#5
0
        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;
 }
示例#8
0
 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;
         }
     }
 }
示例#9
0
        /// <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));
        }
示例#11
0
        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.");
        }
示例#12
0
 public SingletonLockHandle(string leaseId, string lockId, IStorageBlockBlob blob, TimeSpan leasePeriod)
 {
     this.LeaseId      = leaseId;
     this.LockId       = lockId;
     this._leasePeriod = leasePeriod;
     this.Blob         = blob;
 }
示例#13
0
        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;
                }
            }
        }
示例#14
0
        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;
 }
示例#16
0
 public RenewLeaseCommand(IStorageBlockBlob leaseBlob, string leaseId, string lockId, IDelayStrategy speedupStrategy, TraceWriter trace)
 {
     _leaseBlob       = leaseBlob;
     _leaseId         = leaseId;
     _lockId          = lockId;
     _speedupStrategy = speedupStrategy;
     _trace           = trace;
 }
示例#17
0
        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;
                }
            }
        }
示例#18
0
        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;
        }
示例#20
0
        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);
        }
示例#24
0
        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);
        }
示例#25
0
        public async Task <BlobReceipt> TryReadAsync(IStorageBlockBlob blob, CancellationToken cancellationToken)
        {
            if (!await blob.TryFetchAttributesAsync(cancellationToken))
            {
                return(null);
            }

            return(BlobReceipt.FromMetadata(blob.Metadata));
        }
示例#26
0
 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
            });
        }
示例#28
0
        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)));
        }
示例#29
0
        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);
        }
示例#30
0
        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);
        }
示例#32
0
        /// <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;
        }
示例#35
0
        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;
        }
示例#38
0
        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;
                }
            }
        }
示例#39
0
 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);
 }
示例#44
0
        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;
         }
     }
 }
示例#46
0
 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;
 }
示例#50
0
        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;
                }
            }
        }