Thursday, August 13, 2009

Curiosity

After I started blogging, I learned one thing: The same topic has been already blogged by someone else, better. As I try to strictly follow the first rule of programming - DRY - I will have to not repeat myself.

So, I started a new blog called curiosity.srikanths.net where I will just post the links to the answers of my curious questions and have all my questions at one place as an archive. If you're interested, here's the FeedBurner link: feeds.feedburner.com/SrikanthS/Curiosity

Tuesday, June 23, 2009

My Ubuntu Desktop with Compiz and Mac4Lin

I recently tried Mac4Lin, and followed some of the instructions found here on Howto Forge (which is a bit outdated but good enough). Well, this was the result and I'm loving it!

(You've to click on the image to see the original maximized version.)

Plain Desktop:


Win + Tab:


Exposé:


Cube:


Ctrl + Alt + Down:


Crowded Desktop:


Now, I'm really confused if I should give a shot at installing a Hackintosh.

Wednesday, April 29, 2009

Keep Your Head above Water

Water Hyderabad: A plea to not waste water.

Friday, January 9, 2009

On Never Using System.exit()

In one of the code reviews, I got a feedback to not use System.exit() function call at all. This was a little surprising for me but the explanation for that rule was very simple and made total sense. It's because there may be some worker thread is doing some important job (like committing a database transaction) and System.exit() will abruptly kill those threads leading to nasty bugs as you already might know.

The scenario is roughly as follows:

// A program that uses System.exit().

// MainUsingSystemExit.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class MainUsingSystemExit {
  public static void main(String[] args)
      throws IOException { // You should never do this, I'm doing here for the
                           // sake of brevity of the example in the blog.
    DatabaseThread dbThread = new DatabaseThread();
    dbThread.start();

    BufferedReader reader
        = new BufferedReader(new InputStreamReader(System.in));
    while (true) {
      // TIP: In the code below, the letter 'N' is uppercase, you know why? It's
      // because that's the default answer if you don't enter anything. This is
      // a very common convention in CLI apps.
      System.out.print("Do you want to terminate? [y/N]: ");
      String userInput = reader.readLine();

      if ("y".equalsIgnoreCase(userInput)) {
        // The problem with the System.exit() below is simple, the
        // DatabaseThread is killed and that's very bad as you know.
        System.exit(0);
      }
    }
  }
}

// DatabaseThread.java
public class DatabaseThread extends Thread {
  public void run() {
    // Some db related operation.
    while (true) {
      try {
        Thread.sleep(5000);
      } catch (InterruptedException e) {}

      System.out.println("Database thread is still alive.");
    }
  }
}

So, how do we deal with such a code, in a clean way from the design point of view too? Solution: Observer pattern to the rescue!

We'll create a listener interface called ShutdownListener which will have a single method called shutdown() which is invoked when the system is about to go down. Those who'd like to clean-up stuff before shutdown can implement the interface and do their clean-up in the shutdown() method.

// A program that DOES NOT use System.exit().
public interface ShutdownListener {
  // Called when it's time to shutdown.
  public void shutdown();
}

And the DatabaseThread is one such class that should implement the ShutdownListener interface.

// DatabaseThread.java (modified)
public class DatabaseThread
    extends Thread
    implements ShutdownListener {
  private boolean shutdown;

  public void run() {
    // Some db related operation.
    while (!shutdown) {
      try {
        Thread.sleep(5000);
      } catch (InterruptedException e) {}

      System.out.println("Database thread is still alive.");
    }

    System.out.println("Database thread going down.");
  }

  public void shutdown() {
    shutdown = true;
    this.interrupt();
  }
}

The synchronization issues aren't handled here to not clutter the code in the blog but should be taken care.

We'll have a ShutdownHandler class where all the listeners will be registered. It can also register a shutdown hook* which does nothing but calls its own initiateShutdown() method which goes and calls the shutdown() method of all the registered ShutdownListeners.

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ShutdownHandler {
  private List shutdownListeners;

  public ShutdownHandler() {
    shutdownListeners = new ArrayList();

    // For handling TERM, INT signals.
    Runtime.getRuntime().addShutdownHook(new Thread() {
      public void run() {
        ShutdownHandler.this.initiateShutdown();
      }
    });
  }

  public void registerShutdownListener(ShutdownListener listener) {
    shutdownListeners.add(listener);
  }

  public void initiateShutdown() {
    Iterator iterator = shutdownListeners.iterator();

    while (iterator.hasNext()) {
      ShutdownListener listener = (ShutdownListener) iterator.next();
      listener.shutdown();
    }
  }
}

