2
\$\begingroup\$

I am a beginner and trying to send data from AWS DynamoDB to Azure Queues. Note that this code will be invoked 10,000 and alot more. Can you guys review it once.

using System;
using System.IO;
using System.Text;

using Newtonsoft.Json;

using Amazon.Lambda.Core;
using Amazon.Lambda.DynamoDBEvents;
using Amazon.DynamoDBv2.Model;
using Microsoft.Azure.ServiceBus;
using System.Threading.Tasks;

    // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
    [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))]

namespace Lambda
{
    public class Function
    {
        private static readonly JsonSerializer _jsonSerializer = new JsonSerializer();

        public async Task FunctionHandler(DynamoDBEvent dynamoEvent, ILambdaContext context)
        {
            context.Logger.LogLine($"Beginning to process {dynamoEvent.Records.Count} records...");

            foreach (var record in dynamoEvent.Records)
            {
                context.Logger.LogLine($"Event ID: {record.EventID}");
                context.Logger.LogLine($"Event Name: {record.EventName}");

                string streamRecordJson = SerializeStreamRecord(record.Dynamodb);
                await Send(streamRecordJson);
                context.Logger.LogLine($"DynamoDB Record:");
                context.Logger.LogLine(streamRecordJson );
            }

            context.Logger.LogLine("Stream processing complete.");
        }

        private static async Task Send(string stream)
        {
            const string connectionString = "QUEUE END POINT";
            string queueName = "QUEUE NAME";
            ServiceBusConnectionStringBuilder svc = new ServiceBusConnectionStringBuilder(connectionString);
            ServiceBusConnection svc1 = new ServiceBusConnection(svc);
            var client = new QueueClient(svc1, queueName, ReceiveMode.PeekLock, RetryPolicy.Default);
            var message = new Message(Encoding.UTF8.GetBytes(stream));
            await client.SendAsync(message);
        }

        private string SerializeStreamRecord(StreamRecord streamRecord)
        {
            using (var writer = new StringWriter())
            {
                _jsonSerializer.Serialize(writer, streamRecord);
                return writer.ToString();
            }
        }
    }
}
\$\endgroup\$
2
\$\begingroup\$

If the connection and queue name are not changing per record then there is no reason to be creating a new client for each record in the loop. Especially for the amount of times stated in the original post.

Move that to the constructor of the class.

public class Function {
    private static readonly JsonSerializer _jsonSerializer = new JsonSerializer();
    private readonly IQueueClient client;
    private const string connectionString = "QUEUE END POINT";
    private const string queueName = "QUEUE NAME";

    public Function() {            
        ServiceBusConnectionStringBuilder builder = new ServiceBusConnectionStringBuilder(connectionString);
        ServiceBusConnection connection = new ServiceBusConnection(builder);
        client = new QueueClient(connection, queueName, ReceiveMode.PeekLock, RetryPolicy.Default);
    }

    public async Task FunctionHandler(DynamoDBEvent dynamoEvent, ILambdaContext context) {
        var logger = context.Logger;
        logger.LogLine($"Beginning to process {dynamoEvent.Records.Count} records...");

        foreach (var record in dynamoEvent.Records) {
            logger.LogLine($"Event ID: {record.EventID}");
            logger.LogLine($"Event Name: {record.EventName}");

            string streamRecordJson = SerializeStreamRecord(record.Dynamodb);
            await SendAsync(streamRecordJson);

            logger.LogLine($"DynamoDB Record:");
            logger.LogLine(streamRecordJson);
        }

        context.Logger.LogLine("Stream processing complete.");
    }

    private Task SendAsync(string body) {
        var message = new Message(Encoding.UTF8.GetBytes(body));
        return client.SendAsync(message);
    }

    private string SerializeStreamRecord(StreamRecord streamRecord) {
        using (var writer = new StringWriter()) {
            _jsonSerializer.Serialize(writer, streamRecord);
            return writer.ToString();
        }
    }
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Do you think I should make the azure client static? Or doing that will create issues? \$\endgroup\$ – Unbreakable Mar 30 at 0:42
  • \$\begingroup\$ @Unbreakable I that case you would need to make the function constructor static as well to avoid overrides but I do not see that as being an issue. \$\endgroup\$ – Nkosi Mar 30 at 0:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.