From 540f646431294a367378dd0be96e4803a097d2ff Mon Sep 17 00:00:00 2001 From: josieusa Date: Wed, 4 Jan 2017 09:45:01 +0100 Subject: [PATCH] Workaround issue #17 with cujojs/when --- package.json | 3 ++- server/current-context.js | 14 +++++++++++- test/main.test.js | 47 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) 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/current-context.js b/server/current-context.js index a63ee67..a4054b1 100644 --- a/server/current-context.js +++ b/server/current-context.js @@ -78,7 +78,19 @@ LoopBackContext.createContext = function(scopeName) { process.context[scopeName] = ns; // Set up LoopBackContext.getCurrentContext() LoopBackContext.getCurrentContext = function() { - return ns && ns.active ? ns : null; + var boundMethods = { + get: ns.bind(ns.get).bind(ns), + set: ns.bind(ns.set).bind(ns), + }; + var handler = { + get: function(target, name) { + return ['get', 'set'].includes(name) ? + boundMethods[name] : + target[name]; + }, + }; + var proxy = new Proxy(ns, handler); + return ns && ns.active ? proxy : null; }; } return ns; diff --git a/test/main.test.js b/test/main.test.js index 29a4d16..e02f475 100644 --- a/test/main.test.js +++ b/test/main.test.js @@ -6,6 +6,7 @@ 'use strict'; var async = require('async'); +var when = require('when'); var LoopBackContext = require('..'); var Domain = require('domain'); var EventEmitter = require('events').EventEmitter; @@ -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]); + }); });