Sunday, July 20, 2014

World Cup thoughts & numbers for ComunidadProde

If you read my last post from June 8th, I was kind of impressed about the numbers in general for ComunidadProde because of the FIFA World Cup, such as new people signing up, visits, and so on. Well, tournament is now over, and in terms of numbers, this is what it meant for the site (still can't believe how close we -Argentina- have been to get the trophy :( !!)

It was great to see many companies trusting us to create internal tournaments. There were big names, that I don't feel like revealing since I didn't ask for permission :P.

In terms of online public media, there were a few more articles published:


The iOS app was ranked pretty high, alternating the first positions in the country

Images from AppViz

Posted on June 8th, number of people signed up was around 5,000. Today I can say it is close to 15,000!

Posted on June 8th, number of visits per day was around 1,100. Today... hmm, peaks of 17,000!! I let the screenshots below to speak by themselves :)


Images from Quicklytics, awesome app from my bud Eduardo Scoz

What's next, will see, I have been thinking on UI redesign, taking advantage of great new frameworks out there...


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!

Saturday, May 3, 2014

Comunidad Prode keep on growing

Exactly 2 years ago, first commit to the git repo was made


Today, I am releasing code base 3.0, which in terms of end users, means support for not only "league-style" tournaments, but also "cup-style". The reason is quite straightforward: the ability to play predictions for the FIFA World Cup 2014, given the large group of users who asked for this feature.

Since this is a programming blog, lets go to the point. From the domain perspective, even though this is arguably, there were differences on how to represent a match as it was, versus a world cup match (knockout match from now on). Even though the match has a date and time to be played, we never wanted to tie that to the match just because AFA schedule is a real mess, with kickoff times changing from one day to another. That said, the decision was for the week to have a date (one week has many matches), and past that date, the related match results can no longer be predicted.

The situation for the knockout matches was different, we did want to predict on a match by match basis, and we needed to group them by an identifier (group A, group B, semi-final, etc).   

Now, when a user predicts a match, that gets persisted as a user_match. The relation between both is that each user match belongs to match, but now, it can also belong to a knockout match. How to achieve this, at least decently? I had the opportunity to use active record polymorphic associations a year ago or so, and I saw a perfect fit here for that as well. Here is the outcome.

 class Match < ActiveRecord::Base  
   has_many :user_matches, as: :related_match  
   ...  
 end  

 class KnockoutMatch < ActiveRecord::Base
   has_many :user_matches, as: :related_match
   ...
 end

 class UserMatch < ActiveRecord::Base
   belongs_to :related_match, polymorphic: true # match or knockout_match
   ...
 end

so now, by calling user_match.related_match you will get the associated "real" match, no matter if it is a match or a knockout match, for instance, to get the real score and calculate the user prediction points.

The rest of the changes are just around that, and those who don't, are the usual gem version upgrades to stay up to date, for instance, bump rails from 4.0.4 to 4.1.0, as well as ruby from 2.0.0 to 2.1.1.

Monday, February 3, 2014

How long does it take?

Here is the scenario, a user of your system (end-user, business, stakeholder, etc) finds a bug, which gets reported to you. You analyse it, you know how to fix it, you go right ahead and code it in; but, how long does it take for your user to actually see it implemented? Think of that bug as any code change; a real defect, a new feature, whatever; if it takes a few hours to get it coded, why does the user need to wait a week, or two, to actually see it? Oh!, I see, this is why:
  • the developer needs to stop doing what he is doing, developing!
  • build the code
  • change a few configs
  • make the deploy package
  • submit a request to the deployment team
  • call one of your contacts cause deployment team is not responding
  • call again, luckily someone is available
  • got an email “Deployment completed!”
  • open the site to run a smoke test, 500s all over the place :o
  • jump on a conference call, bla bla bla
  • … (oh my God, I said not to delete that file)
  • deployment finished
  • let QA know to go ahead and test it
  • QA is in the other side of the world, not gonna happen today
  • QA finds something, another email, another day
  • change the code, another email, another day
  • done! staging looks good; what, staging? Yes, but don’t worry, move this to production will be straightforward (ha!)
  • (more or less, I think I made my point clear)

