¿Cómo puedo evitar las condiciones de carrera en node.js cuando estoy manipulando la sesión a través de socket.io?

Estoy usando esta función de autorización en mi configuración socket.io:

io.set('authorization', function (data, accept) { if (!data.headers.cookie) { return accept('Session cookie required.', false); } data.cookie = require("cookie").parse(data.headers.cookie); data.cookie = require("connect").utils.parseSignedCookies(data.cookie,"yeah whatever"); data.sessionID = data.cookie['connect.sid']; sessionStore.get(data.sessionID, function(err, session){ if (err) { return accept('Error in session store.', false); } else if (!session) { return accept('Session not found.', false); } // success! we're authenticated with a known session.info. return accept(null, true); }); }); 

Entonces manipulo las variables de sesión como esta:

 var addAchievementToUser = function(achievement, sessionID) { sessionStore.get(sessionID, function(err, session) { //stuff happens here such as session.info.username = "whatever"; sessionStore.set(sessionID, session, function () { }); } }); }; 

esto funciona bien y hace lo que quiero pero a veces produce algunas condiciones de raza malvadas.

Entonces, ¿cómo puedo reescribir esto para que no cree condiciones de carrera? He buscado en el middleware de conexión para ver si es posible manipular solo un único par de clave / valor en lugar de todo el objeto de la sesión. pero parece que esto no es posible ya que la sesión debe ser una cadena:

 MemoryStore.prototype.set = function(sid, sess, fn){ var self = this; process.nextTick(function(){ self.sessions[sid] = JSON.stringify(sess); fn && fn(); }); }; 

¿algunas ideas?

ok, así que empecé a usar redis middleware, que realmente no me ayudó con el problema. de todos modos, básicamente solo edito la sesión a través de socket.io (y una vez cuando el cliente se conecta por primera vez), así que pensé que sería “lo mejor” crear una matriz de sesión que contenga todas las sesiones activas como esta:

 io.set('authorization', function (data, accept) { if (!data.headers.cookie) { return accept('Session cookie required.', false); } data.cookie = require("cookie").parse(data.headers.cookie); data.cookie = require("connect").utils.parseSignedCookies(data.cookie, "rawr"); data.sessionID = data.cookie['connect.sid']; sessionStore.get(data.sessionID, function(err, session){ if (err) { return accept('Error in session store.', false); } else if (!session) { return accept('Session not found.', false); } // success! we're authenticated with a known session.info. if (!sessions[data.sessionID]) { sessions[data.sessionID] = session; } return accept(null, true); }); }); 

así que nunca necesito usar el método de obtener sesión para editar los datos de mi sesión (solo el método de configuración). Lo bueno es que de esta manera, incluso funciona cuando el mismo cliente se conecta con múltiples sockets.