Saturday, September 15, 2012

Elisp utility to open SQLplus from a remote host

If you are in a situation when you have to login to an intermediate or jump host to open SQLplus session to your database, here is a utility that you can make use of. You can store this utility in your .emacs file. Then the utility can be invoked interactively from inside Emacs, by typing "Alt-x open-remote-sqlplus-session-interactive".

With autocmpletion, you can specify the session alias that you would like to open.

To make the best use of the utility, you need to specify the list of jump hosts and the SQLplus connection strings in the "alias-to-jumphosts-alist" variable. If you need to run any custom commands immediately after opening SQLplus session (in addition to commands in your login.sql or glogin.sql files), you can add these commands in list-of-sqlplus-setup-commands.

I find this utility to be a tremendous time saver. Hope you also find it the same way.

Here is the utility as a gist:

Saturday, September 08, 2012

Have a timestamp, for Christ's sake!

This post is an appeal to all the developers and content writers. Please take it seriously. Let us help each other by following the simple guideline of timestamping each artifact that is produced.

Whenever you encounter an issue, or while troubleshooting a problem, what is the first thing you do? I just copy and paste the error message in Google and search if someone else have encountered the same problem and if a resolution is available. Sometimes I get conflicting resolutions showing up in the Google results. For e.g. one site might suggest me to perform task A to resolve the problem, while another site might suggest to perform task B. If I have time, I will try each one of them until the issue is resolved. But unfortunately I find it a terrible waste of my time. Instead of appreciating the good intention of the author to share his wisdom, I end up cursing the person.

Why? The reason most of the times is very simple. Those articles don't have a date and time about when they were published. Most of the time, I find that the most recent ones are accurate. Rarely it might be otherwise too. Think how many times you have gone back and updated your old entries when your suggested method will no longer work! In my case, almost none. So, unless someone have a time of reference, they will not be able to compare two solutions to decide which one might be more recent.

So I appeal to all the developers and content writers this:
Please produce all your contents with both date and time. Timestamp all the artifacts that you produce. This will tremendously help everyone and save a lot of time.
Please don't publish an article just with time alone (like "Sun 12:00 PM", as you might find in most of the blogs!). It is just as useless as not having the timestamp at all.

With HTML5's time tag, you can also help the search engines to identify when the artifact was actually produced.

Thursday, September 06, 2012

Who invented email?

Sometime back I received a link in my Facebook account shared by one of my friends which claims that Mr. V.A. Shiva Ayyadurai is the one who invented email. My first reaction was WTH? As far as I know, email existed since early 70s. As per the article, Mr. Ayyadurai invented email  in 1978. I spent a lot of time in that website reading through all the documents and verifying how far it is true. To the best of my knowledge, as per the documented evidence, I am convinced that Mr. Ayyadurai is the inventor of email.

But just around the same time, another link surfaced in Hacker News, with the title "Email Will Never Die - The Man Who Invented It Reveals Why". The article wrongly claims that Mr. Ray Tomlinson was the one who invented email in 1971. While I hold high respect for the hacks of Mr. Tomlinson to send a file from one machine to another machine, the SNDMSG program by no way comes close to the email as we know it today. Worse, until the end of the article, the article doesn't give a single point that substantiates WHY email will never die. The article in itself is too shallow.

Here are my reasons/opinions why Mr. Tomlinson did not invent email.

  1.  To my knowledge, the term email doesn't appear anywhere in literature around early 1970s. In fact, the term doesn't even show up in the first RFC for SMTP published in 1982 (which is the protocol used to send mail messages). You can check that here. Then how can you claim that someone invented email in 1971?
  2. Suppose I wrote a program in 1970s that copied a piece of text from user1@host1 to user2@host2. Later someone comes up with email which also copies a piece of text from user1@host1 to user2@host2. Hence can I claim that I invented email?
  3. What most of us have understood as email is way too different than the messaging systems that existed in the early systems. The RFC 196 provided as a reference in Mr. Tomlinson's web page, doesn't resemble the email systems we use today. For e.g. that RFC or the RFC that obsoletes that doesn't talk about organizing mails in folders (like inbox, sent, etc.) which was first used by the system designed by Mr. Ayyadurai.
  4. It feels like there is a lot of shallow PR cry by BBN. This is a company that has vested interest in claiming to be the first to have invented email.
In summary, give credit where its due. Its a shame that when I submitted a comment for the article with my thoughts, my comment was censored by the author. Hence this article.

