Reputation: 3435
I want to make a function that calls an API (third party) and returns immediately, but it is waiting for API response.
Here is the code sample:
var request = require('request');
// When I call functionOne it should trigger functionTwo and should end immediately,
// but unfortunately, it is waiting for functionTwo to end
module.exports.functionOne = (event, context, cb) => {
const uri = 'https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/functionTwo';
request.post({ uri: uri });
cb(null, "done functionOne");
};
module.exports.functionTwo = (event, context, cb) => {
console.log("i'm functionTwo");
setTimeout(function () {
console.log("I'm functionTwo about to end");
context.succeed("done functionTwo");
}, 5000);
};
Moreover, if i try to call context.succeed()
instead of cb()
, it even prevent API call and function return immediately without calling the API.
I have also created an issue on GitHub.
Additional info:
Upvotes: 3
Views: 1821
Reputation: 83
In your handler you can use flag callbackWaitsForEmptyEventLoop = false
module.exports.functionOne = (event, context, cb) => {
context.callbackWaitsForEmptyEventLoop = false
const uri = 'https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/functionTwo';
request.post({ uri: uri });
cb(null, "done functionOne");
};
Upvotes: 0
Reputation: 30760
Sorry, but you can't achieve what you want, at least not in this way.
When you call another function using request.post()
, you must provide a callback and you must wait for it to finish.
What you could do is to call request.abort()
, but this is a hacky solution.
module.exports.functionOne = (event, context, cb) => {
const uri = 'https://xxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/functionTwo';
const r = request.post({ uri: uri }, (error, response, body) => {
cb(error, "done functionOne");
});
r.abort();
cb(null, 'forced abort on functionOne');
};
Why is this hacky? Because you can't abort immediately. You need to wait a few milliseconds for the request to be received in the other server, but there is no way to know exactly when it happens.
If you know that the second Lambda will run for 2 minutes, you could add a setTimeout
function to abort the request after 5 seconds and avoid having the functionOne
running for a long time in a idle state. But again, this is a bad solution.
Why don't you place the functionTwo
code inside functionOne
to avoid starting a second Lambda?
Another workaround would be to call a SNS topic from functionOne
and configure this topic to trigger functionTwo
.
Upvotes: 3