Skip to content

Commit 6762977

Browse files
Improved resource handling in DynamoDBRepository.ScanAsync
1 parent 0caa565 commit 6762977

File tree

2 files changed

+48
-29
lines changed

2 files changed

+48
-29
lines changed

GuiStack/Models/DynamoDBItem.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ protected virtual void Dispose(bool disposing)
8686

8787
// Free unmanaged resources
8888
// Set large fields to null
89+
Attributes = null;
8990

9091
disposedValue = true;
9192
}

GuiStack/Repositories/IDynamoDBRepository.cs

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* This Source Code Form is subject to the terms of the Mozilla Public
33
* License, v. 2.0. If a copy of the MPL was not distributed with this
44
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
@@ -82,7 +82,7 @@ public async Task<string[]> GetTablesAsync()
8282
public async Task<DynamoDBTableModel> GetTableInfoAsync(string tableName)
8383
{
8484
if(string.IsNullOrWhiteSpace(tableName))
85-
throw new ArgumentNullException(nameof(tableName));
85+
throw new ArgumentException("Table name cannot be empty", nameof(tableName));
8686

8787
using var dynamodb = authenticator.Authenticate();
8888
var response = await dynamodb.DescribeTableAsync(tableName);
@@ -122,7 +122,7 @@ public async Task<DynamoDBTableModel> GetTableInfoAsync(string tableName)
122122
public async Task DeleteTableAsync(string tableName)
123123
{
124124
if(string.IsNullOrWhiteSpace(tableName))
125-
throw new ArgumentNullException(nameof(tableName));
125+
throw new ArgumentException("Table name cannot be empty", nameof(tableName));
126126

127127
using var dynamodb = authenticator.Authenticate();
128128
var response = await dynamodb.DeleteTableAsync(tableName);
@@ -133,7 +133,10 @@ public async Task DeleteTableAsync(string tableName)
133133
public async Task PutItemAsync(string tableName, IDictionary<string, DynamoDBFieldModel> itemData)
134134
{
135135
if(string.IsNullOrWhiteSpace(tableName))
136-
throw new ArgumentNullException(nameof(tableName));
136+
throw new ArgumentException("Table name cannot be empty", nameof(tableName));
137+
138+
if(itemData == null)
139+
throw new ArgumentNullException(nameof(itemData));
137140

138141
using var dynamodb = authenticator.Authenticate();
139142
using var item = itemData.ToDynamoDBItem();
@@ -149,42 +152,57 @@ public async Task PutItemAsync(string tableName, IDictionary<string, DynamoDBFie
149152
public async Task<DynamoDBTableScanResults> ScanAsync(string tableName, int limit, DynamoDBItemModel lastEvaluatedKey = null)
150153
{
151154
if(string.IsNullOrWhiteSpace(tableName))
152-
throw new ArgumentNullException(nameof(tableName));
155+
throw new ArgumentException("Table name cannot be empty", nameof(tableName));
153156

154157
if(limit < 1 || limit > 500)
155158
throw new ArgumentOutOfRangeException(nameof(limit), limit, "Item limit must be between 1 and 500");
156159

157160
using var dynamodb = authenticator.Authenticate();
158161

159162
List<Dictionary<string, AttributeValue>> items = new();
160-
Dictionary<string, AttributeValue> lastEvalKey = lastEvaluatedKey?.ToDynamoDBItem().Attributes;
163+
DynamoDBItem lastEvalKey = lastEvaluatedKey?.ToDynamoDBItem();
161164

162-
while(items.Count < limit)
165+
try
163166
{
164-
var result = await dynamodb.ScanAsync(new ScanRequest() {
165-
TableName = tableName,
166-
ConsistentRead = true,
167-
Select = Select.ALL_ATTRIBUTES,
168-
ReturnConsumedCapacity = ReturnConsumedCapacity.NONE,
169-
ExclusiveStartKey = lastEvalKey,
170-
Limit = limit
171-
});
172-
173-
result.ThrowIfUnsuccessful("DynamoDB");
174-
result.Items.ForEach(item => items.Add(item));
175-
176-
lastEvalKey = result.LastEvaluatedKey;
177-
178-
if(lastEvalKey == null || lastEvalKey.Count <= 0)
179-
break; // No more items in result
167+
while(items.Count < limit)
168+
{
169+
var result = await dynamodb.ScanAsync(new ScanRequest() {
170+
TableName = tableName,
171+
ConsistentRead = true,
172+
Select = Select.ALL_ATTRIBUTES,
173+
ReturnConsumedCapacity = ReturnConsumedCapacity.NONE,
174+
ExclusiveStartKey = lastEvalKey?.Attributes,
175+
Limit = limit
176+
});
177+
178+
result.ThrowIfUnsuccessful("DynamoDB");
179+
result.Items.ForEach(item => items.Add(item));
180+
181+
lastEvalKey?.Dispose();
182+
lastEvalKey = result.LastEvaluatedKey != null
183+
? new DynamoDBItem() { Attributes = result.LastEvaluatedKey }
184+
: null;
185+
186+
if(lastEvalKey == null || lastEvalKey.Attributes.Count <= 0)
187+
break; // No more items in result
188+
}
189+
190+
return new DynamoDBTableScanResults() {
191+
Items = items.Select(item => item.ToDynamoDBItemModel()).ToArray(),
192+
LastEvaluatedKey = lastEvalKey != null && lastEvalKey.Attributes.Count > 0
193+
? lastEvalKey.Attributes.ToDynamoDBItemModel()
194+
: null
195+
};
180196
}
197+
finally
198+
{
199+
lastEvalKey?.Dispose();
181200

182-
return new DynamoDBTableScanResults() {
183-
Items = items.Select(item => item.ToDynamoDBItemModel()).ToArray(),
184-
LastEvaluatedKey = lastEvalKey != null && lastEvalKey.Count > 0
185-
? lastEvalKey.ToDynamoDBItemModel()
186-
: null
187-
};
201+
foreach (var item in items)
202+
{
203+
new DynamoDBItem() { Attributes = item }.Dispose();
204+
}
205+
}
188206
}
189207
}
190208
}

0 commit comments

Comments
 (0)