Sunday, June 8, 2014

Old friends: Iterative Development & Comunidad Prode

The FIFA World Cup has brought a lot of attention to the internet: social, games, portals and so on... (pause) duh, we are in 2014, aren't we?
Alright, Comunidad Prode was not an exception. During the last couple of weeks, I saw a lot (I mean a lot) of new people signing up, creating user groups to have their own private tournaments.

In numbers, we had 2000 users in the system, but only 600 were active (by active I mean actually playing predictions for the last AFA season). During the last weeks, number of signups raised to 5000 users, and around 2800 active.
Also, while we used to have between 300 and 400 visits per day, we are now going over 1000:

Images from Quicklytics, awesome app from my bud Eduardo Scoz 

Something that also caught my attention while looking at these analytic info was the referral pages. People was coming the to site, as expected, from Facebook, Google searchs, etc, but surprisingly, a lot was coming from an online newspaper. The reason was because of this article that I share with you.

At the same time, Fernando Carolei, a journalist who covers technology and new tendencies in public television channels in Argentina, was promoting the site as well in some of his "live" sections. After that, we had exchanged a few twitter direct messages, and he was telling me that he was using Comunidad Prode for a while, and found it actually pretty good :).

Anyway, as most of my blog posts, tech/programming stuff are present, and here is what I have today before wrapping up.
As iterative software development promotes, you might have heard to not overdesing; for a given problem and context, solve it in the "smartly-cheapest" way. In eXtremme Programming, this means DTSTTCPW: do the simplest thing that could possibly work.

That said, in the first version of Comunidad Prode, the way to handle user rankings was to calculate, on the fly, the points for a given user coming into the site. When the number of people started to grow, I started to see some heavy processing time. Long story short, rather than calculate points "dynamicaly", I moved it as part of the publishing results process (this is when the results of real games are set).

In a few words, the way to do this was getting all the users playing on a given tournament, do the calculation, and then save it for future requests.
Considering that active users is now going from 600 to now 3000, I am anticipating a bottleneck here; processing time will definitely go up, so, it is time to *refactor*. What's the simplest solution here? Maybe multithreading processing. Let's try that, and see... I leave you with these lines of code!


  page_size = ENV['PUBLISH_PAGE_SIZE'] || 500
  users = week.tournament.users
  pages = (users.count / page_size) + 1  
  
  threads = (1..pages).map do |i|
    Thread.new(i) do |i|
      update_ranking_for week, users.shift(page_size)
    end
  end
  threads.each {|t| t.join}  


Before, the method update_ranking_for was just taking the week as a param, and the users to update was getting figured out in the inside. Now, a group of users is passed into, and processing will happen in parallel. Technically speaking, if 600 users were taking a minute long to get processed, if we do it now in three groups of 200, time will go down to 20 seconds (1/3 of a minute).

Enjoy!