Thursday, June 21, 2012

Broken pipe error in Flask server

I am using Flask for some of my internal services. If you haven't used Flask, I would absolutely recommend that you check it out.

Recently I got the following error while I was attempting to serve a page from template. In an attempt to troubleshoot the error, I wasted almost half an hour.

127.0.0.1 - - [19/Jun/2012 17:48:37] "POST /" 500 -
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 55176)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 284, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 310, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 323, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 641, in __init__
    self.finish()
  File "/usr/lib/python2.7/SocketServer.py", line 694, in finish
    self.wfile.flush()
  File "/usr/lib/python2.7/socket.py", line 303, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe
----------------------------------------


If you happen to receive this error, most likely cause is that the template you are attempting to render using "render_template" function is not found under PROJ_ROOT/templates directory. All the templates should be present under the PROJ_ROOT/templates directory. Unfortunately you don't see an accurate error message indicating that the template is missing!

Monday, June 11, 2012

Installing Emacs 24.1

I was excited to see the announcement that Emacs 24.1 has been released.  I wanted to install and try. There were a few glitches that I faced during the installation. I thought it might be useful for someone who might be hitting the same blocks.

Once I downloaded the source code and verified the signature, I unzipped the Emacs 24.1 source code. The first "configure" run gave the following error:
configure: error: You seem to be running X, but no X development libraries
were found.  You should install the relevant development files for X
and for the toolkit you want, such as Gtk+, Lesstif or Motif.  Also make
sure you have development files for image handling, i.e.
tiff, gif, jpeg, png and xpm.
If you are sure you want Emacs compiled without X window support, pass
  --without-x
