Saturday, March 15, 2008

The funniest post I've read in the recent past...

... is Ek, Anek, aur Ekta. The Vishal Patel guy is back. And, how!

Although his website is full of gems that are going to get you LMAOWOPITOAGMTL [1], this one post about the Ek-Anek national integration cartoon is enough to get you in splits!

Checkout the next/previous links at the end of the first page... "Anek chidiyon ki kahaani sunoge?" "haan, haan >>" / "<< nahin bas"! Ha ha!

'Nuff said. (And do click on the "haan, haan >>" link to LMAOWOPITOAGMTL [1]!)

[1] Note: Laughing My Ass Off While Other People In The Office Are Giving Me The Looks!

Tuesday, March 11, 2008

What if you can't design for yourself?

Picking up from Jason's post at SvN:

Apart from the flame war that's going on the comments section there, there is one thing about the "design for yourself" philosophy that has intrigued me. What if you really aren't designing for yourself? What if the software that you are developing/designing is not for your daily use? For example an accounting+finance system that is to be used by hardcore accountants? Do you not concede to how the end user wants the software to function? Don't you lose confidence in your "gut feel" automatically?

The products that 37signals are working on are general purpose products, as such. A project management tool, todo list, CRM application can be used by any company or department. What about specialized software? Can we apply the same principles there?

Sunday, March 09, 2008

How to reset an Oracle sequence at midnight everyday

Oracle, unlike MySQL, does not auto-generate values for the primary key column for you. That means, you can't "auto_increment" a column in Oracle. With each INSERT statement you have to provide the value for the primary key column yourself. Oracle has database sequences to help you generate series of numbers for this purpose.

Sometimes you end up using Oracle sequences for stuff other than as a source of values for your primary key. And sometimes you need to reset the value of the sequence back to 1 at midnight everyday. I ended up with the same problem and I couldn't find a canned solution off the Net for this. I spent a day trying to solve this and ended up learning a lot about Oracle sequences, Oracle packages and PL/SQL, the dbms_lock package, and the dbms_scheduler package.

