Thursday, October 29, 2015

Places I travelled in a year

Has it been a year this quick? oh yes it has. I remember the first time I watched FRIENDS, 2 years ago. Any way, traveling was not always my favorite thing to do until a year ago when I traveled to Pokhara. Since my childhood I have always been afraid of adventures and the jungles and the things that live in the jungle. But my first tour to Pokhara changed everything.

Since that day, I have been traveling awfully a lot, and my parents complain about it. To be fair, I have also trekked solo up to an altitude of 3800m.

Places I have traveled to

Pokhara on Oct 2014
MT flight on Jan 2014
Jhor on May 2015
Dolalghat on June 2015
Kulekhani - Chitlang on Jul 2015
Kalinchowk on Sep 2015

On my wishlist

ABC trek  (2016 april 9 -14) trek completed
Langtang trek (covering Gosainkunda)
Chisapani  (this hike is completed)
Chamadevi (this hike is completed)
Rara (far cry)

Pokhara
MT Flight
Jhor
Dolalghat
Kulekhani

Chitlang
Kalinchowk

How maggie worn me out ?


Maggie is a facebook app, that lets you add filter with your name and change your profile picture. I would not have bothered building an app that was already built by many talented developers out there. But we offered something different than the rest of those apps. A friend of mine proposed that we add the name of the user in the image because it would make our app a little different than what is out there. I loved the idea. Another friend of mine told me to finish this app as soon as possible, 24 hrs, urgent. When a programmers hear the word "URGENT", they loose control and screw things up. I am no different than them.

I started developing the app, while the login with facebook and getting the logged in users data was finished in a matter of minutes , the main problem was merging the user`s image with the overlay and to make it even worse adding text to the image with a different font style.

Day 1

Finished login the user using fb, getting users data, adding users to database. Then I had to merge those images, so I tried couple of different techniques. The first was using the user`s image as a background and the overlay image in the img tag. But that was a noob mistake. Then I tried canvas. It worked but since I needed to download the image to send it to the graph api, I could not convert the base64 into the real image. So I had to drop that and go with rmagick. After a couple of hours of hair pulling, what seemed impossible was done. So the next step was to add post to facebook and make it profile picture. After a while of googling, it was also solved. Seriously, why do not we call programming, stackoverflowing and we are the stackoverflow bots that rely on the very first result we get on stackoverlfow without even understaing the problem or the system we are working on.

Day2

As my friend wanted, text on the image, I had no idea how to do that. But why fear when stackoverflow is there? Some one already had the problem I had and it was solved too. Ctrl c+ v, god I need to change this habit.  Text was added , fonts was working perfect until , until I had to push it to production. Then it was just hell.  Fonts were not working as excepted. This time no google or no stackoverflow could help me but I was very determined. So I wrote a simple ruby script with the same image manipulation code and ran it and surprisingly it worked. Then I tried it on my rails app but it did not work. I had to google the whole night.

Day3

It was raining, cold and the right excuse to cancel my morning walk. Got my laptop and started working on it again from 6 am. Little did I knew, it was already 10 am and still I had no luck plus I forgot to take my medications. Is that determination?? haha I hope so. Then I made the rails app to execute the ruby script I wrote to manipulate image but again it did not worked. I still have no idea why? Why was it not working? I finally gave up and settled for the default font. Now even though there are some problems with the app , I feel like I have accomplished something that I thought I was incapable to develop.

There is something I have learned though.
If a certain tool that you are using, does not make your life easier, then stop using it.
Brace yourself while pushing the code to production mode and pray to Buddha (God).
Never push security keys to VC`s.
Premature optimization can be hell.
First get the functionality that your app depends upon then work on the rest.
TDD development is for those who have still plenty of time left to code.

Saturday, October 24, 2015

Why I would avoid materializecss for my next app?


Material design is taking over the UI/UX by storm these days so I also decided to give materializecss, a CSS framework, a try. I heard about this framework through my colleague and it did surprised me with its tons of cool effects.

So for my app, Fuitter, I added the framework using the materializecss gem because I was not able to make the fonts work by manually adding the links to files.(it was a bummer)

Materializecss have everything I needed for my app`s design, like the side nav bar, wave in the buttons and more. While the materializecss team is doing a great job with its framework, I am planning to not use it anymore in the future.

