Forgive me for reviving this debate about threadlocals. Before anyone loses their heads, I'm not suggesting a need for threads or anything like that. However, I've used threadlocal a bit in other languages and and the lack of threadlocal(or something with a less contentious name that has nothing to do with threads) in node.js makes me wonder how people would solve problems like distributed transaction coordination? In frameworks I've used in the past it was common to associate transaction context in threadlocal. That way, if any part of the program needed to interact with the transaction coordinator (start, rollback, pause, resume, commit) the transaction coordinator could look in thread local for the transaction context and know exactly which transaction was in progress on "this thread". That concept doesn't go away in node.js just because things are processed in an event loop, each pass of the event loop could be for different transactions.
It seems that the only way around this is to always have a direct reference to the transaction context, meaning passed to every function that might need the transaction context. This approach seems to require transaction api details be litered throughout the code, and makes it nearly impossible for a 3rd party to quietly manage transactions.
I use mongoose, and have created a plugin for tracking some audit information for each record change:
module.exports.auditAttributesPlugin = function(schema, options) {
schema.add({
createdOn : {type: Date, default: Date.now, required: true}
, changedOn : {type: Date, default: Date.now, required: true}
, createdBy : {type: Schema.ObjectId}
, changedBy : {type: Schema.ObjectId}
});
schema.pre('save', function (next) {
this.createdOn = this.createdOn || Date.now;
this.changedOn = Date.now;
this.createdBy = this.createdBy || app.context.userId;
this.changedBy = app.context.userId;
console.log('orm plugin createdOn: %s, createdBy: %s, updatedOn: %s, updatedBy: %s', this.createdOn, this.createdBy, this.changedOn, this.changedBy);
next()
});
};
The part where I do app.context.userId, without a threadlocal, I need access directly to the request or session that contains the user id. Typically(in threaded languages) I'd use threadlocal to store information like the userid executing in this iteration of the event loop. This technique is pretty common, distributed transaction coordination, JAAS, etc. all use this technique.
So far I haven't seen any solutions to this problem, so this post is either about to start a flame war, or could just be considered a vote for "threadlocal like behavior", or if anyone has any good suggestions, I'd like to hear them.
Thanks, Dave