Sunday, November 25, 2012

Writing usable scripts in Ruby


Usable command line tools/scripts

There are a lot of command line tools written in ruby, python, bash, c or any other languages. They are usable simply because there is a standard way in dealing with them
this way can be summarized in the following points:
  1. There has to be a usage example/brief help at the finger tips of the user ( by running with --help      or -h)
  2. arguments should have default values which are explained in the help
  3. misusage or missing mandatory arguments should fire the help message

ruby tools

OptionParser is part of the standard library in ruby that takes care of this script packaging.  they show long and short examples
This is an example of the script:
require 'optparse'
options = {}
OptionParser.new do |opts|
opts.banner = "Usage: script_name.rb [options]"
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
  options[:verbose] = v
end
end.parse!
p options
p ARGV
# Actual script code goes here
this allows the script to be used as:
$ ./script_name.rb -h
Usage: script_name.rb [options]
            -v, --[no-]verbose Run verbosely

$ ./script_name.rb -v
{:verbose=>true}
[]

$ ./script_name.rb
{}
[]

Packaging

no matter how small your script is, it is still better to package it as a gem. to keep track of releases, version, author.
let the actual code be part of the lib content. and the wrapper running (under bin) user OptParser and then call the script code with the specified options

Tuesday, November 20, 2012

Success of Startups

Entrepreneurship has become one of the one of the most interesting topic in the business side in any country in the world. While it is digging its way in the middle east, there is some sort of confusion and a lot of aspects related to that topic. A Startup can act and advance to tackle business opportunities in a way that competes with large enterprises. and most of the times, they need to be supported by Investors to back them up.

One of the things that started to really bother me in the culture is the definition of success of a startup. No one denies that a decent revenue generating startup is a successful one. However, some people believe that just raising an investment is a success.... umm, debatable.

