예제 #1
0
        public async Task ClearAsync()
        {
            int count = await Table.CreateQuery <DataItem>().CountAsync();

            var batch = new TableBatchOperation();

            for (int i = count - 1; i >= 0; i--)
            {
                batch.RemoveAt(i);
            }
            await Table.ExecuteBatchAsync(batch);
        }
        public void TableBatchLockToPartitionKey()
        {
            TableBatchOperation batch = new TableBatchOperation();

            batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo")));

            try
            {
                batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo2")));
                Assert.Fail();
            }
            catch (ArgumentException)
            {
                // no op
            }
            catch (Exception)
            {
                Assert.Fail();
            }

            // should reset pk lock
            batch.RemoveAt(0);
            batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo2")));

            try
            {
                batch.Add(TableOperation.Insert(GenerateRandomEnitity("foo2")));
            }
            catch (ArgumentException)
            {
                Assert.Fail();
            }
            catch (Exception)
            {
                Assert.Fail();
            }
        }
        public void TableBatchLockToPartitionKey()
        {
            TableBatchOperation batch = new TableBatchOperation();
            batch.Add(TableOperation.Insert(GenerateRandomEntity("foo")));

            try
            {
                batch.Add(TableOperation.Insert(GenerateRandomEntity("foo2")));
                Assert.Fail();
            }
            catch (ArgumentException)
            {
                // no op
            }
            catch (Exception)
            {
                Assert.Fail();
            }

            // should reset pk lock
            batch.RemoveAt(0);
            batch.Add(TableOperation.Insert(GenerateRandomEntity("foo2")));

            try
            {
                batch.Add(TableOperation.Insert(GenerateRandomEntity("foo2")));
            }
            catch (ArgumentException)
            {
                Assert.Fail();
            }
            catch (Exception)
            {
                Assert.Fail();
            }
        }
예제 #4
0
        /// <summary>
        /// Removes a batch of items from the table.
        /// </summary>
        /// <param name="table">CloudTable instance.</param>
        /// <param name="tbo">TableBatchOperations instance.</param>
        internal async Task <int> RemoveItemsAsync(CloudTable table, TableBatchOperation tbo)
        {
            if (null == table)
            {
                throw new ArgumentNullException("Argument is null", nameof(table));
            }
            if (null == tbo)
            {
                throw new ArgumentNullException("Argument is null", nameof(tbo));
            }

            int       count         = 0;
            const int maxRetryCount = 5;
            int       retry         = maxRetryCount;

            do
            {
                // Reset count in case the while was retried.
                count = 0;
                try
                {
                    TableRequestOptions tro = new TableRequestOptions()
                    {
                        MaximumExecutionTime = TimeSpan.FromSeconds(60),
                        ServerTimeout        = TimeSpan.FromSeconds(5),
                        RetryPolicy          = new ExponentialRetry(TimeSpan.FromSeconds(1), 3)
                    };

                    // Ensure that the batch isn't empty, if it is, return the count.
                    if (0 == tbo.Count)
                    {
                        break;
                    }

                    // Execute the batch operations.
                    IList <TableResult> results = results = await table.ExecuteBatchAsync(tbo, tro, null, this._token);

                    if ((null != results) && (results.Count > 0))
                    {
                        int itemCount = 0, failureCount = 0;
                        foreach (TableResult result in results)
                        {
                            itemCount++;
                            if (false == ((HttpStatusCode)result.HttpStatusCode).IsSuccessCode())
                            {
                                failureCount++;
                            }
                        }

                        ServiceEventSource.Current.Trace($"Removed {itemCount - failureCount} of {itemCount} items from {table.Name}.");
                        count = itemCount - failureCount;
                    }
                }
                catch (StorageException ex)
                {
                    // ResourceNotFound is returned when one of the batch items isn't found. Need to remove it and try again.
                    if (ex.RequestInformation?.ExtendedErrorInformation?.ErrorCode.Contains("ResourceNotFound") ?? false)
                    {
                        // Get the index of the item within the batch.
                        if (false == int.TryParse(
                                ex.RequestInformation?.ExtendedErrorInformation?.ErrorMessage.Split(':')[0],
                                out int
                                index))
                        {
                            ServiceEventSource.Current.Trace("Unknown index, setting to 0", table.Name);
                            index = 0;
                        }

                        if (index < tbo.Count)
                        {
                            ServiceEventSource.Current.Trace($"StorageException: ResourceNotFound for item {index}", table.Name);
                            await Task.Delay(500);

                            tbo.RemoveAt(index);
                            retry--;
                        }
                        else
                        {
                            ServiceEventSource.Current.Trace("Abandoning batch.", table.Name);
                            break;
                        }
                    }
                    else
                    {
                        ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, ex.StackTrace);
                        break;
                    }
                }
            } while ((retry > 0) && (retry < maxRetryCount)); // Only retry if we hit a retryable exception or run out of retries.

            return(count);
        }