to configure.
To address this error I had to do the following:
sudo apt-get install libgtk2.0-dev libtiff4-dev libgif-dev libjpeg62-dev libpng12-dev libxpm-dev 
Then when I attempted to run configure again, I got the following error:
configure: error: The required function `tputs' was not found in any library.
These libraries were tried: libncurses, libterminfo, libtermcap, libcurses.
Please try installing whichever of these libraries is most appropriate
for your system, together with its header files.
For example, a libncurses-dev(el) or similar package.
To resolve this error I had to do the following:
sudo apt-get install libncurses-dev
Thats it. The installation was smooth. Here is the summary of commands you need to run:
sudo apt-get install libgtk2.0-dev libtiff4-dev libgif-dev libjpeg62-dev libpng12-dev libxpm-dev libncurses-dev
# You can skip this step if you don't want to verify the signature.
gpg --verify emacs-24.1.tar.bz2.sig emacs-24.1.tar.bz2
tar xvfj emacs-24.1.tar.bz2
cd emacs-24.1
./configure
make
sudo make install

Tuesday, May 29, 2012

Which hashing algorithm to use?

The  answer to the question "which hashing algorithm to use?"  in StackOverflow is one of the best answers I have ever read. You can find the answer here:
http://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed/145633#145633

Mr Ian Boyd, thank you so much for taking time to come up with such an excellent answer.

Tuesday, May 08, 2012

Creating a shortcut to folders in task bar in Windows 7

If you are using Windows 7, you might have noticed that you cannot "pin" a folder in the task bar. You can pin only programs. I wanted to create a shortcut to a folder in the task bar, so that I can open that folder by just a single click.

Here is an excellent hack I came across: http://www.unawave.de/windows-7-tipps/folder-to-taskbar.html?lang=EN. Whoever wrote that tip, a big thank you.

Thursday, April 26, 2012

Patching /etc/resolv.conf file in VMs

I use a Linux VM for my development. I run my VM using VMWare Player. The VM obtains the IP address using a DHCP client run by NetworkManager (it is a part of vmware-tools suite). Every time the VMWare Player issues a new IP address, my /etc/resolv.conf file gets overwritten and I am left with only "localhost" as the search domain.

Some of the machines that I connect to require fully qualified names to resolve. For e.g. I cannot look up host1, instead I should look up host1.corpdomain.com. Hence I should make sure that the /etc/resolv.conf has the correct search directive after every DHCP lease.

The NetworkManager first copies the /etc/dhcp/dhclient.conf file under /var/run/nm-dhclient-eth0.conf and then adds a few extra directives of its own. So all that I had to do to fix the issue is to add the following two lines at the end of /etc/dhcp/dhclient.conf file:

prepend domain-search "corpdomain.com";
prepend dhcp6.domain-search "corpdomain.com";

Please make sure you don't miss the double-quotes and the semi-colon. Otherwise it will silently fail without giving any error. After adding this just restart your VM. Everything should work fine.

Wednesday, April 18, 2012

A minor annoyance of running "rails console" inside Emacs

If you run "rails console" from within Emacs, you might have been annoyed by the output that contains control characters whenever you run a query. Like the one given below:

1.9.3-p125 :001 > BlogPost.all
^[[1m^[[36mBlogPost Load (0.2ms)^[[0m  ^[[1mSELECT "blog_posts".* FROM "blog_posts" ^[[0m
I could not find a satisfactory solution for this anywhere. So I came up with the following solution that works fine for me.


What this code does is to make use of "term" instead of "shell" to run the rails console. In term-mode you have better support for rendering these control chars. To make navigation and kill/yank easier, it switches to line-mode. The default mode is char-mode. You can switch between line-mode and char-mode using C-c C-j and C-c C-k respectively. Hope that helps.

Friday, April 13, 2012

Have a primary key, for Christ's sake!

This posting is a venting of my frustration.

Never ever agree to have a table that doesn't have a primary key. There may be forces of nature that might attempt to convince you to have one, like:

  • Your peers might say you don't need to perform an UPDATE in that table, now or ever
  • You just need that table only for audit or reporting purposes
  • We store data in that table just to go back and refer later which may never happen, so don't bother
  • You may be under a gun where the big boss says "you don't need a primary key, because I say so!"
For Christ's sake, don't yield to any of these things. I was in a limbo recently where I had to make use of one of the legacy tables that didn't have a primary key. This table was once thought as insignificant, but now has suddenly become an important table. The issue is that, for me to perform the operations that I want to perform, I need a primary key.

The issue is that this monster table has more than 40 million rows. Eventually I needed to create a primary key (ID) and back fill all the rows using a sequence. Had to add a trigger to make sure the ID column is populated every time when the application INSERTs a row into that table in future. It was unnecessary hassle.

So, my friend, here are my two cents:
  • Always make sure your table has a primary key. It is very cheap to have one right from the beginning, and populate it using AUTO_INCREMENT (MySQL) or triggers (Oracle), rather than attempting to fix later.
  • If you will perform UPDATEs in a table, make sure you have VERSION column. This is important since it will help you in performing optimistic locking. And if you have more than one instance of application running, it definitely helps. I have seen people using LAST_UPDATE_TIME for optimistic locking. Though that works, it is error prone.
Versioning is an important aspect, which gets easily overlooked. Today you may have only one Tomcat (or any application server) running. Say your product becomes a hit and you need to double the number of application servers. Versioning helps you to perform optimistic locking, and ensure you don't screw up the integrity of data.

Tuesday, April 10, 2012

Converting a byte array to long - a performance test

WARNING: Micro benchmarks are mostly deceiving, if you aren't careful about how to interpret the results. I leave it up to you to interpret these results.

Recently I came across a problem when I had to convert an array of bytes into a long value. The obvious choice was for me to write a bytesToLong method that takes a byte array as an argument and returns a long value. When I dug around a little bit, I found that I could also make use of the ByteBuffer to wrap the bytes and  make use of the getLong() method to get the long value.

I was curious to know if there is any performance benefits of going one way or the other. So I wrote a small micro benchmark, and here is the source code and the results:

The results are given below:
The columns are: number of iterations, time taken by the shift version, time taken by the ByteBuffer version, the ratio between the two times. As you can see, the ByteBuffer version is four times slower than the hand coded version. For my case, this slowness doesn't make any difference. But depending on your application, it may be significant.

Thursday, March 15, 2012

A powerful but lesser known command line option in find command

Let us say you want to find all the files that are ending with .tmp and remove them. I have always used the following command:
find . -name '*.tmp' -exec rm -f {} \;

This will find all the files that are ending with .tmp, and for each file rm is invoked with the file name as argument. Hence if you have 100 files, the rm command will be invoked 100 times.

There is a better way of doing this:

find . -name '*.tmp' -exec rm -f {} +

The "+" at the end tells the find command to concatenate all the file names with a space in between them, and invoke rm only once. To understand how it works, let me slightly change the command and show you:


$ find . -name '*.tmp' -exec echo {} \;
./b.tmp
./a.tmp
$ find . -name '*.tmp' -exec echo {} +
./b.tmp ./a.tmp


Isn't that cool?