Continuous Delivery (CD) has being around from the early days of the agilism (is that a word?) and extreme programming, and before that as well, if we dig into the lean manufacturing principles of the Toyota Production System. In these days, and with the popularity of DevOps and the cloud, CD has exploded and tons of options are available to overcome the aforementioned situation, technology-specific as well as technology-agnostic.

I was not planning on writing this much, I rather show what I got. The following is just one setup that I have for one specific project. If you see it with clinic eyes, you will tell areas of improvement, there are, but it fulfils the needs as is (push your decisions up to the point where you really need to make them, rather than “guessing” what’s gonna happen, as Martin Alaimo told me once).

Alright, this is my deployment pipeline, it is a visual representation of the health of the system and environments. The more boxes (jobs) you have, probably better, since if anyone turns red, you know exactly where to get your hands on.
This is running on a GUI-less Ubuntu server, Jenkins is the continuous integration server, and through the build pipeline plugin is how you get the graphical dashboard.


Lets break down each job to understand its responsibility.
  • CEMS_CI
    • Git is used as a SCM, so the Jenkins git plugin needs to be installed
    • Poll the upstream git repository at night, which is alright in terms of a daily build, but not exactly what I would like, I tell you why. Jenkins exposes a REST webapi that you can leverage to request a given job to run. That said, it is fairly simple to configure a post-receive git hook to run a curl command, so with that, what you would accomplish is to have one build per developer’s commit (even more frequent feedback of the system health). 
      In the case of this project, the git repo is an in-company instance of gitorious, so a development team has no access to manipulate the given hooks. Github does give you that possibility, which is neat, so if Github is your upstream repo, and your Jenkins is accessible through the internet, you could accomplish this.
    • Pull the latest changes from the upstream git repository. This will look only after to the master branch, so any code not ready to be integrated needs to be on its own branch (refer to this great branching strategy).
      The job will run under the jenkins user, so you need to make sure that it is able to ssh connect to the repo, load everything needed on its PATH, rvm etc etc (not the scope of this post)
    • Run a bash script to install new ruby gems and run common rake tasks. The last task, running your tests, should really be your QA. If all tests pass, you must be able to ship the software without fear.
       #!/bin/bash
       bundle install
       bundle exec rake db:migrate
       bundle exec rake db:seed
       bundle exec rake db:test:prepare
       bundle exec rake ci:setup:rspecdoc spec
    • Publish rails stats and ruby code coverage results, which in terms of quality, you can set it up to make the build fail if it goes below a given % threshold
    • Tag the upstream repo for traceability (read more about git tags)
    • and finally, if all above steps are ok, automatically trigger the next job Deploy to Dev
  • Deploy to Dev
    • Clone the repo, push it to a bare local one, created to mimic the upstream one (given that one is within our control, we can manage the hooks at our own will)
       #!/bin/bash -e
       echo "Preparing to deploy dev..."
      
       if [ -d "./tmp" ]; then
         echo "Removing old files"
         rm -rf "./tmp"
       fi
      
       mkdir tmp
       git clone git@[repo_url].git tmp
       
       cd tmp
       git remote add [remote] "/opt/git/[local_repo].git"
       
       echo "Pushing source code to dev..."
       git push [remote] master
       
       echo "Done!"
    • Now, on your post-receive hook of the local repo, run this (make sure it is executable first)
       $ chmod +x hooks/post-receive 
       # hooks/post-receive
       
       #!/bin/sh
       # Deploy Development environment
       
       echo "Sit back, your deployment is kicking off..."
       
       # Kill server
       kill -9 $(pidof ruby)
       
       APP_PATH="[my_app_path]"
       
       if [ -d "$APP_PATH" ]; then
         echo "Backing up old version..."
         ./backup_site.sh
         rm -rf $APP_PATH
       fi
       
       cd $APP_PATH
       unset GIT_DIR
       git pull origin master
       bundle install
       bundle exec rake db:migrate
       bundle exec rake db:seed
       
       # Start server once again on the background
       nohup rails server &> /dev/null &
    • and finally, if all above steps are ok, automatically trigger the next job Dev Readiness
  • Dev Readiness
    • Its responsibility is to ask the app if it is up and running by executing a curl command to a preconfigured route
       #!/bin/bash
       curl -X GET 'http://localhost:[port]/health' -I 
    • finally, its post-build action is to set to manual-trigger a deploy to the next environment (this is the only human interaction to get app on the next server, upgraded and running)