The problem would be fairly easy to solve if resetting an Oracle sequence were a single atomic SQL statement. No, it turns out that you have to do a bit of circus involving multiple statements to reset the sequence back to 1. I figured that you basically have two options:

  1. Drop the sequence (statement #1) and recreate the sequence (statement #2)

  2. Change the INCREMENT BY property of the sequence to be negative of the CURRVAL (statement #1). Increment the seqeunce (statment #2). Reset the INCREMENT BY property back to 1 (statement #3).


In both the solutions, you run the risk of some other process coming along and doing a seq.nextval on the sequence while the reset is underway. Boom! A bit like getting caught with your pants down.

So, here's what I did:

  1. Create a PL/SQL package in Oracle which acts as a proxy for the sequence. Make sure that no application module does a seq.nextval directly. All requests to get the nextval have to go through the getNextSeq() function/procedure provided by the PL/SQL pacakge.

  2. The getNextSeq() function first acquires a lock in shared mode provided by the dbms_lock package in Oracle. Increments the sequence. Releases the lock, and returns the nextval. (Note: The dbms_lock package is a general purpose lock library. It does not mean that you acquired a lock on the sequence - that's not possible in Oracle, as some gurus told me. You just acquire a lock. Very much like a mutex lock you acquire in programming languages.)

  3. In the same PL/SQL package, you create a function resetSeq() which acquires the same lock in exclusive mode, resets the sequence using either of the solutions given above, and releases the lock.

  4. Now, you can create a scheduled job in the DB using the dbms_scheduler package to run the resetSeq() function at midnight everyday. In fact, you can execute that at whatever frequency/interval you want.


In the process I also realised that Oracle has the capability of doing a fair amount of metaprogramming through the EXECUTE IMMEDIATE statement. You can pass it any string and Oracle tries to parse + execute that as an Oracle statement, much like eval in Ruby or Lisp.

I spent most of my time breaking my head over why dbms_lock.request didn't seem to be working. Then I realized that dmbs_lock.allocate_unique worked on a per session basis. What that means is, if two separate connections called dmbs_lock.allocate_unique to create a lock with the same lock handle, both of them would end up getting lock objects that would behave independently of each other. In which case, effectively, both the processes were working on different locks and the whole purpose of using locks would be defeated. This is why, I'm calling allocate_unique just once, and "hard coding" the lock id in the package definition using Oracle "metaprogramming".

PS: I'm still not sure whether this is the best solution to this problem, but it's a solution that works. Please let me know if you have a better way of solving this.

Here's the script:

set serveroutput on;
declare
lock_handle number;
begin
dbms_lock.allocate_unique('my_lock', lock_handle, 31536000);
dbms_output.put_line('Dropping my_seq');
execute immediate 'drop sequence my_seq';

dbms_output.put_line('Creating my_seq');
execute immediate 'create sequence my_seq minvalue 1 nocache increment by 1';

dbms_output.put_line('Creating my_pkg declaration');
execute immediate 'CREATE OR REPLACE PACKAGE "my_PKG" AS
procedure reset_my_seq;
function get_my_next_seq return number;
END;';

dbms_output.put_line('Creating my_pkg definition');
execute immediate 'CREATE OR REPLACE PACKAGE BODY "my_PKG" AS
my_lock_handle number := ' || lock_handle || ';

procedure reset_my_seq is
lock_status integer;
curr_val integer;
begin
lock_status := dbms_lock.REQUEST(lockhandle => my_lock_handle, lockmode => dbms_lock.x_mode);

execute immediate ''alter sequence my_seq minvalue 0'';
execute immediate ''select my_seq.nextval from dual'' into curr_val ;
execute immediate ''alter sequence my_seq increment by -'' || curr_val ;
execute immediate ''select my_seq.nextval from dual'' into curr_val ;
execute immediate ''alter sequence my_seq increment by 1'';

lock_status := dbms_lock.release(lockhandle => my_lock_handle);
end;


function get_my_next_seq return number is
lock_status integer;
next_seq number;
begin
lock_status := dbms_lock.REQUEST(lockhandle => my_lock_handle, lockmode => dbms_lock.s_mode);
select my_seq.nextval into next_seq from dual;
lock_status := dbms_lock.release(lockhandle => my_lock_handle);
return next_seq;
end;
END;';


-- dbms_output.put_line('Dropping scheduler job');
-- dbms_scheduler.drop_job('reset_my_seq');

dbms_output.put_line('Creating scheduler job');
dbms_scheduler.create_job( job_name=> 'reset_my_seq',
job_type=>'PLSQL_BLOCK',
job_action=> 'begin my_pkg.reset_my_seq; end;',
start_date=> systimestamp,
repeat_interval=>'frequency=daily;interval=1;byhour=0; byminute=0; bysecond=0;',
enabled=>true);
commit;
end;
/

Thursday, February 07, 2008

FOSSKriti at Techkriti 2008 -- The IIT Kanpur Technical Festival

Cleartrip is supporting FOSSKriti – a 4 day mini-conference about Free/Open Source Software. It'll have technical talks, hands-on workshops, hackfests, and general geek chatter.

In an RoR workshop I'll be creating the OARS (Online Academic Registration System) website in 90 minutes – or something that can at least be called the OARS website. My friend Chaitanya will be giving a talk on Common Lisp.

If you're somewhere around, be there – it'll be fun.

FOSSKriti

Trains search by Cleartrip

We've just launched a new product – Cleartrip Trains Search It's simple. It's fast. It's comprehensive. And it rocks! Give it a spin and let us know at Cleartrip Forums

A lot of hard work put in by Piyush, Anurag, of course our rocking UI team (Hrush, Varun, Rakesh, et al).

Saturday, December 29, 2007

Most Persistent Telemarketer

Minutes after I blogged about this I came across this this. Watch it! It's hilarious. (NSFW warning, though)

The Customer Satisfaction Survey From Hell

Reliance Infocomm - How clueless can a company be about customer service. Sample this.

The Background


My billing address has changed since I moved from Goa to Mumbai. I don't have the time (or inclination) to run around Reliance Web Worlds (with characteristically rude people manning the counters) with my address proofs to get the billing address changed. I don't care much about the hard copy of the bill anyways. I pay my bills online and just need a printout of the PDF to submit for official claims.

Reliance has a website which lets you view your past bills and lets you pay bills online. Which is good. Really good. But the problem is, downloading past bills doesn't work most of the time. So, I wanted my bill to land up in my inbox, by email, every month.

I had made this request in the past. I had received my bill via email once (last month), and now it had again stopped coming.

The Call


I called up *333, almost jumping in surprise with the extremely loud "Marathi karita ek daba" (press 1 for Marathi), waited for a decent 90 seconds, and finally being answered by a human.

Me: Maine request kari thi bill email se bhejne ke liye. Ek maheene ka bill email se aaya bhi hai. Uske baad band ho gaya. Kyun band ho gaya?
Reliance human: Sir, yeh number aap hi ka hai? Aapka billing address kya hai?
Me: [tell the old address]
Reliance human: Sir, aapka naam kya hai?
Me: [Tell the name]
Reliance human: To sir aapko apna billing address change karwaana hai?
Me: [edgy] Nahin. Maine yeh nahin bola. Maine bola ki maine email se bill bhejne ki request kari thi. Ek maheene bill aaya. Fir band ho gaya. Kyun?
Reliance human: Sir, hum email se bill bhejte hi nahin hai!
Me: [completely zapped and irritated] Kya baat kar rahin hain aap. Maine khud picchli baar request kari thi. Aapke supervisor se baat kari thi. Ek maheene email se bill bhi aaya hai!
Reliance human: accha sir, ek minute...
[and she puts me on hold. No music, nothing! The line could've been dead for all you know]
Reliance human: Accha sir, humne apne system mein note daal diya hai
Me: Mujhe request number dijiye please [that's one thing you should always ask for when you're talking to the Reliance call center. These guys are in the habit of not taking a request -- a fact that their supervisor has told me in the past]
Reliance human: Nahin sir, is cheez ke liye hum system mein request nahin le sakte!!!
Me: [completely losing it] kya bakwaas kar rahi hain aap... aap kya chahti hain, aapke supervisor se fir baat karni pade mujhe... maine khud picchli baar request kari hai... aur number bhi mila hai
Reliance human: [now on the defence] accha sir, ek min, ek min...
[more wait]
Reliance human: Sir, aapka request number hai XYZ

Finally! Though I still haven't gotten my bill on email. But stay with me, the best is yet to come.

The Customer "Satisfaction" Survey


[phone rings -- I recognize the Reliance number. I'm good at it]
Reliance human: Sir, main Reliance ki taraf se bol raha hoon. Humaari company ko Reliance ki taraf se grahak santushti survey karne ka contract mila hai. Sir kya aapne 27 Dec 12:03 pe Reliance customer care mein request darj karwayi thi
Me: Haan
Reliance human: Sir, kya yeh aapne khud kiya tha ya fir kisi aur ne aapki taraf se kiya tha...
Me: Nahin maine khud kiya tha
Reliance human: Sir, kya aap is survey ke liye apne keemti samay to thoda waqt nikaal sakte hain?
Me: [obviously, dude. I have a bone to pick!] Haan
Reliance human: Theek hai sir, toh fir prashnon ka uttar aap paanch ankon mein de sakte hai, 5 ka matlab bahut santusht, 4 ka matlab santusht, 3 ka matbal na hi santush-na asantusht, 2 ka matlab asantush, aur 1 ka matlab bahut asantush. Sir, kya aapko ankon ki jaankari ho gayi hai?
Me: Haan
Reliance human: To sir, humaara pehla sawaal, aapk poorna roop se, reliance customer care mein hui vartalaap ko kya ank denge
Me: 2
Reliance human: Sir, 2 -- uska matlab?
Me: [wtf?] asantush
Reliance human: Sir, iski wajah kya hai?
Me: kyunki customer care executive meri request lene se mana kar raha tha
Reliance human: Sir, aapka doosra sawal, reliance mein phone milne se lekar customer care executive tak pahunchne mein jo samay laga, usko aap kitne ank dete hain
Me: 4 - santusht
Reliance human: Sir, teesra sawal, customer service executive ke baat karne ke dhang ko aapa kitne ank dete hain?
Me: 3 - na santush, na asantusht
Reliance human: iski koi wajah?
Me: [getting irritated] nahin koi khaas wajah nahin
Reliance human: nahin sir koi wajah to hogi
Me: arre bhai, koi wajah nahin... har cheez ki koi wajah nahin hoti
Reliance human: nahin sir, aap 3, 2, 1, mein wajah bataayenge tabhi to mein yahaan likhoonga na sir.
Me: Mere paas wajah nahin hai... aapko aage ka sawaal poocchna hai toh theek hai... nahin to phone rakh raha hoon main
Reliance human: Nahin sir, aap na to santusht hai, na asantusht hain, iski koi to wajah hogi na..."

[i wish I could bang the phone down! but I had to make do with a simple click of the red button on my cell. That's a fucking problem with these cell phones (especially if you own them) -- they don't aid in anger management as well as landlines do!]

I was left dumbfounded. Seriously, is customer satisfaction so hard to get right? These guys are not even in the right direction!

Wednesday, December 05, 2007

Highbrow v/s Lowbrow

Talking (in part) on how the two cultures, Unix and Microsoft, differ fundamentally, Joel Spolsky nails it in his Talk at Yale:
Anyway, the two cultures roughly correspond to highbrow vs. lowbrow, and in fact, it’s reflected accurately in the curriculum of computer science departments throughout the country. At Ivy League institutions, everything is Unix, functional programming, and theoretical stuff about state machines. As you move down the chain to less and less selective schools Java starts to appear. Move even lower and you literally start to see classes in topics like Microsoft Visual Studio 2005 101, three credits. By the time you get to the 2 year institutions, you see the same kind of SQL-Server-in-21-days “certification” courses you see advertised on the weekends on cable TV. Isn’t it time to start your career in (different voice) Java Enterprise Beans!

In my experience the perfect mix is a "highbrow" computer education (to get the basics right) with a pinch of exposure to the "lowbrow", which will give the person the ability to get stuff done. Not just sit there and come up with beautiful architectures, theoretical proofs, and DSLs which have no frikking use whatsoever.

I've previously written about my experience with an extremely "lowbrow" college when I went recruiting for Cleartrip.

On a separate note, we're always on the lookout for developers who're passionate and thoughtful about the work they do. We are a travel company, but technology is a core component. We can't bear to see sloppy code at any level (and that also includes the HTML). If you think you'd be interested in working with us, drop me a line.

Tuesday, December 04, 2007

Lord of War - Hits your hard, hits you good.

I just finished watching Lord of War. It blew me away. Totally fucking awesome movie. Just love the way it's been narrated. Liked the way the opening credits have been shot. Guffawed at the numerous one liners. Especially liked the one where Yuri Orlov (Nicolas Cage) says this about how his relationship with his trophy wife started:
Some of the most successful relationships are based on lies and deceit. Since that's where they usually end up anyway, it's a logical place to start.

Was surprised to hear the "Bombay Theme" by A.R. Rahman on the soundtrack. It plays in the background after the part where Yuri distributes the arms to the locals to get the Interpol off his back (when Jack Valentine "arrests" him for 24 hours).

The end hits you hard. Really hard.

PS: In case you liked this movie, I would also recommend Blood Diamond and Death of a President.