Skip to content

Commit

Permalink
feat: support server timeout (#3133)
Browse files Browse the repository at this point in the history
  • Loading branch information
atian25 authored Nov 14, 2018
1 parent ff79101 commit 7802528
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 1 deletion.
10 changes: 10 additions & 0 deletions config/config.default.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,16 @@ module.exports = appInfo => {
*/
config.workerStartTimeout = 10 * 60 * 1000;

/**
* server timeout in milliseconds, default to 2 minutes.
*
* for special request, just use `ctx.req.setTimeout(ms)`
*
* @member {Number} Config#serverTimeout
* @see https://nodejs.org/api/http.html#http_server_timeout
*/
config.serverTimeout = null;

/**
*
* @member {Object} Config#cluster
Expand Down
13 changes: 13 additions & 0 deletions lib/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const path = require('path');
const fs = require('fs');
const ms = require('ms');
const is = require('is-type-of');
const graceful = require('graceful');
const http = require('http');
const cluster = require('cluster-client');
Expand Down Expand Up @@ -154,6 +155,14 @@ class Application extends EggApplication {
}
}

_onServerTimeout(socket) {
const req = socket.parser.incoming;
if (req) {
this.coreLogger.warn('[http_server] A request `%s %s` timeout with client (%s:%d)', req.method, req.url, socket.remoteAddress, socket.remotePort);
}
socket.destroy();
}

onServer(server) {
// expose app.server
this.server = server;
Expand All @@ -170,6 +179,10 @@ class Application extends EggApplication {
});

server.on('clientError', (err, socket) => this.onClientError(err, socket));

// server timeout
if (is.number(this.config.serverTimeout)) server.setTimeout(this.config.serverTimeout);
server.on('timeout', socket => this._onServerTimeout(socket));
}

/**
Expand Down
14 changes: 14 additions & 0 deletions test/fixtures/apps/app-server-timeout/app/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use strict';

const { sleep } = require('mz-modules');

module.exports = app => {
app.get('/', async ctx => {
ctx.body = 'ok';
});

app.get('/timeout', async ctx => {
await sleep(500);
ctx.body = 'timeout';
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
exports.keys = 'my keys';

exports.serverTimeout = 100;
3 changes: 3 additions & 0 deletions test/fixtures/apps/app-server-timeout/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "app-server-timeout"
}
25 changes: 24 additions & 1 deletion test/lib/cluster/app_worker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const net = require('net');
const request = require('supertest');
const address = require('address');
const assert = require('assert');
const assert = require('assert-extends');
const sleep = require('mz-modules/sleep');
const utils = require('../../utils');

Expand Down Expand Up @@ -64,6 +64,29 @@ describe('test/lib/cluster/app_worker.test.js', () => {
]);
});

describe('server timeout', () => {
let app;
beforeEach(() => {
app = utils.cluster('apps/app-server-timeout');
// app.debug();
return app.ready();
});
afterEach(() => app.close());

it('should not timeout', () => {
return app.httpRequest()
.get('/')
.expect(200);
});

it('should timeout', async () => {
await assert.asyncThrows(() => {
return app.httpRequest().get('/timeout');
}, /socket hang up/);
app.expect('stdout', /\[http_server] A request `GET \/timeout` timeout with client/);
});
});

describe('customized client error', () => {
let app;
beforeEach(() => {
Expand Down

0 comments on commit 7802528

Please sign in to comment.