Skip to content

Commit

Permalink
feat(server): new router and middleware system (#1561)
Browse files Browse the repository at this point in the history
BREAKING CHANGE:
- Server returns `RequestCloseError` instead of `RequestAbortedError`
- Non-strict routing is gone
- Different `RegExp` usage in router path and wildcards
- Remove already deprecated `next.ifError`
- Disable DTrace probes by default
- Change in calling `next` multiple times
- Router versioning and content type as a separate plugin: `conditionalHandler`
- After event fires when both request is flushed and the last handler is finished
- Metrics plugin latency logic changes and new latencies were added

For more info see the `/guides/6to7guide.md`.
  • Loading branch information
hekike committed Mar 20, 2018
1 parent 49eb008 commit 8283277
Show file tree
Hide file tree
Showing 60 changed files with 3,864 additions and 3,105 deletions.
3 changes: 1 addition & 2 deletions Makefile
Expand Up @@ -24,7 +24,6 @@ NODEUNIT := ./node_modules/.bin/nodeunit
MOCHA := ./node_modules/.bin/mocha
NODECOVER := ./node_modules/.bin/cover
DOCS_BUILD := ./tools/docsBuild.js
BENCHMARK := ./benchmark/index.js
NPM := npm
NODE := node
PRETTIER := ./node_modules/.bin/prettier
Expand Down Expand Up @@ -74,7 +73,7 @@ docs-build:

.PHONY: benchmark
benchmark:
@($(NODE) $(BENCHMARK))
@(cd ./benchmark && $(NPM) i && $(NODE) index.js)

include ./tools/mk/Makefile.deps
include ./tools/mk/Makefile.targ
33 changes: 33 additions & 0 deletions benchmark/benchmarks/middleware.js
@@ -0,0 +1,33 @@
'use strict';

var restify = process.argv.includes('version=head')
? require('../../lib')
: require('restify');

var server = restify.createServer();
var path = '/';
var port = 3000;

module.exports = {
url: 'http://localhost:' + port + path
};

function handler(req, res, next) {
next();
}

for (var i = 0; i < 10; i++) {
server.pre(handler);
}

for (var j = 0; j < 10; j++) {
server.use(handler);
}

server.get(path, function get(req, res) {
res.send('hello world');
});

if (!module.parent) {
server.listen(port);
}
12 changes: 10 additions & 2 deletions benchmark/benchmarks/response-json.js
Expand Up @@ -5,9 +5,17 @@ var restify = process.argv.includes('version=head')
: require('restify');

var server = restify.createServer();
var path = '/';
var port = 3000;

server.get('/', function onRequest(req, res) {
module.exports = {
url: 'http://localhost:' + port + path
};

server.get(path, function onRequest(req, res) {
res.send({ hello: 'world' });
});

server.listen(3000);
if (!module.parent) {
server.listen(port);
}
12 changes: 10 additions & 2 deletions benchmark/benchmarks/response-text.js
Expand Up @@ -5,9 +5,17 @@ var restify = process.argv.includes('version=head')
: require('restify');

var server = restify.createServer();
var path = '/';
var port = 3000;

server.get('/', function onRequest(req, res) {
module.exports = {
url: 'http://localhost:' + port + path
};

server.get(path, function onRequest(req, res) {
res.send('hello world');
});

server.listen(3000);
if (!module.parent) {
server.listen(port);
}
132 changes: 132 additions & 0 deletions benchmark/benchmarks/router-heavy.js
@@ -0,0 +1,132 @@
'use strict';

var restify = process.argv.includes('version=head')
? require('../../lib')
: require('restify');

var server = restify.createServer();
var path = '/whiskeys/scotch/islay/lagavulin/16-years/50';
var methods = ['post', 'put', 'get', 'del', 'patch'];
var _ = require('lodash');
var port = 3000;

// Disabling cache: it's not fair as it aims to the worst case, when
// cache hit ratio is 0%. However, it's still better than the worst
// as it doesn't require extra time to maintain the LRU cache.
// There is no other way to simulate 100+ different endpoint
// calls with the current benchmark suite.
if (!process.argv.includes('version=head')) {
server.router.cache = {
get: function get() {
return null;
},
set: function get() {
return null;
},
dump: function get() {
return [];
}
};
}

module.exports = {
url: 'http://localhost:' + port + path
};

var routes = {
beers: {
ale: {
'pale-ale': {
'american-pale-ale': [],
'indian-pale-ale': []
},
lambic: [],
stout: {
'american-porter': [],
'imperial-stout': [],
'irish-stout': []
}
},
lager: {
'german-lager': {
marzen: []
},
pilsner: {
'german-pilsner': []
}
}
},

whiskeys: {
american: {
bourbon: {
kentchuky: {
'jim-beam': ['jim-beam', 'bookers', 'old-crow'],
'makers-mark': ['makers-mark'],
'woodford-reserve': ['woodford-reserve']
},
tennessee: {
'jack-daniels': ['jack-daniels']
}
},
rye: {
'beam-suntory': ['jim-beam-rye', 'knob-creek']
}
},
irish: {
'single-malt': {
bushmills: ['bushmills'],
connemare: ['connemare']
},
'single-pot': {
redbreast: ['redbreast'],
jameson: ['jameson-15-year']
}
},
japanese: {
nikka: ['coffeey-malt', 'blended', 'from-the-barrel'],
hibiki: ['japanese-harmony'],
yamazakura: ['blended']
},
scotch: {
islay: {
bruichladdich: ['25-years', 'islay-barley-2009'],
octomore: ['7.2', 'islay-barley-8.3'],
laphroaig: ['lore', '15-years', 'four-oak'],
lagavulin: ['distillers-edition', '8-years', '16-years']
}
}
}
};

function handler(req, res) {
res.send('hello');
}

function attachRoute(parent, routeConfig) {
_.map(routeConfig, function map(route, routeKey) {
var pathChunk = _.isString(routeKey) ? routeKey : route;
var routePath = parent + '/' + pathChunk;

methods.forEach(function forEach(method) {
server[method](routePath, handler);
});

if (_.isObject(route) || _.isArray(route)) {
attachRoute(routePath, route);
}
if (_.isString(route)) {
for (var i = 0; i <= 100; i++) {
methods.forEach(function forEach(method) {
server[method](routePath + '/' + i, handler);
});
}
}
});
}

attachRoute('', routes);

if (!module.parent) {
server.listen(port);
}
7 changes: 6 additions & 1 deletion benchmark/index.js
Expand Up @@ -5,7 +5,12 @@ var inquirer = require('inquirer');
var bench = require('./lib/bench');
var stableVersion = require('restify/package.json').version;

var BENCHMARKS = ['response-json', 'response-text'];
var BENCHMARKS = [
'response-json',
'response-text',
'router-heavy',
'middleware'
];

function select(callback) {
var choices = BENCHMARKS.map(function map(name) {
Expand Down
2 changes: 1 addition & 1 deletion benchmark/lib/autocannon.js
Expand Up @@ -22,7 +22,7 @@ function writeResult(handler, version, result) {

function fire(opts, handler, version, save, cb) {
opts = opts || {};
opts.url = 'http://localhost:3000';
opts.url = opts.url || 'http://localhost:3000';

var instance = autocannon(opts, function onResult(err, result) {
if (err) {
Expand Down
10 changes: 8 additions & 2 deletions benchmark/lib/bench.js
Expand Up @@ -14,6 +14,7 @@ function runBenchmark(opts, handler, version, cb) {

var spinner = ora('Started ' + version + '/' + handler).start();
var modulePath = path.join(__dirname, '../benchmarks', handler);
var url = require(modulePath).url;
var forked = fork(modulePath, ['version=' + version]);

pipeline(
Expand All @@ -24,8 +25,12 @@ function runBenchmark(opts, handler, version, cb) {
spinner.text =
'Warming ' + version + '/' + handler + ' for 5s';

var fireOpts = Object.assign({}, opts, {
duration: 5,
url: url
});
autocannon.fire(
Object.assign({}, opts, { duration: 5 }),
fireOpts,
handler,
version,
false,
Expand All @@ -48,7 +53,8 @@ function runBenchmark(opts, handler, version, cb) {
's';
}

autocannon.fire(opts, handler, version, true, callback);
var fireOpts = Object.assign({}, opts, { url: url });
autocannon.fire(fireOpts, handler, version, true, callback);
}
]
},
Expand Down
19 changes: 19 additions & 0 deletions benchmark/package.json
@@ -0,0 +1,19 @@
{
"name": "restify-benchmark",
"homepage": "http://restifyjs.com",
"description": "Restify benchmark",
"version": "0.0.0",
"private": true,
"main": "index.js",
"engines": {
"node": ">=0.10"
},
"dependencies": {
"restify": "*"
},
"devDependencies": {},
"license": "MIT",
"scripts": {
"start": "node indec"
}
}
1 change: 1 addition & 0 deletions docs/config/plugins.yaml
Expand Up @@ -29,6 +29,7 @@ toc:
- requestExpiry
- inflightRequestThrottle
- cpuUsageThrottle
- conditionalHandler
- conditionalRequest
- auditLogger
- metrics
Expand Down

0 comments on commit 8283277

Please sign in to comment.