I wanted a select field for the TLD in the domain section and I rendered it  using rails form helper but after I refreshed my page the select field was not rendered, it was present in the DOM but it was hidden. I had to spend a good one hour before the Eureka moment hit me. The default select field in materializecss overrides the browser default property, so to render it I had to use javascript and that is not cool. So why the heck this is not cool? What if I had dynamically created select fields? Meteorjs renders view on the fly , so I would have to write tons of logic in each template to initialize the select every time the view loads.

<%= form_tag() do %>
    www.
    <%=  text_field_tag(:domain_name) %>
    <%= select_tag(:tld, options_for_select([['.com', '.com'], ['.org', '.org']])) %>
<% end %>

This will be hidden until you add some javascripts.
<script>

$(document).ready(function() {
    $('select').material_select();
});
</script>

So, the design of select functionality in materialize CSS is, in my opinion, a pretty good reason not to use it.


By the way, the wave effects in the buttons also has the same problem.

While materializecss provides a lot about all the 'effects' modern apps will demand I'm not sure those types of designs and concepts fit into large scale software just yet.

Sunday, October 18, 2015

Phusion passenger with nginx




Lately I decided to do something different than I was usually inclined to. I was using unicorn as my web application server in my development environment so I wanted to use Phusion passenger.  I was looking forward to use passenger in my production environment, so I thought how about I learn it now to install and run it in my development environment ? It took some time for me to wrap my head around it but eventually I figured it out.

I already had my nginx installed but I had to remove it because I screwed some config files while figuring out   passenger. Any way, the beginning is always the hard part.

I am assuming that you have no nginx installed.  Run this command, it will walk you through a very easy process of installing the server with passenger.

rvmsudo passenger-install-nginx-module
After everything is done, navigate to localhost in your browser. It should be working.

If you have ruby installed via rvm then no problemo. In your terminal run

Open up your /opt/nginx/conf/nginx.conf file and add the value of command from the terminal output to passenger_ruby

passenger_ruby /home/sushant/.rvm/gems/ruby-2.2.3/wrappers/ruby;

The work is still not done yet. You still have to put the right value for passenger_root. Just type

passenger-config --root
and it will output the location to the passenger. Copy that and paste it in your nginx.conf file like so

passenger_root /home/sushant/.rvm/gems/ruby-2.2.3/gems/passenger-5.0.20;

Now browser localhost and you will see the default nginx page.Lets add a vhost in case if that is what you are looking for.

server {
        passenger_ruby /home/sushant/.rvm/gems/ruby-2.2.3/wrappers/ruby;
        rails_env development; # add this if you get error like “Incomplete response received from application” from nginx / passenger
        listen 80;
        server_name sushant.com *.sushant.com;
        root /usr/share/nginx/html/fuitter/public;

        # You must explicitly set 'passenger_enabled on', otherwise
        # Passenger won't serve this app.
        passenger_enabled on;
    }

Ok now to make your changes take effect, you have to restart your server. I had to download an init script because it could not find nginx command. So if you had the same problem, again, I got you covered.
git clone git://github.com/jnstq/rails-nginx-passenger-ubuntu.git
sudo mv rails-nginx-passenger-ubuntu/nginx/nginx  /etc/init.d/nginx
sudo chown root:root /etc/init.d/nginx




Thursday, October 8, 2015

Laravel for RAD


Just as good as rails, laravel can really speed up the development process. I finished a fully functional real estate system in a day. Yes there were not much requirements plus I did not follow TDD but that is just whole another story.

As laravel provides authentication out of the box, I had to spend couple of minutes configuring it. Since my app required different access control, I used a module that helped me setup the ACL in few minutes. Since CRUD is a frequent visitor I used another composer package for it and again the setup took just few minutes. The crud generator followed repository design pattern.