And finally, the new main():

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class MainWithoutSystemExit {
  public static void main(String[] args) throws IOException {
    DatabaseThread dbThread = new DatabaseThread();
    dbThread.start();

    ShutdownHandler shutdownHandler = new ShutdownHandler();
    shutdownHandler.registerShutdownListener(dbThread);

    BufferedReader reader
        = new BufferedReader(new InputStreamReader(System.in));
    while (true) {
      System.out.print("Do you want to terminate? [y/N]: ");
      String userInput = reader.readLine();

      if ("y".equalsIgnoreCase(userInput)) {
        // Calling the ShutdownHandler's shutdown() method
        // instead of System.exit()
        shutdownHandler.initiateShutdown();
        return;
      }
    }
  }
}

As you can see, the ShutdownHandler's initiateShutdown() is called instead of System.exit() in the new main() method. Now if we've a new SocketThread or some other thread that needs a graceful exit, all we've to do is implement ShutdownListener and register it with the ShutdownHandler.

Now, go look in your code and see how you can eliminate System.exit() calls altogether. See if that brings out a better design. Or do you think this idea of not using System.exit() is just crazy?

* Thanks to Ajeya for reminding me about shutdown hooks.

Make Sure to Return the Right Exit Codes

Every process that finished its execution can return an integer value back to the parent process indicating its result. Often an exit code of '0' means the child process was executed successfully and a value greater than '0' indicates failure.

On a *NIX machine, the variable '$?' has the exit code returned by the last executed process. For example:

