<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Srirangan</title>
	<atom:link href="http://srirangan.net/feed" rel="self" type="application/rss+xml" />
	<link>http://srirangan.net</link>
	<description>Programmer, Author, Founder of Review19.com</description>
	<lastBuildDate>Wed, 16 May 2012 13:52:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Becoming Programming Language Agnostic</title>
		<link>http://srirangan.net/2012-05-becoming-programming-language-agnostic</link>
		<comments>http://srirangan.net/2012-05-becoming-programming-language-agnostic#comments</comments>
		<pubDate>Wed, 16 May 2012 13:52:34 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[languages]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=1086</guid>
		<description><![CDATA[Over the years, I have written a lot of code. As a twelve year old, I was introduced to GW-Basic. I remember scribbling my &#8216;programs&#8217; on paper because I didn&#8217;t always have access to a machine. I grew up to &#8230; <a href="http://srirangan.net/2012-05-becoming-programming-language-agnostic">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Over the years, I have written a lot of code. </p>
<p>As a twelve year old, I was introduced to GW-Basic.  I remember scribbling my &#8216;programs&#8217; on paper because I didn&#8217;t always have access to a machine. I grew up to spend a lot more time with C / C++.</p>
<p>My first freelancing gigs introduced me to Perl and PHP and one couldn&#8217;t escape writing HTML, JavaScript and CSS code. </p>
<p>While at university I sharpened my C / C++ skills while getting familiarized with Java. After university my work dictated that I immerse myself in PHP and Java. </p>
<p>This was when (2005-07) the Ruby on Rails hype machine really got kicking and I remember evaluating / using RoR for personal projects. About that time I took a look at Python and fell in love. For subsequent projects, my first choice would have always been Python.</p>
<p>Of course client side programming was difficult back then and my (temporary) answer to that was ActionScript / Adobe Flex. As time progressed and browsers improved, I hopped back onto to the HTML5 bandwagon. This was when I re-learnt JavaScript and really started appreciating it.</p>
<p>Not to be left behind on the server side of things, I experimented and used Scala for work while also making use of new frameworks spawning in the Java universe.</p>
<p>Recently I bought into the Node.js hype and decided to evaluate it. It definitely was a good choice for a certain kind of apps I wanted to create. Yes, Node.js has been a good choice for <a href='http://review19.com'>Review19</a>.</p>
<p>&#8212;</p>
<p>If I was to start a new project today, my first choice would either be Node.js or Python. That&#8217;s not to say I have definitively ruled out other technologies, but I feel between these two most kinds of apps can be built. JVM based languages could be a choice for compute heavy, threaded apps. </p>
<p>Now the purpose of this post isn&#8217;t to recommend my technology choices and try to convert you. <em>Au contraire</em> I feel the choice of language is almost always irrelevant. This is especially true if you&#8217;re building a generic app.</p>
<p>Don&#8217;t get me wrong, I certainly believe in picking the right tool for the job so for example if you&#8217;re building a real-time app with long lasting (web socket) connections then Node.js + Socket.io is probably one of the best choices for you.</p>
<p>&#8212;</p>
<p>What drives us to make any choice depends on our personal bias, project context and business constraints. In which order? Don&#8217;t know. It varies from time to time. </p>
<p>It would be nice if we minimize the influence of personal bias.</p>
<p>&#8212;</p>
<p>One lesson for all programmers out there, and for myself of course, is not to let ourselves be identified with any camp. Which programming language we like isn&#8217;t our identity.</p>
<p>If we are to spend time in this industry, we&#8217;ll have to learn a wide array of languages. Let&#8217;s be open to learning and overcome the reluctance to change.</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2012-05-becoming-programming-language-agnostic/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The New MFAs &#8211; &#8216;Made for Acquisition&#8217; Startups</title>
		<link>http://srirangan.net/2012-05-the-new-mfas-made-for-acquisition-startups</link>
		<comments>http://srirangan.net/2012-05-the-new-mfas-made-for-acquisition-startups#comments</comments>
		<pubDate>Mon, 07 May 2012 00:56:12 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[entrepreneurship]]></category>
		<category><![CDATA[startups]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=1083</guid>
		<description><![CDATA[A few years ago there was a rush to create cheap, content scraping &#8220;Made for Adsense&#8221; (MFA) websites. These websites&#8217; sole purpose was to quickly generate content, get listed on Google and other search engines to get users, use the &#8230; <a href="http://srirangan.net/2012-05-the-new-mfas-made-for-acquisition-startups">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A few years ago there was a rush to create cheap, content scraping &#8220;Made for Adsense&#8221; (MFA) websites. </p>
<p>These websites&#8217; sole purpose was to quickly generate content, get listed on Google and other search engines to get users, use the Google Adsense program to get advertisers, display these ads prominently and make a quick buck.</p>
<p>Built on open source CMS&#8217;s, the costs of creating and running MFA websites were so negligible that many of these MFA websites showed up literally over night. The situation is eerily similar today in the tech startups universe.</p>
<p>There&#8217;s a new MFA is town &#8211; Made for acquisition &#8211; startups. MFA startups want to be acquired, as quickly as possible. And given the bubble we&#8217;re in, it&#8217;s occurring with rather obscene frequency.</p>
<p>Here are some MFA startup models I&#8217;ve been able to identify:</p>
<h2>Clone Model</h2>
<p>As an MFA startup, your job is to clone a fast rising startup. This again, unfortunately, can be done for a really low cost and in a very short amount of time. </p>
<p>Then you tap into your local market with the clone, gain some traction and sell out to the original startup or a big established entity that wants to compete with the original success.</p>
<h2>Add a Feature Model</h2>
<p>Here your job is to offer a complementary feature to an already successful entity. It can be a really small feature, or more substantive. </p>
<p>Integrate it deeply with the API&#8217;s the larger entity provides. Then gain some traction and hope and pray for the buy out.</p>
<h2>Ethical and legal issues</h2>
<p>Generally the Clone Model is unethical but legal because they&#8217;re doing their thing in a different country. However there might be legal complexities depending on the context and the local situation. But generally there isn&#8217;t much the original innovator can do to stop clones popping up around the world.</p>
<p>The Add a Feature Model is definitely ethical and legal. There&#8217;s probably nothing wrong with them.</p>
<h2>Innovations</h2>
<p>My main complaint with both these models is that its innovation that takes a hit. You&#8217;re smart, you&#8217;re intelligent and you&#8217;re perceptive. Why piggy bank on someone else&#8217;s success?</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2012-05-the-new-mfas-made-for-acquisition-startups/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>When should a web app send marketing emails?</title>
		<link>http://srirangan.net/2012-05-when-should-a-web-app-send-marketing-emails</link>
		<comments>http://srirangan.net/2012-05-when-should-a-web-app-send-marketing-emails#comments</comments>
		<pubDate>Sun, 06 May 2012 03:28:58 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[apps]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[marketing]]></category>
		<category><![CDATA[review19]]></category>
		<category><![CDATA[web apps]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=1067</guid>
		<description><![CDATA[I know this has been happening for a while but I&#8217;ve recently started to notice this quite a bit. Web apps, usually with SAAS based business models send out recurring marketing emails to active and inactive users. These emails hit &#8230; <a href="http://srirangan.net/2012-05-when-should-a-web-app-send-marketing-emails">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I know this has been happening for a while but I&#8217;ve recently started to notice this quite a bit. </p>
<p>Web apps, usually with SAAS based business models send out recurring marketing emails to active and inactive users. These emails hit your inbox like clockwork. Usually asking you to restart using their product, purchase a paid plan, try out a new feature etc. </p>
<p>Sometimes the frequency of these marketing emails can be smart, driven by user activity, nevertheless the emails remain unsolicited and purely marketing / advertising in purpose.</p>
<p>However I can&#8217;t remember when was the last time GitHub sent me a pure marketing email. Or Google, or any other trustworthy internet brand doing the same. Then why should your web app do so?</p>
<p>Of course being an app founder / creator myself &#8212; <a href="http://review19.com">Review19</a> &#8212; I can understand the urge. You want engagement, you want your registered users to come back. You want to help them understand and use the app better. Bottom line, you want more traction.</p>
<p>But isn&#8217;t your email inbox your personal space. Should you take advantage of the trust your users have placed in you in sharing their email addresses?</p>
<p>Out of respect, <a href="http://review19.com">Review19</a> wouldn&#8217;t send you an marketing emails (Disclaimer: Some team collaboration features on <a href="http://review19.com">Review19</a> do trigger notifications).</p>
<p>What&#8217;s required is probably a balance. You don&#8217;t want to send out a lot of these emails as people are more internet savvy, likely to ignore / mark as spam, and you really risk hurting your brand.</p>
<p>If you&#8217;re in it for the long run, it&#8217;s critical to win trust and sending out too many marketing emails is one of the quicker ways to lose user trust.</p>
<p>What do you think? What&#8217;s the acceptable etiquette for this</p>
<p>Join the discussion on <a href="http://news.ycombinator.com/item?id=3934063">Hacker News</a>, <a href="http://hackerstreet.in/item?id=16066">Hacker Street India</a>, <a href="http://www.reddit.com/r/startups/comments/tatjm/when_should_a_web_app_send_marketing_emails/">Reddit</a></p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2012-05-when-should-a-web-app-send-marketing-emails/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How do you make decisions?</title>
		<link>http://srirangan.net/2012-04-how-do-you-make-decisions</link>
		<comments>http://srirangan.net/2012-04-how-do-you-make-decisions#comments</comments>
		<pubDate>Sun, 29 Apr 2012 03:12:14 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[review19]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=1051</guid>
		<description><![CDATA[How do you make decisions? How does your team contribute to this process? How easy is it to share resources (docs, images, videos, links) amongst yourselves? And how easy is it to access them in a single workspace? Do you &#8230; <a href="http://srirangan.net/2012-04-how-do-you-make-decisions">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>How do you make decisions? How does your team contribute to this process? How easy is it to share resources (docs, images, videos, links) amongst yourselves? And how easy is it to access them in a single workspace?</p>
<p>Do you have a simple way to conduct polls and pool in opinions of all participants? Do you have the tools to perform fact based, merit driven analyses?</p>
<p>Is there a simple way to track all this activity while it happens? And can you audit a past decision? Can you check what facts were known, analysis done and conclusions drawn?</p>
<p>Is your decision process archived? And can it be shared within the organization? Is the decision process consolidated in a single workspace? Or does it lie scattered across various mail boxes and document folders?</p>
<p>Progressive organizations are changing the way they make decisions. Try Review19.</p>
<h1 style="font-size: 24px; letter-spacing: -1px; margin: 6px 0 0 0;"><a href="http://review19.com">Review19</a></h1>
<p><strong>Collaborate &#038; Track Decisions</strong><br />
<em>Collaborate, track and audit decision processes and projects</em><br />
<a href="http://review19.com">http://review19.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2012-04-how-do-you-make-decisions/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Need a quick start? Try express-bootstrap</title>
		<link>http://srirangan.net/2012-04-need-a-quick-start-try-express-bootstrap</link>
		<comments>http://srirangan.net/2012-04-need-a-quick-start-try-express-bootstrap#comments</comments>
		<pubDate>Thu, 26 Apr 2012 17:05:26 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[express]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[twitter bootstrap]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=1045</guid>
		<description><![CDATA[If you (like me) end up spawning and destroying experimental web apps all the time, this one&#8217;s for you. express-bootstrap Clone this and you have a fully configured single page web app with jQuery and Twitter Bootstrap bundled in.]]></description>
			<content:encoded><![CDATA[<p>If you (like me) end up spawning and destroying experimental web apps all the time, this one&#8217;s for you.</p>
<p><a href="https://github.com/Srirangan/express-bootstrap" title="Template for an Express.js single page web app bundled with jQuery and Twitter Bootstrap"><strong>express-bootstrap</strong></a></p>
<p>Clone this and you have a fully configured single page web app with jQuery and Twitter Bootstrap bundled in.</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2012-04-need-a-quick-start-try-express-bootstrap/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My Talk @ JSFoo, Chennai 2012</title>
		<link>http://srirangan.net/2012-03-my-talk-jsfoo-chennai-2012</link>
		<comments>http://srirangan.net/2012-03-my-talk-jsfoo-chennai-2012#comments</comments>
		<pubDate>Tue, 27 Mar 2012 13:27:41 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jsfoo]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[review19]]></category>
		<category><![CDATA[socket.io]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=1028</guid>
		<description><![CDATA[Topic: Next generation web apps, web sockets, real-time collaboration apps Venue: IIT Madras Research Park Date: 18th February 2012]]></description>
			<content:encoded><![CDATA[<p><strong>Topic:</strong> Next generation web apps, web sockets, real-time collaboration apps<br />
<strong>Venue:</strong> IIT Madras Research Park<br />
<strong>Date:</strong> 18th February 2012</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/V4ooP1SmVPk" frameborder="0" allowfullscreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2012-03-my-talk-jsfoo-chennai-2012/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My predictions on Scala..</title>
		<link>http://srirangan.net/2012-02-my-predictions-on-scala</link>
		<comments>http://srirangan.net/2012-02-my-predictions-on-scala#comments</comments>
		<pubDate>Thu, 23 Feb 2012 03:34:26 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[liftweb]]></category>
		<category><![CDATA[play! framework]]></category>
		<category><![CDATA[predictions]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=1016</guid>
		<description><![CDATA[Here&#8217;s my take for whatever its worth. * Scala will become a specialized language driven by its frameworks and libraries. * Scala will never become the popular general purpose language that Java once was. * Scala will heavily influence Java &#8230; <a href="http://srirangan.net/2012-02-my-predictions-on-scala">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s my take for whatever its worth.</p>
<p>* Scala will become a specialized language driven by its frameworks and libraries.</p>
<p>* Scala will never become the popular general purpose language that Java once was.</p>
<p>* Scala will heavily influence Java 8 and future Java iterations.</p>
<p>* Bonus non-Scala prediction &#8211; Oracle needs to speed up language improvements or Java the language will face extinction. JVM will be around for long.</p>
<p>* Scala (and Java) will cede the web / mobile app space to the likes of Node.js, Python.</p>
<p>* Bonus non-Scala prediction &#8211; Ruby will die.</p>
<p>* Bonus non-Scala prediction &#8211; Native mobile apps are stupid. They&#8217;ll eventually become irrelevant as browser based web / mobile apps consolidate and take over.</p>
<p>* Simpler, less complex dialect of Scala will arrive tailored for specific genre of apps.</p>
<p>* Scala community will someday realize that over-engineering can&#8217;t go on forever and business needs have to be addressed.</p>
<p>* LiftWeb is the devil.</p>
<p>* LiftWeb will die.</p>
<p>* SBT is the lesser devil.</p>
<p>* SBT will, nevertheless, die.</p>
<p>* Scala compiler will always be very slow.</p>
<p>* Play! will dominate.</p>
<p>* Play! won&#8217;t drive the Scala language adoption.</p>
<p>* If Java implements functions as first class members tomorrow, half of Scala&#8217;s oomph will be lost.</p>
<p>More predictions welcome &#8211; please comment below and I add them to the list.</p>
<p>Friends, well-wishers, trolls and haters welcome to post comments. Will screen for obscenities but otherwise will publish all comments.</p>
<blockquote><p>Disclaimer &#8211; None of these predictions are legally binding on me. </p>
<p>Situations do change. </p>
<p>If you&#8217;re reading this in the future and are likely to base a business decision on them, you are advised to hire me to analyze the then existing technology situation through the prism of your business scenario. </p>
<p>That&#8217;ll enable me to provide you relevant and actionable advise.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2012-02-my-predictions-on-scala/feed</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Speaking at JSFoo, Chennai 2012</title>
		<link>http://srirangan.net/2012-02-speaking-at-jsfoo-chennai-2012</link>
		<comments>http://srirangan.net/2012-02-speaking-at-jsfoo-chennai-2012#comments</comments>
		<pubDate>Thu, 16 Feb 2012 16:00:46 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[review19]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=1003</guid>
		<description><![CDATA[I will be speaking at India&#8217;s largest JavaScript and Node.js event JSFoo Chennai 2012 on the 18th of February 2012. Excited to demo Review19 and share my insights on the evolution of next generation web apps. Looking forward to seeing &#8230; <a href="http://srirangan.net/2012-02-speaking-at-jsfoo-chennai-2012">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I will be speaking at India&#8217;s largest JavaScript and Node.js event <a href="http://jsfoo.in/chennai2012/">JSFoo</a> Chennai 2012 on the 18th of February 2012. </p>
<p>Excited to demo <a href="http://www.review19.com">Review19</a> and share my insights on the evolution of next generation web apps. Looking forward to seeing you there!</p>
<p><a href="http://funnel.hasgeek.com/jsfoo-chennai/218-ajax-is-history-build-real-time-apps-in-javascript">Details of my talk</a> | <a href="http://jsfoo.in/chennai2012/venue">Venue</a> | <a href="http://jsfoo.in/chennai2012/schedule">Schedule</a> | <a href="http://jsfoo.in/">JSFoo</a></p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2012-02-speaking-at-jsfoo-chennai-2012/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Published on HowToNode.org</title>
		<link>http://srirangan.net/2012-02-published-on-howtonode-org</link>
		<comments>http://srirangan.net/2012-02-published-on-howtonode-org#comments</comments>
		<pubDate>Mon, 13 Feb 2012 04:22:55 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=1000</guid>
		<description><![CDATA[Submitted two of my recent posts to HowToNode.org. Love their excellent Git / GitHub based publishing workflow, excellent way to attract good content from programmers. Here are the links: * Node.js and MongoDB &#8211; Getting started with MongoJS * Really &#8230; <a href="http://srirangan.net/2012-02-published-on-howtonode-org">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Submitted two of my recent posts to <a href="http://howtonode.org">HowToNode.org</a>. </p>
<p>Love their excellent Git / GitHub based publishing workflow, excellent way to attract good content from programmers.</p>
<p>Here are the links:<br />
* <a href="http://howtonode.org/node-js-and-mongodb-getting-started-with-mongojs">Node.js and MongoDB &#8211; Getting started with MongoJS</a><br />
* <a href="http://howtonode.org/really-simple-file-uploads">Really simple file uploads with Express</a></p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2012-02-published-on-howtonode-org/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Node.js and MongoDB &#8211; Getting started with MongoJS</title>
		<link>http://srirangan.net/2012-02-node-js-and-mongodb-getting-started-with-mongojs</link>
		<comments>http://srirangan.net/2012-02-node-js-and-mongodb-getting-started-with-mongojs#comments</comments>
		<pubDate>Mon, 06 Feb 2012 12:53:39 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[mongojs]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=957</guid>
		<description><![CDATA[It won&#8217;t be an exaggeration if one claims that in the past few months Node.js and MongoDB have literally taken the software and web industries by storm. Not just bleeding-edge startups but even medium and large enterprises are leveraging these &#8230; <a href="http://srirangan.net/2012-02-node-js-and-mongodb-getting-started-with-mongojs">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>It won&#8217;t be an exaggeration if one claims that in the past few months Node.js and MongoDB have literally taken the software and web industries by storm. </p>
<p>Not just bleeding-edge startups but even medium and large enterprises are leveraging these two technologies to deliver a better experience to their users by build more capable, performant and scalable apps.</p>
<p>So what is Node.js?</p>
<blockquote><p>Node.js is a platform built on Chrome&#8217;s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.</p></blockquote>
<p>..and what is MongoDB?</p>
<blockquote><p>MongoDB is a scalable, high-performance, open source NoSQL database.</p></blockquote>
<p>This post will cover the basics and get you started with your Node.js + MongoDB app. Make sure you have <a href="http://nodejs.org/#download">Node.js installed</a> and <a href="http://www.mongodb.org/downloads">MongoDB setup</a> on your developer machine.</p>
<p>Let&#8217;s verify your Node.js installation and start the MongoDB server:</p>
<pre>
$ node -v
$ mongod
</pre>
<p><strong>Introducing MongoJS</strong><br />
<a href="https://github.com/gett/mongojs">MongoJS</a> is a brilliant little Node.js package that lets you access MongoDB using an API that is extremely similar to MongoDB&#8217;s JavaScript shell.</p>
<p><strong>Installing MongoJS</strong><br />
Once Node.js has been setup correctly on your machine, you can use its internal package manager <a href="http://npmjs.org/">NPM</a> to install MongoJS:</p>
<pre>
$ npm install mongojs
</pre>
<p>We can now start building our JavaScript application and connect to our MongoDB server:</p>
<pre>
// app.js
var databaseUrl = "mydb"; // "username:password@example.com/mydb"
var collections = ["users", "reports"]
var db = require("mongojs").connect(databaseUrl, collections);
</pre>
<p>The <code>databaseUrl</code> can contain the database server host and port along with the database name to connect to. By default the host is &#8220;<code>localhost</code>&#8221; and the port is &#8220;<code>27017</code>&#8220;. If you&#8217;re using the default, which is likely on a developer environment, the <code>databaseUrl</code> can contain just the actual database name for our app.</p>
<p>The <code>collections</code> is a set (array) of collections our application uses. It isn&#8217;t mandatory but is preferred as it allows us to emulate a MongoDB JavaScript client like API within our Node.js app.</p>
<p>Here&#8217;s an example for finding documents within a collection specifically in this case to find all female users.</p>
<pre>
// app.js
db.users.find({sex: "female"}, function(err, users) {
  if( err || !users) console.log("No female users found");
  else users.forEach( function(femaleUser) {
    console.log(femaleUser);
  } );
});
</pre>
<p>Notice how our initial query is a near duplication of the corresponding query in MongoDB&#8217;s console. In addition to the query, in our Node.js source code (i.e. app.js) we pass a callback function to handle the results of the query. </p>
<p>Node.js implements an event based concurrency paradigm and almost everything is always a callback. This allows your Node.js app to be non-blocking and high performing. </p>
<p>What happens in our specific callback is self-explanatory &#8212; we check for errors and results, and if the query returns female users they are logged to the console.</p>
<p>Okay, how do I save a new user in my collection? Exactly how you would do it in the console, your code will look like this:</p>
<pre>
// app.js
db.users.save({email: "srirangan@gmail.com", password: "iLoveMongo", sex: "male"}, function(err, saved) {
  if( err || !saved ) console.log("User not saved");
  else console.log("User saved");
});
</pre>
<p>Here&#8217;s an example for updating a record / document:</p>
<pre>
// app.js
db.users.update({email: "srirangan@gmail.com"}, {$set: {password: "iReallyLoveMongo"}}, function(err, updated) {
  if( err || !updated ) console.log("User not updated");
  else console.log("User updated");
});
</pre>
<p>Okay, now we run this app in the console:</p>
<pre>
$ node app.js
</pre>
<p>And there we have it, an incredibly simple quick start for Node.js + MongoDB enthusiasts. Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2012-02-node-js-and-mongodb-getting-started-with-mongojs/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>At what stage should scalability be addressed?</title>
		<link>http://srirangan.net/2012-02-at-what-stage-should-scalability-be-addressed</link>
		<comments>http://srirangan.net/2012-02-at-what-stage-should-scalability-be-addressed#comments</comments>
		<pubDate>Mon, 06 Feb 2012 05:36:52 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[scalability]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=937</guid>
		<description><![CDATA[In this post I will try to be as non-partisan as possible with respect to technology, platforms, programming languages, databases etc. Do forgive me if I fail in this attempt. Here&#8217;s the question on hand: When should business, leadership, dev &#8230; <a href="http://srirangan.net/2012-02-at-what-stage-should-scalability-be-addressed">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In this post I will try to be as non-partisan as possible with respect to technology, platforms, programming languages, databases etc. Do forgive me if I fail in this attempt.</p>
<p>Here&#8217;s the question on hand:<br />
<strong>When should business, leadership, dev teams and other stakeholders address the scalability question.</strong></p>
<p>It&#8217;s a dilema I face and others depend on my advise so I&#8217;m pooling in your wisdon. </p>
<p>Allow me to ellaborate the question. We&#8217;re building a product and we have two choices:</p>
<p><strong>Choice 1</strong></p>
<p>Go in for a technology that is extremely popular. It has been around in the mainstream for at least half a decade. It&#8217;s a good business choice because of the maturity of the environment, the availability of talent / outsourcing firms and positive feedback overall. </p>
<p>However there are some questions over scalability. There are many case-studies where headline grabbing companies have had to abandon this technology and go in for a complete / partial rewrite on another platform. </p>
<p>The argument here goes like this:</p>
<blockquote><p>&#8220;If we use this technology and we face scalability problems few months down the line, it&#8217;s a good problem to have because it means we have done really well. So lets go ahead with this for now, even if it means a rewrite six months down the line.&#8221;</p></blockquote>
<p><strong>Choice 2</strong></p>
<p>We can opt for another much younger technology. It has an active community but comparatively less mature environment / toolkits. In comparison to Choice 1, it is harder to find good and affordable talent. </p>
<p>The programming language here is extremely expressive yet heavily misunderstood.</p>
<p>However there are bona fide scaling credentials. It&#8217;s been a choice for organisations that are proven technology leaders. And its perhaps a safer bet in the long run on the scalability parameter.</p>
<p><strong>Your call</strong></p>
<p>As a programmer / hacker / geek, Choice 2 is an obvious winner. At least for me its a no-brainer.</p>
<p>However put yourself in a product owner / manager / CTO / decision-making role. Does your opinion change?</p>
<p>Welcoming all your comments, thanks!</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2012-02-at-what-stage-should-scalability-be-addressed/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Really simple file uploads with Node.js and Express</title>
		<link>http://srirangan.net/2012-02-really-simple-file-uploads-with-node-js-and-express</link>
		<comments>http://srirangan.net/2012-02-really-simple-file-uploads-with-node-js-and-express#comments</comments>
		<pubDate>Sun, 05 Feb 2012 08:55:44 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[express.js]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=926</guid>
		<description><![CDATA[Few days ago I was working on a fairly typical web application and I faced the challenge of implementing a fairly typical web application feature &#8211; file uploads. It was the first time I was implementing file uploads with Node &#8230; <a href="http://srirangan.net/2012-02-really-simple-file-uploads-with-node-js-and-express">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Few days ago I was working on a fairly typical web application and I faced the challenge of implementing a fairly typical web application feature &#8211; file uploads. It was the first time I was implementing file uploads with Node (and Express) and I did what anyone else would do &#8211; I googled it.</p>
<p>Unfortunately all the articles / posts out there are either outdated, too complex or plain wrong. So I did the next most obvious thing &#8211; post a question on the mailing list. As always Mr. Holowaychuk was incredibly quick to respond. His answer lead me to do what I should have done in the first place &#8211; read the docs.</p>
<p><strong>The upload form</strong></p>
<p>This is the most obvious part of the challenge. You&#8217;re probably familiar with this already. Anyway, for the sake of completeness of this article, here it is.</p>
<p>You will need a form in your browser for the file upload. I use Jade to generate my HTML and here how it looks:</p>
<pre>
form(action="...", method="post", enctype="multipart/form-data")
  input(type="file", name="displayImage")
</pre>
<p>The form.action will point to a route that handles the file upload. More below.</p>
<p><strong>Accessing the uploaded file</strong></p>
<p>If you&#8217;re using recents versions of Node and Express, file uploads are a piece of cake. And I&#8217;ll back this claim but before we go any further make sure you&#8217;re familiar with routes, requests and responses in Express.</p>
<p>Okay, now let&#8217;s justify the &#8220;piece of cake&#8221; claim. In our file upload route, the req parameter has req.files available. Here&#8217;s an example of what the req.files would contain:</p>
<pre>
{
  displayImage: {
    size: 11885,
    path: '/tmp/1574bb60b4f7e0211fd9ab48f932f3ab',
    name: 'avatar.png',
    type: 'image/png',
    lastModifiedDate: Sun, 05 Feb 2012 05:31:09 GMT,
    _writeStream: {
      path: '/tmp/1574bb60b4f7e0211fd9ab48f932f3ab',
      fd: 14,
      writable: false,
      flags: 'w',
      encoding: 'binary',
      mode: 438,
      bytesWritten: 11885,
      busy: false,
      _queue: [],
      drainable: true
    },
    length: [Getter],
    filename: [Getter],
    mime: [Getter]
  }
}
</pre>
<p>In the <code>req.files</code> object above, the property <code>displayImage</code> is the name of the file field in your HTML form and <code>req.files</code> will contain one property each for every valid HTML file form field.</p>
<p>The file object contains the <code>type</code>, <code>size</code> and <code>name</code> properties for your server side validations.</p>
<p><strong>Saving the uploaded file</strong></p>
<p>Assuming the file is valid, you use the <code>path</code> property for the next step. The <code>path</code> would typically contain a location in the tmp folder. Your application logic could either require you to access the contents of the file or simply move the uploaded file to another location.</p>
<pre>
fs.readFile(req.files.displayImage.path, function (err, data) {
  // ...
  var newPath = __dirname + "/uploads/uploadedFileName";
  fs.writeFile(newPath, data, function (err) {
    res.redirect("back");
  });
});
</pre>
<p>In the <code>fs.readFile</code> callback, we have the data parameter through which we can access the contents of the file. The example above is taken from an application that needed to modify the file and save it in a new location. Thus <code>fs.writeFile</code> is used to write data to the newPath.</p>
<p>If your app needs to simply move the uploaded file without modifying the contents <code>fs.rename</code> can be used as more simpler option.</p>
<p>&#8212;</p>
<p>That&#8217;s all there is to it. I&#8217;ve done file uploads in many server side languages including Python, Java, Scala and PHP and I don&#8217;t think its ever been this simple. </p>
<p>So much for JavaScript being labeled as an inferior server side language.</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2012-02-really-simple-file-uploads-with-node-js-and-express/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>JSFoo Chennai 2012 &#8211; Ajax is history &#8211; Build real time apps in JavaScript</title>
		<link>http://srirangan.net/2012-02-jsfoo-chennai-2012-ajax-is-history-build-real-time-apps-in-javascript</link>
		<comments>http://srirangan.net/2012-02-jsfoo-chennai-2012-ajax-is-history-build-real-time-apps-in-javascript#comments</comments>
		<pubDate>Sun, 05 Feb 2012 04:39:05 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jsfoo]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[review19]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=921</guid>
		<description><![CDATA[Submitted a proposal for JSFoo Chennai 2012 titled Ajax is history &#8211; Build real time apps in JavaScript. Quick preview: Objective How to build the next generation of real-time browser based apps with JavaScript and related technologies. Description Ajax is &#8230; <a href="http://srirangan.net/2012-02-jsfoo-chennai-2012-ajax-is-history-build-real-time-apps-in-javascript">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Submitted a proposal for JSFoo Chennai 2012 titled <a href="http://funnel.hasgeek.com/jsfoo-chennai/218-ajax-is-history-build-real-time-apps-in-javascript">Ajax is history &#8211; Build real time apps in JavaScript</a>.</p>
<p>Quick preview:</p>
<blockquote><p><strong>Objective</strong><br />
How to build the next generation of real-time browser based apps with JavaScript and related technologies.</p>
<p><strong>Description</strong><br />
Ajax is history. After having built Review19 &#8212; Review19.com provides next generation real-time collaborative tools &#8212; I&#8217;d like to share my approach, the technologies used, the architecture followed by a quick demo and code walk through.</p>
<p><strong>Requirements</strong><br />
* Good sense of humor<br />
* Appreciation for random katrina kaif pics inserted between slides<br />
* Knowledge of web app development in general<br />
* More JavaScript (Node, NPM etc.) stack knowledge, the better</p></blockquote>
<p>If you&#8217;re interested, don&#8217;t forget to <a href="http://funnel.hasgeek.com/jsfoo-chennai/218-ajax-is-history-build-real-time-apps-in-javascript">vote</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2012-02-jsfoo-chennai-2012-ajax-is-history-build-real-time-apps-in-javascript/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How I built a real-time collaborative app with MongoDB</title>
		<link>http://srirangan.net/2012-01-how-i-built-a-real-time-collaborative-app-with-mongodb</link>
		<comments>http://srirangan.net/2012-01-how-i-built-a-real-time-collaborative-app-with-mongodb#comments</comments>
		<pubDate>Sat, 14 Jan 2012 13:10:03 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[review19]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=904</guid>
		<description><![CDATA[This is an account of how Review19 was built in just a couple of weeks and how MongoDB was an excellent choice for this genre of browser based, real-time collaborative apps. First things first &#8212; what is Review19? Review19 is &#8230; <a href="http://srirangan.net/2012-01-how-i-built-a-real-time-collaborative-app-with-mongodb">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is an account of how <a href="http://www.review19.com">Review19</a> was built in just a couple of weeks and how <a href="http://www.mongodb.org/">MongoDB</a> was an excellent choice for this genre of browser based, real-time collaborative apps.</p>
<p>First things first &#8212; what is Review19? Review19 is the next generation, real-time project collaboration tool for web, creative and software teams. Think of it as a minimalist, real-time Pivotal Tracker alternative. It&#8217;s like Trello, but caters to a focused target audience.</p>
<p>Give it a shot, try out <a href="http://www.review19.com">Review19</a>. If you&#8217;re stuck behind a proxy that doesn&#8217;t like web sockets, here&#8217;s the <a href="http://review19.com:3000">failover link</a>.</p>
<h2>The Technology Stack</h2>
<p>Obviously an app can&#8217;t be built with a data store alone. </p>
<p>In addition to a MongoDB based storage engine, the APIs and backend for Review19 are built on the Node.js platform and make use of popular frameworks including Express and Socket.io.</p>
<p>The frontend client app &#8212; which is under heavy refactoring as we speak &#8212; leverages advances in browser capability with respect to JavaScript execution and CSS renderings. The frameworks here include jQuery, jQuery UI and Sugar among others.</p>
<p>Why am I mentioning all of this? The overall technology stack needs to be known to highlight a huge advantage:</p>
<h2>JSON. Everywhere!</h2>
<p>I&#8217;ve been a professional programmer for ten years now and I&#8217;ve had the fortune (misfortune?) of working with a diverse set of technologies. </p>
<p>I happen to have dealt with:</p>
<ul>
<li>the typical enterprise Java stack &#8211; Spring, Hibernate etc.</li>
<li>
recent advances in Java technologies including Scala, LiftWeb, Play! etc.</li>
<li>
built apps in Python using Django, Tornado and Google App Engine</li>
<li>
built apps in PHP and its set of frameworks</li>
<li>
built apps in Adobe Flex working with different types backend APIs</li>
</ul>
<p>In each of these technologies, a developer has to deal with the mundane task of transforming his model between the client, server and data store. Better development teams would automate this process with the use of ORMs or helper frameworks. However this would still need the inclusion of these dependencies and the configuration of these frameworks.</p>
<p>While developing Review19 with the chosen technologies, things worked out of the box. It was JSON on the server, JSON on the client and, thanks to MongoDB, JSON on the data store. The productivity benefit was huge, especially for an independent developer like me, or small teams with tough deadlines.</p>
<p>The advantage of this cannot be underplayed. It strikes you right away when you build your first proof-of-concept and it stays with you throughout your development cycle. </p>
<h2>Flexibility is not just a buzz-word</h2>
<p>About 10-12 months ago, I was working on a project for an SF Bay startup that wanted to built an analytics / BI suite running on top of customer databases. </p>
<p>It wasn&#8217;t a very complex project, but just a large and poorly managed one. I remember being asked repeatedly about how the database was being versioned. The answer &#8220;it was being versioned in the code&#8221; wasn&#8217;t good enough for the &#8216;expert&#8217; and his evil overlords.</p>
<p>Hmm.. generating and storing multiple versions of the data model as an .sql file in your source code repository. Sounds familiar? Of course it does. And it sounds just as painful as it sounds familiar. Even if this process is somehow painstakingly automated and devs don&#8217;t have to deal with it any more, you still often end up with multiple version of SQL files never being used.</p>
<p>Whatever your application be, the entities / models are bound to evolve with time. Things will change, sometimes so much that they won&#8217;t share even the slightest resemblance with the original designs. </p>
<p>With MongoDB, however, the data store adapts seamlessly to your app. There isn&#8217;t the slightest need to run scripts, create tables, alter columns etc. on the data store prior to each deployment. This is how it&#8217;s done for Review19 and I&#8217;d assume for a majority of projects using MongoDB.</p>
<p>This will bring a small morale boost and a large productivity boost for your dev and devops teams.</p>
<h2>Node.js + MongoDB = MongoJS</h2>
<p>MongoDB is one of the most mature NoSQL options available today and that maturity is proven by the rich set of APIs MongoDB provides that allow you to perform basic and advanced operations on your data.</p>
<p>Furthermore the MongoDB Querying APIs are ridiculously simple, yet powerful and easy to master. In fact its so easy to learn that you wouldn&#8217;t miss the very same SQL that you spent years to master.</p>
<p>A majority of MongoDB evangelists and proponents I&#8217;ve interacted with swear by this capability. After spending sometime on the MongDB Interactive Shell, I could see what they meant.</p>
<p>I needed to access the same capabilities in my Node.js backend app. Node.js has got a well maintained MongoDB driver and a lot of interesting abractions on top of that driver. </p>
<p>My choice zeroed in on <a href="https://github.com/gett/mongojs">MongoJS</a> and the clinching argument was the MongoJS mission statement:</p>
<blockquote><p>&#8220;A node.js module for mongodb, that emulates the mongodb API as much as possible.&#8221;</p></blockquote>
<p>Your actual executable JavaScript code looks exactly the same to what you do the MongoDB console. How can this not be a #win? I like minimalism and MongoJS was as minimalist as possible.</p>
<p>There are a lot of other options as well for Node.js &#8211; MongoDB interaction and it would be best to cover them in detail in a future post.</p>
<h2>Speed</h2>
<p>Did I mention Review19 is incredibly fast? Almost in all the feedback received, the users mention among other things how fast it is and how it improved their experience.</p>
<p>I understand that application architecture has a role to play in this but one can&#8217;t take all the credit for the speed and performance witnessed by Review19 users. One must thank the underlying platforms it was built on which includes Node.js and MongoDB.</p>
<p>I&#8217;m sure you&#8217;ll find all the MongoDB speed benchmarks you want. They&#8217;re just a Google search away. What I intend to highlight here is that in a real world collaborative app which has a single instance running on standard, non-fancy hardware, Node.js and MongoDB are serving the needs brilliantly. </p>
<p>Remember this is a real-time collaboration app where instead of frequent smaller requests, a frontend client has a long lived connection with the backend server. This is exactly the kind of app that would have faced scaling issues few years ago and would have needed a lot of infrastructure both in terms of code and hardware.</p>
<p>Node.js and MongoDB make this economical for independent devs like me without the resources big corps can provide.</p>
<h2>Conclusion</h2>
<p>I&#8217;m extremely pleased with the technology choices made in which of course MongoDB is a critical component. I&#8217;ve completed the entire product cycle from conceptualization and design to testing, development and deployments.  </p>
<p>Described above are ways MongoDB made this enitre process simpler, kept deployments easy and provided all the features and more needed by Review the app.</p>
<p>Now I look forward the the next set of challenges which include maintaining, scaling and enhancing the system. And I promise to let you know how that goes. Stay tuned to this blog! ;-)</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2012-01-how-i-built-a-real-time-collaborative-app-with-mongodb/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>How Trello is *not* different</title>
		<link>http://srirangan.net/2012-01-how-trello-is-not-different</link>
		<comments>http://srirangan.net/2012-01-how-trello-is-not-different#comments</comments>
		<pubDate>Sat, 07 Jan 2012 05:36:27 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[review19]]></category>
		<category><![CDATA[trello]]></category>
		<category><![CDATA[web sockets]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=887</guid>
		<description><![CDATA[Joel Spolsky, a figure lot of us look up to, made a very interesting post about Trello and how it is different. Note &#8211; Before reading any further, you should know I am the creator of Review19, a tool quite &#8230; <a href="http://srirangan.net/2012-01-how-trello-is-not-different">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Joel Spolsky, a figure lot of us look up to, made a very interesting <a href="http://www.joelonsoftware.com/items/2012/01/06.html">post</a> about <a href="https://trello.com/">Trello</a> and how it is different.</p>
<blockquote><p>Note &#8211; Before reading any further, you should know I am the creator of <a href="http://review19.com/">Review19</a>, a tool quite similar to Trello.
</p></blockquote>
<p>I loved Spolsky&#8217;s post, except the title. Trello didn&#8217;t seem different at all. Going by a lot of Spolsky&#8217;s parameters, Review19 and Trello are <em>very</em> similar.</p>
<p>Here&#8217;s trying to shed more light on my claim:</p>
<h2>Hosted Only</h2>
<p>Review19 &#8211; Yes<br />
Trello &#8211; Yes</p>
<p>Both Review19 and Trello are hosted only solutions, at least as of now. You cannot buy a license and install privately on your servers.</p>
<h2>Continuous Delivery</h2>
<p>Review19 &#8211; Yes<br />
Trello &#8211; Yes</p>
<p>Just like Google Chrome &#8212; which still maintains versions &#8212; but is released / delivered continuously for all intents and purposes both Review19 and Trello share this development / delivery model.</p>
<h2>Inexhaustive Testing</h2>
<p>Review19 &#8211; Yes<br />
Trello &#8211; Yes</p>
<p>Joel&#8217;s team at Fog Creek, by choice, don&#8217;t exhaustively test Trello before each release. Review19 is being development and maintained by a single individual, i.e. me, it&#8217;s not really possible to exhaustively test Review19 either. Sorry about that!</p>
<h2>Work in public</h2>
<p>Review19 &#8211; Yes<br />
Trello &#8211; Yes</p>
<p>Trello works in public by offering a public status board. Review19 puts itself out their through a public mailing list and roadmap. Volunteers are added to a private status board.</p>
<h2>Get big fast</h2>
<p>Review19 &#8211; Yes<br />
Trello &#8211; Yes</p>
<p>Trello aims to get 100 million users. I&#8217;d be an idiot if I didn&#8217;t want that for Review19 either. ;-)</p>
<h2>Free</h2>
<p>Review19 &#8211; Yes<br />
Trello &#8211; Yes</p>
<h2>Plugin architecture</h2>
<p>Review19 &#8211; Yes<br />
Trello &#8211; Yes</p>
<p>The merits of such an architecture are obvious. Review19 uses client and server side JavaScript modules for achieving such an architecture. I&#8217;m not sure how Trello does it but we have no reason to doubt Joel&#8217;s remark.</p>
<h2>Node.js</h2>
<p>Review19 &#8211; Yes<br />
Trello &#8211; Yes</p>
<h2>MongoDB</h2>
<p>Review19 &#8211; Yes<br />
Trello &#8211; Yes</p>
<h2>Web Sockets</h2>
<p>Review19 &#8211; Yes<br />
Trello &#8211; Yes</p>
<h2><em>How Review19 is different</em></h2>
<h2>Horizontal</h2>
<p>Review19 &#8211; No<br />
Trello &#8211; Yes</p>
<p>Trello is for everybody. Review19 is for distributed or colocated web, creative and software teams. Spolsky notes the benefits of being vertical, I agree.</p>
<p>Spolsky wants Trello to be horizontal, I can understand. I did consider making Review19 horizontal but chose against it.</p>
<h2>Video conferencing</h2>
<p>Review19 &#8211; Yes<br />
Trello &#8211; No</p>
<p>Review19&#8242;s target audience &#8212; web, creative and software teams &#8212; are often distributed around the world. Offering an in-browser, video conferencing option is a critical feature for Review19.</p>
<h2>CoffeeScript</h2>
<p>Review19 &#8211; No<br />
Trello &#8211; Yes</p>
<p>No thanks, I see far too many benefits of staying with JavaScript at least as of now.</p>
<h2>APIs top priority?</h2>
<p>Review19 &#8211; I wish!<br />
Trello &#8211; Yes</p>
<p>I wish! I&#8217;m only a single guy working full-time on multiple projects to earn my living. Review19 will have APIs, at some point of time!</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2012-01-how-trello-is-not-different/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>An Introduction to Functional Programming in JavaScript</title>
		<link>http://srirangan.net/2011-12-functional-programming-in-javascript</link>
		<comments>http://srirangan.net/2011-12-functional-programming-in-javascript#comments</comments>
		<pubDate>Sun, 25 Dec 2011 16:06:20 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[fp]]></category>
		<category><![CDATA[functional programming]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=808</guid>
		<description><![CDATA[For me, in many ways, 2011 has been the year of the rediscovery of JavaScript. I have been programming in JavaScript for many years (like most other programmers) but now I&#8217;ve come to appreciate JavaScript the language a little better. &#8230; <a href="http://srirangan.net/2011-12-functional-programming-in-javascript">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For me, in many ways, 2011 has been the year of the rediscovery of JavaScript. I have been programming in JavaScript for many years (like most other programmers) but now I&#8217;ve come to appreciate JavaScript the language a little better.</p>
<p>2011 was also when I had to dig into Scala. Thus I was compelled to implement more solutions in a functional manner. </p>
<p>Like many programmers unfamiliar with Functional Programming or others familiar with Functional Programming but more comfortable with Object Oriented Programming, it was daunting at first. </p>
<p>But persist through and one starts to see the benefits of Functional Programming (or at least understand it enough and execute your projects).</p>
<p>If you&#8217;re looking for a quick start in Functional Programming, JavaScript is the perfect language for you. Here&#8217;s why:</p>
<ul>
<li>Almost all programmers have tweaked and / or written JavaScript code at some point of time &#8212; hence there should be a certain familiarity</li>
<li>JavaScript comes as close to a standardized programming language we&#8217;ll get &#8212; it&#8217;s the only programming language available across all web browsers</li>
<li>JavaScript comes with a very familiar C like syntax and should be readable to most programmers</li>
<li>Functions have always been first class members in JavaScript, support for Functional Programming is very good and in many ways JavaScript has been ahead of its time</li>
<li>JavaScript doesn&#8217;t have Java like Class based Object Oriented Programming support so in many ways you&#8217;re forced to be Functional in JavaScript</li>
</ul>
<p>These should be enough reasons, so without meandering any further in the introduction, I present <em>Functional Programming with JavaScript</em>:</p>
<hr/>
<h2>Functions in JavaScript</h2>
<p>Almost everyone reading would have seen <strong>function declarations</strong> in JavaScript. However JavaScript lets you explicitly express functions as objects.</p>
<p>In fact, all <strong>function declarations</strong> are automatically converted to <strong>function expressions</strong> and hoisted. </p>
<p>By <strong>hoisting</strong>, the converted function expression is automatically placed in the beginning and thus is available in lines before it has been declared.</p>
<p><script src="https://gist.github.com/1519440.js"> </script></p>
<hr/>
<p>JavaScript functions are also different in the sense that each function, regardless of how it is defined, has dynamic arguments and a dynamic context.</p>
<p>A JavaScript function can, of course, access its arguments by their variable names. </p>
<p>By dynamic arguments, I mean, in the function body, we are provided an <strong>arguments</strong> array which contain all the arguments sequentially in the order they were passed. This means any function can be called with any set of arguments, thus giving us a lot of flexibility.</p>
<p>By dynamic context, I am refering to the <strong>this</strong> object. Typically the <strong>this</strong> object defaults sensibly to the context of the function. However it is possible to explicitly call a function with a user defined <strong>this</strong> / context object.</p>
<p><script src="https://gist.github.com/1519443.js"> </script></p>
<p>Notice how <code>functionName.apply()</code> allows us to explicitly set the context and pass arguments.</p>
<hr/>
<p>I must point out that JavaScript presents us with <strong>functional scoping</strong> instead of <strong>block scoping</strong> (C, C++ etc.). This usually becomes more relevant when you need to implement Object Oriented patterns in JavaScript but more on that in a later blog post.</p>
<p>Another trick for you is the capability to define <strong>self-executing anonymous function</strong>. These can be creatively used to implement modular namespaces / packages. Here are some examples:</p>
<p><script src="https://gist.github.com/1519445.js"> </script></p>
<hr/>
<h2>Higher Order Functions</h2>
<p>We know functions in JavaScript are nothing but objects. Does this mean functions can be passed around as arguments to other functions? And can one function return another function?</p>
<p>The answer to both questions is &#8220;Yes&#8221;. And such functions which taking in other functions are arguments and / or return functions are typically called <strong>higher order functions</strong>.</p>
<p>In the example below, we will define a higher order function <code>forEach</code>. This function takes in two arguments: a <code>list</code> and an <code>action</code>. The first argument list is an array containing containing objects and the second argument action is a function that will be invoked for each item in list.</p>
<p><script src="https://gist.github.com/1519447.js"> </script></p>
<p>The simple example above shows how a named function <code>logItem</code> and an <code>anonymous function</code> are being passed as arguments to the higher order function <code>forEach</code>.</p>
<hr/>
<h2>Map / Reduce Implementations</h2>
<p>In the example above, we saw how the <code>forEach</code> algorithm was expressed as a function and reused multiple times as an when required. We avoided repeating loops and thus made the code more readable.</p>
<p>This is one of the prime reasons to write functional code. If done correctly, you&#8217;ll be able to abstract out complex algorithms, replace it with a nice function call and keep code condensed and readable.</p>
<p>To further stress this idea, we need a better example. For each was too simple an algorithm to abstract. Let&#8217;s try implementing higher order functions for <strong>Map and Reduce algorithms</strong>.</p>
<p>We start with the Map function. What is the map function? Our <code>map</code> function should allow the user to perform a particular action over each item of a <code>list</code>, and then return a <code>result</code> list containing results of actions performed on each list item.</p>
<p>Simple enough, show me the code!</p>
<p><script src="https://gist.github.com/1519448.js"> </script></p>
<p>Notice we reuse the <code>forEach</code> function from the previous example. Our <code>map</code> function takes in two arguments, the first one being the <code>mappingFunction</code> that is to be applied on every item of the second argument <code>list</code>.</p>
<p>The implementation for <code>map</code> is straightforward. We prepare an array result, iterate through the list, call the <code>mappingFunction</code> for each item in <code>list</code>, push the result in the result array return it when all done.</p>
<p>As an example, we are calling map function and passing the function <code>doubleIt</code> as the <code>mapperFunction</code> on each item of an anonymous list.</p>
<p>Time for the <code>reduce</code> function. What is the reduce algorithm? The <code>reduce</code> function will be given a <code>combine</code> function, a <code>base</code> value and a <code>list</code>. We need to apply the <code>combine</code> function on the base value and each value in the list and finally return the result. In short, Reduce function takes in a list, combines it and gives us a single result.</p>
<p><script src="https://gist.github.com/1519449.js"> </script></p>
<p>This solution again makes use of the previous create <code>forEach</code> function. Our <code>reduce</code> function is simple, it iterates through the <code>list</code>, applies <code>combine</code> on <code>base</code> and each list item, stores the result in base and returns it after completion.</p>
<p>As a usage example, we use <code>reduce</code> to get a count of the negative numbers in a list.</p>
<p>These two examples are fairly simple and still show us how, with functional programming, we can effectively abstract out algorithms as functions, use them as and when required and still retain simplicility and readability in the code.</p>
<hr/>
<h2>Closures in JavaScript</h2>
<p>If you&#8217;ve heard of Functional Programming, there&#8217;s a very good chance you&#8217;ve also heard about <strong>closures</strong>. They are often mentioned in the same breath.</p>
<p>But what are closures? Think of closures as a composite of two things:</p>
<ol>
<li>A function being returned by another function</li>
<li>A closed environment in which this returned function is forced to execute</li>
</ol>
<p>This is what a closure is.</p>
<p>In our first example of a closure implementation, we have <code>getAreaFunction</code> which reads the shape argument and returns an appropriate area function.</p>
<p><script src="https://gist.github.com/1519450.js"> </script></p>
<p>Notice how <code>getAreaFunction</code> returns an anonymous function. This returned function contains a switch case on shape which is available in the <em>environment</em>.</p>
<p>Finally, of course, we see how to use the closure as a <em>function factory</em> to get area functions for different types of shapes.</p>
<hr/>
<p>In our second closure example, we see how closures are used to implement private class members in JavaScript.</p>
<p><script src="https://gist.github.com/1519451.js"> </script></p>
<p>I&#8217;ll not explain Object Oriented Programming implementations in JavaScript as part of this post. They aren&#8217;t complex but are different, surely worthy of a dedicated post.</p>
<p>If you&#8217;re already familiar with OOP concepts and their implementations in JavaScript, note how the class <code>Shape</code> (which is, yes, expressed as a function) contains a private function <code>area</code> and isn&#8217;t exposed.</p>
<p>Instead an instance function <code>getArea</code> is available which does internally make use of the private function <code>area</code>.</p>
<p>This is one of the most common use-cases of closures in JavaScript.</p>
<hr/>
<p>Another classic use-case for closures in JavaScript is to avoid the annoying problem that crops up every time you try to set event handlers within a loop.</p>
<p>Consider the following example:</p>
<p><script src="https://gist.github.com/1519452.js"> </script></p>
<p>In the for loop, we first assign an <code>onclick</code> handler to all the red boxes. However, thanks to functional scoping, all three red boxes have onclick handlers with <code>redBoxId</code> value 3.</p>
<p>However for green boxes we assign <code>onclick</code> handlers in a slightly different manner. We have a self executing anonymous function which returns another function which then is assigned as the onclick handler.</p>
<p>Due to functional scopes, each <code>onclick</code> handler for the green boxes have correct values for <code>greenBoxId</code>.</p>
<hr/>
<p>I realize this has been a fairly lengthy post. Will end it now. Hopefully this would have served as a good enough introduction to Functional Programming concepts and their corresponding implementations in JavaScript.</p>
<p>All code available on <a href="https://github.com/Srirangan/javascript-playground/tree/master/functional-javascript">GitHub</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2011-12-functional-programming-in-javascript/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>JavaScript &#8211; Function Declarations vs. Function Expressions</title>
		<link>http://srirangan.net/2011-12-javascript-function-declarations-vs-function-expressions</link>
		<comments>http://srirangan.net/2011-12-javascript-function-declarations-vs-function-expressions#comments</comments>
		<pubDate>Sat, 24 Dec 2011 06:31:36 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=791</guid>
		<description><![CDATA[Here&#8217;s an example of a function declaration in JavaScript: function sayMyName() { console.log("!Xobile"); } Looks very familiar. And is probably the most obvious way programmers have created functions since the beginning of time JavaScript. In JavaScript, everything is an object. &#8230; <a href="http://srirangan.net/2011-12-javascript-function-declarations-vs-function-expressions">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s an example of a function declaration in JavaScript:</p>
<pre>
function sayMyName() {
  console.log("!Xobile");
}
</pre>
<p>Looks very familiar. And is probably the most obvious way programmers have created functions since the beginning of <del>time</del> JavaScript.</p>
<p>In JavaScript, everything is an object. What happens internally is this declaration gets converted into an expression.</p>
<p>What&#8217;s an expression? An expression is any statement that produces a value.</p>
<p>Thus, a function expression becomes:</p>
<pre>
var sayMyName = function() {
  console.log("!Xobile");
};
</pre>
<p>Function declarations try to hide the fact that the function is indeed an object. </p>
<p>While this may be okay in some cases, it could create confusion when the function is actually being used as a object i.e. being returned, passed around, modified etc.</p>
<p>JavaScript programming (and the programming world in general) is becoming more functional by the day, and it may be a better practice to avoid function declarations altogether in favor of function expressions.</p>
<p>But why? Hoisting. </p>
<p>Function declarations are automatically &#8220;hoisted&#8221;. The compiler automatically expresses all function declarations at the top of the code regardless of where in the code the function is declared.</p>
<p>This may or may not be a problem depending on the scope-complexity of your code. However it is something that happens automatically, whether you want it or not, and it may be advisable to take such control away from the compiler.</p>
<p>Especially since scoping is very different in JavaScript compared to traditional languages. More on JavaScript scoping in a future blog post.</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2011-12-javascript-function-declarations-vs-function-expressions/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Why you must use Review19 for your project</title>
		<link>http://srirangan.net/2011-12-why-you-must-use-review19-for-your-project</link>
		<comments>http://srirangan.net/2011-12-why-you-must-use-review19-for-your-project#comments</comments>
		<pubDate>Wed, 07 Dec 2011 08:12:34 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[review19]]></category>
		<category><![CDATA[socket.io]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=772</guid>
		<description><![CDATA[Last week I rolled out a new preview release of Review19. Review19 is a simple and intuitive project management tool. It is just as suited for teams distributed around the world as it is for colleagues working in the same &#8230; <a href="http://srirangan.net/2011-12-why-you-must-use-review19-for-your-project">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Last week I rolled out a new preview release of <a href="http://review19.com:3000"><strong>Review19</strong></a>.</p>
<p>Review19 is a simple and intuitive project management tool. It is just as suited for teams distributed around the world as it is for colleagues working in the same office.</p>
<p><a href="http://review19.com"><img class="alignright" src="http://review19.com/images/thumbnail-screenshot1.png"/></a></p>
<p>However it doesn&#8217;t try to be a universal, multi-purpose app. Review19 has been built, finetuned and polished specifically for web, creative and software teams.</p>
<p>To begin you create a project and invite members to your project team. Then you (and your team) can add tickets which can be features, enhancements, bugs or chores. Tickets have a description with optional additional details and one or more sub-tasks. In addition, tickets have a priority and can be assigned to a team member.</p>
<p><a href="http://review19.com"><img class="alignright" src="http://review19.com/images/thumbnail-screenshot3.png"/></a></p>
<p>On the status board, you see all tickets arranged in columns for backlog, scheduled, in progress and complete. Tickets can be dragged across columns and filters can be applied based on user or ticket type.</p>
<p>Oh by the way, while you do all this, the changes you make are synced realtime and your team members can see them and vice-versa. The user interface, built exclusively in HTML5+CSS, keeps this app really simple and intuitive for first time users.</p>
<p><a href="http://review19.com"><img class="alignright" src="http://review19.com/images/thumbnail-screenshot2.png"/></a></p>
<p>Then there is the &#8220;Conference&#8221; tab, which lets you engage with your team members with video chats and text chat sessions. The video chat runs in-browser with the flash plugin and doesn&#8217;t require any external application be downloaded / installed.</p>
<p>Personally for me, the most exciting part of Review19 is the yet unreleased roadmap which ensures continuous improvements of the core product along with some more incredible features currently unseen in similar products.</p>
<p>Give <a href="http://review19.com"><strong>Review19</strong></a> a spin and let me know how it works out!</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2011-12-why-you-must-use-review19-for-your-project/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>A brand new Review19</title>
		<link>http://srirangan.net/2011-12-a-brand-new-review19</link>
		<comments>http://srirangan.net/2011-12-a-brand-new-review19#comments</comments>
		<pubDate>Fri, 02 Dec 2011 02:20:08 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[google app engine]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[review19]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=755</guid>
		<description><![CDATA[Last night I rolled out a completely new version of Review19. Umm.. what is Review19? Review19 tries to be a simpler alternative to the likes of Atlassian JIRA and Pivotal Tracker. Its design was driven by the principle of &#8220;less &#8230; <a href="http://srirangan.net/2011-12-a-brand-new-review19">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Last night I rolled out a completely new version of <a href="http://www.review19.com">Review19</a>.</p>
<p><em>Umm.. what is Review19?</em></p>
<p>Review19 tries to be a simpler alternative to the likes of Atlassian JIRA and Pivotal Tracker. Its design was driven by the principle of &#8220;less is more&#8221; yet it can boast of better usability and features.</p>
<p>The new Review19 is a move away from Google App Engine towards Node.js and other open source technologies. The reason is to avoid vendor lock in and leverage new technologies where the Google App Engine SDK lags behind.</p>
<p>However the new Review19 is lot more than just a migration of underlying technology. Presenting some of the more significant updates:</p>
<ul>
<li><strong>Video Conferencing</strong> &#8211; Conduct video chat sessions with your project team within your web browser. Goodbye Skype!</li>
<li><strong>Kanban + Scrum Board</strong> &#8211; No complex work flows imposed, just works</li>
<li>Tickets support <strong>features</strong>, <strong>bugs</strong>, <strong>chores</strong> and <strong>enhancements</strong></li>
<li>Sub-tasking support within tickets</li>
<li>Numerous usability and user interface enhancements, less glare and intuitive interactions</li>
</ul>
<p>Give it a spin, try out <a href="http://www.review19.com">Review19</a> at <a href="http://www.review19.com">http://www.review19.com</a></p>
<p>Interested in your feedback, feel free to drop in a message. Join the <a href="https://groups.google.com/forum/#!forum/review19-community">mailing list</a> for more.</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2011-12-a-brand-new-review19/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Notifier.js &#8211; Elegant Javascript notifications</title>
		<link>http://srirangan.net/2011-11-notifier-js-elegant-javascript-notifications</link>
		<comments>http://srirangan.net/2011-11-notifier-js-elegant-javascript-notifications#comments</comments>
		<pubDate>Thu, 03 Nov 2011 11:21:28 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[notifications]]></category>
		<category><![CDATA[notifier.js]]></category>
		<category><![CDATA[Open source]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=723</guid>
		<description><![CDATA[Before starting a major project, I&#8217;m laying out the groundwork and creating some of the libraries required. This includes Notifier.js &#8212; a Javascript library for Gnome / Growl type non-blocking notifications. It depends on Jquery. At 68 lines of code, &#8230; <a href="http://srirangan.net/2011-11-notifier-js-elegant-javascript-notifications">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Before starting a major project, I&#8217;m laying out the groundwork and creating some of the libraries required.</p>
<p>This includes <a href="http://opensource.srirangan.net/notifier.js/">Notifier.js</a> &#8212; a Javascript library for Gnome / Growl type non-blocking notifications. <a href="http://s7.postimage.org/at9xw1diz/notifierjs_screenshot.png"><img class="alignright" title="Notifier.js" src="http://s7.postimage.org/at9xw1diz/notifierjs_screenshot.png" alt="" width="270" /></a></p>
<p>It depends on Jquery. At 68 lines of code, Notifier.js can be classified as minimalist.</p>
<p>Notifier.js supports <code>success</code>, <code>info</code>, <code>warning</code> and <code>error</code> notifications.</p>
<p>Notifications show up at the top-right corner and fade away in 5 seconds (by default). Click and it fades away even sooner.</p>
<p>Multiple notifications at the same time stash up in a vertical list.</p>
<p>Notifier.js has been designed for easy inclusion in any existing small or large project.</p>
<p><a href="http://opensource.srirangan.net/notifier.js/">Demo</a> | <a href="https://github.com/downloads/Srirangan/notifer.js/notifier.js.zip">Download (.zip archive, 26.8KBs)</a></p>
<p>The source code and usage examples can be found on GitHub &#8211; <a href="https://github.com/Srirangan/notifer.js">https://github.com/Srirangan/notifer.js</a></p>
<p>Feel free to use it, fork it and provide feedback / pull requests.</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2011-11-notifier-js-elegant-javascript-notifications/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Getting Nginx + PHP 5.3 to work, properly!</title>
		<link>http://srirangan.net/2011-10-getting-nginx-php-5-3-to-work-properly</link>
		<comments>http://srirangan.net/2011-10-getting-nginx-php-5-3-to-work-properly#comments</comments>
		<pubDate>Sun, 09 Oct 2011 12:16:30 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=711</guid>
		<description><![CDATA[Over the past few days, I moved a few Apache2 + PHP webapps (including this WordPress blog) from a shared host to a dedicated CentOS server. By default the server came with Apache2 (httpd) web server, but I wanted to &#8230; <a href="http://srirangan.net/2011-10-getting-nginx-php-5-3-to-work-properly">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Over the past few days, I moved a few Apache2 + PHP webapps (including this WordPress blog) from a shared host to a dedicated CentOS server. By default the server came with Apache2 (httpd) web server, but I wanted to use Nginx instead. Why Nginx? It&#8217;s *much* faster and scales better with lower resource usage.</p>
<p>Installing Nginx, PHP and MySQL wasn&#8217;t a problem and there were tonnes of resources on the internet to help me through. Where I did face a challenge was to get Nginx and PHP to play nicely.</p>
<p>Before I explain what went wrong, I will note the differences in the way Apache2 and Nginx handle PHP. </p>
<p>For Apache2, in many cases, PHP is configured as an internal module. Alternatively it can also be used in CGI mode. However, no matter how it&#8217;s configured, it is the web server&#8217;s responsibility to interface with PHP (which means having to spawn PHP instances as an when required).</p>
<p>In the case of Nginx, things are very different. Casually put, Nginx acts as a proxy server and will redirect requests to a PHP-CGI server instance running on your box. This means, of course, you are now responsible for spawning a PHP-CGI server instance and configuring Nginx to use it.</p>
<p>Not so bad, so I went ahead and did it. Here&#8217;s where the real problem comes in. </p>
<p>After some time, I found that the PHP-CGI instance automatically hung up and needed to be restarted. In the browser this showed up as 502 Bad Gateway errors. I Google&#8217;d it for a few hours and couldn&#8217;t find a definite solution. However few links did indicate that some PHP modules were the cause for the PHP-CGI crash. The best solution out there I could find was to setup a cron to re-up the PHP-CGI instance every N minutes. </p>
<p>But even if this cron interval is 1 minute, it still leaves a low but significant probability that a user sees the error, refreshes immediately, sees the error again and quits your website. Not acceptable.</p>
<p>My quick fix solution? Reduce this probability. How?</p>
<h2>Setup multiple instances of PHP-CGI</h2>
<pre>
$ php-cgi -b 127.0.0.1:9000 &#038;
$ php-cgi -b 127.0.0.1:9001 &#038;
$ php-cgi -b 127.0.0.1:9002 &#038;
$ php-cgi -b 127.0.0.1:9003 &#038;
$ php-cgi -b 127.0.0.1:9004 &#038;
</pre>
<h2>Setup the cron to re-up the PHP-CGI instances if they&#8217;re down</h2>
<pre>
$ crontab
*/2  *  *  *  *  php-cgi -b 127.0.0.1:9000
*/2  *  *  *  *  php-cgi -b 127.0.0.1:9001
*/2  *  *  *  *  php-cgi -b 127.0.0.1:9002
*/2  *  *  *  *  php-cgi -b 127.0.0.1:9003
*/2  *  *  *  *  php-cgi -b 127.0.0.1:9004
</pre>
<h2>Configure Nginx to choose from this pool</h2>
<pre>
http {
    ...
    upstream phpfcgi {
        server 127.0.0.1:9000;
        server 127.0.0.1:9001;
        server 127.0.0.1:9002;
        server 127.0.0.1:9003;
        server 127.0.0.1:9004;
    }
    ...
    server {
        server_name        {server name};
        root               {path to document root};

        location / {
            index          index.php;
        }

        location ~\.php$ {
            fastcgi_pass    phpfcgi;
            fastcgi_index   index.php;
            include         fastcgi_params;
            fastcgi_param   SCRIPT_FILENAME $document_root/$fastcgi_script_name;
        }
    }

}
</pre>
<p>This reduces the probability of the user to repeatedly see the 502 Bad Gateway errors. This can be improved by having the cron trigger a script which checks if the php-cgi process has hung up before attempting to restart it.</p>
<p>But a real solution would be to figure out which PHP module *really* is causing the php-cgi to hang in the first place and fix this bug.</p>
<p>I&#8217;ve also stumbled across something called PHP-FPM but I don&#8217;t know enough about it to as yet. You might consider checking that out.</p>
<p>Hope this helps.</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2011-10-getting-nginx-php-5-3-to-work-properly/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Download Sources and Docs with SBT</title>
		<link>http://srirangan.net/2011-09-download-sources-docs-sbt</link>
		<comments>http://srirangan.net/2011-09-download-sources-docs-sbt#comments</comments>
		<pubDate>Fri, 30 Sep 2011 01:51:02 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[intellij idea]]></category>
		<category><![CDATA[sbt]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=696</guid>
		<description><![CDATA[Working on a Scala project and figuring out how to get SBT to download sources and docs for all dependencies? It took a while to figure out but this is what works for SBT 0.10 or higher: sbt update-classifiers For &#8230; <a href="http://srirangan.net/2011-09-download-sources-docs-sbt">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Working on a Scala project and figuring out how to get SBT to download sources and docs for all dependencies? </p>
<p>It took a while to figure out but this is what works for SBT 0.10 or higher:</p>
<pre>  sbt update-classifiers</pre>
<p>For my Scala projects, I return to using an IDE &#8212; IntelliJ IDEA Community (Ultimate is a bit bloated and slow for my liking). The SBT-Idea project links dependencies, sources and docs to your IDEA project with this command:</p>
<pre>  sbt gen-idea</pre>
<p>Make sure you&#8217;ve included SBT Idea as a plugin: <a href="https://github.com/mpeltonen/sbt-idea">https://github.com/mpeltonen/sbt-idea</a></p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2011-09-download-sources-docs-sbt/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hot reload / Build on save for Adobe Flex</title>
		<link>http://srirangan.net/2011-09-hot-reload-build-on-save-for-adobe-flex</link>
		<comments>http://srirangan.net/2011-09-hot-reload-build-on-save-for-adobe-flex#comments</comments>
		<pubDate>Mon, 26 Sep 2011 06:48:56 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Adobe Flex]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=667</guid>
		<description><![CDATA[If you&#8217;re not using Adobe Flash Builder for developing Adobe Flex apps, you might be missing the build on save (or build automatically / hot reload) feature. Here&#8217;s a little Node.js utility that does the same. While working on Flex &#8230; <a href="http://srirangan.net/2011-09-hot-reload-build-on-save-for-adobe-flex">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re not using Adobe Flash Builder for developing Adobe Flex apps, you might be missing the  build on save (or build automatically / hot reload) feature. </p>
<p>Here&#8217;s a little Node.js utility that does the same. While working on Flex with gedit (or any other text editor), just keep &#8220;hotflex&#8221; running in the background. It watches all MXML and AS3 files and rebuilds the project on save.</p>
<h2>Screenshots</h2>

<a href='http://srirangan.net/2011-09-hot-reload-build-on-save-for-adobe-flex/hotflex-build-success' title='hotflex-build-success'><img width="150" height="150" src="http://srirangan.net/wp-content/uploads/2011/09/hotflex-build-success-150x150.png" class="attachment-thumbnail" alt="hotflex-build-success" title="hotflex-build-success" /></a>
<a href='http://srirangan.net/2011-09-hot-reload-build-on-save-for-adobe-flex/hotflex-build-fail' title='hotflex-build-fail'><img width="150" height="150" src="http://srirangan.net/wp-content/uploads/2011/09/hotflex-build-fail-150x150.png" class="attachment-thumbnail" alt="hotflex-build-fail" title="hotflex-build-fail" /></a>

<h2>Dependencies</h2>
<p>Node.js and NPM are required, refer to &#8211; <a href="http://srirangan.net/2011-09-setup-node-js-and-npm-on-ubuntu">Setup Node.js and NPM on Ubuntu</a></p>
<p>For notifications on Ubuntu, install libnotify-bin:</p>
<pre>    sudo apt-get install libnotify-bin</pre>
<p>The Flex SDK is, of course, required and the Flex SDK&#8217;s bin folder should be on the $PATH.</p>
<h2>Install</h2>
<p>From NPM:</p>
<pre>    sudo npm install hotflex -g</pre>
<p>From GitHub:</p>
<pre>    git clone git://github.com/Srirangan/hotflex.git
    cd hotflex
    sudo npm install -g</pre>
<h2>Configure</h2>
<p>You will need to create a <code>hotflex.json</code> file containing the following parameters:</p>
<pre>    { "source": "./src/main/flex/main.mxml"
    , "sourceFolder": "./src"
    , "target": "./bin/main.swf"
    , "lib": "./lib"
    }</pre>
<p>The <code>lib</code> parameter is optional while the rest are mandatory.</p>
<h2>Run</h2>
<p>Execute <code>hotflex</code> from the folder containing the <code>hotflex.json</code> file, preferably your project root.</p>
<pre>hotflex</pre>
<h2>Meta</h2>
<p>GitHub repository &#8211; <a href="https://github.com/Srirangan/hotflex">https://github.com/Srirangan/hotflex</a><br />
NPM &#8211; <a href="http://search.npmjs.org/#/hotflex">http://search.npmjs.org/#/hotflex</a></p>
<h2>Todo</h2>
<ul>
<li>Integration with Adobe Flex Compiler Shell <code>fcsh</code> for faster builds</li>
<li>Integration for Growl for OSX notifications. Currently notifications work for Ubuntu.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2011-09-hot-reload-build-on-save-for-adobe-flex/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Setup Node.js and NPM on Ubuntu</title>
		<link>http://srirangan.net/2011-09-setup-node-js-and-npm-on-ubuntu</link>
		<comments>http://srirangan.net/2011-09-setup-node-js-and-npm-on-ubuntu#comments</comments>
		<pubDate>Sun, 25 Sep 2011 13:23:49 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=653</guid>
		<description><![CDATA[Avoid installing Node.js on Ubuntu from the repositories. They are out-dated. The best option is to download the sources and build. Node.js sources can be downloaded from http://nodejs.org/#download Alternatively, if you&#8217;re a GitHub user, you can clone the repository with: &#8230; <a href="http://srirangan.net/2011-09-setup-node-js-and-npm-on-ubuntu">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Avoid installing <a href="http://nodejs.org/">Node.js</a> on Ubuntu from the repositories. They are out-dated. The best option is to download the sources and build.</p>
<p>Node.js sources can be downloaded from <a href="http://nodejs.org/#download" title="Download Node.js">http://nodejs.org/#download</a><br />
Alternatively, if you&#8217;re a GitHub user, you can clone the repository with:</p>
<pre>git clone git://github.com/joyent/node.git</pre>
<p>Next step, navigate to the Node.js source root folder and execute the following:</p>
<pre>./configure
make
sudo make install</pre>
<p><a href="http://npmjs.org/">NPM</a> is a package manager for Node similar to Apache Maven, Gradle, SBT etc.</p>
<blockquote><p>npm is a package manager for node. You can use it to install and publish your node programs. It manages dependencies and does other cool stuff.</p></blockquote>
<p>Install it with this one line command:</p>
<pre>curl http://npmjs.org/install.sh | sh</pre>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2011-09-setup-node-js-and-npm-on-ubuntu/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>What Java engineers need to know about Node.js</title>
		<link>http://srirangan.net/2011-09-what-java-engineers-need-to-know-about-node-js</link>
		<comments>http://srirangan.net/2011-09-what-java-engineers-need-to-know-about-node-js#comments</comments>
		<pubDate>Sun, 18 Sep 2011 18:48:15 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=620</guid>
		<description><![CDATA[If you&#8217;re new to Node.js and are transitioning from Java, it will not be the same as learning just another programming language. There will be a few surprises, good surprises. Here&#8217;s attempt to capture a few of these &#8220;paradigm shifts&#8221; &#8230; <a href="http://srirangan.net/2011-09-what-java-engineers-need-to-know-about-node-js">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re new to Node.js and are transitioning from Java, it will not be the same as learning just another programming language. There will be a few surprises, good surprises. </p>
<p>Here&#8217;s attempt to capture a few of these &#8220;paradigm shifts&#8221; you may have to make. ;-)</p>
<h2>Non-blocking + Asynchronous</h2>
<p>Line #4 need not execute before line #6. Your design should not require it to do so. Express your implementation as actions and responses i.e. events and handlers.</p>
<p>For instance, in Java you may write:</p>
<pre>
List users = userService.listUsersByStatus(pending);
users.doSomething();
// Something else happens
</pre>
<p>In Node, this would be expressed as:</p>
<pre>
userService.listUsersByStatus(pending, function(users) {
  users.doSomething()
});
// Something else happens
</pre>
<p>The difference in these two examples is that in Java &#8220;something else happens&#8221; always executes after <code>users.doSomething()</code>.</p>
<p>This is not the case in Node, &#8220;something else happens&#8221; would typically execute before <code>users.doSomething()</code>.</p>
<p><code>users.doSomething()</code> is called in an anonymous method that serves as a callback for <code>userService.listUsersByStatus()</code>.</p>
<h2>Less code! Less architecture! Less layers!</h2>
<p>JEE tries to over-do everything. Node keeps it very simple. There isn&#8217;t any need to ritually create a complex package structure, superstitiously over-design with interfaces, spit out cross generational implementations and follow other bloated JEE patterns.</p>
<p>This doesn&#8217;t mean that Node forces you to cramp all your code into a single file either. You can lay it out and distribute it among modules as required. These modules are objects by default and the underlying design principle is minimalism.</p>
<p>For example, a hot topic for debate on Hacker News &#8211; ORMs. In Node, you can do an ORM if you want. But is it required? </p>
<p>Given that the persisted objects are to be consumed by a browser, most of the times passing a MongoDB object to browser (JS) object is sufficient. My opinion on ORMs is that, if possible, they should be avoided. However I&#8217;m digressing from topic and this post is not about ORMs.</p>
<h2>No Application Containers</h2>
<p>You don&#8217;t deploy a Node webapp on Tomcat. You are much closer to the OS. Typically the entry point of a Node app would listen to a socket and *be* a server.</p>
<p>For example, here&#8217;s an ExpressJS webapp:</p>
<pre>
var app = express.createServer();

app.get('/', function(req, res){
res.send('Hello World');
});

app.listen(3000);
</pre>
<p>This and its asynchronous nature gives Node apps its high performance, low latencies and real-time capabilities.</p>
<h2>IDEs Aren&#8217;t Required</h2>
<p>I can&#8217;t think of working with Java without my trusted JetBrains IntelliJ IDEA. I&#8217;ve used Eclipse and NetBeans in the past and they have worked great as well. Without these IDEs for a modern Java Enterprise project, I would be handicapped.</p>
<p>Not so for Node. I&#8217;ve been productive without an IDE and while I do miss IntelliJ IDEAs amazing Javascript refactoring features, I gained tremendous performance with a text editor (gedit) and with handy plugins available the trade-off is worth it.</p>
<p>Just a small list of what Java programmers should expect if moving to Node, feel free to add on!</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2011-09-what-java-engineers-need-to-know-about-node-js/feed</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Node.js &#8211; Hot reloading with notifications for Ubuntu</title>
		<link>http://srirangan.net/2011-09-node-js-hot-reloading-with-notifications-for-ubuntu</link>
		<comments>http://srirangan.net/2011-09-node-js-hot-reloading-with-notifications-for-ubuntu#comments</comments>
		<pubDate>Sun, 11 Sep 2011 05:29:56 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[hot reloading]]></category>
		<category><![CDATA[hotnode]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[opensource]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=613</guid>
		<description><![CDATA[I needed hot reloading for my Node.js project. Google&#8217;d and found Hotnode which worked great .. until .. realized it supports Growl notifications (OSX) instead of Ubuntu&#8217;s sexy native notifs. Tweaked it and made it notify for Ubuntu and we &#8230; <a href="http://srirangan.net/2011-09-node-js-hot-reloading-with-notifications-for-ubuntu">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I needed hot reloading for my Node.js project. Google&#8217;d and found <a href="https://github.com/saschagehlich/hotnode">Hotnode</a> which worked great .. until .. realized it supports Growl notifications (OSX) instead of Ubuntu&#8217;s sexy native notifs.</p>
<p>Tweaked it and made it notify for Ubuntu and we have <a href="https://github.com/Srirangan/hotnode">Hotnode with Ubuntu Notifications</a>.</p>
<p>Let&#8217;s get started:</p>
<h1>Install it..</h1>
<p>Dependencies:<br />
<code>sudo apt-get install libnotify-bin</code></p>
<p>Hotnode:<br />
<code>git clone git://github.com/Srirangan/hotnode.git<br />
cd hotnode<br />
sudo npm install -g</code></p>
<h1>Use it..</h1>
<p>Use:<br />
<code>hotnode server.js</code></p>
<p>Instead of:<br />
<code>node server.js</code></p>
<p>..there you go!</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2011-09-node-js-hot-reloading-with-notifications-for-ubuntu/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Google faces backlash over new App Engine pricing</title>
		<link>http://srirangan.net/2011-09-google-faces-backlash-for-new-app-engine-pricing</link>
		<comments>http://srirangan.net/2011-09-google-faces-backlash-for-new-app-engine-pricing#comments</comments>
		<pubDate>Thu, 01 Sep 2011 03:57:18 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[google app engine]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=584</guid>
		<description><![CDATA[As Google App Engine moves out of &#8220;preview&#8221;, a new pricing model has been revealed. This new pricing model is expected to come into effect sometime in September. Google has made available to App Engine users comparisons of their current &#8230; <a href="http://srirangan.net/2011-09-google-faces-backlash-for-new-app-engine-pricing">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As Google App Engine moves out of &#8220;preview&#8221;, a <a href="http://www.google.com/enterprise/cloud/appengine/pricing.html">new pricing model</a> has been revealed. This new pricing model is expected to come into effect sometime in September. Google has made available to App Engine users comparisons of their current bills versus expected bills with the new pricing model.</p>
<p>Things don&#8217;t look pretty. In short this is what has happened:</p>
<ul>
<li>&#8220;Free&#8221; quotas have been drastically reduced</li>
<li>Price of various billiable &#8220;units&#8221; has seen a sharp rise</li>
</ul>
<p>The reaction of the Google App Engine customer base has been predictable. Here are some quotes from the official Google App Engine mailing list / group:</p>
<blockquote><p>&#8220;We are going from $5,400/month to $26,500/month (Python) &#8211; and this is only one of our apps. We are going to work hard to optimize our application because we really like App Engine, but failing that, we may have to move elsewhere.&#8221; &#8212; Jason Collins</p>
<p>&#8220;Sorry google, but that doesn&#8217;t work for me. It makes more sense to go back to django and run the apps on a box in my home. I&#8217;ve disabled my apps as of today.&#8221; &#8212; Johnny G</p>
<p>&#8220;Is it really 10 times the original cost.!! Now we will be paying from $200/month to $2000/month under new billing. Just out of our reach, does not make any business sense to stay with GAE.&#8221; &#8212; smwatch</p>
<p>&#8220;I love Google App Engine, but right now I am at a loss for what to do. My current billing is $4.98/day. Under the new system it is $34.41/day, and that is with the 50% frontend discount. The effort that would be involved in porting my app to a different architecture is far beyond what I could accomplish in the next few weeks, and to be honest I don&#8217;t want to move off of App Engine.&#8221; &#8212; Michael Robellard</p>
<p>&#8220;It&#8217;s 300% for me (3x what I pay now). Most of the cost is datastore writes and reads, followed by instance hours.&#8221; &#8212; Waleed</p>
<p>&#8220;For my app, Aug 26, estimated increase of ~150%.&#8221; &#8212; Will Xu</p>
<p>&#8220;For mine (python): 317% I think I am forced to leave GAE to EC2.&#8221; &#8212; Raymond C</p></blockquote>
<p>Is Google setting a precedent for unreliable and unstable cloud billing? Are they pricing themselves out of this market?</p>
<p>If you go by the most popular thread in the Google App Engine community &#8211; <a href="https://groups.google.com/d/topic/google-appengine/obfGjbIkOTI/discussion">Keep it short: Who is forced to leave GAE?</a> &#8211; then the answer is yes!</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2011-09-google-faces-backlash-for-new-app-engine-pricing/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Review19 is here.</title>
		<link>http://srirangan.net/2011-08-review19-is-here</link>
		<comments>http://srirangan.net/2011-08-review19-is-here#comments</comments>
		<pubDate>Wed, 31 Aug 2011 15:48:33 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[products]]></category>
		<category><![CDATA[review19]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=579</guid>
		<description><![CDATA[Excited to reveal the first public release of Review19 &#8211; The next generation, real-time project collaboration tool. The complete announcement from the mailing list: The first public release of Review19 is out. Review19 is the next generation, real-time project collaboration &#8230; <a href="http://srirangan.net/2011-08-review19-is-here">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Excited to reveal the first public release of <a href="http://www.review19.com">Review19</a> &#8211; <a href="http://www.review19.com">The next generation, real-time project collaboration tool</a>.</p>
<p>The complete announcement from the <a href="https://groups.google.com/forum/#!forum/review19-community">mailing list</a>:</p>
<blockquote><p>The first public release of Review19 is out.</p>
<p>Review19 is the next generation, real-time project collaboration tool. It serves as an alternative to Pivotal Tracker, Atlassian JIRA / GreenHopper and other agile / project management tools.</p>
<p>Review19 supports stories, sprints, story board and teams. The interface is simple. No complex rules and work-flows are imposed. Run your project as you like.</p>
<p>Review19 is real-time software. AJAX / asynchronous calls are history. All team members experience real-time collaboration and synchronicity with Review19 eliminating errors and confusions.</p>
<p>Review19 can be accessed at <a href="http://www.review19.com/" target="_blank">http://www.review19.com/</a></p>
<p>Review19 is built on Google App Engine, Python, HTML5, JQuery and CSS. It works on recent versions of all real browsers and has been extensively tested on Google Chrome.</p></blockquote>
<p><a href="http://www.review19.com/">Review19</a> was the result of my disillusionment with Pivotal Tracker which promised so much for so long.</p>
<p>A key design principle for <a href="http://www.review19.com/">Review19</a> is for it to be <strong>real-time</strong>. Real-time as in <strong>real-time collaboration</strong>. All team members see updates as they happen. Real-time as in Google Docs or Google Wave (RIP).</p>
<p>Simplicity. Pivotal Tracker / Atlassian JIRA etc. were simply too complex to use. They did too much. <a href="http://www.review19.com/">Review19</a> does very little. Imposes very few rules and helps you implement almost any workflow (Lean, Agile, Scrum, Kanban etc.)</p>
<p>Please try out <a href="http://www.review19.com/">Review19</a>. Join the <a href="https://groups.google.com/forum/#!forum/review19-community">community</a> and share your <a href="https://groups.google.com/forum/#!forum/review19-community">feedback</a>. Thanks!</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2011-08-review19-is-here/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to install the DotCloud CLI on Ubuntu</title>
		<link>http://srirangan.net/2011-06-how-to-install-the-dotcloud-cli-on-ubuntu</link>
		<comments>http://srirangan.net/2011-06-how-to-install-the-dotcloud-cli-on-ubuntu#comments</comments>
		<pubDate>Fri, 10 Jun 2011 10:32:23 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[dotcloud]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=546</guid>
		<description><![CDATA[If you aren&#8217;t familiar with DotCloud by now, you ought to be. DotCloud is a cloud platform built on top of Amazon EC2 that is programmer friendly and not targeted specifically at sysadmins. It will not lock you in to &#8230; <a href="http://srirangan.net/2011-06-how-to-install-the-dotcloud-cli-on-ubuntu">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you aren&#8217;t familiar with <a href="https://www.dotcloud.com" rel="nofollow">DotCloud</a> by now, you ought to be. </p>
<p>DotCloud is a cloud platform built on top of Amazon EC2 that is programmer friendly and not targeted specifically at sysadmins. It will not lock you in to any platform and supports a wide range of open source technologies including MySQL, Node.Js, PHP, PostgreSQL, Python, Redis, Ruby, Java, Perl, SMTP, MongoDB, Solr etc.</p>
<p>DotCloud provides a CLI (Command Line Interface) for performing every action possible including creating new applications, deploying new services, pushing code, running remote commands etc. However Python and related tools are required to get DotCloud CLI working on your Ubuntu machine.</p>
<p>Follow the steps below to get started:</p>
<p><code># Install Python (Ubuntu should have it by default)<br />
$ sudo apt-get install python</code></p>
<p><code># Download <a href="http://pypi.python.org/pypi/setuptools" rel="nofollow">setuptools</a> and install it with the following command<br />
$ sudo sh ~/Downloads/setuptools-0.6c11-py2.7.egg</code></p>
<p><code># Use easy_install to setup the DotCloud CLI<br />
$ sudo easy_install dotcloud</code></p>
<p>That&#8217;s it! You&#8217;re now all set to <a href="http://docs.dotcloud.com/tutorials/" rel="nofollow">create your first DotCloud app</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2011-06-how-to-install-the-dotcloud-cli-on-ubuntu/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Get started with Django .. django-kick-start!</title>
		<link>http://srirangan.net/2011-05-get-started-with-django-django-kick-start</link>
		<comments>http://srirangan.net/2011-05-get-started-with-django-django-kick-start#comments</comments>
		<pubDate>Sun, 22 May 2011 02:49:45 +0000</pubDate>
		<dc:creator>Srirangan</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://srirangan.net/?p=537</guid>
		<description><![CDATA[The Django Framework is an extremely popular and powerful Python based framework for web application development. The project began way back in 2003 and have for the past few years really matured and has gained mainstream and enterprise adoption. I &#8230; <a href="http://srirangan.net/2011-05-get-started-with-django-django-kick-start">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The Django Framework is an extremely popular and powerful Python based framework for web application development. The project began way back in 2003 and have for the past few years really matured and has gained mainstream and enterprise adoption.</p>
<p>I recently conducted an intensive training session titled &#8220;django-kick-start&#8221; at the Inphina iBat dated 21st May 2011.</p>
<p><a href="https://github.com/Srirangan/django-kick-start">Download source code</a></p>
<p><iframe src="https://docs.google.com/present/embed?id=dwhrwm2_130c99bszf6&#038;size=m" frameborder="0" width="555" height="451"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://srirangan.net/2011-05-get-started-with-django-django-kick-start/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

