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 juggler = require('loopback-datasource-juggler');
|
||||||
var remoting = require('strong-remoting');
|
var remoting = require('strong-remoting');
|
||||||
var cls = require('continuation-local-storage');
|
var cls = require('continuation-local-storage');
|
||||||
|
var domain = require('domain');
|
||||||
|
|
||||||
module.exports = context;
|
module.exports = context;
|
||||||
|
|
||||||
|
@ -44,6 +45,13 @@ function context(options) {
|
||||||
var scope = options.name || name;
|
var scope = options.name || name;
|
||||||
var enableHttpContext = options.enableHttpContext || false;
|
var enableHttpContext = options.enableHttpContext || false;
|
||||||
var ns = createContext(scope);
|
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 the middleware
|
||||||
return function contextHandler(req, res, next) {
|
return function contextHandler(req, res, next) {
|
||||||
if (req.loopbackContext) {
|
if (req.loopbackContext) {
|
||||||
|
@ -53,13 +61,19 @@ function context(options) {
|
||||||
// Bind req/res event emitters to the given namespace
|
// Bind req/res event emitters to the given namespace
|
||||||
ns.bindEmitter(req);
|
ns.bindEmitter(req);
|
||||||
ns.bindEmitter(res);
|
ns.bindEmitter(res);
|
||||||
|
|
||||||
|
currentDomain.add(req);
|
||||||
|
currentDomain.add(res);
|
||||||
|
|
||||||
// Create namespace for the request context
|
// Create namespace for the request context
|
||||||
ns.run(function processRequestInContext(context) {
|
currentDomain.run(function() {
|
||||||
// Run the code in the context of the namespace
|
ns.run(function processRequestInContext(context) {
|
||||||
if (enableHttpContext) {
|
// Run the code in the context of the namespace
|
||||||
ns.set('http', {req: req, res: res}); // Set up the transport context
|
if (enableHttpContext) {
|
||||||
}
|
ns.set('http', {req: req, res: res}); // Set up the transport context
|
||||||
next();
|
}
|
||||||
|
next();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
var it = require('./util/it');
|
var it = require('./util/it');
|
||||||
|
var describe = require('./util/describe');
|
||||||
|
var Domain = require('domain');
|
||||||
|
var EventEmitter = require('events').EventEmitter;
|
||||||
|
|
||||||
describe('loopback', function() {
|
describe('loopback', function() {
|
||||||
var nameCounter = 0;
|
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