Skip to content

Commit

Permalink
Merge pull request #885 from projectxmaker/master
Browse files Browse the repository at this point in the history
MongoDB - loopback.getCurrentContext() returns null

Close #885
Fix #809
  • Loading branch information
Miroslav Bajtoš committed Jan 7, 2015
2 parents d77c5fa + ca0208d commit 989abf6
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 6 deletions.
26 changes: 20 additions & 6 deletions server/middleware/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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) {
Expand All @@ -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();
});
});
};
}
Expand Down
71 changes: 71 additions & 0 deletions test/loopback.test.js
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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();
});
});
});
});

0 comments on commit 989abf6

Please sign in to comment.