Importing the project assets were as easy as ABC`s unlike in Rails where you have to understand the esoteric asset pipeline.

Since it did not provided default generated test codes for the codes I generated I may end up solving a bug or may be a crisis in the near future. Rails is much generous with this and Rspec with Capybara makes testing even more fun.

Eloquent makes it even simpler to query from the database.

Package I used for:

acl: Entrust
generator: CRUD generator
data tables: Data Tables


My fetish for scaling Everest

Everest as seen from the window I sat during my MT Flight

Scaling Everest can cost a fortune or even a life and that is what ignites my passion to summit the world`s highest mountain. In every step there is danger , waiting for the right moment to violently shake you from the feet down and swallow you into its deep crevasse or maybe put you to sleep under its massive blanket of snow and if you are lucky , altitude sickness, hypothermia. When you get caught in these, death is inevitable.

Top of everest as seen from the cockpit
I am pretty sure that this alacrity to climb the Everest did not engendered because I watched the Everest movie. I had a dream to summit it before that but after my first solo trek.

MT everest covered with clouds
I did a lot of research on Everest and the results were astounding. If we push our body beyond its limit, we end either die trying or we make a history. There are many fatalities around the year trying to scale Everest but still people risk their life to climb it because they know that whatever maybe the consequences the risk is worth it and I feel the same too. 2013 avalanche was a deadly one as it killed many Sherpas and sadly among them was a father of one of the girl I knew from my high school.
With the blistering cold temperature and fierce wind to just make it worse, the summit may seem impossible. At these altitude the weather changes in a fickle.
Standing 8848m above , you can realize how tiny you are and how cosmic the space outside the earth is. I probably bet, I will mistake the view from summit analogous to heaven.  I wonder how the sky will look from there. Will there be any clouds above than us? How will Mt Kangchenjunga look, piercing the benevolent looking clouds, that looks as if they will cushion the fall.

Climbing Everest is definitely on my wish list and I am really hoping to do it when I am 30.

Wednesday, October 7, 2015

TDD is not enough for your software`s QA


Recently the rise of unit testing, test-driven development, and agile methods has attested to a surge of interest in making the most of testing throughout all phases of the SDLC. However, testing is just one of many tools that you can use to ameliorate the code quality.
Almost every language has a tool that probe for violations of style guides, common gotchas, and sometimes crafty errors that can be hard to detect. Static analysis tool got in the reputation radar for giving a large number of false positive warnings and warnings to follow the style guide that are not necessarily required to follow.The good news about static analysis tools are that they can be configured to your needs. These tools can be configured either in your IDE or through command-line.
When rolling out a fresh new project, the team, unanimously should follow a certain standard of coding throughout the whole SDLC. In all, a coding standard should make it easier to work in the project, and maintain development speed from the beginning to the end.Obviosuly your linting tool will rain you with plethora of false positive error because it would not be able to guess your project`s coding pattern. But like I said earlier, they can be configured and you can roll your own static checker.
So, do not let testing be the terminal of your QA, make sure to take advantage of analysis tool.

Monday, October 5, 2015

Restarting unicorn


Every time you make any changes to your config files , you have to restart you server, at least that is what rails will notify you. It would be easy as pressing ctrl + c  if only you had run the rails server by doing rails s. But that is not the case if you are using servers such as nginx as your reverse proxy.

What you can do is, run service unicorn_appname restart in your app directory. If it works then that is fine. But if it does not and show you an error telling you to check your stderr file in the log directory, then follow on.
If you take a look at you stderr log file you will see something like this.
It is telling me that there is a process already running. So you have to kill that process and start your unicorn application server again.

Run ps aux | grep unicorn and it will list all the running processes. Since unicorn is running on 2710 i need to kill it.
pkill 2710 will kill the process and after that run service unicorn_fuitter start and now your app will be working just fine.

Sunday, October 4, 2015

Running rails app with Unicorn + Nginx


