Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test execution continues even after lambda callback is called. #31

Closed
nikhilkakade2108 opened this issue Apr 3, 2018 · 7 comments
Closed

Comments

@nikhilkakade2108
Copy link

my lambda handler function-

exports.handler = async function(event, context, callback) {
    context.callbackWaitsForEmptyEventLoop = false;
    var headers = event.headers;
    var xOdmBusinessUnit = headers["x-odm-business-unit"];

    if (xOdmBusinessUnit == null || typeof xOdmBusinessUnit == 'undefined') {
        console.log("inside if..");
        callback("header must present",null);
    }
        console.log("outside if..");
        callback(null,"success");
};

unit test function

var expect = require('chai').expect;

var LambdaTester = require('lambda-tester').noVersionCheck();
//var tokenGenerationLambda = require('../lambda/customauthorizer/TokenGeneration');
var testLambda = require('../lambda/customauthorizer/Test');

describe('TokenGenerationTest', function () {

    it('successful invocation',
        function () {
            this.timeout(15000);

            return LambdaTester(testLambda.handler)
                .event({ "headers": { "x-odm-authorization-id": "testapp1" } })
                .expectError();

        });
});

When I run it with mocha.
Result-

  TokenGenerationTest
inside if..
outside if..
    √ successful invocation


  1 passing (41ms)

You can see, it has printed both console.log statements here. If it is going in if block then callback() inside if must have got called. Ideally code execution should return from this point, but it is going further and executing 2nd console.log statement.

@clocked0ne
Copy link

You have no return before / after the callback so both callbacks are called, it's not an issue with this package

@nikhilkakade2108
Copy link
Author

image
As per aws documentation, callback() will return to user. So no need to write explicit return statement.

@clocked0ne
Copy link

clocked0ne commented Apr 3, 2018

It will return data implicitly either way to the caller, but as it states it will still continue the Lambda function execution until the event loop is empty, i.e. your if statement with no return will finish and it will continue to the next line, executing your console.log.

@richardhyatt
Copy link
Contributor

@clocked0ne is correct and referenced documentation states this in the last line. Closing.

@nikhilkakade2108
Copy link
Author

@clocked0ne @richardhyatt if you check the lambda handler, I have added context.callbackWaitsForEmptyEventLoop = false; This will not wait for event loop to be emptied and will immediately return once callback gets called. This will not continue execution of lambda until event loop gets emptied. I am not saying that it is a lambda-tester library issue, but just want to understand the working of it.
Your inputs will be helpful. Thanks.

@clocked0ne
Copy link

clocked0ne commented Apr 4, 2018

Hi @nikhilkakade2108

callbackWaitsForEmptyEventLoop

The default value is true. This property is useful only to modify the default behavior of the callback.
By default, the callback will wait until the event loop is empty before freezing the process and returning the results to the caller.
You can set this property to false to request AWS Lambda to freeze the process soon after the callback is called, even if there are events in the event loop.
AWS Lambda will freeze the process, any state data and the events in the event loop (any remaining events in the event loop processed when the Lambda function is called next and if AWS Lambda chooses to use the frozen process).
For more information about callback, see Using the Callback Parameter.

In addition, the context object provides the following properties that you can use obtain runtime information

I think the key part here is "freeze the process soon after the callback is called, even if there are events in the event loop." - it does not guarantee a return from the callback straight away, you still have an arbitrary amount of time before the execution is finalised and the value returned to the caller, probably plenty of time to finish your function.

Personally I would not set callbackWaitsForEmptyEventLoop to false unless you have a specific use case for doing so (such as re-using an open MongoDB connection) as Lambda re-uses this process for subsequent events. Instead, rely on your functions returning correctly (which is the right thing to do anywhere in javascript land).

@nikhilkakade2108
Copy link
Author

@clocked0ne
We faced lambda timeout issues, hence made callbackWaitsForEmptyEventLoop false(not a good practice).
Thanks for the convincing answer. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants