Пример #1
0
        //--- Methods ---
        private void PrepareRequest(bool fetchAllAttributes)
        {
            // inherit the expected types from the query select construct
            foreach (var expectedType in _queryClause.TypeFilters)
            {
                _converter.AddExpectedType(expectedType);
            }

            // initialize request
            _request.IndexName = _queryClause.IndexName;
            _request.KeyConditionExpression = _queryClause.GetKeyConditionExpression(_converter);
            _request.FilterExpression       = _converter.ConvertConditions(_table.Options);
            _request.ProjectionExpression   = _converter.ConvertProjections();

            // NOTE (2021-06-23, bjorg): the following logic matches the default behavior, but makes it explicit
            // if `ProjectionExpression` is set, only return specified attributes; otherwise, for an index, return projected attributes only; for tables, return all attributes from each row
            if (_request.ProjectionExpression is null)
            {
                if ((_request.IndexName is null) || fetchAllAttributes)
                {
                    _request.Select = Select.ALL_ATTRIBUTES;
                }
                else
                {
                    _request.Select = Select.ALL_PROJECTED_ATTRIBUTES;
                }
            }
Пример #2
0
        public async Task <TRecord?> ExecuteAsync(CancellationToken cancellationToken)
        {
            _request.ProjectionExpression = _converter.ConvertProjections();
            var response = await _table.DynamoClient.GetItemAsync(_request, cancellationToken);

            return(response.IsItemSet
                ? _table.DeserializeItem <TRecord>(response.Item)
                : null);
        }
        public async Task <IEnumerable <TRecord> > ExecuteAsync(int maxAttempts, CancellationToken cancellationToken = default)
        {
            var requestTableAndKeys = _request.RequestItems.First();

            requestTableAndKeys.Value.ProjectionExpression = _converter.ConvertProjections();

            // NOTE (2021-06-30, bjorg): batch operations may run out of capacity/bandwidth and may have to be completed in batches themselves
            var result   = new List <TRecord>();
            var attempts = 1;

            do
            {
                try {
                    var response = await _table.DynamoClient.BatchGetItemAsync(_request, cancellationToken);

                    if (response.Responses.Any())
                    {
                        foreach (var item in response.Responses.Single().Value)
                        {
                            var record = _table.DeserializeItem <TRecord>(item);
                            if (!(record is null))
                            {
                                result.Add(record);
                            }
                        }
                    }

                    // check if all requested primary keys were processed
                    if (!response.UnprocessedKeys.Any())
                    {
                        break;
                    }

                    // repeat request with unprocessed primary keys
                    requestTableAndKeys.Value.Keys = response.UnprocessedKeys.First().Value.Keys;
                } catch (ProvisionedThroughputExceededException) {
                    // NOTE (2021-06-30, bjorg): not a single item could be returned due to insufficient read capacity
                }

                // use exponential backoff before attempting next operation
                if (attempts >= maxAttempts)
                {
                    throw new DynamoTableBatchGetItemsMaxAttemptsExceededException(result);
                }
                await Task.Delay(TimeSpan.FromMilliseconds(MILLISECOND_BACKOFF << (attempts++ - 1)));
            } while(true);
            return(result);
        }