The Deploy to Stage job will pretty much do the same as Deploy to Dev. We can then add jobs like this one for any other environment we want to manage, with pretty much very low effort, repeatable, repeatable, repeatable.

Wrapping up, I don't want to leave without mentioning Nico Paez, who was the one who has shown me the Jenkins build pipeline for the first time, in one of the many agile events we connect in.

Saturday, July 27, 2013

Kicking off second year of Comunidad Prode

We are just a few days away of a new season of the Argentina professional soccer league, which in terms of Comunidad Prode, means the site second year of life!

During the off-season (and a little before too), I have tried to focus on upgrading the site, in order to bring end users always a better experience. That means, keep up with the latest and greatest versions of frameworks, gems, etc, as well as improving performance by running different set of profiling tools. Major list of upgrades are as follows...






As of now, we have around 1100 people playing on the site, and we look forward to, not only have more players, but to enrich experience of current ones!!

Sunday, July 21, 2013

Screencasting the RomanNumerals kata

In every aspect of life, it is known that practice something will make you better at it. Sportsman practice long hours before a given competition, musicians practice as well before performing on stage, but us, software people (developers, architects, etc), not always do the same thing.

Quoting Robert Martin (aka Uncle Bob) in his book The Clean Coder, "you should plan on working 60 hours per week. The first 40 are for your employer. The remaining 20 are for you [...] you should be reading, practicing, learning, and otherwise enhancing your career. [...]  During that 20 hours you should be doing those things that reinforce that passion [towards software]. Those 20 hours should be fun!"

That said, I have decided to record and share this following kata, hoping that someone picks it up and get contagious, in a good way :).
Audio is in Spanish thou, bummer, I know.

Closing... If you haven't read The Clean Coder, and now you feel like doing it, I humbly suggest reading Clean Code first.


Wednesday, March 6, 2013

20th anniversary of Ruby, version 2.0 is out!

Ten days ago or so, the first stable release of ruby 2.0 was shipped, so I decided to give it a try. Since I had to do a few things to get it working, I list them all below as a cheat sheet for myself, or others as well...

First of all, I should mention that I run OSX 10.8 Mountain Lion.That said, let's see.

Get the latest version of RVM and check if I am missing any required package:

 $ rvm get stable  
 $ rvm requirements  

In my case, openssl is what I needed to install, but other scenarios might be different.

 $ rvm pkg install openssl  

Then, when I tried to install a gem, i got an error like the following:

 ERROR: Loading command: install (LoadError) 
 cannot load such file -- openssl

That might be because there is an incorrect reference to the openssl config file, so, let's see where it did install, and then provide the correct path

 $ find . -type f -name "openssl.cnf"  
 $ rvm install 2.0.0 --with-openssl-dir=[path_found_above] --verify-downloads 1

After that, everything went fine.
In order to check all ruby installations your system has, you can run:

 $ rvm list  

Version 2.0.0-p0 should be there, and if you want to make your default, do:

 $ rvm --default use 2.0.0  

Even though you make any given ruby version the system's default, I humbly suggest creating gemsets per directory, with its own version of ruby and gems. For further reading about gemsets, check this out.



Sunday, January 27, 2013

Speaking at January monthly meeting of Agiles Buenos Aires

