不要怂,就是干,撸起袖子干!

Commit 2161b3f5 by Mick Hansen

Merge pull request #3694 from mdarveau/master

Fix CLS propagation for all Bluebird methods
2 parents 642fbbd2 071485f4
'use strict';
var Promise = require('bluebird')
, _then = Promise.prototype._then;
, shimmer = require('shimmer');
Promise.prototype._then = function (didFulfill, didReject, didProgress, receiver, internalData) {
if (Promise.Sequelize.cls) {
var ns = Promise.Sequelize.cls;
if (typeof didFulfill === 'function') didFulfill = ns.bind(didFulfill);
if (typeof didReject === 'function') didReject = ns.bind(didReject);
if (typeof didProgress === 'function') didProgress = ns.bind(didProgress);
}
return _then.call(this, didFulfill, didReject, didProgress, receiver, internalData);
};
// functionName: The Promise function that should be shimmed
// fnArgs: The arguments index that should be CLS enabled (typically all callbacks). Offset from last if negative
function shimCLS(object, functionName, fnArgs){
shimmer.wrap(object, functionName, function(fn) {
return function () {
if (Promise.Sequelize && Promise.Sequelize.cls) {
var ns = Promise.Sequelize.cls;
for(var x=0; x<fnArgs.length; x++) {
var argIndex = fnArgs[x] < 0 ? arguments.length + fnArgs[x] : fnArgs[x];
if ( argIndex < arguments.length && typeof arguments[argIndex] === 'function' ) {
arguments[argIndex] = ns.bind( arguments[argIndex] );
}
}
}
module.exports = Promise;
\ No newline at end of file
return fn.apply(this, arguments);
};
});
}
// Core
shimCLS(Promise, 'join', [-1]);
shimCLS(Promise.prototype, 'then', [0, 1, 2]);
shimCLS(Promise.prototype, 'spread', [0, 1]);
shimCLS(Promise.prototype, 'catch', [-1]);
shimCLS(Promise.prototype, 'error', [0]);
shimCLS(Promise.prototype, 'finally', [0]);
// Collections
shimCLS(Promise.prototype, 'map', [0]);
shimCLS(Promise.prototype, 'reduce', [0]);
shimCLS(Promise.prototype, 'filter', [0]);
shimCLS(Promise.prototype, 'each', [0]);
// Utility
shimCLS(Promise.prototype, 'tap', [0]);
module.exports = Promise;
......@@ -40,7 +40,8 @@
"moment": "^2.9.0",
"node-uuid": "~1.4.1",
"toposort-class": "~0.3.0",
"validator": "^3.34.0"
"validator": "^3.34.0",
"shimmer": "1.0.0"
},
"devDependencies": {
"chai": "^2.1.2",
......
......@@ -138,5 +138,155 @@ if (current.dialect.supports.transactions) {
});
});
});
describe('bluebird shims', function () {
beforeEach(function () {
// Make sure we have some data so the each, map, filter, ... actually run and validate asserts
return this.sequelize.Promise.all([this.User.create({ name: 'bob' }), this.User.create({ name: 'joe' })]);
});
it('join', function () {
var self = this;
return this.sequelize.transaction(function () {
var tid = self.ns.get('transaction').id;
return self.sequelize.Promise.join(self.User.findAll(), function () {
expect(self.ns.get('transaction').id).to.be.ok;
expect(self.ns.get('transaction').id).to.equal(tid);
});
});
});
it('then fulfilled', function () {
var self = this;
return this.sequelize.transaction(function () {
var tid = self.ns.get('transaction').id;
return self.User.findAll().then(function () {
expect(self.ns.get('transaction').id).to.be.ok;
expect(self.ns.get('transaction').id).to.equal(tid);
});
});
});
it('then rejected', function () {
var self = this;
return this.sequelize.transaction(function () {
var tid = self.ns.get('transaction').id;
return self.sequelize.Promise.reject('test rejection handler').then(null,function () {
expect(self.ns.get('transaction').id).to.be.ok;
expect(self.ns.get('transaction').id).to.equal(tid);
});
});
});
it('spread', function () {
var self = this;
return this.sequelize.transaction(function () {
var tid = self.ns.get('transaction').id;
return self.User.findAll().spread(function () {
expect(self.ns.get('transaction').id).to.be.ok;
expect(self.ns.get('transaction').id).to.equal(tid);
},function () {
expect(self.ns.get('transaction').id).to.be.ok;
expect(self.ns.get('transaction').id).to.equal(tid);
});
});
});
it('catch', function () {
var self = this;
return this.sequelize.transaction(function () {
var tid = self.ns.get('transaction').id;
return self.sequelize.Promise.try(function () {
throw new Error('To test catch');
}).catch(function () {
expect(self.ns.get('transaction').id).to.be.ok;
expect(self.ns.get('transaction').id).to.equal(tid);
});
});
});
it('error', function () {
var self = this;
return this.sequelize.transaction(function () {
var tid = self.ns.get('transaction').id;
return self.sequelize.Promise.try(function () {
throw new self.sequelize.Promise.OperationalError('To test catch');
}).error(function () {
expect(self.ns.get('transaction').id).to.be.ok;
expect(self.ns.get('transaction').id).to.equal(tid);
});
});
});
it('finally', function () {
var self = this;
return this.sequelize.transaction(function () {
var tid = self.ns.get('transaction').id;
return self.User.findAll().finally( function(){
expect(self.ns.get('transaction').id).to.be.ok;
expect(self.ns.get('transaction').id).to.equal(tid);
});
});
});
it('map', function () {
var self = this;
return this.sequelize.transaction(function () {
var tid = self.ns.get('transaction').id;
return self.User.findAll().map(function () {
expect(self.ns.get('transaction').id).to.be.ok;
expect(self.ns.get('transaction').id).to.equal(tid);
});
});
});
it('reduce', function () {
var self = this;
return this.sequelize.transaction(function () {
var tid = self.ns.get('transaction').id;
return self.User.findAll().reduce(function () {
expect(self.ns.get('transaction').id).to.be.ok;
expect(self.ns.get('transaction').id).to.equal(tid);
});
});
});
it('filter', function () {
var self = this;
return this.sequelize.transaction(function () {
var tid = self.ns.get('transaction').id;
return self.User.findAll().filter(function () {
expect(self.ns.get('transaction').id).to.be.ok;
expect(self.ns.get('transaction').id).to.equal(tid);
});
});
});
it('each', function () {
var self = this;
return this.sequelize.transaction(function () {
var tid = self.ns.get('transaction').id;
return self.User.findAll().each(function () {
expect(self.ns.get('transaction').id).to.be.ok;
expect(self.ns.get('transaction').id).to.equal(tid);
});
});
});
it('tap', function () {
var self = this;
return this.sequelize.transaction(function () {
var tid = self.ns.get('transaction').id;
return self.User.findAll().tap(function () {
expect(self.ns.get('transaction').id).to.be.ok;
expect(self.ns.get('transaction').id).to.equal(tid);
});
});
});
});
});
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!