<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Vysnu &#187; chaff</title>
	<atom:link href="http://vysnu.com/tag/chaff/feed/" rel="self" type="application/rss+xml" />
	<link>http://vysnu.com</link>
	<description>Unchecked Ramblings, writing, code and more.</description>
	<pubDate>Tue, 29 Jul 2008 00:30:28 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<item>
		<title>Nginx Startup Script for CentOS &#038;&#160;Redhat</title>
		<link>http://vysnu.com/log/2008/07/19/nginx-startup-script-for-centos-redhat.html</link>
		<comments>http://vysnu.com/log/2008/07/19/nginx-startup-script-for-centos-redhat.html#comments</comments>
		<pubDate>Sat, 19 Jul 2008 11:19:25 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<guid isPermaLink="false">http://vysnu.com/?p=995</guid>
		<description><![CDATA[Had to make an Nginx startup script for CentOS today. It&#8217;s here, adapted from other scripts found on the net. Move it to /etc/init.d/, chmod +x, and /sbin/chkconfig &#8212;add&#160;nginx ]]></description>
			<content:encoded><![CDATA[Had to make an Nginx startup script for CentOS today. It&#8217;s <a href="http://vysnu.com/files/nginx">here</a>, adapted from other scripts found on the net. Move it to /etc/init.d/, chmod +x, and /sbin/chkconfig &#8212;add&nbsp;nginx ]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/07/19/nginx-startup-script-for-centos-redhat.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Wordle&#160;Delicious</title>
		<link>http://vysnu.com/log/2008/06/24/wordle-delicious.html</link>
		<comments>http://vysnu.com/log/2008/06/24/wordle-delicious.html#comments</comments>
		<pubDate>Tue, 24 Jun 2008 16:21:41 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<guid isPermaLink="false">http://vysnu.com/?p=981</guid>
		<description><![CDATA[I just visualized my delicious tags using wordle, and they look good! Thought I&#8217;ll share! Note: they use Java instead of Flash for these effects,&#160;interesting!
]]></description>
			<content:encoded><![CDATA[<p>I just visualized my delicious tags using <a href="http://wordle.net/">wordle</a>, and they look good! Thought I&#8217;ll share! Note: they use Java instead of Flash for these effects,&nbsp;interesting!</p>
<p><a href='http://vysnu.com/wp-content/uploads/2008/06/wordle-delicious-vishnu.png'><img src="http://vysnu.com/wp-content/uploads/2008/06/wordle-delicious-vishnu-300x199.png" alt="" title="Wordle Delicious Vishnu" width="300" height="199" class="alignnone size-medium wp-image-980" /></a></p>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/06/24/wordle-delicious.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>India-STD-Identifier and a Thrift Interface Between Ruby and&#160;PHP</title>
		<link>http://vysnu.com/log/2008/06/13/india-std-identifier-and-a-thrift-interface-between-ruby-and-php.html</link>
		<comments>http://vysnu.com/log/2008/06/13/india-std-identifier-and-a-thrift-interface-between-ruby-and-php.html#comments</comments>
		<pubDate>Fri, 13 Jun 2008 09:32:08 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<guid isPermaLink="false">http://vysnu.com/?p=968</guid>
		<description><![CDATA[So there was interesting and possibly useful problem that I wanted to tackle. Get a landline STD BSNL number and find out the location and state. As you can see, it&#8217;s a simple mapping problem with the map being available from here (just leave everything blank and hit search). The idea was to parse that [...]]]></description>
			<content:encoded><![CDATA[<p>So there was interesting and possibly useful problem that I wanted to tackle. Get a landline <span class="caps">STD</span> <span class="caps">BSNL</span> number and find out the location and state. As you can see, it&#8217;s a simple mapping problem with the map being available from <a href="http://www.bsnl.co.in/stdsearch.php">here</a> (just leave everything blank and hit search). The idea was to parse that html file, extract the good bits and return an array of hashes. Since the easiest language to do this is Ruby I chose to use&nbsp;that.</p>
<p>The implementation itself is just bits of activesupport and hpricot magic (nothing to write home about), but after I did the simple ruby client, I thought about writing up a webserver frontend for it. In the ruby world, deployments a bitch (maybe <a href="http://modrails.com/">phusion passenger</a> - now that it has support for rack - will change this). The ideal way for a simple script like this to be deployed is just to write a single page <span class="caps">PHP</span> file. How to call the ruby function&nbsp;though?</p>
<p>Enter <a href="http://wiki.apache.org/thrift/">thrift</a> [<a href="http://developers.facebook.com/thrift/">2</a>]. I&#8217;ve always wanted to play around with it and this seemed a perfect opportunity. The magic with thrift is that it works with a service definition that defines the functions to be used and auto-generates most of the interface code. You just have to write it&#8217;s&nbsp;implementation.</p>
<p>
<a href='http://vysnu.com/wp-content/uploads/2008/06/picture-1.png'><img src="http://vysnu.com/wp-content/uploads/2008/06/picture-1-300x81.png" alt="" title="STD Identifier 1" /></a><br />
<a href='http://vysnu.com/wp-content/uploads/2008/06/picture-2.png'><img src="http://vysnu.com/wp-content/uploads/2008/06/picture-2-300x124.png" alt="" title="India STD Identifier 2" /></a>
</p>
<div class="clear"></div>
<p>First you have to make a service definition like&nbsp;this:</p>
<pre>
<code>
service STDService {
   map&lt;string, string&gt; lookup(1:string lookup)  
}
</code>
</pre>
<p>Then run the thrift&nbsp;generator:</p>
<pre>
<code>
thrift --gen rb -php std.thrift
</code>
</pre>
<p>This will create two folders in the source tree: gen-rb and gen-php which contains stubs for client and server implementations of the thrift interface. A lot of the boilerplate code is written for you so you don&#8217;t have to bother, but you do have to write the implementation at the client and server&nbsp;end.</p>
<p>This is how the client bit looks like (in&nbsp;<span class="caps">PHP</span>):</p>
<pre>
<code>
function lookup_number($number) {
  $transport = new TBufferedTransport(new TSocket(&#x27;localhost&#x27;, 9090));
  $protocol = new TBinaryProtocol($transport);
  $client = new STDServiceClient($protocol);

  $transport-&gt;open();
  $info = $client-&gt;lookup($number);
  $transport-&gt;close();
  
  return $info;
}
</code>
</pre>
<p>The relevant server bit is&nbsp;this:</p>
<pre>
<code>
class STDServiceHandler 
  def initialize
    @std_parser = STDParser.instance
  end
  
  def lookup(number)
    @std_parser.query(number)
  end
end
  
handler = STDServiceHandler.new()
processor = STDService::Processor.new(handler)
transport = TServerSocket.new(9090)
transportFactory = TBufferedTransportFactory.new()
server = TSimpleServer.new(processor, transport, transportFactory)
 
puts &quot;Starting the STDService server...&quot;
server.serve()
puts &quot;Done&quot;
</code>
</pre>
<p>The original files are <a href="http://code.google.com/p/india-std-identifier/source/browse/trunk/std_client.php">here</a> and <a href="http://code.google.com/p/india-std-identifier/source/browse/trunk/std_server.rb">here</a>.</p>
<p>It&#8217;s nice to see how it works: I fire up Apache, point to my <span class="caps">PHP</span> file and once I submit the form, all the interaction happens behind the scenes automatically. Thrift makes it easy to call one language from the&nbsp;other.</p>
<p><a href="http://code.google.com/p/india-std-identifier/">India <span class="caps">STD</span> identifier</a> is up at&nbsp;googlecode.</p>
<p>A quick addendum on how you get started with&nbsp;Thrift:</p>
<ol>
<li>You need boost C++ to compile thrift so get that&nbsp;installed.</li>
<li>Download the thrift source from <a href="http://developers.facebook.com/thrift/">Facebook</a> and do a <code>./configure</code> <code>make</code> and <code>make install</code></li>
<li>Be sure to install the necessary language bindings from lib/. For <span class="caps">PHP</span> these are simple <span class="caps">PHP</span> files (although there seems to be a native C extension to speed things up), for Ruby and Python they employ the native setuptools&nbsp;interface.</li></ol>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/06/13/india-std-identifier-and-a-thrift-interface-between-ruby-and-php.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Five Awesome and Small Unix&#160;Tools</title>
		<link>http://vysnu.com/log/2008/06/08/five-awesome-and-small-unix-tools.html</link>
		<comments>http://vysnu.com/log/2008/06/08/five-awesome-and-small-unix-tools.html#comments</comments>
		<pubDate>Sat, 07 Jun 2008 19:56:14 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<guid isPermaLink="false">http://vysnu.com/?p=962</guid>
		<description><![CDATA[The UNIX philosophy has always been to tie in small tools and make a bigger whole. During the course of my programming and sysadmin carer, I&#8217;ve found these tools to be invaluable, and I&#8217;ve often noticed that many people don&#8217;t know about&#160;them:  Rlwrap  This binds functionality of the readline library to applications which [...]]]></description>
			<content:encoded><![CDATA[<p>The <span class="caps">UNIX</span> philosophy has always been to tie in small tools and make a bigger whole. During the course of my programming and sysadmin carer, I&#8217;ve found these tools to be invaluable, and I&#8217;ve often noticed that many people don&#8217;t know about&nbsp;them:</p>  <h3>Rlwrap</h3>  <p>This binds functionality of the readline library to applications which doesn&#8217;t have native readline bindings. Ever wanted the bash-shell Ctrl+R reverse history search in another <span class="caps">REPL</span>? Just start the program with <a href="http://utopia.knoware.nl/~hlub/uck/software/">Rlwrap</a> like so (this is for Jan&#8217;s really nice <a href="http://jan.kneschke.de/projects/php-shell/">php-shell</a>):</p>  <pre><code>rlwrap php-shell

</code></pre>

<p>This sort of a thing makes working with the otherwise clumsy php-shell a&nbsp;breeze.</p>

<h3>Daemonize</h3>

<p>Often you want to run programs as a daemon but they themselves don&#8217;t have any sort of functionality like that. <a href="http://www.clapper.org/software/daemonize/">Daemonize</a> comes to the rescue. (For ruby programs that I write I use the similarly named but much more capable <a href="http://daemons.rubyforge.org/">daemons</a> gem). Use this like&nbsp;so:</p>

<p></p>

<pre><code>daemonize tail -f log/apache&gt;log &gt; /home/vishnu/.log
</code></pre>

<h3>Redir</h3>

<p><a href="http://sammy.net/~sammy/hacks/">Redir</a> is another gem. It redirects transparently <span class="caps">TCP</span>/<span class="caps">IP</span> traffic from one port to another <span class="caps">IP</span> and port. Use this for <span class="caps">IP</span> masking and&nbsp;redirect:</p>

<p></p>

<pre>redir --lport=81&nbsp;--cport=80</pre>

<h3>Dtach</h3>

<p>Dtach is again great at what it does. It&#8217;s like daemonize, but it allows you to detach and attach from a running process. I&#8217;ve <a href="http://vysnu.com/log/2008/03/04/dtach-a-brilliant-daemonizer.html">written about this before</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/06/08/five-awesome-and-small-unix-tools.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Most. Irritating. CAPTCHA.&#160;Ever.</title>
		<link>http://vysnu.com/log/2008/05/12/most-irritating-captcha-ever.html</link>
		<comments>http://vysnu.com/log/2008/05/12/most-irritating-captcha-ever.html#comments</comments>
		<pubDate>Sun, 11 May 2008 21:41:48 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<guid isPermaLink="false">http://vysnu.com/?p=941</guid>
		<description><![CDATA[  Please enter all letters having a cat below. Enough&#160;said.]]></description>
			<content:encoded><![CDATA[<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" border="0" alt="Picture 2" align="right" src="http://vysnu.com/wp-content/uploads/2008/05/picture-2-thumb.png" width="423" height="214" /></p>  <p>Please enter all letters having a cat below. Enough&nbsp;said.</p>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/05/12/most-irritating-captcha-ever.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Hpricot/LibXML&#160;Benchmark</title>
		<link>http://vysnu.com/log/2008/04/29/hpricotlibxml-benchmark.html</link>
		<comments>http://vysnu.com/log/2008/04/29/hpricotlibxml-benchmark.html#comments</comments>
		<pubDate>Tue, 29 Apr 2008 11:58:16 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<guid isPermaLink="false">http://vysnu.com/?p=931</guid>
		<description><![CDATA[I&#8217;m off to release an internal XML conversion script. I began using Hpricot, but after hearing good things about LibXML, decided to switch to that. Here&#8217;s a&#160;benchmark:


real	0m11.692s
user	0m11.497s
sys	0m0.188s


&#8230; for Hpricot&#160;versus&#8230;


real	0m6.441s
user	0m6.258s
sys	0m0.177s


&#8230; for LibXML
So that&#8217;s almost twice as fast. Nice to&#160;know.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m off to release an <a href="http://mobme.in">internal</a> <span class="caps">XML</span> conversion script. I began using Hpricot, but after hearing good things about LibXML, decided to switch to that. Here&#8217;s a&nbsp;benchmark:</p>
<pre>
<code>
real	0m11.692s
user	0m11.497s
sys	0m0.188s
</code>
</pre>
<p>&#8230; for <a href="http://code.whytheluckystiff.net/hpricot/">Hpricot</a>&nbsp;versus&#8230;</p>
<pre>
<code>
real	0m6.441s
user	0m6.258s
sys	0m0.177s
</code>
</pre>
<p>&#8230; for <a href="http://libxml.rubyforge.org/">LibXML</a></p>
<p>So that&#8217;s almost twice as fast. Nice to&nbsp;know.</p>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/04/29/hpricotlibxml-benchmark.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Symfony 0.6.2 Sandbox&#160;Script</title>
		<link>http://vysnu.com/log/2008/04/10/symfony-062-sandbox-script.html</link>
		<comments>http://vysnu.com/log/2008/04/10/symfony-062-sandbox-script.html#comments</comments>
		<pubDate>Thu, 10 Apr 2008 10:51:09 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<guid isPermaLink="false">http://vysnu.com/?p=919</guid>
		<description><![CDATA[This is for people who still use the old Symfony&#160;0.6.2.
Get the script from here and execute it&#160;so:


sh ./symfony_sandbox.sh


This is largely plagiarized from the create quickstart script from the Symfony SVN but changed to make the pake install&#160;work.]]></description>
			<content:encoded><![CDATA[<p>This is for people who still use the old Symfony&nbsp;0.6.2.</p>
<p>Get the script from <a href="http://vysnu.com/files/symfony_sandbox.sh">here</a> and execute it&nbsp;so:</p>
<pre>
<code>
sh ./symfony_sandbox.sh
</code>
</pre>
<p>This is largely plagiarized from the <a href="http://trac.symfony-project.com/browser/tags/RELEASE_0_6_2/bin/create_quickstart.sh">create quickstart script</a> from the Symfony <span class="caps">SVN</span> but changed to make the pake install&nbsp;work.</p>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/04/10/symfony-062-sandbox-script.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>kup.in: URL redirection off Google&#8217;s App&#160;Engine</title>
		<link>http://vysnu.com/log/2008/04/09/kup-url-redirection-off-google-appengine.html</link>
		<comments>http://vysnu.com/log/2008/04/09/kup-url-redirection-off-google-appengine.html#comments</comments>
		<pubDate>Tue, 08 Apr 2008 21:50:32 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<guid isPermaLink="false">http://vysnu.com/?p=914</guid>
		<description><![CDATA[First the URL: Kup.in is a fast URL redirection service run off Google&#8217;s new App&#160;Engine.
This was mostly a test project than anything else, just to gauge how easy App Engine is to start up and get going (very easy!). I&#8217;ll post in detail later, but here are bulleted&#160;observations:

I&#8217;ve been sitting on this project for ~6 [...]]]></description>
			<content:encoded><![CDATA[<p>First the <span class="caps">URL</span>: <a href="http://www.kup.in/">Kup.in</a> is a fast <span class="caps">URL</span> redirection service run off Google&#8217;s new App&nbsp;Engine.</p>
<p>This was mostly a test project than anything else, just to gauge how easy <a href="http://code.google.com/appengine/">App Engine</a> is to start up and get going (very easy!). I&#8217;ll post in detail later, but here are bulleted&nbsp;observations:</p>
<ol>
<li>I&#8217;ve been sitting on this project for ~6 months. The dilemma was that if I did this in <span class="caps">PHP</span>, I&#8217;d be slow coding it (and also ugly) but fast to deploy. If I did this in Python/Ruby, it&#8217;d be much easier, but deployment&#8217;s a bitch. With the App Engine, deployment is a simple <code>appcfg.py update .</code> which is uber&nbsp;cool.</li>
<li>You&#8217;ve got to have py25-openssl installed if you&#8217;re on&nbsp;Macports.</li>
<li>I couldn&#8217;t get Django templates to work (some <code>import _md5</code> error which I suspect again is my Macports). I didn&#8217;t need templates&nbsp;here.</li>
<li>The code is <a href="http://github.com/gvishnu/kup/tree/master">opensource</a> on Github. Fork it and do what you will! I&#8217;ll decide on a license after I wake&nbsp;up!</li>
</ol>
<p>Speaking of which, it&#8217;s 3 in the morn here and I&#8217;ve got office&nbsp;tomorrow!</p>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/04/09/kup-url-redirection-off-google-appengine.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>file_get_contents_with_timeout</title>
		<link>http://vysnu.com/log/2008/04/06/file_get_contents_with_timeout.html</link>
		<comments>http://vysnu.com/log/2008/04/06/file_get_contents_with_timeout.html#comments</comments>
		<pubDate>Sun, 06 Apr 2008 07:52:58 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<guid isPermaLink="false">http://vysnu.com/?p=913</guid>
		<description><![CDATA[So here&#8217;s a piece of code which I think you guys will like. It&#8217;s a URL call with timeout function in&#160;PHP. 


/* This works only for simple URIs
  Returns:

  array(headers, body): if everything&#x27;s fine.
  TIMED OUT if it times out.
  UNABLE TO OPEN if we can&#x27;t connect to host.
  */
private [...]]]></description>
			<content:encoded><![CDATA[<p>So here&#8217;s a piece of code which I think you guys will like. It&#8217;s a <span class="caps">URL</span> call with timeout function in&nbsp;<span class="caps">PHP</span>.</p> 
<pre>
<code>
/* This works only for simple URIs
  Returns:

  array(headers, body): if everything&#x27;s fine.
  TIMED OUT if it times out.
  UNABLE TO OPEN if we can&#x27;t connect to host.
  */
private function file_get_contents_with_timeout($url, $read_timeout = 5, $connection_timeout = 5) {
  $url_parts = parse_url($url);

  $host = $url_parts[&#x27;host&#x27;];
  $get = $url_parts[&#x27;path&#x27;] . &#x27;?&#x27; . $url_parts[&#x27;query&#x27;];

  $fp = fsockopen($host, 80, $errno, $errstr, $connection_timeout);
  if (!$fp) {
    return &quot;UNABLE TO OPEN&quot;;
  } else {
    $out = &quot;GET $get HTTP/1.1\r\n&quot;;
    $out .= &quot;Host: $host\r\n&quot;;
    $out .= &quot;Connection: Close\r\n\r\n&quot;;

    fwrite($fp, $out);
    stream_set_timeout($fp, $read_timeout);

    $result = stream_get_contents($fp);
    $divider = strpos($result, &quot;\r\n\r\n&quot;);
    $headers = substr($result, 0, $divider);

    $body = substr($result, $divider, strlen($result));

    $info = stream_get_meta_data($fp);

    fclose($fp);

    if ($info[&#x27;timed_out&#x27;]) {
      return &#x27;TIMED OUT&#x27;;
    } else {
      return array(&#x27;headers&#x27; =&gt; $headers, &#x27;body&#x27; =&gt; $body);
    }
  }
}
</code>
</pre>
<p>Yup, a bit crude, but hey it works for me! (Oh, and it probably needs <span class="caps">PHP5</span>). Feel free to take the core logic out and wrap it up in exceptions and what have&nbsp;you.</p>
<p>Why did I have to write this contraption? Ah, the joys of the Indian <span class="caps">SMS</span> scene. Let me take you through a tour: <a href="http://fastalerts.in/">Fastalerts</a> is a bulk <span class="caps">SMS</span> solution for end users and resellers. The web frontend is written in <span class="caps">PHP</span> using <a href="http://www.symfony-project.org/">Symfony</a> (an older version, 0.6). The <a href="http://api.fastalerts.in/fastclient/"><span class="caps">API</span></a> is written in plain <span class="caps">PHP</span> and it connects to a <span class="caps">SOAP</span>-based (using nuSOAP) <span class="caps">SMS</span> sending&nbsp;solution.</p>
<p>This is a comment I have on top of the new backend code which sums up all the&nbsp;complexity:</p>
<pre>
<code>
/*
  A note on message sending.

  These actions have to happen as transactions:
  * Calling the GATEWAY.
  * Entering data into LOGS.
  * Reducing CREDITS.

  ONLY if:
  * User has "enough" credits.
  * Input is valid (numbers and mesage)
  * User has valid credentials

  AND we have to handle:
  * Gateway timeouts
  * Gateway errors
  * CDMA senderid correction.

  ALSO:
  If the user doesn't have enough credits to send the entirety of numbers,
  messages are sent until his credits are exhausted.

  AND:
  A separate status message is returned for each of these conditions.

  BUT WE ENSURE:
  That everything is logged appropriately:
  
  * All successfully sent messages are logged and credits reduced.
  * In every other case, credits are NOT reduced (we are customer friendly).
  * When gateway times out or errors out, the messages are logged.

*/
</code></pre>

<p>Interested people should note that there is a lot more you can add on to this: dynamic gateway switches (automatic failover), regular gateway tests, more backend support etc. but this is the bare minimum that&#8217;s needed for the backend to work. If you spend some time thinking about the problem, you&#8217;ll come to the realization that this&nbsp;bit:</p>
<pre>
<code>
 AND we have to handle:
  * Gateway timeouts
  * Gateway errors
</code>
</pre>
<p>means that we have to handle gateways that time out and never return a response. Most of the <a href="http://en.wikipedia.org/wiki/SMPP"><span class="caps">SMPP</span></a> providers in India use something called <a href="http://nowsms.com/">NowSMS</a> to manage their backend connectivity to the operator. In short: we connect to a vendor via his common gateway, he routes it (depending on destination) to multiple operators. NowSMS exposes a simple <span class="caps">HTTP</span> service (a <span class="caps">URL</span> call in other words) to add <span class="caps">SMS</span> to the vendor queue and it&#8217;s this service that&#8217;s preferred by a majority of the good vendors. However, <span class="caps">HTTP</span> traffic being what it is, a monolithic backend in <span class="caps">PHP</span> will stall if the request doesn&#8217;t return a response. Hence that <code>file_get_contents_with_timeout</code>.</p>
<p>Note: this is hardly an ideal solution (that would be a separate daemon). But without adding moving parts, this simple function should increase the reliability of our&nbsp;backend.</p>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/04/06/file_get_contents_with_timeout.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>How to Design&#160;Programs</title>
		<link>http://vysnu.com/log/2008/04/05/how-to-design-programs.html</link>
		<comments>http://vysnu.com/log/2008/04/05/how-to-design-programs.html#comments</comments>
		<pubDate>Fri, 04 Apr 2008 20:11:54 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[beginner]]></category>

		<category><![CDATA[htdp]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[scheme]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2008/04/05/how-to-design-programs.html</guid>
		<description><![CDATA[How to Design Programs: An Introduction to Computing and Programming: 
A computer&#8217;s language of instruction and information is a PROGRAMMING LANGUAGE. Information expressed in a programming language is called DATA. There are many flavors of data.  Wish somebody had taught programming this way in our college!  ]]></description>
			<content:encoded><![CDATA[<a href="http://www.htdp.org/2003-09-26/Book/curriculum-Z-H-4.html">How to Design Programs: An Introduction to Computing and Programming</a>: 
A computer&#8217;s language of instruction and information is a <span class="caps">PROGRAMMING</span> <span class="caps">LANGUAGE</span>. Information expressed in a programming language is called <span class="caps">DATA</span>. There are many flavors of data. <br /> Wish somebody had taught programming this way in our college! <img src='http://vysnu.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/04/05/how-to-design-programs.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Mobshare.in Broadcast&#160;Widget</title>
		<link>http://vysnu.com/log/2008/03/25/mobsharein-broadcast-widget.html</link>
		<comments>http://vysnu.com/log/2008/03/25/mobsharein-broadcast-widget.html#comments</comments>
		<pubDate>Tue, 25 Mar 2008 16:41:40 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[broadcast]]></category>

		<category><![CDATA[cool]]></category>

		<category><![CDATA[javascript]]></category>

		<category><![CDATA[json]]></category>

		<category><![CDATA[mobshare.in]]></category>

		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2008/03/25/mobsharein-broadcast-widget.html</guid>
		<description><![CDATA[
Here&#8217;s a sneak peek of the Mobshare broadcast widget I&#8217;ve been working on. If you look to the right and below, you can see that in action live. You&#8217;ll see the last ten pics I&#8217;ve uploaded and direct from the widget you can subscribe to my feed or send me an&#160;SMS.
The widget is the first [...]]]></description>
			<content:encoded><![CDATA[<a href="http://mobshare.in/" title="Mobshare.in"><img src='http://vysnu.com/wp-content/uploads/2008/03/mobsharein_broadcast_widget.png' alt='Mobshare.in Broadcast Widget' /></a>
<p>Here&#8217;s a sneak peek of the Mobshare broadcast widget I&#8217;ve been working on. If you look to the right and below, you can see that in action live. You&#8217;ll see the last ten pics I&#8217;ve uploaded and direct from the widget you can subscribe to my feed or send me an&nbsp;<span class="caps">SMS</span>.</p>
<p>The widget is the first released code which uses our internal <span class="caps">API</span>. While the <span class="caps">API</span> itself is undocumented [which hopefully will soon change], it&#8217;s public and it&#8217;s <a href="http://vysnu.com/log/2008/03/06/delegate-rendering-in-symfony.html"><span class="caps">JSON</span></a> (which makes implementing Javascript widgets incredibly&nbsp;easy).</p>
<p>How do you get your own widget? You can&#8217;t do that easily right now (the pleasures of cutting-edge code eh?), but paste this code&nbsp;somewhere:</p>
<pre>
<code>
&lt;iframe width=&quot;150&quot; height=&quot;150&quot; src=&quot;http://mobshare.in/user/:mobshare_id:/broadcast/widget&quot;&gt;&lt;/iframe&gt;
</code>
</pre>
<p>&#8230;and change <code>:mobshare_id:</code> to your Mobshare&nbsp;ID.</p>
<p>Try it out and let me know if you like&nbsp;it!</p>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/03/25/mobsharein-broadcast-widget.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Loving&#160;Git</title>
		<link>http://vysnu.com/log/2008/03/18/loving-git.html</link>
		<comments>http://vysnu.com/log/2008/03/18/loving-git.html#comments</comments>
		<pubDate>Mon, 17 Mar 2008 20:44:08 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[git]]></category>

		<category><![CDATA[source control]]></category>

		<category><![CDATA[subversion]]></category>

		<category><![CDATA[sysadmin]]></category>

		<category><![CDATA[vcs]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2008/03/18/loving-git.html</guid>
		<description><![CDATA[I suppose this must be the zillionth post about how Git is so cool, but I&#8217;ll tell you what I love about&#160;it:

Ultra fast commits. Coming from subversion, typing commit and getting a prompt back instantly is so surprising that you double check the first few&#160;times.
Branching! God, you don&#8217;t realize how much you miss it until [...]]]></description>
			<content:encoded><![CDATA[<p>I suppose this must be the zillionth post about how <a href="http://git.or.cz/">Git</a> is so cool, but I&#8217;ll tell you what I love about&nbsp;it:</p>
<ol>
<li><em>Ultra</em> fast commits. Coming from subversion, typing commit and getting a prompt back instantly is so surprising that you double check the first few&nbsp;times.</li>
<li>Branching! God, you don&#8217;t realize how much you miss it until you have fast branching and merging. Without the pain of creating <code>cp</code>s, just a simple <code>git checkout -b branch_name</code> and <code>git merge branch_name</code> and everything just&nbsp;works.</li>
<li>The above was the reason I tried git in the first place. mobME&#8217;s an <span class="caps">SVN</span> shop and we do the usual trunk, tags, branches dance. When the trunk shapes up to be stable though I can&#8217;t seem to do anything on it. I can fork off a new branch in <span class="caps">SVN</span> but that&#8217;s too painful to even think about. What do I do now? <code>git clone</code> it, create a branch, and do regular <code>git svn rebase</code>s and <code>dcommit</code>s.</li>
<li>Oh did I mention bidirectional <span class="caps">SVN</span> support? Without which I wouldn&#8217;t/couldn&#8217;t have switched no matter how much I wanted to try this cool new&nbsp;thing.</li>
</ol>But it&#8217;s great and it really changes the way you think about <span class="caps">VCS</span>. Notice something? I didn&#8217;t even talk about distributed source control, and that&#8217;s coz even when I use git like I use <span class="caps">SVN</span> - committing to a central repo at the end and pulling changes from it, it&#8217;s brilliant. I&#8217;d definitely want to explore cool stuff like <a href="http://github.com/">github</a> soon for personal use (some gracious soul gave me an invite some time&nbsp;back).]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/03/18/loving-git.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>An Orkut Application via a JSON&#160;API</title>
		<link>http://vysnu.com/log/2008/03/08/an-orkut-application-via-a-json-api.html</link>
		<comments>http://vysnu.com/log/2008/03/08/an-orkut-application-via-a-json-api.html#comments</comments>
		<pubDate>Fri, 07 Mar 2008 20:05:49 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[api]]></category>

		<category><![CDATA[application]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[javascript]]></category>

		<category><![CDATA[json]]></category>

		<category><![CDATA[opensocial]]></category>

		<category><![CDATA[orkut]]></category>

		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2008/03/08/an-orkut-application-via-a-json-api.html</guid>
		<description><![CDATA[I talked about delegating rendering in Symfony for creating a JSON API. Now here&#8217;s a consumer: an Orkut opensocial&#160;gadget:


MobshareOrkutAPI = {
	
	api_url: &#x27;http://api.mobshare/api.php&#x27;,
	cache_time: 0, //0 to disable
	
	makeCachedRequest: function(url, callback, params, refreshInterval) {
	  var ts = new Date().getTime();
	  var sep = &#34;?&#34;;
	  if (refreshInterval &#38;&#38; refreshInterval &#62; 0) {
	    ts = [...]]]></description>
			<content:encoded><![CDATA[<p>I talked about <a href="http://vysnu.com/log/2008/03/06/delegate-rendering-in-symfony.html">delegating rendering in Symfony</a> for creating a <span class="caps">JSON</span> <span class="caps">API</span>. Now here&#8217;s a consumer: an Orkut opensocial&nbsp;gadget:</p>
<pre>
<code>
MobshareOrkutAPI = {
	
	api_url: &#x27;http://api.mobshare/api.php&#x27;,
	cache_time: 0, //0 to disable
	
	makeCachedRequest: function(url, callback, params, refreshInterval) {
	  var ts = new Date().getTime();
	  var sep = &quot;?&quot;;
	  if (refreshInterval &amp;&amp; refreshInterval &gt; 0) {
	    ts = Math.floor(ts / (refreshInterval * 1000));
	  }
	  if (url.indexOf(&quot;?&quot;) &gt; -1) {
	    sep = &quot;&amp;&quot;;
	  }
	  url = [ url, sep, &quot;nocache=&quot;, ts ].join(&quot;&quot;);
	  gadgets.io.makeRequest(url, callback, params);
	},
	
	call: function(module, action, params, callback) {
		var options = {};
		options[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
		this.makeCachedRequest(this.api_url + &#x27;/&#x27; + module + &#x27;/&#x27; + action + &#x27;?&#x27; + params, callback, options, this.cache_time);
	}

};
</code>
</pre>
<p><code>makeCachedRequest</code> has been plaigarized from the Opensocial documentation and it&#8217;s very useful to bust the cache for requests. Also, notice this line for setting the content-type to&nbsp;JSON:</p>
<pre>
<code>
options[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
</code>
</pre>
<p>This is how we access that <span class="caps">API</span>, a code&nbsp;fragment:</p>
<pre>
<code>
...
authenticate: function(alias, mobile_no, password) {
	MobshareOrkutAPI.call(&#x27;user&#x27;, &#x27;authenticate&#x27;, 
		&#x27;alias=&#x27; + encodeURIComponent(alias) + &#x27;&amp;mobile_no=&#x27; + encodeURIComponent(mobile_no) + 
			&#x27;&amp;password=&#x27; + encodeURIComponent(password),
 		MyOrkutApp.login
	);
}
...
login: function(orkut_response) {
	response = orkut_response.data;
	data_success = response[&#x27;success&#x27;];
	data_error = response[&#x27;error&#x27;];
	
	if(data_success) {
		html = &#x27;&lt;h2&gt;Login Successful!&lt;/h2&gt;&#x27;;
		html += &#x27;&lt;p&gt;Welcome: &#x27; + data_success.name + &#x27;!&lt;/p&gt;&#x27;;
	} else if(data_error) {
		html = &#x27;&lt;h2&gt;Login Unsuccessful!&lt;/h2&gt;&#x27;;
		html += &#x27;&lt;p&gt;&#x27; + data_error + &#x27;!&lt;/p&gt;&#x27;;
	}
	
	document.getElementById(&#x27;mobshare_login&#x27;).innerHTML += html;
},
...
</code>
</pre>
<p>Note that <code>orkut_response.data</code> is automatically set by Orkut because you passed in the JSON content type; it parses the data received and creates a javascript object. Cool, ain&#8217;t it? It&#8217;s very easy to create a proper interactive Opensocial app this&nbsp;way.</p>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/03/08/an-orkut-application-via-a-json-api.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Delegate Rendering in&#160;Symfony</title>
		<link>http://vysnu.com/log/2008/03/06/delegate-rendering-in-symfony.html</link>
		<comments>http://vysnu.com/log/2008/03/06/delegate-rendering-in-symfony.html#comments</comments>
		<pubDate>Thu, 06 Mar 2008 16:28:57 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[api]]></category>

		<category><![CDATA[cool]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[json]]></category>

		<category><![CDATA[jsonp]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[symfony]]></category>

		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2008/03/06/delegate-rendering-in-symfony.html</guid>
		<description><![CDATA[Warning: pretty advanced Symfony ahead: if you&#8217;re not familiar with the framework, this wouldn&#8217;t make&#160;sense.
I recently developed a bare-bones API for Mobshare (it&#8217;s not yet live), and to keep everything clean, I abstracted away the rendering bit from the controller to an external class. It ended up being a sweet solution, so here it&#160;is!
I wanted [...]]]></description>
			<content:encoded><![CDATA[<p>Warning: pretty advanced <a href="http://symfony-project.com/">Symfony</a> ahead: if you&#8217;re not familiar with the framework, this wouldn&#8217;t make&nbsp;sense.</p>
<p>I recently developed a bare-bones <span class="caps">API</span> for <a href="http://mobshare.in/">Mobshare</a> (it&#8217;s not yet live), and to keep everything clean, I abstracted away the rendering bit from the controller to an external class. It ended up being a sweet solution, so here it&nbsp;is!</p>
<p>I wanted this to be a <a href="http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/"><span class="caps">JSONP</span></a> <span class="caps">API</span> (the major use case would be a <span class="caps">JS</span> client, and parsing <span class="caps">XML</span> etc. via <span class="caps">JS</span> is a pain. Besides <span class="caps">JSON</span> is much shorter over the wire). I didn&#8217;t want to rewrite a lot of code: checking for a callback parameter and wrapping the returned string around the <span class="caps">JSON</span> output was just begging to be refactored away. So here it is, a generic Symfony <span class="caps">JSON</span> <span class="caps">API</span> wrapper&nbsp;class:</p>
<pre>
<code>
&lt;?php

class JSONPAPI {
	
	const CALLBACK_PARAMETER = &#x27;callback&#x27;;
	
	var $status;
	var $data;
	var $callback;
	
	
	public function __construct($status, $data) {
		$this-&gt;status = $status;
		$this-&gt;data = $data;
		
		$callback_parameter_value = $this-&gt;getCurrentAction()-&gt;getRequestParameter(self::CALLBACK_PARAMETER);
		if($callback_parameter_value) 
			$this-&gt;callback = $callback_parameter_value;
	}
	
	public function render() {
		$render_text = json_encode(array($this-&gt;status =&gt; $this-&gt;data));
		
		if($this-&gt;callback)
			$render_text = $this-&gt;callback . &#x27;(&#x27; . $render_text . &#x27;);&#x27;;
		
		$this-&gt;setJavascriptHeaders();
		return $this-&gt;getCurrentAction()-&gt;renderText($render_text);
	}
	
	//hack to get the current action
	private function getCurrentAction() {
		return sfContext::getInstance()-&gt;getActionStack()-&gt;getLastEntry()-&gt;getActionInstance();
	}
	
	private function setJavascriptHeaders() {
		sfContext::getInstance()-&gt;getResponse()-&gt;setParameter(&#x27;Content-Type&#x27;, &#x27;application/javascript&#x27;, &#x27;symfony/response/http/headers&#x27;);
	}
}
</code>
</pre>
<p>The bits of magic here are the <code>getCurrentAction()</code> function and the <code>render()</code> call. It works on one very simple idea: <em>everything</em> in Symfony can be accessed from the <code>sfContext::getInstance()</code> object, you just need to dig deep&nbsp;enough.</p>
<p>Once you write this boiler-plate code, using it is very elegant. First, subclass it for your&nbsp;<span class="caps">API</span>:</p>
<pre>
<code>
&lt;?php

require_once('JSONPAPI.class.php');

class MobshareAPI extends JSONPAPI {
	

}
</code>
</pre>
<p>And then, use it like so within your&nbsp;controller:</p>
<pre>
<code>
&lt;?php
class userActions extends sfActions
{
	
	public function executeAuthenticate() {
		$valid_user = UserPeer::authenticate($this-&gt;getRequestParameter(&#x27;alias&#x27;), 
			$this-&gt;getRequestParameter(&#x27;mobile_no&#x27;), $this-&gt;getRequestParameter(&#x27;password&#x27;));
		if($valid_user instanceOf User) {
			$success = new MobshareAPI(&#x27;success&#x27;, $valid_user-&gt;toArray());
			return $success-&gt;render();
		} else {
			$error = new MobshareAPI(&#x27;error&#x27;, &#x27;Authentication failed: Alias, mobile number or password invalid.&#x27;);
			return $error-&gt;render();
		}
	}
	
}
</code>
</pre>
<p>Note: the rendering has been delegated to the <code>$success</code> and <code>$error</code> MobshareAPI objects. This allows for a really maintainable API. Adding functionality is much simpler since you don&#8217;t have to worry about the&nbsp;boilerplate.</p> 
<p>You end up calling the <span class="caps">API</span> like&nbsp;this:</p><p> 
<pre>
<code>
http://api.mobshare/user/authenticate?alias=vish&#038;password=xxx&#038;callback=handler
</code>
</pre>
</p><p>and you get back data which looks like&nbsp;this:</p>
<pre>
<code>
handler({"success":{"alias":"vish","name":"Vishnu Gopal","photo_mini": ...);
</code>
</pre>
<p>Note that callback handling is done entirely by the <span class="caps">API</span> and the controller needn&#8217;t worry about this parameter at&nbsp;all!</p>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/03/06/delegate-rendering-in-symfony.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>dtach, a brilliant&#160;daemonizer</title>
		<link>http://vysnu.com/log/2008/03/04/dtach-a-brilliant-daemonizer.html</link>
		<comments>http://vysnu.com/log/2008/03/04/dtach-a-brilliant-daemonizer.html#comments</comments>
		<pubDate>Tue, 04 Mar 2008 16:09:52 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[*nix]]></category>

		<category><![CDATA[applications]]></category>

		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2008/03/04/dtach-a-brilliant-daemonizer.html</guid>
		<description><![CDATA[Most people use GNU screen (or equivalent) to daemonize processes. There is a better alternative called dtach which should become the definitive way to run a process in the background as a&#160;daemon.
Installing dtach is easy. If you&#8217;re on gentoo, it is a&#160;simple:


$ emerge dtach


dtach --help provides the following&#160;output:


Usage: dtach -a &#60;socket&#62; &#60;options&#62;
    [...]]]></description>
			<content:encoded><![CDATA[<p>Most people use <a href="http://www.gnu.org/software/screen/"><span class="caps">GNU</span> screen</a> (or equivalent) to daemonize processes. There is a better alternative called <a href="http://dtach.sourceforge.net/">dtach</a> which should become the definitive way to run a process in the background as a&nbsp;daemon.</p>
<p>Installing dtach is easy. If you&#8217;re on gentoo, it is a&nbsp;simple:</p>
<pre>
<code>
$ emerge dtach
</code>
</pre>
<p><code>dtach --help</code> provides the following&nbsp;output:</p>
<pre>
<code>
Usage: dtach -a &lt;socket&gt; &lt;options&gt;
       dtach -A &lt;socket&gt; &lt;options&gt; &lt;command...&gt;
       dtach -c &lt;socket> &lt;options&gt; &lt;command...&gt;
       dtach -n &lt;socket> &lt;options&gt; &lt;command...&gt;
Modes:
  -a		Attach to the specified socket.
  -A		Attach to the specified socket, or create it if it
		  does not exist, running the specified command.
  -c		Create a new socket and run the specified command.
  -n		Create a new socket and run the specified command detached.
</code>
</pre>
<p>This basically means that you start dtach like&nbsp;so:</p>
<pre>
<code>
$ dtach -c ~/rtorrent/.socket/dtach rtorrent
</code>
</pre>
<p>The command-shortcut <code>Ctrl+\</code> detaches the running command and runs it in the background. To re-attach, just&nbsp;enter:</p>
<pre>
<code>
$ dtach -a ~/rtorrent/.socket/dtach
</code>
</pre>
<p>dtach hasn&#8217;t got much more functionality, but that&#8217;s what makes it superb. Tiny and functional. As you can see, I&#8217;m using dtach to run a <a href="http://en.wikipedia.org/wiki/Seedbox">Seedbox</a> <img src='http://vysnu.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/03/04/dtach-a-brilliant-daemonizer.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>EC2-like instances with&#160;Slicehost</title>
		<link>http://vysnu.com/log/2008/02/24/ec2-like-instances-with-slicehost.html</link>
		<comments>http://vysnu.com/log/2008/02/24/ec2-like-instances-with-slicehost.html#comments</comments>
		<pubDate>Sun, 24 Feb 2008 06:22:43 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[ec2]]></category>

		<category><![CDATA[hosting]]></category>

		<category><![CDATA[puppet]]></category>

		<category><![CDATA[slicehost]]></category>

		<category><![CDATA[sysadmin]]></category>

		<category><![CDATA[virtual]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2008/02/24/ec2-like-instances-with-slicehost.html</guid>
		<description><![CDATA[
Virtual hosting and infrastructure is coming up in a big way, and Amazon&#8217;s EC2 is leading the pack. However, there doesn&#8217;t exist a comprehensive &#038; provably scalable system for deploying applications to such a stack yet: the components are in place or being developed (SimpleDB or equivalent, EC2 and S3) but the crucial connecting layer [...]]]></description>
			<content:encoded><![CDATA[<img src='http://vysnu.com/wp-content/uploads/2008/02/slicehost-virtual-infra-20080224.png' alt='Slicehost’s backup and add new slice' />
<p>Virtual hosting and infrastructure is coming up in a big way, and <a href="http://aws.amazon.com/ec2">Amazon&#8217;s <span class="caps">EC2</span></a> is leading the pack. However, there doesn&#8217;t exist a comprehensive &#038; provably scalable system for deploying applications to such a stack yet: the components are in place or being developed (SimpleDB or equivalent, <span class="caps">EC2</span> and S3) but the crucial connecting layer is missing. Several attempts are on to fill the&nbsp;gap.</p>
<p>Until it becomes a reality (and perhaps even then), a great intermediate tool is <a href="http://slicehost.com/">Slicehost</a>&#8217;s xen-based virtual machines: &#8220;slices&#8221;, that allow for a quick snapshot from any particular slice and the creation of a new slice <em>from</em> that&nbsp;snapshot.</p>
<p>The way it works is a bit cumbersome now (and they really should expose this feature more), but the idea is&nbsp;simple:</p>
<ol>
<li>Take a snapshot of a slice, currently you have to go to the backups tab to take a snapshot&nbsp;backup.</li>
<li>When you choose to create a new slice, you have the option to create from that backup snapshot (see&nbsp;picture).</li>
<li>Change a few variables specific to the host (maybe add a <a href="http://reductivelabs.com/trac/puppet">puppet</a> instance to reconfigure automatically), and wham! <span class="caps">EC2</span>-like virtual infrastructure at half the&nbsp;pain.</li>
</ol>
<p>I plan to use this for factory-like instances across <a href="http://mobme.in/">MobME</a>&#8217;s&nbsp;infrastructure.</p>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/02/24/ec2-like-instances-with-slicehost.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Mobshare in 25&#160;Days</title>
		<link>http://vysnu.com/log/2008/02/20/mobshare-in-25-days.html</link>
		<comments>http://vysnu.com/log/2008/02/20/mobshare-in-25-days.html#comments</comments>
		<pubDate>Wed, 20 Feb 2008 07:04:28 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[coding]]></category>

		<category><![CDATA[me outside]]></category>

		<category><![CDATA[mobshare]]></category>

		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2008/02/20/mobshare-in-25-days.html</guid>
		<description><![CDATA[Mobshare in 25 Days. Cool&#160;stuff!
]]></description>
			<content:encoded><![CDATA[<a href="http://d.olph.in/mobshare-in-25-days/">Mobshare in 25 Days</a>. Cool&nbsp;stuff!
]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/02/20/mobshare-in-25-days.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Leading a&#160;team</title>
		<link>http://vysnu.com/log/2008/02/11/leading-a-team.html</link>
		<comments>http://vysnu.com/log/2008/02/11/leading-a-team.html#comments</comments>
		<pubDate>Mon, 11 Feb 2008 09:11:12 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[me outside]]></category>

		<category><![CDATA[mobme]]></category>

		<category><![CDATA[musings]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2008/02/11/leading-a-team.html</guid>
		<description><![CDATA[I&#8217;ve recently switched to a new role at MobME, and here are my initial impressions and a few lessons learnt in the past few months. This is a rather free-flowing account, but I want to write this down and codify before I&#160;forget.
Rule uno: people aren&#8217;t resources. There&#8217;s a constant management-level question I hear: &#8220;How many [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently <a href="http://vysnu.com/log/2008/02/09/me-right-now.html">switched to</a> a new role at <a href="http://mobme.in/">MobME</a>, and here are my initial impressions and a few lessons learnt in the past few months. This is a rather free-flowing account, but I want to write this down and codify before I&nbsp;forget.</p>
<p>Rule uno: people aren&#8217;t resources. There&#8217;s a constant management-level question I hear: &#8220;How many resources can you allocate to a particular product?&#8221; or &#8220;How much time and resources do you need to solve this problem?&#8221;. I don&#8217;t answer such questions at all, or when I do, I talk about the people I have in my team and their skills and limitations. I&#8217;ve strongly felt that no organization can grow without taking care of its people, and especially for small startups, to make attrition low and happiness high, this is a concern that should be addressed from the top. Rephrase these questions this way: &#8220;Can person X solve this problem?&#8221; and &#8220;Can person X and Y be reallocated to this&nbsp;task?&#8221;.</p>
<p>Following on, every person is special: they have different skills, learning speeds and communication capabilities. Every good person can improve, and they should constantly be pushed to do that. Nobody should be idle and&nbsp;static.</p>
<p>And nobody should do make-work. It&#8217;s not necessary because there are always real problems to solve. If anybody is picking up a new language or skill, after a few tutorial-level sessions and a max of two days, he should jump into the new role and start fixing bugs and solving real&nbsp;problems.</p>
<p>Good processes make a good team. At MobME, I&#8217;m implementing a few things I learnt while working at <a href="http://uzanto.com/">Uzanto</a>: Daily End-Of-Day reports for the team, <a href="http://en.wikipedia.org/wiki/Scrum_(development)"><span class="caps">SCRUM</span></a> in the morning, and constant communication via a small office and approachable managers. The work atmosphere is relaxed, and people are given time to learn. There&#8217;s no fixed time for lunch or a quick smoke. There&#8217;s an attendance register and people are held accountable for their work and&nbsp;leave.</p>
<p>At the end of the day, Work is Everything&#8482;. If there&#8217;s a deadline to be met, do or die, we meet it. People remain late in the office (till 1 at night is the current MobME record) and finish work before they&nbsp;go.</p>
<p>What you do when you&#8217;re not in office is none of anybody else&#8217;s business. Although as a rule, work hard, party&nbsp;hard.</p>
<p>When you lead a technical team, if you have problems you use technology to solve them. This is obvious, but I&#8217;ve so often seen this overlooked. You can&#8217;t find a way for developers to collaborate? Find an effective source control method. Project management? Bug tracking? Time tracking? A caveat: too many tools is a mess. Find effective and simple ones. We use <a href="http://beanstalkapp.com">Beanstalk</a> and <a href="http://lighthouseapp.com/">Lighthouse</a> along with Google Apps for documents and&nbsp;mail.</p>
<p>As a corollary to the above, not every problem is technical. Instead of inventing one, try simplifying the product or the spec or going back to the drawing board. If it&#8217;s too much of a hassle technically, it&#8217;s the product pushing back at you, resisting crappy things being done to it. Hear it out and redo things. Redoing things the right way is a good thing. Take time out, fix stuff and it won&#8217;t bite you in the ass the next&nbsp;time.</p>
<p>Another gem: keep internal mail to a minimum. When everybody is in the same office, shout out to him (or take him outside) instead of firing off a mail thread. It&#8217;ll solve problems so much more efficiently. Having the management &#038; technical wing in nearby offices means that for us, most problems are solved in a week. No network cabling in office? A quick discussion with my operations lead and I get work done. No firing off complaint&nbsp;mails.</p>
<p>Communication is key. Let everybody know your worries. Everybody includes the people under you. A lot of the time, they&#8217;ll end up finding a better&nbsp;solution.</p>
<p>The primary role of a technical lead as I understand it is to get work done. It&#8217;s not to go off to conferences evangelizing the product (although it&#8217;s a good thing to do). Meet the deadlines your boss sets for you. Make sure your people work hard and they learn lots of stuff in the process. Keep an eye out for new technology. Document your processes. When you find problems, fix it and ensure it doesn&#8217;t happen again. Get good infrastructure. Communicate problems with the&nbsp;management.</p>
<p>Everybody in sales, marketing, etc. should know more than a little bit of tech. Increase technical awareness and make the process transparent so anybody can ask questions no matter how stupid it is. Often a completely new way of thinking about a problem brings in new technical insights&nbsp;too.</p>
<p>When there&#8217;s a problem, criticize. This is hard to do initially, but good people realize that your criticism is for the work and not the person. If they still have issues after you talk it out, ask them politely to leave or toe the line. When you find people improving and processes becoming smoother after you&#8217;ve talked it out with the team, it&#8217;s a real nice&nbsp;feeling.</p>
<p>And at the end of the day, make people happy and be happy yourself. Which of the lot, is the&nbsp;hardest.</p>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/02/11/leading-a-team.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Me Right&#160;Now</title>
		<link>http://vysnu.com/log/2008/02/09/me-right-now.html</link>
		<comments>http://vysnu.com/log/2008/02/09/me-right-now.html#comments</comments>
		<pubDate>Fri, 08 Feb 2008 19:38:08 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2008/02/09/me-right-now.html</guid>
		<description><![CDATA[So this is me right&#160;now:


]]></description>
			<content:encoded><![CDATA[<p>So this is me right&nbsp;now:</p>
<a href="http://mobshare.in/user/vish">
<img src='http://vysnu.com/wp-content/uploads/2008/02/picture-2.png' alt='Me Right Now' />
</a>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/02/09/me-right-now.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Mobile Social Networking In 25&#160;Days</title>
		<link>http://vysnu.com/log/2008/02/03/mobile-social-networking-in-25-days.html</link>
		<comments>http://vysnu.com/log/2008/02/03/mobile-social-networking-in-25-days.html#comments</comments>
		<pubDate>Sun, 03 Feb 2008 13:32:45 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[barcampkerala]]></category>

		<category><![CDATA[barcampkerala2]]></category>

		<category><![CDATA[me]]></category>

		<category><![CDATA[mobme]]></category>

		<category><![CDATA[mobshare]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2008/02/03/mobile-social-networking-in-25-days.html</guid>
		<description><![CDATA[This was my talk for BarcampKerala2. Decent event, although I had to leave&#160;post-noon.

 &#124; View &#124; Upload your own]]></description>
			<content:encoded><![CDATA[<p>This was my talk for <a href="http://barcamp.org/BarCampKerala2">BarcampKerala2</a>. Decent event, although I had to leave&nbsp;post-noon.</p>

<div style="width:425px;text-align:left" id="__ss_250939"><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=mobile-social-networking-in-25-days-1202045134736196-4"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=mobile-social-networking-in-25-days-1202045134736196-4" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"><a href="http://www.slideshare.net/?src=embed"><img src="http://static.slideshare.net/swf/logo_embd.png" style="border:0px none;margin-bottom:-5px" alt="SlideShare"/></a> | <a href="http://www.slideshare.net/vishnu/mobile-social-networking-in-25-days?src=embed" title="View 'Mobile Social Networking In 25 Days' on SlideShare">View</a> | <a href="http://www.slideshare.net/upload?src=embed">Upload your own</a></div></div>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/02/03/mobile-social-networking-in-25-days.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Mouse Wheel Handling in&#160;Prototype/Javascript</title>
		<link>http://vysnu.com/log/2008/01/27/mouse-wheel-handling-in-prototypejavascript.html</link>
		<comments>http://vysnu.com/log/2008/01/27/mouse-wheel-handling-in-prototypejavascript.html#comments</comments>
		<pubDate>Sat, 26 Jan 2008 21:16:15 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[code]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[snippet]]></category>

		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2008/01/27/mouse-wheel-handling-in-prototypejavascript.html</guid>
		<description><![CDATA[Here&#8217;s how to handle mouse wheel events in prototype, code heavily borrowed from other places on the net, but brought together and made&#160;unobtrusive:


/* Mouse Wheel */

Object.extend(Event, {
	wheel:function (event){
		var delta = 0;
		if (!event) event = window.event;
		if (event.wheelDelta) {
			delta = event.wheelDelta/120; 
			if (window.opera) delta = -delta;
		} else if (event.detail) { delta = -event.detail/3;	}
		return Math.round(delta); //Safari Round
	}
});

SetupMouseWheel = [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s how to handle mouse wheel events in prototype, code heavily borrowed from other places on the net, but brought together and made&nbsp;unobtrusive:</p>
<pre>
<code>
/* Mouse Wheel */

Object.extend(Event, {
	wheel:function (event){
		var delta = 0;
		if (!event) event = window.event;
		if (event.wheelDelta) {
			delta = event.wheelDelta/120; 
			if (window.opera) delta = -delta;
		} else if (event.detail) { delta = -event.detail/3;	}
		return Math.round(delta); //Safari Round
	}
});

SetupMouseWheel = {
	initialize: function() {
		Event.observe(document, 'dom:loaded', this.setup_mouse_wheel);
	},
	
	setup_mouse_wheel: function() {
		Event.observe($('element'), "mousewheel", function(e) { SetupMouseWheel.handleDiv(e) }, false);
		Event.observe($('element'), "DOMMouseScroll", function(e) { SetupMouseWheel.handleDiv(e) }, false); // Firefox
	},
	
	handleDiv: function(e) {
		direction = Event.wheel(e) < 0 ? leftSeek : rightSeek;
		console.log(direction); //handle scroll 
		console.log(Event.wheel(e));
		direction(); //call leftSeek or rightSeek depending on direction.
	}
};
</code>
</code></pre>
<p>The problem with this code though, and the reason I haven&#8217;t found a productive use for this yet is that the browser always scrolls the viewport when it extends beyond screen dimensions. So you have your scroll handler and the browser&#8217;s scrolling viewport playing hanky-panky, and it&#8217;s not a good sight to see. For applications which always stays within the browser window though, this is useful&nbsp;code.</p>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/01/27/mouse-wheel-handling-in-prototypejavascript.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Self-labeling text entry INPUT boxes using Prototype&#160;JS</title>
		<link>http://vysnu.com/log/2008/01/15/self-labeling-text-entry-input-boxes-using-prototype-js.html</link>
		<comments>http://vysnu.com/log/2008/01/15/self-labeling-text-entry-input-boxes-using-prototype-js.html#comments</comments>
		<pubDate>Tue, 15 Jan 2008 17:53:57 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[code]]></category>

		<category><![CDATA[javascript]]></category>

		<category><![CDATA[prototype]]></category>

		<category><![CDATA[snippet]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2008/01/15/self-labeling-text-entry-input-boxes-using-prototype-js.html</guid>
		<description><![CDATA[Like previous code snippets, this one is mostly all code and no&#160;explanation.
A brief primer: you&#8217;ve often seen self-labeling input boxes, the ones that display a label inside in gray text, and when you click replaces with an empty input element using Javascript. This is a simple class to help you achieve that&#160;effect:


SelfLabelingBox = {
	initialize: function(box_id, [...]]]></description>
			<content:encoded><![CDATA[<p>Like previous <a href="http://vysnu.com/log/2008/01/12/simple-javascript-validation.html">code</a> <a href="http://vysnu.com/log/2008/01/12/multiple-db-connections-in-railsactiverecord.html">snippets</a>, this one is mostly all code and no&nbsp;explanation.</p>
<p>A brief primer: you&#8217;ve often seen self-labeling input boxes, the ones that display a label inside in gray text, and when you click replaces with an empty input element using Javascript. This is a simple class to help you achieve that&nbsp;effect:</p>
<pre>
<code>
SelfLabelingBox = {
	initialize: function(box_id, message) {
		this.setup_behavior(box_id, message);
	},
	
	setup_behavior: function(box_id, message) {
		box_id = $(box_id);
		if(box_id) {
			if(box_id.value == '') {
				box_id.value = message;
				box_id.addClassName('inactive');
			}
			Event.observe(box_id, 'focus', function() {
				if(box_id.value == message) {
					box_id.value = '';
					box_id.removeClassName('inactive');
				}
			});
			Event.observe(box_id, 'blur', function() {
				if(box_id.value == '') {
					box_id.addClassName('inactive');
					box_id.value = message;
				}
			});
		}
	}
};

SetupDefaultInputs = {
	initialize: function() {
		Event.observe(document, 'dom:loaded', this.setup_default_inputs);
	},
	
	setup_default_inputs: function() {
		SelfLabelingBox.initialize('search_text', 'Search');
	}
};
</code>
</pre>
<p>Until next&nbsp;time!</p>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/01/15/self-labeling-text-entry-input-boxes-using-prototype-js.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Simple Javascript&#160;Validation</title>
		<link>http://vysnu.com/log/2008/01/12/simple-javascript-validation.html</link>
		<comments>http://vysnu.com/log/2008/01/12/simple-javascript-validation.html#comments</comments>
		<pubDate>Sat, 12 Jan 2008 17:05:24 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[javascript]]></category>

		<category><![CDATA[validation]]></category>

		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2008/01/12/simple-javascript-validation.html</guid>
		<description><![CDATA[I hunted around for a good Javascript class to use for validation and finally clobbered together this from various sources on the net. This should be extremely useful for anyone doing client-side&#160;validation.


Validate = {	
	forMinLength: function(whatYouTyped, length_min) {
		var fieldset = whatYouTyped.parentNode;
		var txt = whatYouTyped.value;
		if (txt.length >= length_min) {
			fieldset.className = "valid";
		} else {
			fieldset.className = "invalid";
		}
	},
	
	forMaxLength: function(whatYouTyped, length_max) [...]]]></description>
			<content:encoded><![CDATA[<p>I hunted around for a good Javascript class to use for validation and finally clobbered together this from various sources on the net. This should be extremely useful for anyone doing client-side&nbsp;validation.</p>
<pre>
<code>
Validate = {	
	forMinLength: function(whatYouTyped, length_min) {
		var fieldset = whatYouTyped.parentNode;
		var txt = whatYouTyped.value;
		if (txt.length >= length_min) {
			fieldset.className = "valid";
		} else {
			fieldset.className = "invalid";
		}
	},
	
	forMaxLength: function(whatYouTyped, length_max) {
		var fieldset = whatYouTyped.parentNode;
		var txt = whatYouTyped.value;
		if (txt.length < = length_max) {
			fieldset.className = "valid";
		} else {
			fieldset.className = "invalid";
		}
	},

	forLength: function(whatYouTyped, length) {
		var fieldset = whatYouTyped.parentNode;
		var txt = whatYouTyped.value;
		if (txt.length == length) {
			fieldset.className = "valid";
		} else {
			fieldset.className = "invalid";
		}
	},
	
	asEmail: function(whatYouTyped) {
		var fieldset = whatYouTyped.parentNode;
		var txt = whatYouTyped.value;
		if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(txt)) {
			fieldset.className = "valid";
		} else {
			fieldset.className = "invalid";
		}
	},
	
	asNumber: function(whatYouTyped) {
		var fieldset = whatYouTyped.parentNode;
		var txt = whatYouTyped.value;
		if (/^\d+$/.test(txt)) {
			fieldset.className = "valid";
		} else {
			fieldset.className = "invalid";
		}
	},
	
	asEqualTo: function(whatYouTyped, whatYouMatchWith) {
		var fieldset = whatYouTyped.parentNode;
		var txt = whatYouTyped.value;
		var expect = whatYouMatchWith.value;
		if (txt == expect &#038;& txt != "") {
			fieldset.className = "valid";
		} else {
			fieldset.className = "invalid";
		}
	},
	
	asNotEqualTovalue: function(whatYouTyped, whatYouMatchWith) {
		var fieldset = whatYouTyped.parentNode;
		var txt = whatYouTyped.value;
		var expect = whatYouMatchWith;
		if (txt != expect) {
			fieldset.className = "valid";
		} else {
			fieldset.className = "invalid";
		}
	},
	
	withRegex: function(whatYouTyped, regex) {
		var fieldset = whatYouTyped.parentNode;
		txt = whatYouTyped.value;
		if (regex.test(txt)) {
			fieldset.className = "valid";
		} else {
			fieldset.className = "invalid";
		}
	}
	
};
</code>
</code></pre>
<p>How do you use it? This is&nbsp;how:</p>
<p><span class="caps">HTML</span>:</p>
<pre>
<code>
&lt;form name=&quot;signup&quot; id=&quot;signup&quot;&gt;
&lt;label for=&quot;alias&quot;&gt;Alias &lt;sup&gt;*&lt;/sup&gt;&lt;/label&gt;
&lt;fieldset&gt;
&lt;input type=&quot;text&quot; name=&quot;alias&quot; id=&quot;alias&quot; value=&quot;&quot; /&gt;
&lt;/fieldset&gt;
&lt;br /&gt;
&lt;label for=&quot;mobile_no&quot;&gt;Mobile Number &lt;sup&gt;*&lt;/sup&gt;&lt;/label&gt;
&lt;fieldset&gt;
&lt;input type=&quot;text&quot; name=&quot;mobile_no&quot; id=&quot;mobile_no&quot; /&gt;
&lt;/fieldset&gt;
&lt;br /&gt;
[..]
&lt;/form&gt;
</code>
</pre>
<p><span class="caps">CSS</span> (different images for fieldset.valid and&nbsp;fieldset.invalid):</p>
<pre>
<code>
fieldset.valid {
	background:transparent url(/images/bg-fieldset-valid.gif) no-repeat 194px 0px;
}

fieldset.invalid {
	background:transparent url(/images/bg-fieldset-invalid.gif) no-repeat 194px 0px;
}
</code>
</pre>
<p>And I hate onclick and onkeyup, so here&#8217;s some unobtrusive Javascript to tie it all&nbsp;in:</p>
<pre>
<code>
SignupValidation = {
	initialize: function() {
		Event.observe(document, "dom:loaded", this.setup_validation)
	},
	
	setup_validation: function() {
		if($('signup_body')) {
			Event.observe($('alias'), 'keyup', function() { 
				Validate.withRegex($('alias'), /^[A-Za-z]+[A-Za-z0-9]{4,}$/);
			});
			Event.observe($('mobile_no'), 'keyup', function() { 
				Validate.withRegex($('mobile_no'), /^9[0-9]{9,9}$/)
			});
		}
	}
};

SignupValidation.initialize();
</code>
</pre>
<p>That&#8217;s it. The idea (for those who can&#8217;t bother to grok code) is that a fieldset changes its class from valid to invalid depending on the status of the field, this is then reflected in the&nbsp;styling.</p>
<p><a href="http://www.askthecssguy.com/examples/validationhints/formfieldhints.html">AsktheCSSGuy</a> was of much&nbsp;help.</p>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/01/12/simple-javascript-validation.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Multiple DB connections in&#160;Rails/ActiveRecord</title>
		<link>http://vysnu.com/log/2008/01/12/multiple-db-connections-in-railsactiverecord.html</link>
		<comments>http://vysnu.com/log/2008/01/12/multiple-db-connections-in-railsactiverecord.html#comments</comments>
		<pubDate>Sat, 12 Jan 2008 11:51:29 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[activerecord]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[ruby]]></category>

		<category><![CDATA[rubyonrails]]></category>

		<category><![CDATA[tutorial]]></category>

		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2008/01/12/multiple-db-connections-in-railsactiverecord.html</guid>
		<description><![CDATA[You might often want to connect to different databases using ActiveRecord. Here&#8217;s how you do&#160;it:


#DB definitions:

class DatabaseCurrent &#60; ActiveRecord::Base
  self.abstract_class = true
  establish_connection settings['database']
end

class DatabaseOld &#60; ActiveRecord::Base
  self.abstract_class = true
  establish_connection settings['database2']
end

#Model definitions (current):

class Video &#60; DatabaseCurrent
  belongs_to :user
  
  set_table_name :videos
end

class Photo &#60; DatabaseCurrent
  belongs_to :user
 [...]]]></description>
			<content:encoded><![CDATA[<p>You might often want to connect to different databases using ActiveRecord. Here&#8217;s how you do&nbsp;it:</p>
<pre>
<code>
#DB definitions:

class DatabaseCurrent &lt; ActiveRecord::Base
  self.abstract_class = true
  establish_connection settings['database']
end

class DatabaseOld &lt; ActiveRecord::Base
  self.abstract_class = true
  establish_connection settings['database2']
end

#Model definitions (current):

class Video &lt; DatabaseCurrent
  belongs_to :user
  
  set_table_name :videos
end

class Photo &lt; DatabaseCurrent
  belongs_to :user
  
  set_table_name :photos
end

class User &lt; DatabaseCurrent
  has_many :videos
  has_many :photos
  
  set_table_name :user
end

class Tag &lt; DatabaseCurrent
  set_table_name :tag
end

#Model definitions (old):

class FileDB &lt; DatabaseOld
  set_table_name :file
end
</code>
</pre>
<p>Pretty easy. The only thing to note is that you should <code>set_table_name</code>, otherwise, AR chokes up. Also, often you want to directly play directly with SQL. Unfortunately, <code>ActiveRecord::Base.execute</code> doesn&#8217;t work any longer (coz it doesn&#8217;t have a connection), but you can do it this&nbsp;way:</p>
<pre>
<code>
DatabaseCurrent.connection.execute("SQL")
</code>
</pre>
<p>That&#8217;s the tutorial for the&nbsp;day!</p>]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2008/01/12/multiple-db-connections-in-railsactiverecord.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>TOEFL iBT&#160;Prerequisite</title>
		<link>http://vysnu.com/log/2007/12/18/toefl-ibt-prerequisite.html</link>
		<comments>http://vysnu.com/log/2007/12/18/toefl-ibt-prerequisite.html#comments</comments>
		<pubDate>Tue, 18 Dec 2007 18:09:38 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[ibt]]></category>

		<category><![CDATA[rant]]></category>

		<category><![CDATA[stupidity]]></category>

		<category><![CDATA[toefl]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2007/12/18/toefl-ibt-prerequisite.html</guid>
		<description><![CDATA[I recently registered for the TOEFL again. Anal-retentive ETS only stocks its TOEFL scores for 2 years. Why, may I ask, does my English deteriorate so much after a couple years of a perfect score? Money-loving land lubbers if you ask me&#8230; but that is a topic for another&#160;day.
Here&#8217;s what you&#8217;re presented when you seek [...]]]></description>
			<content:encoded><![CDATA[<p>I recently registered for the <span class="caps">TOEFL</span> again. Anal-retentive <span class="caps">ETS</span> only stocks its <span class="caps">TOEFL</span> scores for 2 years. Why, may I ask, does my English deteriorate so much after a couple years of a perfect score? Money-loving land lubbers if you ask me&#8230; but that is a topic for another&nbsp;day.</p>
<p>Here&#8217;s what you&#8217;re presented when you seek to create a username and password at the <span class="caps">TOEFL</span> site to register for an&nbsp;exam:</p>
<blockquote>
<pre>
Important User Name and Password Information
User names must be between 6 and 16 characters long and may contain both letters and numbers. The user name may NOT contain any special characters like !, $, #, % or +.

Passwords must be a minimum of 8 characters in length. The maximum is 16 characters. For added security, they must also contain three of the following four character categories:
English uppercase characters (A through Z)
English lowercase characters (a through z)
Numeric characters (0 through 9)
Special characters (for example, !, $, #, %)
Examples of allowable passwords are:

Urt#5489
RT@GR125
UIrty452
H!tTh3M@rK
Your password is case-sensitive. For example, "H!tTh3M@rK" is not equal to "h!TtH3m@Rk".
Only English characters are allowed and your password cannot contain your user name, first/given name, or last/family&nbsp;name.
</pre>
</blockquote>
<p>Let&#8217;s see: A username must be between six and sixteen chars long. Check. Cannot contain special chars. Check. Passwords must be a min of 8 chars long. Check. Max is 16&#8230; Check. They must contain three of four character categories&#8230;. what is this my bank&nbsp;vault?</p>
<p>Or think of this another way: a reading comprehension test even before the exam starts. Can we applaud and bring the roof down&nbsp;already?</p>

]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2007/12/18/toefl-ibt-prerequisite.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Terminal in&#160;Leopard</title>
		<link>http://vysnu.com/log/2007/12/13/terminal-in-leopard.html</link>
		<comments>http://vysnu.com/log/2007/12/13/terminal-in-leopard.html#comments</comments>
		<pubDate>Thu, 13 Dec 2007 16:13:01 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[leopard]]></category>

		<category><![CDATA[mac]]></category>

		<category><![CDATA[osx]]></category>

		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2007/12/13/terminal-in-leopard.html</guid>
		<description><![CDATA[I haven&#8217;t really seen it mentioned before, but the Leopard terminal is finally up to a Gnome&#8217;s or KDE&#8217;s terminal&#8217;s standards, and as is usual with Apple, especially with some of the window style selections, much better. It has tabs too, and there&#8217;s a preset which closely matches the way I used to customize iTerm. [...]]]></description>
			<content:encoded><![CDATA[I haven&#8217;t really seen it mentioned before, but the Leopard terminal is finally up to a Gnome&#8217;s or <span class="caps">KDE</span>&#8217;s terminal&#8217;s standards, and as is usual with Apple, especially with some of the window style selections, much better. It has tabs too, and there&#8217;s a preset which closely matches the way I used to customize iTerm. Great&nbsp;stuff.]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2007/12/13/terminal-in-leopard.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Version of&#160;Centos</title>
		<link>http://vysnu.com/log/2007/12/08/version-of-centos.html</link>
		<comments>http://vysnu.com/log/2007/12/08/version-of-centos.html#comments</comments>
		<pubDate>Sat, 08 Dec 2007 18:15:55 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[centos]]></category>

		<category><![CDATA[packages]]></category>

		<category><![CDATA[version]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2007/12/08/version-of-centos.html</guid>
		<description><![CDATA[Just a little tidbit. To know the version of Centos you&#8217;ve got installed, do cat /etc/redhat-release. Various sysadmins have Centos 4 installed in which case you&#8217;ll need updated packages too.]]></description>
			<content:encoded><![CDATA[Just a little tidbit. To know the version of Centos you&#8217;ve got installed, do <code>cat /etc/redhat-release</code>. Various sysadmins have Centos 4 installed in which case you&#8217;ll need <a href="http://dag.wieers.com/rpm/">updated packages too</a>.]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2007/12/08/version-of-centos.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>100 IT Innovators&#160;2007</title>
		<link>http://vysnu.com/log/2007/12/08/100-it-innovators-2007.html</link>
		<comments>http://vysnu.com/log/2007/12/08/100-it-innovators-2007.html#comments</comments>
		<pubDate>Sat, 08 Dec 2007 17:36:31 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[mobme]]></category>

		<category><![CDATA[technology]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2007/12/08/100-it-innovators-2007.html</guid>
		<description><![CDATA[Nasscom&#8217;s 100 IT Innovators 2007. And there&#8217;s MobME in the list.&#160;Cool!
]]></description>
			<content:encoded><![CDATA[Nasscom&#8217;s <a href="http://www.nasscom.in/Nasscom/templates/NormalPage.aspx?id=53050#M">100 <span class="caps">IT</span> Innovators 2007</a>. And there&#8217;s <a href="http://mobme.in/">MobME</a> in the list.&nbsp;Cool!
]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2007/12/08/100-it-innovators-2007.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>VectorMagic</title>
		<link>http://vysnu.com/log/2007/11/29/vectormagic.html</link>
		<comments>http://vysnu.com/log/2007/11/29/vectormagic.html#comments</comments>
		<pubDate>Thu, 29 Nov 2007 16:27:57 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[editing]]></category>

		<category><![CDATA[graphics]]></category>

		<category><![CDATA[image]]></category>

		<category><![CDATA[vector]]></category>

		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2007/11/29/vectormagic.html</guid>
		<description><![CDATA[VectorMagic is simply awesome!]]></description>
			<content:encoded><![CDATA[<a href="http://vectormagic.stanford.edu/">VectorMagic</a> is simply <a href="http://vectormagic.stanford.edu/vctr/vctr_flex?g=503252&#038;k=0XAyVDOk1sWaBfoR&#038;p=g">awesome</a>!]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2007/11/29/vectormagic.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Apple - Events - Demo&#160;Days</title>
		<link>http://vysnu.com/log/2007/11/28/apple-events-demo-days.html</link>
		<comments>http://vysnu.com/log/2007/11/28/apple-events-demo-days.html#comments</comments>
		<pubDate>Wed, 28 Nov 2007 17:07:51 +0000</pubDate>
		<dc:creator>vishnu</dc:creator>
		
		<category><![CDATA[chaff]]></category>

		<category><![CDATA[apple]]></category>

		<category><![CDATA[demo]]></category>

		<category><![CDATA[kerala]]></category>

		<category><![CDATA[kochi]]></category>

		<category><![CDATA[leapord]]></category>

		<guid isPermaLink="false">http://vysnu.com/log/2007/11/28/apple-events-demo-days.html</guid>
		<description><![CDATA[There&#8217;s an Apple Leopard Demo Day soon. There&#8217;s one in Kochi. Be there if you&#160;can.
]]></description>
			<content:encoded><![CDATA[There&#8217;s an <a href="http://www.asia.apple.com/events/demodays/india.html">Apple Leopard Demo Day</a> soon. There&#8217;s one in Kochi. Be there if you&nbsp;can.
]]></content:encoded>
			<wfw:commentRss>http://vysnu.com/log/2007/11/28/apple-events-demo-days.html/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
