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

Socket connections requires set context.callbackWaitsForEmptyEventLoop to false #426

Open
hugosenari opened this issue Nov 26, 2019 · 3 comments

Comments

@hugosenari
Copy link
Contributor

Describe the bug
When my code leaves one open connection (ie: with some DBs), AWS Lambda throws timeout, even after my function run.

To Reproduce
Make any code that uses socket connections (ie: MySQL, Mongodb...);
Resolves function with some value;
And leaves that connection open for the next lambda function call.

Expected behavior
Since using promise to resolve function without laconia doesn't trows timeout.
I would expect the same with it.

Actual behavior
AWS Lambda throws timeout, even after my function resolves.

Additional context
Correct behavior (#48) would break laconia/batch and maybe others user cases

#415 aimed to solve this without contract breaks

@hugosenari
Copy link
Contributor Author

Break API

Pros:

Cons:

  • User upgrade may be more difficult;
  • Require rewrite laconia/batch;

Create another entrypoint

Pros:

  • Easy migration;
  • Left some way to use sync version (ie: laconia/batch);

Cons:

  • More code to deal;
  • More boilerplate;
  • Will not solve problem for adapters (ie: laconia/api, laconia/adapter)

@ceilfors
Copy link
Collaborator

ceilfors commented Nov 27, 2019

Great description @hugosenari.

I have a doubt on the expected behaviour, where you mention:

Since using promise to resolve function without laconia doesn't trows timeout. I would expect the same with it.

In my experience, whenever I open up a socket connection, even without Laconia, I will need to set callbackWaitsForEmptyEventLoop to false, especially if I want to freeze the connection. See also this comment, or this post. Otherwise, it will timeout, which is the expected behaviour from AWS Lambda.

@hugosenari
Copy link
Contributor Author

Almost one year later... sorry :)

Here goes my tests results.

Promise + Connection = Success

REPORT RequestId: e6293e658730
Duration: 10.96 ms
Billed Duration: 100 ms
Memory Size: 128 MB
Max Memory Used: 64 MB
Init Duration: 128.88 ms	

Callback - Connection = Success

REPORT RequestId: 322aebe37100	
Duration: 16.49 ms	
Billed Duration: 100 ms	
Memory Size: 128 MB	
Max Memory Used: 63 MB	
Init Duration: 126.88 ms	

Callback + Connection = Timeout:

REPORT RequestId: dae829af27b9	
Duration: 3003.14 ms	
Billed Duration: 3000 ms	
Memory Size: 128 MB	
Max Memory Used: 14 MB	
2020-06-17T02:26:29.143Z dae829af27b9 Task timed out after 3.00 seconds

Promise Code:

const net = require('net');
const client = net.createConnection(53, '1.1.1.1');
console.log('connecting');
exports.handler = async (event) => {
    const response = await {
        statusCode: 200,
        body: JSON.stringify(`
            Hello from Lambda!
            ${client.destroyed}
            ${client.remoteAddress}
            ${client.write('olar')}
        `),
    };
    console.log(response.body);
    return response;
};

Callback Code:

const net = require('net');
const client = net.createConnection(53, '1.1.1.1');
console.log('connecting');
exports.handler = (event, ctx, cb) => {
    const response = {
        statusCode: 200,
        body: JSON.stringify(`
            Hello from Lambda!
            ${client.destroyed}
            ${client.remoteAddress}
            ${client.write('olar')}
        `),
    };
    console.log(response.body);
    return cb(null, response);
};

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

No branches or pull requests

2 participants