/// <summary> /// Read data entries and their corresponding eTags from the Azure table. /// </summary> /// <param name="filter">Filter string to use for querying the table and filtering the results.</param> /// <returns>Enumeration of entries in the table which match the query condition.</returns> public async Task <IEnumerable <Tuple <T, string> > > ReadTableEntriesAndEtagsAsync(string filter) { const string operation = "ReadTableEntriesAndEtags"; var startTime = DateTime.UtcNow; try { TableQuery <T> cloudTableQuery = filter == null ? new TableQuery <T>() : new TableQuery <T>().Where(filter); try { Func <Task <List <T> > > executeQueryHandleContinuations = async() => { TableQuerySegment <T> querySegment = null; var list = new List <T>(); //ExecuteSegmentedAsync not supported in "WindowsAzure.Storage": "7.2.1" yet while (querySegment == null || querySegment.ContinuationToken != null) { querySegment = await Table.ExecuteQuerySegmentedAsync(cloudTableQuery, querySegment?.ContinuationToken); list.AddRange(querySegment); } return(list); }; #if !ORLEANS_TRANSACTIONS IBackoffProvider backoff = new FixedBackoff(this.StoragePolicyOptions.PauseBetweenOperationRetries); List <T> results = await AsyncExecutorWithRetries.ExecuteWithRetries( counter => executeQueryHandleContinuations(), this.StoragePolicyOptions.MaxOperationRetries, (exc, counter) => AzureTableUtils.AnalyzeReadException(exc.GetBaseException(), counter, TableName, Logger), this.StoragePolicyOptions.OperationTimeout, backoff); #else List <T> results = await executeQueryHandleContinuations(); #endif // Data was read successfully if we got to here return(results.Select(i => Tuple.Create(i, i.ETag)).ToList()); } catch (Exception exc) { // Out of retries... var errorMsg = $"Failed to read Azure storage table {TableName}: {exc.Message}"; if (!AzureTableUtils.TableStorageDataNotFound(exc)) { Logger.Warn((int)Utilities.ErrorCode.AzureTable_09, errorMsg, exc); } throw new OrleansException(errorMsg, exc); } } finally { CheckAlertSlowAccess(startTime, operation); } }
/// <summary> /// Read a single table entry from the storage table. /// </summary> /// <param name="partitionKey">The partition key for the entry.</param> /// <param name="rowKey">The row key for the entry.</param> /// <returns>Value promise for tuple containing the data entry and its corresponding etag.</returns> public async Task <Tuple <T, string> > ReadSingleTableEntryAsync(string partitionKey, string rowKey) { const string operation = "ReadSingleTableEntryAsync"; var startTime = DateTime.UtcNow; if (Logger.IsEnabled(LogLevel.Trace)) { Logger.Trace("{0} table {1} partitionKey {2} rowKey = {3}", operation, TableName, partitionKey, rowKey); } T retrievedResult = default(T); try { try { string queryString = TableQueryFilterBuilder.MatchPartitionKeyAndRowKeyFilter(partitionKey, rowKey); var query = new TableQuery <T>().Where(queryString); TableQuerySegment <T> segment = await Table.ExecuteQuerySegmentedAsync(query, null); retrievedResult = segment.Results.SingleOrDefault(); } catch (StorageException exception) { if (!AzureTableUtils.TableStorageDataNotFound(exception)) { throw; } } //The ETag of data is needed in further operations. if (retrievedResult != null) { return(new Tuple <T, string>(retrievedResult, retrievedResult.ETag)); } if (Logger.IsEnabled(LogLevel.Debug)) { Logger.Debug("Could not find table entry for PartitionKey={0} RowKey={1}", partitionKey, rowKey); } return(null); // No data } finally { CheckAlertSlowAccess(startTime, operation); } }
public async Task <GrainStateRecord> Read(string partitionKey, string rowKey) { if (logger.IsEnabled(LogLevel.Trace)) { logger.Trace((int)AzureProviderErrorCode.AzureTableProvider_Storage_Reading, "Reading: PartitionKey={0} RowKey={1} from Table={2}", partitionKey, rowKey, TableName); } try { Tuple <DynamicTableEntity, string> data = await tableManager.ReadSingleTableEntryAsync(partitionKey, rowKey).ConfigureAwait(false); if (data == null || data.Item1 == null) { if (logger.IsEnabled(LogLevel.Trace)) { logger.Trace((int)AzureProviderErrorCode.AzureTableProvider_DataNotFound, "DataNotFound reading: PartitionKey={0} RowKey={1} from Table={2}", partitionKey, rowKey, TableName); } return(null); } DynamicTableEntity stateEntity = data.Item1; var record = new GrainStateRecord { Entity = stateEntity, ETag = data.Item2 }; if (logger.IsEnabled(LogLevel.Trace)) { logger.Trace((int)AzureProviderErrorCode.AzureTableProvider_Storage_DataRead, "Read: PartitionKey={0} RowKey={1} from Table={2} with ETag={3}", stateEntity.PartitionKey, stateEntity.RowKey, TableName, record.ETag); } return(record); } catch (Exception exc) { if (AzureTableUtils.TableStorageDataNotFound(exc)) { if (logger.IsEnabled(LogLevel.Trace)) { logger.Trace((int)AzureProviderErrorCode.AzureTableProvider_DataNotFound, "DataNotFound reading (exception): PartitionKey={0} RowKey={1} from Table={2} Exception={3}", partitionKey, rowKey, TableName, LogFormatter.PrintException(exc)); } return(null); // No data } throw; } }