September 28, 2012

Don’t pay for web hosting if you don’t have to

A few months ago, I moved all my websites, including my personal homepage www.manki.in to Google hosting.  (That is, some Google product running on my own domain.)  However, there was one piece in the puzzle that was still with my web hosting provider: redirecting any requests to the naked domain manki.in to www.manki.in.  Once the request reaches www.manki.in, Google would take care of it from there on.

This was the setup of my site for several months, until yesterday.  Only yesterday I found out an awesome feature Google Apps has.  It can redirect requests to your naked domain to any subdomain you specify.  Precisely the one thing I was paying my web hosting provider for!   And Google would do this for free because I am on their free Google Apps plan.  That amounts to saving more than $50 a year.  Very cool!

Essentially, I had to set up DNS A records to point my domain name to Google’s IP addresses and tell Google Apps which subdomain I wanted the requests to go to.  Check Google’s help page for detailed step-by-step instructions.

One last thing you need to do is disconnect your domain name from your hosting provider’s IPs so your users are always sent to the right place.  Once you have added the A records to map your domain to Google’s IPs, delete all original A records so your domain is not pointing to your hosting provider anymore.  When your hosting contract runs out next year, you can simply not renew it :)

September 18, 2012

Error-handling: Java vs Go

FotoBlogr is the first toy I wrote using Go.  As a part of FotoBlogr, I also wrote a Flickr client library, an App Engine helper library, (unpublished) Blogger client, and Picasa client, so I got to see some idiomatic Go.  One thing I really missed when writing Go was exceptions.  Many things that are one-liners in languages with exception support (Java, Python, etc.) become 3 or 4 lines in Go.  Let’s take parsing a string as an integer for example.  In Java, you’d write:
int n = Integer.parseInt(str);
and you’re done.  If you expect this conversion to fail, you’d catch NumberFormatException, but it’s not mandatory.  Compare this to equivalent Go code:
n, err := strconv.Atoi(str)
Of course, you can choose to ignore the error by using an underscore in the place of err, but it still won’t be as expressive like in Java.  For instance, you cannot write return math.Sqrt(strconv.Atoi(str)).  You must write that in two different statements:
n, _ := strconv.Atoi(str)
return math.Sqrt(n)
Of course, this is wrong, and it should actually be something like:
n, err := strconv.Atoi(str)
if err != nil {
  // Handle this error.
}
return math.Sqrt(n)
It was very annoying to get used to writing code this way... almost as if writing dumb code.

Fast forward a few months.  I had moved to a C++ project where the style guide prohibits using exceptions.  Existing code in this project ignored errors in several places, but when I was writing new code I always made sure I did something about errors... at the minimum log it and proceed.  I didn’t have to make a conscious effort to do that; writing Go code had trained me to naturally think about error handling.  It felt awkward to not check for errors, in fact.

Now, I am fixing a bug in a Java project.  This is an old project with design decisions independently made by hundreds of engineer over several years.  The change itself is fairly simple: instead of simply sending a request to an RPC server, now we have to first check whether it’s okay to send that request.  If this query fails, we’d show an error message to the user.  But the complication is this: I’m changing a void method that does not throw any exceptions.  (This method in effect promises all its callers that it can never fail!)  This method is being called by half a dozen classes, which are being called a few others, and so on.  Unless I touch a large number of files to handle the new error, I can’t get the code to compile.

I was discussing this issue with a teammate and what he said was remarkable.  He said, “Every method in every class should throw a checked exception irrespective of whether that method can fail or not.  If it cannot fail today, maybe it can tomorrow.”  He didn’t literally mean that, of course.  What he meant was we weren’t using checked exceptions as extensively as we should have.  If this method I am changing now threw some checked exception, I could simply use that in my client code without scratching my head too much.  This is precisely what Go does.  Almost all functions return an error status.  You can choose to ignore it, but when someone new to the codebase reads it, it’s obvious you’re ignoring an error.  I’m starting to think that Go’s way of error-handling is a much superior way than Java’s and C++’s.

