0

My goal is to Trigger a lambda from another lambda, and I am getting stuck because the 2nd lambda never gets started.

public async Task<bool> CallLambda(string functionName)
{
  var request = new InvokeRequest
  {
    FunctionName = functionName + ":" + LAMBDA_ENVIROMENT,
    InvocationType = InvocationType.RequestResponse,
    Payload = ""
  };

    LambdaLogger.Log("Trigger lambda " + request.FunctionName);
    var lambdaClient = new AmazonLambdaClient();
    await lambdaClient.InvokeAsync(request);
    LambdaLogger.Log("Trigger Done ");

    return true;
}

And here is the Lambda function that needs to be triggered

public const string NAME = LAMBDA_BASENAME + "DeleteHandler";

[Cloudformation4dotNET.Lambda.LambdaResourceProperties(TimeoutInSeconds = 900)]
public void DeleteHandler()
{
   Logger.Log(string.Format("Data from the model " + AnaplanIDs.modelId + "has been deleted"));
   ...
}

When executing the 1rst lambda, the output I am getting is: enter image description here

We can see that it calls the correct lambda name, and it never prints the LambdaLogger.Log("Trigger Done "); and the DeleteHandler never get started

4
  • are you sure you are calling the correct function? I'm looking at some code where i've done this and what you are doing looks correct. Here is my example code if you wish to review it: github.com/mrcunninghamz/hi-command/blob/master/… Commented Jun 9, 2020 at 22:05
  • 1
    also, small code optimization... but you should really use string interpolation... example: var functionToCall = $"{functionName}:{LAMBDA_ENVIROMENT}"; you should then log that value. Commented Jun 9, 2020 at 22:09
  • Yes, I have doublechecked the name I hardcoded and I also had tried with the ARN. Commented Jun 10, 2020 at 8:53
  • 1
    I would try to change the InvocationType.RequestResponse to InvocationType.Event also your function method, try changing it to async Task instead of void. Commented Jun 11, 2020 at 12:25

1 Answer 1

1

The problem was that I have not been waiting for the call to be completed. I had

var response = callLambda.CallLambdaAsync(lambdaPayload);

When calling the function that invokes the Lambda, I have solved it by adding it .Result at the end

var response = callLambda.CallLambdaAsync(lambdaPayload).Result;

I tried InvocationType.Event instead of InvocationType.RequestResponse but that was not enough. I have learned that the difference between them is:

  • InvocationType.RequestResponse the current Lambda waits until the invoke lambda is finalized.
  • InvocationType.Event the current Lambda invokes the new one and continue.

Personally, I consider .Event is a better solution in this case since it needs a new lambda to be triggered when the current one finalized—moreover, having a Lambda waiting for another Lambda are not elegant solutions.

Sign up to request clarification or add additional context in comments.

3 Comments

I try to avoid .Result as much as possible, but if you can't async the method, that's all you got. Glad you figured it out!
Thanks, @KarlMerecido for your input, is there any reason why? and would you suggest any alternative in this case?
from my understanding it forces your command to run synchronously. In something I ran into when actually building out async processes is that when you start using it, to be safe you need to go async all the way otherwise you run into the possibility of deadlocks. in the case of a lambda i can see you can't avoid .Result, but here is a reference.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.