In Rails the current thread is used a lot to store global variables (I know, global variables are evil, but they are sometimes necessary).
Thread.current[:authlogic_scope] = scope
Here are some of the places it is used:
The question is, can you do a similar thing in Node.js? Specifically, in an express app.
What is the best way to keep a reference to the current request (or current thread)?
In express you're using callbacks with the request/response objects to avoid having to set global variables, which makes sense:
var express = require('express');
var app = express.createServer();
app.get('/', function(request, response) {
response.send('Hello World');
});
This question is in regards to building an "identity map" for caching database records (scoped to the current HTTP request / current user). In Rails, they can do this by keeping the identity map scoped to Thread.current
, and because everything is synchronous. Is there a way to do this in Node.js?
One way is to pass the request
around to every function. For my particular case this is too complicated to do and I would like to avoid this if at all possible.
Another way to do this is to redefine all of the variables you're going to use in a custom javascript function, similar to the way you do view templating (define variables that feel like global variables from with a template). But for my particular case this would be more confusing than helpful.
The third way to is to set it to some global variable that is accessible only to the current HTTP request, or the current thread. Is this possible in Node.js? If not, what are some other ways to accomplish the same thing?
Basically, I want to be able to do
App.User.where({createdAt: {'>=': _(2).days().ago()}}).all()
and have it internally check some node.js process.CURRENT_REQUEST
that's scoped to the current request, where the App.User
query can store it's results (and any other models can store their results, so if they are requested again it doesn't hit the database). I also want to be able to pass around the currentUser
the same way Authlogic does, so whenever a record is created, for instance, the createdById
field will be set to process.CURRENT_REQUEST.currentUser
automatically (internally).
You don't mean thread. JavaScript is single-threaded, so node is single-threaded. I don't mean to be picky, but people will understand you better if you use the nomenclature they've learned. The words 'thread' and 'process' are already too heavility overloaded at the OS level, best to avoid them unless that's really what we mean.
It is quite common in node to pass the entire request object around.
You have not provided a strong use case for building this identity map. Can you elaborate?
If you really need to keep track of individual callbacks, you could use a guid-generator. Of course, you have to store those guids someplace and depending on how you do that you could end up creating a bottleneck for scaling.
Ah.. I see your edit now... Where you write "where the App.User query can store it's results (and any other models can store their results, so if they are requested again it doesn't hit the database)." you're already thinking at a very high level. This is less of a node.js question and more of a framework question. What I mean is, node.js is a low-level kit which markets itself as a high-level framework. It's basically a mashup of javascript with an event loop supported by a thread pool. That would be OS threads, by the way. I think the answer to your question may be that you need to explicitly provide caching in your objects if you're looking to avoid extra hits to the database. As far as I know, there's no high-level magic for that baked into node. I know that doesn't really help, except maybe to say don't feel bad about not finding something that isn't there.
Re: globals. Just don't do it. Friends don't let their friends write to global. :)