Make sure middleware layer sorting is stable

See https://github.com/strongloop/strong-arc/issues/767
This commit is contained in:
Raymond Feng 2014-12-12 18:15:24 -08:00
parent 5150a58364
commit cd89299163
2 changed files with 35 additions and 3 deletions

View File

@ -214,13 +214,22 @@ proto._sortLayersByPhase = function() {
});
var router = this._router;
// See https://code.google.com/p/v8/issues/detail?id=90
router.stack.forEach(function(layer, ix) {
layer.order = ix;
});
router.stack.sort(compareLayers);
function compareLayers(left, right) {
var leftPhase = left.phase;
var rightPhase = right.phase;
if (leftPhase === rightPhase) return 0;
var result;
if (leftPhase === rightPhase) {
// Keep the order (stable sorting)
return left.order - right.order;
}
// Builtin middleware is always first
if (leftPhase === BUILTIN_MIDDLEWARE) return -1;
@ -232,13 +241,23 @@ proto._sortLayersByPhase = function() {
if (rightPhase === 'routes')
return -1;
return phaseOrder['routes'] - phaseOrder[rightPhase];
result = phaseOrder['routes'] - phaseOrder[rightPhase];
if (result === 0) {
return left.order - right.order;
} else {
return result;
}
}
if (rightPhase === undefined)
return -compareLayers(right, left);
// Layers registered via `app.middleware` are compared via phase & hook
return phaseOrder[leftPhase] - phaseOrder[rightPhase];
result = phaseOrder[leftPhase] - phaseOrder[rightPhase];
if (result === 0) {
return left.order - right.order;
} else {
return result;
}
}
};

View File

@ -297,6 +297,19 @@ describe('app', function() {
});
});
it('keep orders of middleware added by app.use()', function(done) {
var expectedSteps = [];
for (var i = 0; i < 10; i++) {
app.use(namedHandler('m' + i));
expectedSteps.push('m' + i);
}
executeMiddlewareHandlers(app, function(err) {
if (err) return done(err);
expect(steps).to.eql(expectedSteps);
done();
});
});
function namedHandler(name) {
return function(req, res, next) {
steps.push(name);