I believe we can make some kind of analogy with some entities that showed up in the past decade like biznas and skybiz (I'm sure some of you will remember those names).   they used an invalid scheme summarized as:

  • People can register and join the network for a fee (as an investment, their money will get back doubled and doubled)
  • They need to invite 10 friends, and will get rewarded when their friends register and join the network
  • each of the new invited friends will get his money back with profit when he invites more friends.. and so on
The problem here is that, as an entity, you are not providing any value... you are rewarding people on reselling what u offer (which is nothing)... early adopters are usually rewarded and set as a successful example to motivate new ones.. but as time goes on, users form a kind of pyramid while people on top are relieved, and at the bottom are still trying to invite more friends. at least to cover their fees. this is a flawed business.. and officially stated as unlawful scheme

This is known as the "Pyramid Scheme".  from wikipedia: "A pyramid scheme is a non-sustainable business model that involves promising participants payment or services, primarily for enrolling other people into the scheme, rather than supplying any real investment or sale of products or services to the public.[1][2]"

Investment in Startups is different, because startups are meaningful entities with a mission, and need the investment on different levels to expand and grow up. However, if we took the value, the mission and revenue generation of a startup out of our evaluation, And focused only on the amount of money they were able to raise, then we're not anywhere far from the flawed scheme that was used by biznas and others.

We can think of raising investments as an indication that they're progressing in the right direction. well, at least someone has double checked that and invested his own money in this. But if the investor himself was not that mature, and only thought of the value of his equity when the startups goes for VC rounds of investments, then we're also back to the same flawed scheme.

That's why I believe that raising investments alone cannot be a success measure for a Startup


Monday, March 26, 2012

Utilizing Page Caching while using query string parameters using Nginx

One of the common practices for ruby on rails developers is to wrap all parameters in the URI itself, so they can easily make use of page caching. Sometimes having a lot of parameters can start being confusing specially with the ordering of the parameters to match the defined routes.

Let's elaborate with an example.

Consider an API that provides a list of entries, with possible filters:

http://api.example.com/feed.json

This can simply be page cached, rails will place the proper feed.json file in the public directory.

If we wanted to add use some supported filters like:

  1. date (in the format of 2012-03-25)
  2. order (by date, score or relevance)
  3. page (used to get the next pages of the feed)
  4. limit (or the page size.. the expected number of entries per response)
  5. type (some app related filter. let's assume the values can be: post, comment, announcement)

If we used the simply form of

http://api.example.com/feed.json?date=2012-03-25&page=2&limit=20&type=comment&order=score

all the requests will be page cached at public/feed.json regardless of the parameter values. causing them to be ignored. And even worse, if the cached page happened to be generated with filtered requests, the cached response will be filtered for further requests even if no filters was specified.

To Avoid this, most developers will include the parameters in the URL directly with the following route in the config/routes.rb

match '(/date/:date)(/type/:type)(/page/:page)(/limit/:limit)(/order/:order)/feed.json', :to=>'api/feed_entries#index'

And expect request to be:

http://api.example.com/date/2012-03-25/type/comment/page/2/limit/20/order/score/feed.json
http://api.example.com/page/1/limit/20/order/relevance/feed.json
http://api.example.com/date/2012-03-20/page/1/limit/30/order/score/feed.json
http://api.example.com/type/post/page/2/limit/20/feed.json

This will cause all requests to be cached separately and properly. and will work like charm. However, it makes it easy for other developers and API users to mess up the parameters order while constructing the URL. The first approach is definitely easier for them to use. but hard for us to cache.

One approach to fix this, is to step out of the rails app box. and to utilize the webserver (in our case, nginx). Using nginx rewrite module, you can allow developers to use the query string parameters that is easy for them, map the query string parameters to the proper route that is expected by rails, and make use of page caching.

Here is the nginx configuration snippet that does the mapping:

location = /feed.json {
set $apiurl '';
if ($arg_date != '') { set $apiurl /date/$arg_date ;}
if ($arg_type != '') { set $apiurl $apiurl/type/$arg_type ;}
if ($arg_page != '') { set $apiurl $apiurl/page/$arg_page ;}
if ($arg_limit != '') { set $apiurl $apiurl/limit/$arg_limit ;}
if ($arg_order != '') { set $apiurl $apiurl/order/$arg_order ;}
if ($apiurl != '') {rewrite ^ $apiurl/feed.json ; break; }
}

So, using this, both you and developers using your API will be happy. This will needs you to maintain your routes synchronized with nginx configuration. but the gains are awesome.

I am sure the same can be achieved via a rack middleware. which will be fine if handling nginx was not possible. but for high traffic websites. handling this on nginx level will be much more better than reaching rails stack. That's why we used page caching in the first place

The point is that if you are a web developer, you should never be restricted to the constrains made by your application framework. You can utilize anything between the end client/browser to ur most wrapped DB storage. The application server is only one of those components.

Tuesday, January 31, 2012

Cuban Pete





They call me Cuban Pete

I'm the King of the Rumba beat

When I play the marracas

I go chick-chicky-boom

chick-chicky-boom


Yes, Sir, I'm Cuban Pete

I'm the craze of my native street

when I start to dance

everything goes chick-chicky-boom

chick-chicky-boom


There Senoritas they sing

and how they swing

with this rumbero

it's very nice so full of spice


and when they dance and they bring a happy ring of vaqueros

singing a song all the day long


So if you like the beat

take a lesson from Cuban Pete

and I'll teach you to chick-chicky-boom

chick-chicky-boom chick-chicky-boom


Si, Senorita, I know that you will like the chicky boom chick

'cause it's the dance of Latin romance

and Cuban Pete doesn't teach you

in a hurry like Arthur Murray

I come from Havanah and there's always manana


* * *


They call me Sally Sweet

I'm the Queen of Delancy Street

When I start to dance everything goes chick-chicky-boom

chick-chicky-boom


Excuse me Mister Pete

have the Cubans a different beat

if they have will you teach me to chick

chick-chicky-boom chick-chicky-boom


* * *


Si, Senorita, I know that you will like the chicky boom chick

It's very nice so full of spice

I place my hand your hip and if you will just give me your hand

then we shall try just you and I