Last Thursday 17th, the monthly meeting of the Buenos Aires Agile community took place at the MUG. In this opportunity, Gastón Algaze and I have facilitated once again (we don't mean to bore people :)) our session presented at Ágiles 2012: El tamaño Si importa: los desafíos de escalar scrum.

Different from Ágiles, where the talk was time-boxed to 50 minutes in order to fit in the agenda, this time we had a nice 2-hour slot to extend the debate, and drill down whenever the audience required so. 

I am dropping the slides below one more time, in case you have landed here without reading the original post. With not much more to say, I don't want to leave without thanking Adrian Eidelman and Martin Salias, the organizers of this meetup, for giving us the chance to present once again. Thanks!


Thursday, November 29, 2012

Y otro año ágil que se va!

(sorry, this entry is only available in Spanish, at least for now)


Como más de uno sabrá, en Octubre pasado se llevó a cabo la 5ta edición de las Jornadas Latinoamericanas de Metodologías Ágiles, en la ciudad de Córdoba, un evento anual que es impulsado y llevado adelante íntegramente por la comunidad, mas allá del aporte económico de los sponsors.

Al igual que en años anteriores, la diversidad de temas que se trataron en paralelo daba lugar a que cualquiera de los asistentes pudiera armar su propio mini-track. La oferta de temas a elegir variaba desde conceptos teóricos acerca de la metodología, pasando por técnicas de coaching, y llegando hasta temas específicamente técnicos como ser aplicar cierta práctica ágil en un determinado lenguaje de programación y/o contexto.

En mi caso personal, tuve la suerte de quedar elegido para dar una sesión, junto con Gastón Algaze. Cuando propusimos la charla al comité, allá por Mayo, no estábamos muy convencidos si era un tema que la audiencia quisiera escuchar, y viendo la enormidad de tópicos propuestos, fuimos gratamente sorprendidos cuando quedó seleccionada. Así mismo, durante las Jornadas, el aula estaba colmada, habiendo gente sentada hasta en el piso.

La charla fue titulada “El tamaño Si importa: los desafíos de escalar scrum”, si bien el título puede ser muy abarcador, el enfoque de la misma estaba centrado alrededor de las tres siguientes áreas: equipos (muy) grandes, equipos distribuidos y contexto corporativo. Para aquellos interesados, les dejo abajo los slides de la presentación, que por sí sola quizás no tenga tanto valor, dado que hemos priorizado imágenes por sobre texto, pero siéntanse libres de contactarme para mas detalles.



El 2012 no sólo fue este evento; la comunidad se mueve todo el año. En Mayo, Buenos Aires fue sede de un Scrum Gathering, en el cual tuve la suerte de trabajar dentro del comité organizador, también junto a  Gastón Algaze, Carlos Peix, Juan José Zapico, entre otros. Este es un evento regional, que va rotando de sede alrededor del mundo, patrocinado por la ScrumAlliance, y con el apoyo de los sponsors locales.
   
¿Qué hay para el 2013? Seguramente mucho. Por lo pronto ya está definida la sede de las 6tas Jornadas Ágiles anuales, siendo la misma la ciudad de Lima, Perú, y si todo va bien, allí nos veremos!

Saturday, November 10, 2012

ComunidadProde is now on your iPhone



By using this awesome app, Quicklytics (besides that I know its creator, Eduardo Scoz), we saw that about 10-15% of Comunidad Prode users, were accessing the site via a mobile device.

Honestly, not a good thing if you trying to tiny pick portions of your smartphone, to enter data.. this would be for sure impacting negatively in the user experience.

Given that from day zero, we were announcing that mobile support would come soon, other priorities push it aside a little bit, but today is the day; launching the iOS client, where users can now use to submit their predictions, and also keep track of their rankings, either from the different divisions they play in, and also their custom groups.

Info of the app is in Spanish though, given the target audience. You can read more in the AppStore!



Wednesday, August 1, 2012

Launching ComunidadProde

Hi!

Time is up, break is over, and the new season of the different Argentina soccer leagues are kicking off!
If you are from Argentina, I am sure you have heard about the Prode game before. If not, let's say it is a prediction game, where you guess if a soccer match will end up with a home victory, guest victory, or even tied.

Comunidad Prode is a site we are launching these days with Matías Rodriguez, so you can play it online, with some slight differences from the original Prode game, in order to make it more exciting. Our major goal is to give room to true fans whose teams are not playing in first division, so we are including all 5 AFA leagues (Nacional B, Primera A, B, C, and D).

The other intention we look forward is for people to socialize, so, we are not only including Facebook and Twitter support (so you can post how good you are :)), but also the ability to create your own custom groups and play your own little tournament with co-workers, friends, etc.

