Merge pull request #885 from projectxmaker/master
MongoDB - loopback.getCurrentContext() returns null Close #885 Fix #809
This commit is contained in:
commit
989abf6822
|
@ -2,6 +2,7 @@ var loopback = require('../../lib/loopback');
|
|||
var juggler = require('loopback-datasource-juggler');
|
||||
var remoting = require('strong-remoting');
|
||||
var cls = require('continuation-local-storage');
|
||||
var domain = require('domain');
|
||||
|
||||
module.exports = context;
|
||||
|
||||
|
@ -44,6 +45,13 @@ function context(options) {
|
|||
var scope = options.name || name;
|
||||
var enableHttpContext = options.enableHttpContext || false;
|
||||
var ns = createContext(scope);
|
||||
|
||||
var currentDomain = process.domain = domain.create();
|
||||
currentDomain.oldBind = currentDomain.bind;
|
||||
currentDomain.bind = function(callback, context) {
|
||||
return currentDomain.oldBind(ns.bind(callback, context), context);
|
||||
};
|
||||
|
||||
// Return the middleware
|
||||
return function contextHandler(req, res, next) {
|
||||
if (req.loopbackContext) {
|
||||
|
@ -53,13 +61,19 @@ function context(options) {
|
|||
// Bind req/res event emitters to the given namespace
|
||||
ns.bindEmitter(req);
|
||||
ns.bindEmitter(res);
|
||||
|
||||
currentDomain.add(req);
|
||||
currentDomain.add(res);
|
||||
|
||||
// Create namespace for the request context
|
||||
ns.run(function processRequestInContext(context) {
|
||||
// Run the code in the context of the namespace
|
||||
if (enableHttpContext) {
|
||||
ns.set('http', {req: req, res: res}); // Set up the transport context
|
||||
}
|
||||
next();
|
||||
currentDomain.run(function() {
|
||||
ns.run(function processRequestInContext(context) {
|
||||
// Run the code in the context of the namespace
|
||||
if (enableHttpContext) {
|
||||
ns.set('http', {req: req, res: res}); // Set up the transport context
|
||||
}
|
||||
next();
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
var it = require('./util/it');
|
||||
var describe = require('./util/describe');
|
||||
var Domain = require('domain');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
|
||||
describe('loopback', function() {
|
||||
var nameCounter = 0;
|
||||
|
@ -388,4 +391,72 @@ describe('loopback', function() {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe.onServer('loopback.getCurrentContext', function() {
|
||||
var runInOtherDomain;
|
||||
var runnerInterval;
|
||||
|
||||
before(function setupRunInOtherDomain() {
|
||||
var emitterInOtherDomain = new EventEmitter();
|
||||
Domain.create().add(emitterInOtherDomain);
|
||||
|
||||
runInOtherDomain = function(fn) {
|
||||
emitterInOtherDomain.once('run', fn);
|
||||
};
|
||||
|
||||
runnerInterval = setInterval(function() {
|
||||
emitterInOtherDomain.emit('run');
|
||||
}, 10);
|
||||
});
|
||||
|
||||
after(function tearDownRunInOtherDomain() {
|
||||
clearInterval(runnerInterval);
|
||||
});
|
||||
|
||||
// See the following two items for more details:
|
||||
// https://github.com/strongloop/loopback/issues/809
|
||||
// https://github.com/strongloop/loopback/pull/337#issuecomment-61680577
|
||||
it('preserves callback domain', function(done) {
|
||||
var app = loopback();
|
||||
app.use(loopback.rest());
|
||||
app.dataSource('db', { connector: 'memory' });
|
||||
|
||||
var TestModel = loopback.createModel({ name: 'TestModel' });
|
||||
app.model(TestModel, { dataSource: 'db', public: true });
|
||||
|
||||
// function for remote method
|
||||
TestModel.test = function(inst, cb) {
|
||||
var tmpCtx = loopback.getCurrentContext();
|
||||
if (tmpCtx) tmpCtx.set('data', 'a value stored in context');
|
||||
if (process.domain) cb = process.domain.bind(cb); // IMPORTANT
|
||||
runInOtherDomain(cb);
|
||||
};
|
||||
|
||||
// remote method
|
||||
TestModel.remoteMethod('test', {
|
||||
accepts: { arg: 'inst', type: uniqueModelName },
|
||||
returns: { root: true },
|
||||
http: { path: '/test', verb: 'get' }
|
||||
});
|
||||
|
||||
// after remote hook
|
||||
TestModel.afterRemote('**', function(ctxx, inst, next) {
|
||||
var tmpCtx = loopback.getCurrentContext();
|
||||
if (tmpCtx) {
|
||||
ctxx.result.data = tmpCtx.get('data');
|
||||
}else {
|
||||
ctxx.result.data = 'context not available';
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
request(app)
|
||||
.get('/TestModels/test')
|
||||
.end(function(err, res) {
|
||||
if (err) return done(err);
|
||||
expect(res.body.data).to.equal('a value stored in context');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue