Skip to content

Commit 126d3d9

Browse files
author
tvs
committed
Enable function invocation timeout using Promise.race
1 parent b63734e commit 126d3d9

File tree

2 files changed

+27
-9
lines changed

2 files changed

+27
-9
lines changed

bin/cmd.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,17 @@ program.version(pkg.version);
1818
program
1919
.option("-c --config <webpack-config>", "additional webpack configuration")
2020
.option("-p --port <port>", "port to serve from (default: 9000)")
21-
.option("-s --static", "serve pre-built lambda files")
21+
.option("-t --timeout <timeout>", "function invocation timeout in seconds (default: 10)")
22+
.option("-s --static", "serve pre-built lambda files");
2223

2324
program
2425
.command("serve <dir>")
2526
.description("serve and watch functions")
2627
.action(function(cmd, options) {
2728
console.log("netlify-lambda: Starting server");
2829
var static = Boolean(program.static);
29-
var server = serve.listen(program.port || 9000, static);
30-
if (static) return // early terminate, don't build
30+
var server = serve.listen(program.port || 9000, static, Number(program.timeout) || 10);
31+
if (static) return; // early terminate, don't build
3132
build.watch(cmd, program.config, function(err, stats) {
3233
if (err) {
3334
console.error(err);
@@ -75,4 +76,4 @@ var NO_COMMAND_SPECIFIED = program.args.length === 0;
7576
if (NO_COMMAND_SPECIFIED) {
7677
// user did not supply args, so show --help
7778
program.help();
78-
}
79+
}

lib/serve.js

+22-5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,18 @@ function handleErr(err, response) {
1414
return;
1515
}
1616

17+
function handleInvocationTimeout(response, timeout) {
18+
response.statusCode = 500;
19+
response.write(`Function invocation took longer than ${timeout} seconds.`);
20+
response.end();
21+
console.log(
22+
`Your lambda function took longer than ${timeout} seconds to finish.
23+
If you need a longer execution time, you can increase the timeout using the -t or --timeout flag.
24+
Please note that default function invocation is 10 seconds, check our documentation for more information (https://www.netlify.com/docs/functions/#custom-deployment-options).
25+
`
26+
);
27+
}
28+
1729
function createCallback(response) {
1830
return function callback(err, lambdaResponse) {
1931
if (err) {
@@ -50,7 +62,7 @@ function promiseCallback(promise, callback) {
5062
if (typeof promise.then !== 'function') return;
5163
if (typeof callback !== 'function') return;
5264

53-
promise.then(
65+
return promise.then(
5466
function(data) {
5567
callback(null, data);
5668
},
@@ -80,7 +92,7 @@ function buildClientContext(headers) {
8092
}
8193
}
8294

83-
function createHandler(dir, static) {
95+
function createHandler(dir, static, timeout) {
8496
return function(request, response) {
8597
// handle proxies without path re-writes (http-servr)
8698
var cleanPath = request.path.replace(/^\/.netlify\/functions/, '');
@@ -123,11 +135,16 @@ function createHandler(dir, static) {
123135
{ clientContext: buildClientContext(request.headers) || {} },
124136
callback
125137
);
126-
promiseCallback(promise, callback);
138+
Promise.race([
139+
promiseCallback(promise, callback),
140+
setTimeout(function() {
141+
handleInvocationTimeout(response, timeout)
142+
}, timeout * 1000)
143+
])
127144
};
128145
}
129146

130-
exports.listen = function(port, static) {
147+
exports.listen = function(port, static, timeout) {
131148
var config = conf.load();
132149
var app = express();
133150
var dir = config.build.functions || config.build.Functions;
@@ -142,7 +159,7 @@ exports.listen = function(port, static) {
142159
app.get('/favicon.ico', function(req, res) {
143160
res.status(204).end();
144161
});
145-
app.all('*', createHandler(dir, static));
162+
app.all('*', createHandler(dir, static, timeout));
146163

147164
app.listen(port, function(err) {
148165
if (err) {

0 commit comments

Comments
 (0)