Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Context doesn't work with Node 4.3.1 #2094

Closed
kussberg opened this issue Feb 22, 2016 · 7 comments
Closed

Context doesn't work with Node 4.3.1 #2094

kussberg opened this issue Feb 22, 2016 · 7 comments

Comments

@kussberg
Copy link

Hello,

we wanted to update our servers to Node v4.3.1 but unfortunately we have a problem with loopback context. We are using session manager for express and init the session when setContext is run:

// Configure to set current customer or employee                                                                                                                   
app.use(function setContext(req, res, next) {                                                                                                                      
  var loopbackContext = loopback.getCurrentContext();                                                                                                              
  var session = req.session;                                                                                                                                       
  session.sessionID = req.sessionID;                                                                                                                               
  loopbackContext.set('session', session);                                                                                                                                                                                                                                          

  if (req.accessToken) {                                                                                                                                           
    async.parallel({                                                                                                                                               
      customer: function (cb) {                                                                                                                                    
        app.models.Customer.findById(req.accessToken.userId, function (err, customer) {                                                                            
          cb(null, customer);                                                                                                                                      
        });                                                                                                                                                        
      },                                                                                                                                                           
      employee: function (cb) {                                                                                                                                    
        app.models.Employee.findById(req.accessToken.userId, function (err, employee) {                                                                            
          cb(null, employee);                                                                                                                                      
        });                                                                                                                                                        
      }                                                                                                                                                            
    }, function (err, results) {                                                                                                                                   
      if (loopbackContext) {                                                                                                                                       
        if (results.customer)                                                                                                                                      
          loopbackContext.set('customer', results.customer);                                                                                                       
        if (results.employee)                                                                                                                                      
          loopbackContext.set('employee', results.employee);                                                                                                       
      }                                                                                                                                                            
      next();                                                                                                                                                      
    });                                                                                                                                                            
  } else {                                                                                                                                                         
    next();                                                                                                                                                        
  }                                                                                                                                                                
});                

Inside of this function the loopbackContext.get('session') works without problem. The problem is, that when we use the context in a remote method, it doesn't work, as loopbackContext.get('session') - undefined:

var ctx = loopback.getCurrentContext();
var session = ctx && ctx.get('session');                  <===== undefined

Any clues?

@kussberg
Copy link
Author

If we change:
loopbackContext.set('session', session); >>>> loopbackContext.test = {session: session};

Then we can retrieve the session without any problem:

loopbackContext.test.session

Is there a problem in loopback, that this "get" method of context is loosing scope?

@drywolf
Copy link

drywolf commented Feb 24, 2016

Hi, it is being said that loopback.getCurrentContext() is pretty much deprecated at this point.
I had my own odyssey with bumping my head against it, and in the end I completely replaced all usage of getCurrentContext() with the proposed alternative solution of injecting the remote context via the options argument (see #1495).

This is working without any problems so far and I think others are using it as well in place of getCurrentContext(). So you could give it a try and see if you can make it work for your usecase, and avoid all the troubles that lie dormant within getCurrentContext() and the CLS.

Just my 0.02$ 😉

@loay loay added the triaging label Feb 25, 2016
@loay loay self-assigned this Feb 25, 2016
@loay
Copy link
Contributor

loay commented Feb 25, 2016

Thanks @drywolf
@ekussberg does the previous comment by @drywolf fix your issue.
You can have a further look at this case here: #1961
Thanks.

@loay loay added the blocked label Feb 25, 2016
@kussberg
Copy link
Author

What we are using is exactly what is written in the docs:
https://docs.strongloop.com/display/public/LB/Using+current+context

But now i have redefined the part in server.js to:

// Configure to set current customer or employee
function injectOnLoad(ctx, next) {
  // Create foodo object in context
  ctx.foodo = {};
  // Add session to context
  var session = ctx.req.session;
  session.sessionID = ctx.req.sessionID;
  ctx.foodo.session = session;
  if (ctx.req.accessToken) {
    async.parallel({
      customer: function (cb) {
        app.models.Customer.findById(ctx.req.accessToken.userId, function (err, customer) {
          cb(null, customer);
        });
      },
      employee: function (cb) {
        app.models.Employee.findById(ctx.req.accessToken.userId, function (err, employee) {
          cb(null, employee);
        });
      }
    }, function (err, results) {
      if (ctx) {
        if (results.customer)
          ctx.foodo.customer = results.customer;
        if (results.employee)
          ctx.foodo.employee = results.employee;
      }
      next();
    });
  } else {
    next();
  }
}
app.remotes().before('*.*', injectOnLoad);
app.remotes().before('*.prototype.*', function (ctx, instance, next) {
  injectOnLoad(ctx, next);
});

But how now i can get the "ctx" inside of the remote method or other helper classes?

@drywolf
Copy link

drywolf commented Feb 27, 2016

@ekussberg
If you are trying to implement the approach suggested in #1495 then you are missing the most essential parts. You need to patch the remote method parameter lists to include an additional "options" parameter. Then in the relevant remotes().before(...) handlers inject the context into the options object that will be passed to the remote methods.

This means that you also need to include this parameter in the remote method definition where you want to use it. You should end up having a signature like function (...method-args..., options, response_cb).

In the options argument you will receive the context that you injected.

@loay
Copy link
Contributor

loay commented Jul 14, 2016

Hi @ekussberg @drywolf
is this issue resolved?

@loay loay removed their assignment Sep 23, 2016
@bajtos
Copy link
Member

bajtos commented Jan 9, 2017

Hello, we have landed & released an official solution for injecting context via "options" arg, see #1495 and the related pull requests.

There is also a parallel work done by @josieusa where loopback-context was upgraded to use cls-hooked under the hood. Feel free to try the new version [email protected]. If you run into issues, then please report them in loopback-context's issue tracker.

I am closing this issue as it's no longer actionable for us.

@bajtos bajtos closed this as completed Jan 9, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants