I’m using nodejs with connect-redis to store the session data.
I’m saving user data in the session, and use it for in the session lifetime.
I’ve noticed that it’s possible to have a race condition between two requests that changes the session data.
I’ve tried to use redis-lock to lock the session, but it’s a bit problematic for me.
i don’t want to lock the entire session, but instead lock only specific session variable.
I found it to be impossible, and I thought about direction to solve it:
to stop using the session object to store user data, and save the variable directly in the redis and lock before using it.
I know that it can work, but it will require me to manage all the objects manually instead of just accessing redis through the session object.
Can you please share with me the best practice and your suggestions?
Thanks,
Lior
Well, implementing your own storage might be the option for you. This documentation shows that all you need to do is to implement three methods:
.get,.setand.destroy(see the last paragraph). It would be something like this (using node-redis library and modifying the original connect-redis store a bit):Side note: I didn’t implement error handling for
.lockand.unlock. I’m leaving this up to you! 🙂 There might be some minor mistakes (I don’t have NodeJS at the moment and I’m writing this from my memory 😀 ), but you should understand the idea. Here’s the link which contains the discussion about how to usesetnxfor locking/unlocking Redis.The other note: you would probably want to make some custom error handling for routes, because if any route throws an exception, then Redis session won’t be unlocked. The
.setmethod is always called as the last thing in route – opposite to.getmethod which Express calls at the very begining of the route (that’s why I lock at.getand unlock at.set). Still you will be locked only for 5 seconds, so it does not have to be a problem though. Remember to tune it to your needs (especiallythresholdandwait_timevariables).Final note: with this mechanism your request handlers will only fire one after another per user. This means, that you will not be able to run concurrent handlers per user. This might be a problem, so the other idea is to held the data outside the session and handle locking/unlocking manually. After all, there are some things which have to be handled manually.
I hope it helps! Good luck!