srikanth@workstation - [~]
$ find . -nam "*.c"              # Intentionally trying a wrong option
find: invalid predicate `-nam'

srikanth@workstation - [~]
$ echo $?
1                                # >0, process failed

srikanth@workstation - [~]
$ find . -name "*.c"
./test.c

srikanth@workstation - [~]
$ echo $?
0                                # Process execution successful

srikanth@workstation - [~]
$

But too often I've seen programmers not taking care of the exit codes for the applications or some small-time utility programs they write. I've done it myself when I started out programming partly because I didn't know the significance of the exit codes. But they are very helpful.

Sometimes you've to spawn a new process from your program to accomplish something 'cause you don't have an API exposed for it in your language. At these times, the exit code returned by the child process can be extremely useful.

So, when writing some new command line utility or an application, remember to:
  • Always return an exit code: 0 for success; 1 <= exit_code <= 255 for failure
  • Don't return negative exit codes: I've seen this in some code; I didn't know it was invalid till someone had an issue with it. At least on UNIX, the valid exit codes are from 0 to 255
  • Document the exit codes: Like 1 for database failure, 2 for mis-configuration, etc.
That's it, happy coding!

Friday, January 2, 2009

My Simple New Year Resolutions for 2009

I never took new year resolutions but in the previous year at some point I decided to create a list of things I wanted to learn and published it in my blog. It worked very well, I received a lot of invaluable comments, I kept coming back to the same post to keep myself on track. It really helps, you should write one too.

So this year I decided to broaden the scope of my resolutions from just technology to my life as a whole. These are my simple resolutions:

Do As Less As Possible

Sometimes I feel like doing everything, I mean at once. Like learning C++, completing a networking-related certification, mastering Python, doing an Open Source project, going for gym, learning Emacs, participating in Mumbai marathon, photography and watching falling stars.

And the problem I have is, when I'm doing something I would want to do something else. So this year, I decided to do only 3 things:
  • C++
  • Algorithms and Data Structures
  • Gymming
The picky professor in you may say that "Algorithms and Data Structures" are 2 things, but... it's okay, they're a bit related.


Take It Easy

There's something in me that's absolutely restless (I guess that's there in everyone). It constantly screams at you to do something great and significant in life but it doesn't have the patience to wait for you to complete. It wants us to do many things. From now on, I'll refuse to listen to that voice. I've heard it enough, now I want to concentrate on doing it.

It's OK to fail sometimes. It's OK to not achieve some of your goals. It's absolutely fine to do nothing productive on weekends. It's perfectly cool to watch a crappy Hindi movie with coworkers. It's nice to chill out and feel good. It's in fact re-energizing. It's nice to visit places. It's good to pass time chit-chatting with friends on weekends. All work and no play will only make Srikanth a dull boy. But dull no more :)


Be Mr.Fit

I wanted to run like Matt Damon in The Bourne Supremacy today morning. I don't know why. Just wanted to run like there's no ending. That's when I realized I didn't run since I left college. I didn't play any outdoor games too. It's time to do all that, again. And it's also the time to hit the gym to keep me fit.

My friend Ranganathan told me a few inspiring words when I met him recently, it was roughly: "When you lose everything in life, such as money and power, and if you're still alive, the only thing remaining is your body."

So, what are your new year resolutions?

Saturday, November 29, 2008

Srikanth's Favorite Firefox Add-ons

After Google Chrome came out, I haven't been using Firefox a lot. And it's for a very simple reason: speed. Especially the start-up speed. I'm a speed freak and I don't like to keep my browsers opened when I'm working. I'd like to open, search for whatever I was looking for and close the damn window as soon as possible and get back to work. I came to know that Minefield is very fast, but for some reason I like Chrome for quick searching. But on weekends I do full-time browsing. And for that, I use Firefox because I miss one thing in Chrome: add-ons.

I've a few favorite Firefox add-ons and I'm finding browsing irritating and difficult without them in Chrome. These are the my favorites. These may not be in your favorites-list, but hey, I'm me and you're you.

Adblock

Ads can be very annoying, especially when they're embedded in the middle of the contents. Adblock Plus is a must-have plugin if you don't want to see those shining ads that distract you.

Flashblock

This is my next favorite add-on. Flash can consume a lot of bandwidth and slow down the rendering of the other page elements. I find it better to block those flash contents when the page loads and then play it if necessary.

Firebug

I'm not a web-developer, still I find this add-on extremely useful. A couple of my usages are:
  • Tweaking any page and removing unwanted elements before printing
  • Learning CSS and HTML (a better way to view the source)
When I take printouts, I'd like to have the fonts set to my favorite ones. I love to read if the fonts happen to please my eye. Firebug provides me the easy way to change the fonts used by the web-page to whatever I like. And it can also remove the unwanted elements from the page. If you haven't tried Firebug, it's high time you do it.

Menu Editor

Chrome and Firefox place "Open Link in New Tab" menu item at different positions in their context menus. And "Open Link in New Window" is something I never use. Menu Editor add-on helps me customize my Firefox menus (Duh!). I remove all the useless links (useless to me) like Back, Forward, Stop, Refresh, etc. And this add-on also helps me in having the "Open Link in New Tab" menu item's position at the same place in both the browsers I use.

Direct Link

I love this add-on. You can select text, right-click to open it as a link in a new tab (if it's a URL), or as an article in Wikipedia or to do an I'm Feeling Lucky Google search.

Paste to Tab and Go

Unfortunately, Paste and Go add-on is not available for Firefox 3. So the next best thing I could find was this one. I realized this is extremely useful when I started using Chrome. It felt stupid to paste the URL and then click on the Go button to start loading.

IE Tab

Useful when that stupid government site refuses to load in any browser other than IE.

Greasemonkey

People love this but for some reason, I rarely use it. I have "Textarea Resize" script installed but even that I've only used it a very few times. I think this feature (Textarea Resize) should be an out of the box feature in Firefox. Anyway, I like that monkey in its icon but I'm gonna remove this now. Do you think I'm missing some amazing script? Please leave your suggestion in the comments if I'm doing so.

I also have "Customize Google" installed but most of what it does is already incorporated as out of the box features, but I'll let it stay. Some other minor tweaks I do and I don't are:
  • Disable plugins like Acrobat Reader, Google Update
  • No themes, just the default
  • Monospace font as Consolas (I love Consolas)
So, what's your favorite add-on and why? What are the tweakings you do after installing Firefox?