SIDENOTE: The easy and obvious fix is to throw a RuntimeException and catch it in only the places I like to change now.  But that’s a really wrong way to fix a problem like this.  First of all, RuntimeExceptions are not meant for cases like this.  They are for things like division by zero, dereferencing a null pointer, etc.  Things that can happen in any code and thus are impractical to handle specifically.  Since they are rare and usually very serious, they are allowed to propagate through deep call stacks.  Defining application errors, input errors, etc. as RuntimeException can lead to severe debugging issues over time.  You really don’t want that.

September 15, 2012

White headphones

At work, we can pick up headphones for free.  You just walk into the place where they’re kept, take one, and walk away.  You don’t have to ask anyone, and you don’t have to tell anyone.  I took a really nice Sennheiser pair a couple weeks ago.  Though they are expensive (about $60), it was painful to use them.  10 minutes into wearing them, my ears would be paining real bad.

I decided I’d just buy a better pair myself.  Being a predictable BoseSheep, I went to Bose (like iSheep buying Apple without thinking).  They had two different models: OE2 and AE2.  OE is on-ear while AE is around-ear.  AE2, when worn, doesn’t even touch your ears so they are more comfortable than OE2.

But I am not a rational buyer... I’ve never been one.  Very often I’d buy things for totally random reasons.  This time I decided to buy the OE2 because that was the only model available in white.  AE2 came in one colour and that was black.  I just cannot buy a black toy when there’s  a white alternative.

Within two days of usage, I don’t like the OE2 because it’s pushing on my ears almost like the Sennheiser.  Unhappily but with no other choice, I go to Bose Store again to return the OE2 and pick up an AE2.  To my surprise, they had white AE2s now!  Bose must have launched these in the two days I had the OE2!  Funny how lucky I get :)

September 10, 2012

Slow = bad

Having to wait for machines repeatedly is one of the most demoralising things you can experience when trying to get something done.

September 09, 2012

Understanding code

You don’t understand a piece of code until you can confidently add features to it.

September 08, 2012

Is screen the only advantage tablets have?

Quite often, I find myself wanting to read on my Nexus 7 than on my laptops.  Checking my Google Reader, reading any article that’d take more than a couple of minutes, reading Kindle books... I prefer the tablet for all these.  This is not surprising because the Nexus 7 has a 216-dpi screen while my laptop has an incomparable 96-dpi screen.

When it comes to doing some real work... work that involves multitasking and/or precision, touch devices are very inadequate.  Think of writing code, for instance.  I’d have 6+ browser tabs open with various manuals, one terminal for building and running the code, one or two more terminals for other random stuff, one editor/IDE window (usually GVim; occasionally Eclipse), and a few more browser tabs that are pure distraction (Gmail, Google+, etc.)  A touchscreen device without overlapping windows just won’t work for this use case.

Android’s multitasking UI would improve over time, but I doubt if it can catch up with current desktop OSes in the next two years.  On the other hand, it’s likely that before the end of 2013 there will be enough high-res monitors and laptops in the market.  When that happens, I may use the laptop a lot more frequently than the tablets.

While tablets may replace laptops for quite a few people going forward, I don’t see myself giving up the functionality I get from desktop OSes.

September 01, 2012

Inspecting 302 HTTP headers

Let’s say you want to inspect the response header for an HTTP request.  But the response is a 302, so your browser immediately navigates to the new location and you never get to see the 302 response (and the headers).

One way to solve this problem would be to install a browser extension that would keep the headers for you even after the redirect has happened.  But I’m not a big fan of installing browser extensions for functionality that I very rarely need.  So I use the wget command instead:
wget -S -O/dev/null --max-redirect=0 'http://www.google.com/'
-S flag tells wget to print the headers to stderr
-O/dev/null discards the response body (by writing it to the null device)
--max-redirect=0 tells wget to not follow any redirects.

This is the 302 redirect google.com sends for redirecting users to country-specific Google domain:
--2012-09-02 09:54:33--  http://www.google.com/
Resolving www.google.com (www.google.com)... 74.125.237.50, 74.125.237.48, 74.125.237.52, ...
Connecting to www.google.com (www.google.com)|74.125.237.50|:80... connected.
HTTP request sent, awaiting response... 
  HTTP/1.1 302 Found
  Location: http://www.google.com.au/
  Cache-Control: private
  Content-Type: text/html; charset=UTF-8
  [...snip...]
  Date: Sat, 01 Sep 2012 23:54:33 GMT
Location: http://www.google.com.au/ [following]
0 redirections exceeded.