From a335e2b9c8a548c1b01ce666b0309591457d6825 Mon Sep 17 00:00:00 2001 From: josieusa Date: Tue, 3 Jan 2017 16:02:23 +0100 Subject: [PATCH] Workaround issue #17 with cujojs/when --- package.json | 3 +- server/middleware/per-request.js | 9 ++++++ test/main.test.js | 47 ++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 35b97b1..b523730 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "eslint-config-loopback": "^4.0.0", "loopback": "^3.0.0", "mocha": "^2.5.3", - "supertest": "^1.2.0" + "supertest": "^1.2.0", + "when": "3.7.7" } } diff --git a/server/middleware/per-request.js b/server/middleware/per-request.js index 54361e1..1761a79 100644 --- a/server/middleware/per-request.js +++ b/server/middleware/per-request.js @@ -31,6 +31,15 @@ function perRequestContextFactory(options) { var scope = options.name || name; var enableHttpContext = options.enableHttpContext || false; var ns = LoopBackContext.createContext(scope); + // Monkey-patch LoopBackContext.getCurrentContext in order to fix issue #17 + var oldGetCurrentContext = LoopBackContext.getCurrentContext; + LoopBackContext.getCurrentContext = function() { + var context = oldGetCurrentContext(); + return context ? { + get: context.bind(context.get).bind(context), + set: context.bind(context.set).bind(context), + } : null; + }; // Return the middleware return function perRequestContext(req, res, next) { diff --git a/test/main.test.js b/test/main.test.js index 29a4d16..1ae8030 100644 --- a/test/main.test.js +++ b/test/main.test.js @@ -12,6 +12,7 @@ var EventEmitter = require('events').EventEmitter; var expect = require('./helpers/expect'); var loopback = require('loopback'); var request = require('supertest'); +var when = require('when'); describe('LoopBack Context', function() { var runInOtherDomain, runnerInterval; @@ -129,4 +130,50 @@ describe('LoopBack Context', function() { ], done); }); }); + it('doesn\'t mix up contexts if using concurrently then() from when 3.7.7', + function() { + expect(require('when/package.json').version).to.equal('3.7.7'); + var timeout = 50; + // Concurrent execution number 1 of 2 + var execution1 = new Promise(function execution1(outerResolve, reject) { + LoopBackContext.runInContext(function pushToContext1() { + var ctx = LoopBackContext.getCurrentContext(); + expect(ctx).is.an('object'); + ctx.set('test-key', 'test-value-1'); + var whenPromise = when.promise(function(resolve) { + setTimeout(resolve, timeout); + }); + whenPromise.then(function pullFromContext1() { + var testValue = ctx && ctx.get('test-key', 'test-value-1'); + return testValue; + }).then(function verify1(testValue) { + expect(testValue).to.equal('test-value-1'); + outerResolve(); + }).catch(function(error) { + reject(error); + }); + }); + }); + // Concurrent execution number 2 of 2 + var execution2 = new Promise(function execution1(outerResolve, reject) { + LoopBackContext.runInContext(function pushToContext2() { + var ctx = LoopBackContext.getCurrentContext(); + expect(ctx).is.an('object'); + ctx.set('test-key', 'test-value-2'); + var whenPromise = when.promise(function(resolve) { + setTimeout(resolve, timeout); + }); + whenPromise.then(function pullFromContext2() { + var testValue = ctx && ctx.get('test-key', 'test-value-2'); + return testValue; + }).then(function verify2(testValue) { + expect(testValue).to.equal('test-value-2'); + outerResolve(); + }).catch(function(error) { + reject(error); + }); + }); + }); + return Promise.all([execution1, execution2]); + }); });