diff --git a/README.md b/README.md index 9572750..2f4d7bb 100644 --- a/README.md +++ b/README.md @@ -3,15 +3,28 @@ Current context for LoopBack applications, based on node-continuation-local-storage. +## WARNING + +The module node-continuation-local-storage is known to have many problems, +see e.g. [issue #59](https://github.com/othiym23/node-continuation-local-storage/issues/59). +As a result, loopback-context does not work in many situations, as can be +seen from issues reported in LoopBack's +[issue tracker](https://github.com/strongloop/loopback/issues?utf8=%E2%9C%93&q=is%3Aissue%20getCurrentcontext). + +**We recommend AGAINST using this module.** + +If you are running on Node v6, you can try the new alternative +[cls-hooked](https://github.com/Jeff-Lewis/cls-hooked). + ## Usage -1) Add `per-request-context` middleware to your +1) Add `per-request` middleware to your `server/middleware-config.json`: ```json { "initial": { - "loopback-context#per-request-context": { + "loopback-context#per-request": { } } } @@ -31,4 +44,6 @@ MyModel.myMethod = function(cb) { }); ``` -See also https://docs.strongloop.com/display/APIC/Using+current+context +See the official LoopBack +[documentation](https://docs.strongloop.com/display/APIC/Using+current+context) +for more details. diff --git a/server/current-context.js b/server/current-context.js index 733a86a..36bec16 100644 --- a/server/current-context.js +++ b/server/current-context.js @@ -94,3 +94,10 @@ LoopBackContext.createContext = function(scopeName) { } return ns; }; + +/** + * Create middleware that sets up a new context for each incoming HTTP request. + * + * See perRequestContextFactory for more details. + */ +LoopBackContext.perRequest = require('./middleware/per-request'); diff --git a/server/middleware/per-request-context.js b/server/middleware/per-request.js similarity index 91% rename from server/middleware/per-request-context.js rename to server/middleware/per-request.js index 4e8753c..54361e1 100644 --- a/server/middleware/per-request-context.js +++ b/server/middleware/per-request.js @@ -7,7 +7,7 @@ var LoopBackContext = require('../current-context'); -module.exports = context; +module.exports = perRequestContextFactory; var name = 'loopback'; @@ -26,14 +26,14 @@ var name = 'loopback'; * @property {Boolean} enableHttpContext Whether HTTP context is enabled. Default is false. */ -function context(options) { +function perRequestContextFactory(options) { options = options || {}; var scope = options.name || name; var enableHttpContext = options.enableHttpContext || false; var ns = LoopBackContext.createContext(scope); // Return the middleware - return function contextHandler(req, res, next) { + return function perRequestContext(req, res, next) { if (req.loopbackContext) { return next(); } diff --git a/test/main.test.js b/test/main.test.js index 11e8f30..faf5534 100644 --- a/test/main.test.js +++ b/test/main.test.js @@ -5,7 +5,7 @@ 'use strict'; -var ClsContext = require('..'); +var LoopBackContext = require('..'); var Domain = require('domain'); var EventEmitter = require('events').EventEmitter; var expect = require('./helpers/expect'); @@ -39,7 +39,7 @@ describe('LoopBack Context', function() { var app = loopback({localRegistry: true, loadBuiltinModels: true}); app.set('remoting', {context: false}); app.set('legacyExplorer', false); - app.use(require('../server/middleware/per-request-context')()); + app.use(LoopBackContext.perRequest()); app.use(loopback.rest()); app.dataSource('db', {connector: 'memory'}); @@ -48,7 +48,7 @@ describe('LoopBack Context', function() { // function for remote method TestModel.test = function(inst, cb) { - var tmpCtx = ClsContext.getCurrentContext(); + var tmpCtx = LoopBackContext.getCurrentContext(); if (tmpCtx) tmpCtx.set('data', 'a value stored in context'); if (process.domain) cb = process.domain.bind(cb); // IMPORTANT runInOtherDomain(cb); @@ -63,7 +63,7 @@ describe('LoopBack Context', function() { // after remote hook TestModel.afterRemote('**', function(ctxx, inst, next) { - var tmpCtx = ClsContext.getCurrentContext(); + var tmpCtx = LoopBackContext.getCurrentContext(); if (tmpCtx) { ctxx.result.data = tmpCtx.get('data'); } else { @@ -85,12 +85,12 @@ describe('LoopBack Context', function() { }); it('works outside REST middleware', function(done) { - ClsContext.runInContext(function() { - var ctx = ClsContext.getCurrentContext(); + LoopBackContext.runInContext(function() { + var ctx = LoopBackContext.getCurrentContext(); expect(ctx).is.an('object'); ctx.set('test-key', 'test-value'); process.nextTick(function() { - var ctx = ClsContext.getCurrentContext(); + var ctx = LoopBackContext.getCurrentContext(); expect(ctx).is.an('object'); expect(ctx.get('test-key')).to.equal('test-value');