Skip to content

Commit

Permalink
Merge pull request #116 from naipath/invocationTimeout
Browse files Browse the repository at this point in the history
Enable function invocation timeout using Promise.race
  • Loading branch information
swyxio authored Feb 12, 2019
2 parents 6c9b4bf + 126d3d9 commit 520b908
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 9 deletions.
9 changes: 5 additions & 4 deletions bin/cmd.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,17 @@ program.version(pkg.version);
program
.option("-c --config <webpack-config>", "additional webpack configuration")
.option("-p --port <port>", "port to serve from (default: 9000)")
.option("-s --static", "serve pre-built lambda files")
.option("-t --timeout <timeout>", "function invocation timeout in seconds (default: 10)")
.option("-s --static", "serve pre-built lambda files");

program
.command("serve <dir>")
.description("serve and watch functions")
.action(function(cmd, options) {
console.log("netlify-lambda: Starting server");
var static = Boolean(program.static);
var server = serve.listen(program.port || 9000, static);
if (static) return // early terminate, don't build
var server = serve.listen(program.port || 9000, static, Number(program.timeout) || 10);
if (static) return; // early terminate, don't build
build.watch(cmd, program.config, function(err, stats) {
if (err) {
console.error(err);
Expand Down Expand Up @@ -75,4 +76,4 @@ var NO_COMMAND_SPECIFIED = program.args.length === 0;
if (NO_COMMAND_SPECIFIED) {
// user did not supply args, so show --help
program.help();
}
}
27 changes: 22 additions & 5 deletions lib/serve.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ function handleErr(err, response) {
return;
}

function handleInvocationTimeout(response, timeout) {
response.statusCode = 500;
response.write(`Function invocation took longer than ${timeout} seconds.`);
response.end();
console.log(
`Your lambda function took longer than ${timeout} seconds to finish.
If you need a longer execution time, you can increase the timeout using the -t or --timeout flag.
Please note that default function invocation is 10 seconds, check our documentation for more information (https://www.netlify.com/docs/functions/#custom-deployment-options).
`
);
}

function createCallback(response) {
return function callback(err, lambdaResponse) {
if (err) {
Expand Down Expand Up @@ -50,7 +62,7 @@ function promiseCallback(promise, callback) {
if (typeof promise.then !== 'function') return;
if (typeof callback !== 'function') return;

promise.then(
return promise.then(
function(data) {
callback(null, data);
},
Expand Down Expand Up @@ -80,7 +92,7 @@ function buildClientContext(headers) {
}
}

function createHandler(dir, static) {
function createHandler(dir, static, timeout) {
return function(request, response) {
// handle proxies without path re-writes (http-servr)
var cleanPath = request.path.replace(/^\/.netlify\/functions/, '');
Expand Down Expand Up @@ -123,11 +135,16 @@ function createHandler(dir, static) {
{ clientContext: buildClientContext(request.headers) || {} },
callback
);
promiseCallback(promise, callback);
Promise.race([
promiseCallback(promise, callback),
setTimeout(function() {
handleInvocationTimeout(response, timeout)
}, timeout * 1000)
])
};
}

exports.listen = function(port, static) {
exports.listen = function(port, static, timeout) {
var config = conf.load();
var app = express();
var dir = config.build.functions || config.build.Functions;
Expand All @@ -142,7 +159,7 @@ exports.listen = function(port, static) {
app.get('/favicon.ico', function(req, res) {
res.status(204).end();
});
app.all('*', createHandler(dir, static));
app.all('*', createHandler(dir, static, timeout));

app.listen(port, function(err) {
if (err) {
Expand Down

0 comments on commit 520b908

Please sign in to comment.