If you have come from PHP background , you will probably loose your nerve trying to get a simple hello world rails app to work with your server. Getting rails app to work with the server is a little different from any php apps where you just have to place your php app inside the /html folder(in my case).

My system has RVM, rails , ruby, nginx, postgres.

First we need to install unicorn. Unicorn is an application server. Since unicorn cant not be accessed by users directly, we will use Nginx as a reverse proxy.

Navigate to your project directory and open your Gemfile and add gem 'unicorn' gem. Then run bundle install.
Now we need to configure it.

Inside your config directory add unicorn.rb file.

unicorn.rb

# set path to application
app_dir = File.expand_path('./')
shared_dir = "#{app_dir}/tmp"
working_directory app_dir


# Set unicorn options
worker_processes 2
preload_app true
timeout 30

# Set up socket location
listen "#{shared_dir}/sockets/unicorn.sock", :backlog => 64

# Logging
stderr_path "#{shared_dir}/log/unicorn.stderr.log"
stdout_path "#{shared_dir}/log/unicorn.stdout.log"

# Set master PID location
pid "#{shared_dir}/pids/unicorn.pid"


Now lets create the required directories

mkdir -p tmp/log tmp/sockets tmp/pids 

Give those directories necessary read/write permission
Now we will create a init script that will load on boot.

sudo nano /etc/init.d/unicorn_appname
 
You can name appname whatever you want
unicorn_appname

#!/bin/sh

### BEGIN INIT INFO
# Provides:          unicorn
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the unicorn app server
# Description:       starts unicorn using start-stop-daemon
### END INIT INFO

set -e

USAGE="Usage: $0 <start|stop|restart|upgrade|rotate|force-stop>"

# app settings
USER="sushant"
APP_NAME="appname"
APP_ROOT="/usr/share/nginx/html/app" #in my case
ENV="development"

# environment settings
PATH="/home/$USER/.rvm/shims:/home/$USER/.rvm/bin:$PATH"
CMD="cd $APP_ROOT && bundle exec unicorn -c config/unicorn.rb -E $ENV -D"
PID="$APP_ROOT/shared/pids/unicorn.pid"
OLD_PID="$PID.oldbin"

# make sure the app exists
cd $APP_ROOT || exit 1

sig () {
  test -s "$PID" && kill -$1 `cat $PID`
}

oldsig () {
  test -s $OLD_PID && kill -$1 `cat $OLD_PID`
}

case $1 in
  start)
    sig 0 && echo >&2 "Already running" && exit 0
    echo "Starting $APP_NAME"
    su - $USER -c "$CMD"
    ;;
  stop)
    echo "Stopping $APP_NAME"
    sig QUIT && exit 0
    echo >&2 "Not running"
    ;;
  force-stop)
    echo "Force stopping $APP_NAME"
    sig TERM && exit 0
    echo >&2 "Not running"
    ;;
  restart|reload|upgrade)
    sig USR2 && echo "reloaded $APP_NAME" && exit 0
    echo >&2 "Couldn't reload, starting '$CMD' instead"
    $CMD
    ;;
  rotate)
    sig USR1 && echo rotated logs OK && exit 0
    echo >&2 "Couldn't rotate logs" && exit 1
    ;;
  *)
    echo >&2 $USAGE
    exit 1
    ;;
esac


Update the scripts permission and enable unicorn to boot on start

sudo chmod 755 /etc/init.d/unicorn_appname
sudo update-rc.d unicorn_appname defaults
 
Now open

sudo nano /etc/nginx/sites-available/default
 
default

upstream app {
    # Path to Unicorn SOCK file, as defined previously
    server unix:/usr/share/nginx/html/app/tmp/sockets/unicorn.sock fail_timeout=0; #in my case
}

server {
    listen 80;
    server_name example.com;

    root /usr/share/nginx/html/app/public; #in my case

    try_files $uri/index.html $uri @app;

    location @app {
        proxy_pass http://app;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }

    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;
}
  

Open your hosts file and add
127.0.0.1       example.com
then
sudo service unicorn_appname restart
sudo service nginx restart  If you browse to example.com your app should be running