Exemplo n.º 1
0
        private void DeleteEntityBatch(CloudTableClient client, List <TableEntity> entitiesToDelete)
        {
            var batchOperation = new TableBatchOperation();

            foreach (var entity in entitiesToDelete)
            {
                batchOperation.Add(TableOperation.Delete(entity));
            }

            // Save batched changes
            IList <TableResult> results = new TableResult[0];

            try
            {
                this.perfHelper.ExternalOperationBegin(
                    ExternalOperationTime.ExternalOperationType.TableDeletion,
                    0);
#if DotNetCoreClr
                results = client.GetTableReference(this.tableName).ExecuteBatchAsync(batchOperation).Result;
#else
                results = client.GetTableReference(this.tableName).ExecuteBatch(batchOperation);
#endif
                this.perfHelper.ExternalOperationEnd(
                    ExternalOperationTime.ExternalOperationType.TableDeletion,
                    0);
            }
            catch (Exception e)
            {
                AzureTableCommon.TableServiceExceptionAction action = AzureTableCommon.ProcessTableServiceRequestException(
                    this.traceSource,
                    this.logSourceId,
                    e,
                    AzureTableCommon.TableServiceAction.DeleteEntityBatch);
                if (AzureTableCommon.TableServiceExceptionAction.Abort == action)
                {
                    // Give up on this batch
                    return;
                }

                Debug.Assert(AzureTableCommon.TableServiceExceptionAction.ProcessResponse == action);
            }

            for (var idx = 0; idx < batchOperation.Count; idx++)
            {
                TableEntity entity = entitiesToDelete[idx];
                var         result = results[idx];

                if (Utility.IsNetworkError(result.HttpStatusCode))
                {
                    // We encountered a network error that wasn't resolved even
                    // after retries.
                    this.traceSource.WriteError(
                        this.logSourceId,
                        "Error {0} encountered when attempting to delete an entity from table storage. Entity information: {1},{2},{3}.",
                        results[idx],
                        entity.PartitionKey,
                        entity.RowKey,
                        entity.Timestamp);

                    throw new MaxRetriesException();
                }

                if (AzureTableCommon.HttpCodeResourceNotFound == result.HttpStatusCode)
                {
                    continue;
                }

                if (result.HttpStatusCode < AzureTableCommon.HttpSuccessCodeMin ||
                    result.HttpStatusCode > AzureTableCommon.HttpSuccessCodeMax)
                {
                    this.traceSource.WriteError(
                        this.logSourceId,
                        "FabricDCA encountered an error when attempting to delete an entity from table service. Error code: {0}. Entity information: {1},{2},{3}.",
                        result.HttpStatusCode,
                        entity.PartitionKey,
                        entity.RowKey,
                        entity.Timestamp);
                    return;
                }
            }
            this.perfHelper.BatchDeletedFromAzureTable((ulong)batchOperation.Count);
        }
Exemplo n.º 2
0
        private void QueryAndDeleteEntityBatch(CloudStorageAccount storageAccount, CloudTableClient tableServiceContext, DateTime cutoffTime, ref TableContinuationToken continuationToken)
        {
            TableContinuationToken initialContinuationToken = continuationToken;

            continuationToken = null;
            this.traceSource.WriteInfo(this.logSourceId, "Deleting table entries older than {0}.", cutoffTime);

            // Create a query object
            TableQuery <TableEntity> query = this.queryCreationMethod(cutoffTime);

            TableQuerySegment <TableEntity> resultSegment;

            try
            {
                this.perfHelper.ExternalOperationBegin(
                    ExternalOperationTime.ExternalOperationType.TableQuery,
                    0);

                // Execute the query
#if DotNetCoreClr
                resultSegment = tableServiceContext.GetTableReference(this.tableName).ExecuteQuerySegmentedAsync(query, initialContinuationToken).Result;
#else
                resultSegment = tableServiceContext.GetTableReference(this.tableName).ExecuteQuerySegmented(query, initialContinuationToken);
#endif

                this.perfHelper.ExternalOperationEnd(
                    ExternalOperationTime.ExternalOperationType.TableQuery,
                    0);
            }
            catch (Exception e)
            {
                AzureTableCommon.TableServiceExceptionAction action = AzureTableCommon.ProcessTableServiceQueryException(
                    this.traceSource,
                    this.logSourceId,
                    e,
                    AzureTableCommon.TableServiceAction.QueryEntitiesForDeletion);
                // Give up on this batch
                Debug.Assert(AzureTableCommon.TableServiceExceptionAction.Abort == action);
                return;
            }

            continuationToken = resultSegment.ContinuationToken;
            if (!resultSegment.Results.Any())
            {
                // Query did not give us any entities to delete. Nothing more to
                // be done here.
                return;
            }
            this.perfHelper.BatchQueriedFromAzureTable((ulong)resultSegment.Results.Count());

            // Create a table client
            CloudTableClient tableClient = AzureTableCommon.CreateNewTableClient(storageAccount);

            // Walk through the query results
            var    entitiesToDelete = new List <TableEntity>();
            string partitionKey     = String.Empty;
            foreach (var entity in resultSegment.Results)
            {
                // Azure table service requires all entities in a batched transaction to
                // have the same parition key. Hence if the partition key for this entity
                // is not the same as that of the entities we already added to the batch,
                // then delete those entities first and add this one to a new batch.
                if ((false == String.IsNullOrEmpty(partitionKey)) &&
                    (false == entity.PartitionKey.Equals(partitionKey)))
                {
                    DeleteEntityBatch(tableClient, entitiesToDelete);

                    // Clear for the next batch
                    entitiesToDelete.Clear();
                }

                // Record the partition key for the current batch
                partitionKey = entity.PartitionKey;

                entitiesToDelete.Add(entity);

                // If we have reached that maximum entity count for a batch, then
                // delete those entities.
                if (entitiesToDelete.Count == AzureTableCommon.MaxEntitiesInBatch)
                {
                    DeleteEntityBatch(tableClient, entitiesToDelete);

                    // Clear for the next batch
                    entitiesToDelete.Clear();
                }
            }

            if (entitiesToDelete.Any())
            {
                DeleteEntityBatch(tableClient, entitiesToDelete);
            }
        }