The site was built with Ruby on Rails, not only the front end, but also a RESTful api, that us, as admins, can leverage in order to publish matches results. We are now working on extending this api, so to provide mobile support for end users as well... coming soon!

Habemus Prode!

Tuesday, May 15, 2012

New World Code Monkeys


I have been recently asked at work to introduce iOS and MonoTouch to other development teams, who are willing to start exploring down that path.

Given that I rather like coding than speaking, when it comes to this :), I just put together a couple of slides, but the main driver was actually to build a very simple app, experimenting some of the different _flavors_ that iOS development provides.

That said, I am sharing the presentation here, and within it, you would also find the github repo, in case you want to take a look at the codebase. Nothing fancy as you might tell, but as for what the expectations were, it was fair enough, and covered so far. In case you don’t have the MonoTouch official tools running on a Mac, and you still want to open and explore this code, you might find this Visual Studio extension by Jonas Folleso interesting.

I would finally like to thank Carlos Paez for sharing with me his presentation at CodeCamp Buenos Aires 2011, his talk with Martin Salias, so I can build the timeline slide...


Tuesday, September 6, 2011

GpsPing! has made it to the AppStore!!


Today, September 6 2011, GpsPing! has made it to the AppStore, and it is ready for you to get it... for FREE!!

GpsPing! is an iOS application developed with MonoTouch, given my C# (humble) skills! It is not my first iPhone application, but it is indeed the first one that I have submitted to the AppStore. My previous applications were enterprise-cross ones, for employees internal use, so I hope this time I can reach more users from all over.

MonoTouch has built an amazing community and lot of interest for the .Net guys as well, since using their day to day programming language, they can increase the mobile platforms they can target (not even counting Mono for Android!!)

Feel free to drop any comments below, and I would greatly appreciate that if you get a chance, go ahead and rate it.

Sunday, May 15, 2011

Rosario welcomed the Agile Open Tour 2011!!

Another edition of the Agile Open Tour 2011 took place in Rosario, Argentina, with a great convocatory of 100+ attendees.
Sponsored by Kleer among others, and organized by Polo Tecnológico Rosario, this open space event was once again a good oportunity to meet new people, in addition to learn and share experiences from and with the agile community.

There is for sure more than one thing that I can take home with me, but one of them is really worth to mention. Given that my current job situation finds me in a position of having people -developers, testers, clients, etc- understand what agile/scrum is all about, simple things that can drive them to that 'click' are incredible valuable. I like to call that click their 'a-ha moment'...

That is how I have found myself after an activity that Martin Alaimo and Carlos Pantelides presented, where in no more than 25 minutes, the difference between traditional vs agile was clearly put into evidence; period, say no more!

For those interested in the content of it, just leave a comment and will go from there...

Stay tunned with these events at agiles.org!

Tuesday, May 3, 2011

Intro to Object Oriented Programming

Here is the material class I have prepared for the part-time teaching position at the University... hope it helps others while looking for related info!

Friday, February 11, 2011

Kicking off this blog...

Hey there!

Yes, I decided to open this up, so I can write about what's going on.
Could be techies, could be social, I don't know, whatever... whatever I feel like posting!

So, I see you when I see you.