Reputation: 498
I'm trying to run a Lambda function from a console application. The idea is for it to run a quick fire & forget lambda function without waiting for lambda function to return. My code doesn't appear to be executing the lambda function at all though. I know the function works because I can run with the test. When I run the below code I just get a task cancelled exception.
var jsonSerializer = new JsonSerializer();
var lambdaConfig = new AmazonLambdaConfig() { RegionEndpoint = RegionEndpoint.USEast2 };
var lambdaClient = new AmazonLambdaClient(lambdaConfig);
using (var memoryStream = new MemoryStream())
{
jsonSerializer.Serialize(myData, memoryStream);
var lambdaRequest = new InvokeRequest
{
FunctionName = "MyFunction",
InvocationType = "Event",
PayloadStream = memoryStream
};
var result = Task.Run(async () => { return await lambdaClient.InvokeAsync(lambdaRequest); }).Result;
Does anyone have some insight into what I'm doing wrong?
Thanks!
Upvotes: 5
Views: 20456
Reputation: 1479
I believe there are two issues in your code:
memoryStream.Seek(0L, SeekOrigin.Begin)
By the way, assuming that JsonSerializer
is the one from Newtonsoft.Json package, I didn't find Serialize
method that accepts Stream
parameter, only TextWriter
or JsonWriter
. So it might be necessary to wrap it into StreamWriter
and make sure you call Flush
or FlushAsync
(or dispose StreamWriter
before using memory stream as Lambda payload) like this:
await using var stream = new MemoryStream();
await using var streamWriter = new StreamWriter(stream);
var serializer = new JsonSerializer();
serializer.Serialize(streamWriter, payload);
await streamWriter.FlushAsync();
stream.Seek(0L, SeekOrigin.Begin);
log.LogInformation("Batch {0}: sending {1} messages to Lambda", batchId, batch.Count);
var lambdaResponse = await lambda.InvokeAsync(new InvokeRequest
{
InvocationType = InvocationType.RequestResponse,
PayloadStream = stream,
//Payload = JsonConvert.SerializeObject(payload),
FunctionName = lambdaArn
}, stoppingToken);
Upvotes: 4
Reputation: 2104
You can pass your myData
directly instead converting into MemoryStream, if the data is a valid JSON with double quotes.
In function name you can use the ARN or just the name. Both works fine for me in latest version AWSSDK.Lambda -Version 3.3.103.31
static readonly string awsAccessKey = "access key here";
static readonly string awsSecretKey = "secret key here";
private static BasicAWSCredentials awsCredentials = new BasicAWSCredentials(awsAccessKey, awsSecretKey);
private static AmazonLambdaConfig lambdaConfig = new AmazonLambdaConfig() { RegionEndpoint = RegionEndpoint.USEast1 };
private static AmazonLambdaClient lambdaClient = new AmazonLambdaClient(awsCredentials, lambdaConfig);
public async Task<string> GetLambdaResponse(string myData)
{
var lambdaRequest = new InvokeRequest
{
FunctionName = "mylambdafunction",
Payload = myData
};
var response = await lambdaClient.InvokeAsync(lambdaRequest);
if (response != null)
{
using (var sr = new StreamReader(response.Payload))
{
return await sr.ReadToEndAsync();
}
}
return string.Empty;
}
Upvotes: 9
Reputation: 324
The FunctionName in Nkosi's answer should actually be the entire ARN to your lambda function, so taking from Nkosi's answer:
public static void Main(string[] args) {
var jsonSerializer = new JsonSerializer();
var lambdaConfig = new AmazonLambdaConfig() { RegionEndpoint = RegionEndpoint.USEast2 };
var lambdaClient = new AmazonLambdaClient(lambdaConfig);
var memoryStream = new MemoryStream();
jsonSerializer.Serialize(myData, memoryStream);
var lambdaRequest = new InvokeRequest
{
FunctionName = "arn:aws:lambda:ap-southeast-2:{id}:function:MyFunction",
InvocationType = "Event",
PayloadStream = memoryStream
};
lambdaClient.InvokeAsync(lambdaRequest);
Console.ReadLine();
Upvotes: 3
Reputation: 247561
Mixing blocking calls could be causing a deadlock. If the intent is to fire and for get then just call the desired function. Also why give request a stream only to dispose of it after wards
public static void Main(string[] args) {
var jsonSerializer = new JsonSerializer();
var lambdaConfig = new AmazonLambdaConfig() { RegionEndpoint = RegionEndpoint.USEast2 };
var lambdaClient = new AmazonLambdaClient(lambdaConfig);
var memoryStream = new MemoryStream();
jsonSerializer.Serialize(myData, memoryStream);
var lambdaRequest = new InvokeRequest
{
FunctionName = "MyFunction",
InvocationType = "Event",
PayloadStream = memoryStream
};
lambdaClient.InvokeAsync(lambdaRequest);
Console.ReadLine();
}
Upvotes: 3