Wednesday, June 11, 2014

I've reached the point where I am ready to do some coding for Project Venice. I'm starting with the basics: client to server communications. Node.js is a bit different the way it approaches things. Unlike other programming languages, it is not very sequential. Instead, it's all about doing work when a call has completed, rather than just being next in line.

My client (the browser) will communicate with the server (Node.js) using AJAX. So what happens if a user double clicks a button and one request arrives before the previous one is finished? That is the problem I am most worried about. In fact, this issue may also affect my Google App Engine projects, but to a lesser extent. In any case, it is time I solve this problem for good.

Here is a scenario example from the same user who is attempting to purchase some in-game good twice:

Request A: Check Funds

Request B: Check Funds

Request A: Subtract Funds

Request B: Subtract Funds

When we get to the last step, there may not be enough funds left since it doesn't know a previous request subtracted funds. That is a big problem. So how do we go about ensuring requests don't interfere with each other? MongoDB, which is what I am using for this project, doesn't have a concept of transactions. Nor does it really let you lock anything specific down. But is does provide a method to avoid the above issue.

MongoDB provides a findAndModify() function which lets you query and update a document atomically. That means it will happens at the same time and other db operations won't happen in between. Mongoose, the Node.JS ORM, provides wrappers for these functions: findOneandUpdate, findOneandRemove, findByIdAndRemove, findByIdAndUpdate. An example from https://groups.google.com/forum/#!topic/mongoose-orm/5b94sq-pjsg:

var query = model.findOneAndUpdate({

_id: 123,

balance: { $gt: 10 }

},

{

$inc: { balance: -10 }

});

Using these functions, I can avoid some concurrency issues. However, these are only good for a single MongoDB document. What happens if I am accessing multiple documents? That is a post for another time.