On this week’s upcoming episode of Cloud Cover, Wade and I showed our brand new creation, the Apathy Button. This app requires keeping an accurate counter at scale. (See the picture on the left… 36,000 clicks were registered at the time I’m writing this. The majority occurred during the hour-long period we were recording this week’s show.)
The basic challenge in building a scalable counter is one of concurrency. With many simultaneous requests coming to many role instances all updating the same number, the difficulty arises in making sure that number is correct and that the writers don’t spend a lot of time retrying after concurrency failures.
There are a number of potential solutions to this problem, and if you’re interested, I encourage you to watch the Cloud Cover episode for our discussion. Here I’ll outline the solution we chose and share the source code for the Apathy Button application.
The diagram below shows the basic architecture. Each instance keeps a local count that represents the number of clicks handled by that instance (the green “counter” below). This count is incremented using Interlocked.Increment, so it can be safely updated from any number of threads (blue squares). Each instance also has a single thread responsible for pushing that local count into an entity in table storage (purple square). There’s one entity per instance, so no two instances are trying to write to the same entity. The click count is now the sum of all those entities in table storage. Querying for them and summing them is a lightweight operation, because the number of entities is bound by the number of role instances.
To see how it’s implemented, download the full source code here: http://cdn.blog.smarx.com/files/ApathyButton_source.zip and watch this week’s episode of Cloud Cover.
And of course, if none of this interests you in the slightest, be sure to show your apathy over at http://www.apathybutton.com.