public static async Task AddEventSourceAsync() { #region add_dynamodb_event_source using (var streamClient = new AmazonDynamoDBStreamsClient()) using (var lambdaClient = new AmazonLambdaClient()) { // TODO: Enter Lambda function name, this is most likely: ServerlessTODOListStreamProcessor var functionName = ""; if (string.IsNullOrEmpty(functionName)) { Console.Error.WriteLine("You must set the name of the Lambda function you deployed to the \"functionName\" variable"); return; } var listRequest = new ListStreamsRequest { TableName = "TODOList" }; var listResponse = await streamClient.ListStreamsAsync(listRequest); if (listResponse.Streams.Count == 0) { Console.Error.WriteLine($"A stream is not enabled for the table {listRequest.TableName}"); return; } var streamArn = listResponse.Streams[0].StreamArn; Console.WriteLine($"Stream ARN is {streamArn}"); var request = new CreateEventSourceMappingRequest { FunctionName = functionName, EventSourceArn = streamArn, StartingPosition = EventSourcePosition.LATEST, BatchSize = 100 }; await lambdaClient.CreateEventSourceMappingAsync(request); Console.WriteLine($"Event source mapping made between stream {streamArn} and function {functionName}"); } #endregion }
public static async Task TestStreamAsync() { var config = new DynamoDBContextConfig { Conversion = DynamoDBEntryConversion.V2, ConsistentRead = true }; var Context = new DynamoDBContext(new AmazonDynamoDBClient()); #region test_stream_read // Save list to table var list = new TODOList { User = "******", ListId = Guid.NewGuid().ToString(), Complete = false, Name = "StreamTest", CreateDate = DateTime.UtcNow, UpdateDate = DateTime.UtcNow, Items = new List <TODOListItem> { new TODOListItem { Description = "Task1", Complete = true }, new TODOListItem { Description = "Task2", Complete = false } } }; await Context.SaveAsync(list); using (var streamClient = new AmazonDynamoDBStreamsClient()) { // Function for reading records continuously from a shard. Func <string, CancellationToken, Task> shardReader = async(iterator, token) => { while (!token.IsCancellationRequested) { var response = (await streamClient.GetRecordsAsync(new GetRecordsRequest { ShardIterator = iterator })); // Update position in shard iterator iterator = response.NextShardIterator; // This is what you would write in a Lambda function processing DynamoDB Streams. foreach (var record in response.Records) { var newVersion = record.Dynamodb.NewImage; Console.WriteLine($"Item read: {newVersion["User"].S}/{newVersion["ListId"].S}"); } } }; // Find the arn for the DynamoDB Stream var streamArn = (await streamClient.ListStreamsAsync(new ListStreamsRequest { TableName = "TODOList" })) .Streams.FirstOrDefault()?.StreamArn; Console.WriteLine($"The stream arn is {streamArn} shards"); // A stream is made of shards. var shards = (await streamClient.DescribeStreamAsync(new DescribeStreamRequest { StreamArn = streamArn })) .StreamDescription.Shards; Console.WriteLine($"The stream currently has {shards.Count} shards"); // Execute a separate reader for each shard. var cancelSource = new CancellationTokenSource(); var readerTasks = new Task[shards.Count]; for (int i = 0; i < readerTasks.Length; i++) { var shardIteratorRequest = new GetShardIteratorRequest { StreamArn = streamArn, ShardId = shards[i].ShardId, ShardIteratorType = ShardIteratorType.TRIM_HORIZON }; var shardIterator = (await streamClient.GetShardIteratorAsync(shardIteratorRequest)) .ShardIterator; Console.WriteLine($"Shard Iterator {i}: {shardIterator}"); readerTasks[i] = shardReader(shardIterator, cancelSource.Token); } Task.WaitAll(readerTasks, TimeSpan.FromSeconds(5)); cancelSource.Cancel(); } #endregion }