<?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>ReadyState4</title>
	<atom:link href="http://readystate4.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://readystate4.com</link>
	<description>JavaScript, Web Development, Ruby, and Technology.</description>
	<lastBuildDate>Fri, 27 Jan 2012 18:37:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Setting up and using a git wrapper around SVN with git-svn</title>
		<link>http://readystate4.com/2012/01/27/setting-up-and-using-a-git-wrapper-around-svn-with-git-svn/</link>
		<comments>http://readystate4.com/2012/01/27/setting-up-and-using-a-git-wrapper-around-svn-with-git-svn/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 18:29:21 +0000</pubDate>
		<dc:creator>Mauvis</dc:creator>
				<category><![CDATA[git]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://readystate4.com/?p=404</guid>
		<description><![CDATA[Note: I wrote this post a long time ago but never got around to posting it. A lot of these steps are applicable to porting an SVN repo to Git as well. Preface on why I love git Roughly four years ago I switched to git for version control and it&#8217;s changed my development life. [...]]]></description>
			<content:encoded><![CDATA[<p>Note: I wrote this post a long time ago but never got around to posting it. A lot of these steps are applicable to porting an SVN repo to Git as well.</p>
<h3>Preface on why I love git</h3>
<p>Roughly four years ago I switched to <a href="http://git-scm.com/">git</a> for version control and it&#8217;s changed my development life. While SVN is sufficient to &#8220;get the job done&#8221; in terms of keeping a history of your commits with a group of people, Git is truly the next evolutionary step up in every way. I could expound a whole article on the joy of git, but many others already have, and this articles not about that. But I will kindly throw in my 0.02 on why I personally love it:</p>
<ul>
<li>It&#8217;s fast. Git keeps your whole repo&#8217;s history local. So no need to ping your repo server for every command. You can even checkout your codebase from 3 weeks ago or a year ago in under a second.&#8221;</li>
<li>It works offline. That&#8217;s right, no internet. Sync up later.</li>
<li>It has useful modern tools. Like <a href="http://ariejan.net/2008/04/23/git-using-the-stash/">git stash</a> and <a href="http://readystate4.com/2010/12/05/the-wonders-of-git-bisect/">git bisect</a>. Both will save you a lot of time.</li>
<li>It&#8217;s your third hand. Let&#8217;s face it, besides svn being slow, it&#8217;s not friendly enough to do more than throw your past commits into an empty hole you will probably never see again. With <a href="http://jblevins.org/notes/git-colors">very little setup</a>, you have beautiful colored output in your logs and diffs with git. And &#8220;git log&#8221; actually pages by default (while keeping colors) instead of flooding your console with the entire repos history! Want to query something in your history log? What about all commits from your friend Bob in the past 2 weeks?
<pre class="bash">git log --date=relative --author=nizam --since="2 weeks ago"</pre>
<p>Bam. Done.
</li>
<li>Easy repo creation. You don&#8217;t have to be an admin to setup a git repo. Just cd into a folder and type &#8220;git init&#8221;. You just created a new repo. I do this all the time, for example in my folder of todo lists, I use it to track history of my todos. At work someone kept messing up the apache config file, all I had to do was &#8220;git init&#8221; in /etc/httpd/conf and now I can easily &#8220;git diff&#8221; new changes that were made and revert / adjust if needed.</li>
<li>Many ways to use it. Git is promoted as &#8220;decentralized&#8221; version control, but it can be an easy drop in replacement for any job SVN can do. Which leads me to&#8230;
<li>
</ul>
<p>With all those advantages, many larger companies haven&#8217;t jumped on the git bandwagon. I believe there&#8217;s two reasons this is the case.</p>
<ul>
<li>As programmers get more experienced, they generally become more pragmatic (which is generally a good thing.) They adopt a &#8220;if it ain&#8217;t broke, don&#8217;t fix it.&#8221; mentality. After all, SVN get&#8217;s the job done.</li>
<li>There is a bit of a learning curve with git. But there are a ton of good resources for learning it. I recommend getting your hands dirty with <a href="http://gitimmersion.com/">Git Immersion</a> if you&#8217;re new or would like to learn. I don&#8217;t recommend wrapping git around svn as I&#8217;m about to show you for a person who&#8217;s learning git.</li>
</ul>
<h3>Getting down to business.</h3>
<p>In order to use git with an svn repo, you&#8217;ll have to run some commands to import that svn repo, commit by commit into a git repo.</p>
<p>1. First, make sure you have a version of git installed with svn bindings. If you type &#8220;git svn&#8221; and it give you an error, I&#8217;d google one of the resources in reinstalling git with svn bindings.</p>
<p>2. We need to keep</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># In your existing svn repo, lets grab a list of authors</span>
<span style="color: #c20cb9; font-weight: bold;">svn</span> log <span style="color: #660033;">-q</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #660033;">-F</span> <span style="color: #ff0000;">'|'</span> <span style="color: #ff0000;">'/^r/ {sub(&quot;^ &quot;, &quot;&quot;, $2); sub(&quot; $&quot;, &quot;&quot;, $2); print $2&quot; = &quot;$2&quot; &lt;&quot;$2&quot;&gt;&quot;}'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sort</span> <span style="color: #660033;">-u</span> <span style="color: #000000; font-weight: bold;">&gt;</span> authors.txt
<span style="color: #666666; font-style: italic;"># create a new folder</span>
<span style="color: #7a0874; font-weight: bold;">cd</span> ..; <span style="color: #c20cb9; font-weight: bold;">mkdir</span> NEWREPO.git;
git <span style="color: #c20cb9; font-weight: bold;">svn</span> clone <span style="color: #660033;">-A</span> ..<span style="color: #000000; font-weight: bold;">/</span>OLDREPO<span style="color: #000000; font-weight: bold;">/</span>authors.txt https:<span style="color: #000000; font-weight: bold;">//</span>svn<span style="color: #000000; font-weight: bold;">/</span>repo<span style="color: #000000; font-weight: bold;">/</span>trunk
git <span style="color: #c20cb9; font-weight: bold;">svn</span> fetch <span style="color: #666666; font-style: italic;"># this could take a long time as it checks the repo out one rev at a time.</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># update your working copy:</span>
git-svn rebase
&nbsp;
<span style="color: #666666; font-style: italic;"># commit your changes to svn server</span>
git-svn dcommit</pre></div></div>

<p>kudos to:</p>
<p>http://flavio.castelli.name/howto_use_git_with_svn</p>
]]></content:encoded>
			<wfw:commentRss>http://readystate4.com/2012/01/27/setting-up-and-using-a-git-wrapper-around-svn-with-git-svn/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Great little bash snippet to summarize your daily git commits.</title>
		<link>http://readystate4.com/2012/01/09/great-little-bash-snippet-to-summarize-your-daily-git-commits/</link>
		<comments>http://readystate4.com/2012/01/09/great-little-bash-snippet-to-summarize-your-daily-git-commits/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 23:15:02 +0000</pubDate>
		<dc:creator>Mauvis</dc:creator>
				<category><![CDATA[bash]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://readystate4.com/?p=434</guid>
		<description><![CDATA[For general invoicing and hour tracking, I like to post the details of my git commits. Though, I had my own little version of this script, this one posted at stackoverflow was a lot better looking. Posted here for posterity: function gdaily { NEXT=$(date +%F) echo "CHANGELOG" echo ---------------------- git log --no-merges --format="%cd" --date=short &#124; [...]]]></description>
			<content:encoded><![CDATA[<p>For general invoicing and hour tracking, I like to post the details of my git commits. Though, I had my own little version of this script, this one posted at <a href="http://stackoverflow.com/questions/2976665/git-changelog-day-by-day/2979587#2979587">stackoverflow</a> was a lot better looking. Posted here for posterity:</p>
<pre style="overflow: auto; overflow-x:hidden;">
function gdaily {
    NEXT=$(date +%F)
    echo "CHANGELOG"
    echo ----------------------
    git log --no-merges --format="%cd" --date=short | sort -u -r | while read DATE ; do
        echo
        echo [$DATE]
        GIT_PAGER=cat git log --no-merges --format=" * %s" --since=$DATE --until=$NEXT
        NEXT=$DATE
    done
}
</pre>
<p></p>
<p>Which looks like:</p>
<pre style="overflow: auto; overflow-x:hidden;">[2012-01-07]
 * Refactor list portfolio page css and js.
 * namespace.data include to load fake api data until it is ready. Portfolio list working again.
 * CurrentUser model defaults and code cleanup.

[2012-01-06]
 * Upgrade portfolio call from GET and POST. To be discussed in tomorrow's standup.</pre>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://readystate4.com/2012/01/09/great-little-bash-snippet-to-summarize-your-daily-git-commits/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Low powered web servers and resolving issues installing Ubuntu on an Android Galaxy S</title>
		<link>http://readystate4.com/2011/11/21/low-powered-web-servers-and-resolving-issues-installing-ubuntu-on-an-android-galaxy-s/</link>
		<comments>http://readystate4.com/2011/11/21/low-powered-web-servers-and-resolving-issues-installing-ubuntu-on-an-android-galaxy-s/#comments</comments>
		<pubDate>Mon, 21 Nov 2011 08:18:38 +0000</pubDate>
		<dc:creator>Mauvis</dc:creator>
				<category><![CDATA[android]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://readystate4.com/?p=425</guid>
		<description><![CDATA[I&#8217;ve been on a multi-month long side project trying to create a low powered web server for hosting an offline version of Wikipedia in the dessert (long story). I assembled my own machine from Newegg but even with solid-state it was running between 30-50 watts. My latest approach has been modifying a Linksys NSLU2, an [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been on a multi-month long side project trying to create a low powered web server for hosting an offline version of Wikipedia in the dessert (long story). I assembled my own machine from Newegg but even with solid-state it was running between 30-50 watts.</p>
<p>My latest approach has been modifying a <a href="http://en.wikipedia.org/wiki/NSLU2">Linksys NSLU2</a>, an old low-powered network storage device, and installing Debian on it (thanks to <a href="http://www.nslu2-linux.org/">great documentation</a> from the NSLU/Linux community). The end product is a web server that runs between 3-5.5 watts! And it&#8217;s able to support two usb drives. Not the fastest machine but certainly useable, especially at the cost of only $35 used for the device off Craigslist (compared also to the $225 or so I spent assembling the machine above.)</p>
<p>While I think it&#8217;s the approach I&#8217;m going to go with, I found a <a href="http://androlinux.com/android-ubuntu-development/how-to-install-ubuntu-on-android/">link</a> where someone installed Ubuntu on their Android device. This piqued my interest as it&#8217;s also a low wattage device (and the fact that I have a Galaxy S sitting around doing nothing.) I followed the steps, and though it worked well, the Ubuntu package manager has problems when you want to install any new packages or do an update. It just 404&#8242;s like so:</p>
<pre>Err http://ports.ubuntu.com karmic/main Packages
  404  Not Found</pre>
<p>After much research I ended up having to change <code>/etc/apt/sources.list</code> from:</p>
<pre>deb http://ports.ubuntu.com/ubuntu-ports karmic main universe</pre>
<p>to:
<pre>deb http://old-releases.ubuntu.com/ubuntu/ karmic main universe</pre>
<p>I tried to post this update to the blog above but it errored out, so I&#8217;m leaving the solution here instead should anyone else have the issue.</p>
<p>Additional note In the case of the NSLU2: if DHCP has assigned the Slug an ip address but your wireless router doesn&#8217;t find it, use nmap to ping for port 22 on your subnet:</p>
<pre>nmap -p 22 --open -sV 10.0.0.0/24</pre>
]]></content:encoded>
			<wfw:commentRss>http://readystate4.com/2011/11/21/low-powered-web-servers-and-resolving-issues-installing-ubuntu-on-an-android-galaxy-s/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Common Backbone errors and what they mean.</title>
		<link>http://readystate4.com/2011/10/22/common-backbone-errors-and-what-they-mean/</link>
		<comments>http://readystate4.com/2011/10/22/common-backbone-errors-and-what-they-mean/#comments</comments>
		<pubDate>Sun, 23 Oct 2011 02:09:00 +0000</pubDate>
		<dc:creator>Mauvis</dc:creator>
				<category><![CDATA[backbone]]></category>

		<guid isPermaLink="false">http://readystate4.com/?p=420</guid>
		<description><![CDATA[I&#8217;m a big fan of Backbone, the open-source JavaScript MVC framework. It&#8217;s lightweight, extendable, has an awesome event model that allows one to bind to changes from just about anything &#8211; it&#8217;s error messages, however, can be quite cryptic. Simply referencing a missing template file can lead to half an hour of wasted time tracking [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a big fan of <a href="http://documentcloud.github.com/backbone/">Backbone</a>, the open-source JavaScript MVC framework. It&#8217;s lightweight, extendable, has an awesome event model that allows one to bind to changes from just about anything &#8211; it&#8217;s error messages, however, can be quite cryptic. Simply referencing a missing template file can lead to half an hour of wasted time tracking down the issue. Without further ado here&#8217;s a quick list of the day-to-day errors I occasionally encounter and what the problem ended up being: </p>
<div id="outline-container-1" class="outline-3">
<h3 id="sec-1">TypeError: &#8216;undefined&#8217; is not a function (evaluating &#8216;func.apply(obj, args.concat(slice.call(arguments)))&#8217;)</h3>
<div class="outline-text-3" id="text-1">
<p>You probably created an event listener in view that binded to a function that doesn&#8217;t exist. </p>
</p></div>
</p></div>
<div id="outline-container-2" class="outline-3">
<h3 id="sec-2">invalid &#8216;in&#8217; operand attrs</h3>
<div class="outline-text-3" id="text-2">
<p>You probably passed a string instead of an object to a Model.set. This frequently happens to me during an ajax callback using jQuery &#8211; for some reason Webkit browser return and object while Firefox returns a string. </p>
</div></div>
<div id="outline-container-3" class="outline-3">
<h3 id="sec-3">Uncaught TypeError: Cannot call method &#8216;replace&#8217; of null (underscore.js:768)</h3>
<div class="outline-text-3" id="text-3">
<p>    You&#8217;re calling an underscore template put not passing in the data it uses in the template.     You&#8217;re referencing an underscore template that doesn&#8217;t exist.     You could have created a new template but forgot to change it&#8217;s id. </p>
</div></div>
<div id="outline-container-4" class="outline-3">
<h3 id="sec-4">TypeError: &#8216;undefined&#8217; is not an object (evaluating &#8216;func.bind&#8217;)</h3>
<div class="outline-text-3" id="text-4">
<p>You probably set a _bind or _bindAll in your view initiailize code and that method doesn&#8217;t exist in this view. Double check for a typo. </p>
</p></div>
</p></div>
<div id="outline-container-5" class="outline-3">
<h3 id="sec-5">TypeError: &#8216;null&#8217; is not an object (evaluating &#8216;func.bind&#8217;)</h3>
<div class="outline-text-3" id="text-5">
<p>In your view you could be binding an event to a callback that got overwritten during initialization. Commen when your model is called &#8220;contact&#8221; and your model is called the same and gets passed in. </p>
</div></div>
<div id="outline-container-6" class="outline-3">
<h3 id="sec-6">TypeError: &#8216;undefined&#8217; is not a function (evaluating &#8216;this._configure(options || {})&#8217;) backbone.js #881</h3>
<div class="outline-text-3" id="text-6">
<p>    Something went wrong in the routing. You may have not instantiated a new view. </p>
</div></div>
<div id="outline-container-7" class="outline-3">
<h3 id="sec-7">Uncaught TypeError: Cannot call method &#8216;extend&#8217; of undefined (yourfile.js)</h3>
<div class="outline-text-3" id="text-7">
<p>    Your probably extending an object that extended a backbone object, but the reference to the object is wrong or missing. </p>
</p></div>
</p></div>
<div id="outline-container-8" class="outline-3">
<h3 id="sec-8">Uncaught SyntaxError: Unexpected identifier (underscore.js:782)</h3>
<div class="outline-text-3" id="text-8">
<p>    Your template logic might have an error in it. Check that you closed open parens and such. </p>
</div></div>
<p>If you&#8217;ve experienced a Backbone error that&#8217;s not on the list, feel free to post it in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://readystate4.com/2011/10/22/common-backbone-errors-and-what-they-mean/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Response Times: The 3 Important Limits</title>
		<link>http://readystate4.com/2011/10/22/laws-of-load-time/</link>
		<comments>http://readystate4.com/2011/10/22/laws-of-load-time/#comments</comments>
		<pubDate>Sun, 23 Oct 2011 01:55:00 +0000</pubDate>
		<dc:creator>Mauvis</dc:creator>
				<category><![CDATA[General Web Dev]]></category>

		<guid isPermaLink="false">http://readystate4.com/?p=411</guid>
		<description><![CDATA[Regardless of new technology and devices the basic advice regarding (perceived) response time has been the same for forty years in counting. I find that I&#8217;m always having to google around to find this link when the subject pops up so I&#8217;ll post the basics here, and link to the rest if you&#8217;re interested in [...]]]></description>
			<content:encoded><![CDATA[<p> Regardless of new technology and devices the basic advice regarding (perceived) response time has been the same for forty years in counting. I find that I&#8217;m always having to google around to find this link when the subject pops up so I&#8217;ll post the basics here, and link to the rest if you&#8217;re interested in reading more. </p>
<ul>
<li><strong>0.1 second</strong> is about the limit for having the user feel that the system is reacting instantaneously, meaning that no special feedback is necessary except to display the result. </li>
<li><strong>1.0 second</strong> is about the limit for the user&#8217;s flow of thought to stay uninterrupted, even though the user will notice the delay. Normally, no special feedback is necessary during delays of more than 0.1 but less than 1.0 second, but the user does lose the feeling of operating directly on the data. </li>
<li><strong>10 seconds</strong> is about the limit for keeping the user&#8217;s attention focused on the dialogue. For longer delays, users will want to perform other tasks while waiting for the computer to finish, so they should be given feedback indicating when the computer expects to be done. Feedback during the delay is especially important if the response time is likely to be highly variable, since users will then not know what to expect.  </li>
</ul>
<p> From the book  <a href="http://www.amazon.com/gp/product/0125184069/ref=as_li_ss_tl?ie=UTF8&#038;tag=readystate4-20&#038;linkCode=as2&#038;camp=217145&#038;creative=399369&#038;creativeASIN=0125184069">Usability Engineering (1993)</a>. More info <a href="http://www.useit.com/papers/responsetime.html">here</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://readystate4.com/2011/10/22/laws-of-load-time/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Older is sometimes better or why I use an old version of jQuery.</title>
		<link>http://readystate4.com/2011/07/21/older-is-sometimes-better-or-why-i-use-an-old-version-of-jquery/</link>
		<comments>http://readystate4.com/2011/07/21/older-is-sometimes-better-or-why-i-use-an-old-version-of-jquery/#comments</comments>
		<pubDate>Thu, 21 Jul 2011 10:18:02 +0000</pubDate>
		<dc:creator>Mauvis</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[zepto]]></category>

		<guid isPermaLink="false">http://readystate4.com/?p=382</guid>
		<description><![CDATA[For the last year or so I&#8217;ve been predominantly focused on mobile web applications. While I&#8217;m a big fan of jQuery, at it&#8217;s current revision of *32.18 KB (compressed and gzipped) I think it&#8217;s generally too big for the mobile web. That&#8217;s when I discovered Zepto, a jQuery-like library that features 90% of the same [...]]]></description>
			<content:encoded><![CDATA[<p>For the last year or so I&#8217;ve been predominantly focused on mobile web applications. While I&#8217;m a big fan of jQuery, at it&#8217;s current revision of *32.18 KB (compressed and gzipped) I think it&#8217;s generally too big for the mobile web. That&#8217;s when I discovered <a href="http://zeptojs.com/">Zepto</a>, a jQuery-like library that features 90% of the same functionality at a weight of 4.8 KB (compressed and gzipped). Life was good again and I resumed working with iOS and Android web apps, bidding IE adieu.</p>
<p>Fast forward to now and I need to make some general web pages again for a project and I need to support IE once more. These pages have some light-to-moderate js functionality and though I could write a small library from scratch, I&#8217;d be a fool in wasting so much time, though minimally, I only need:</p>
<ul>
<li>Cross-browser event support</li>
<li>Cross-browser ajax support</li>
</ul>
<p>Though one does arguably write faster and more concisely (smaller file size) if one has: </p>
<ul>
<li>A chainable API</li>
<li>A CSS selector engine</li>
</ul>
<p>The answer? Use an older version of jQuery. jQuery 1.2.6 for example is 17.18 KB (compressed and gzipped). Almost half as small as the current version. It gives me all four requirements above. Every version of jQuery has been battle-hardened against the most finicky older browsers and the newest batch of browsers aren&#8217;t really causing too much trouble. I had been writing with Zepto in Chrome initially when I made the switch to test in IE. I made the switch to 1.2.6 without issue. IE and all browsers are happy.</p>
<p>While I would love to take credit for thinking this through, it actually happened by accident. I referenced jQuery version 1.2.6 from Google&#8217;s CDN instead of 1.6.2.</p>
<p>I&#8217;m sure someone&#8217;s going to comment how I&#8217;m missing some major optimizations in later versions, but after trying the project out, I already have split second performance using an old build. If I start doing crazy animations or need .live, I&#8217;ll move up some revisions. If you do plan to try this out for yourself, know that jQuery 1.3 (20.08 KB) is when <a href="http://docs.jquery.com/Release:jQuery_1.3">Sizzle</a> was introduced and in <a href="http://api.jquery.com/category/version/1.6/">jQuery 1.6</a> a lot of the API was modified or had signature changes (nothing that&#8217;s affected me so far).</p>
<p>Here&#8217;s a list of some versions along with their file sizes. Check the <a href="http://blog.jquery.com/">blog</a> for more details.<br />
1.6.2 (32.18 KB) &#8211; misc small bugfixes<br />
1.5 (30.12 KB) &#8211; ajax timeout and abort<br />
1.4.2 (24.86 KB) &#8211; .delegate<br />
1.4 (27.25 KB) &#8211; extended .live support<br />
1.3 (20.08 KB) &#8211; Sizzle and Live<br />
1.2.6 (17.18) &#8211; 100% faster events<br />
1.2 (17.21 KB)</p>
<p>And don&#8217;t forget if you&#8217;re using Google&#8217;s CDN (a good idea), <a href="http://stackoverflow.com/questions/6382639/is-it-safe-to-reference-googles-jquery-library/6382668#6382668">always fallback to your own version, too, just in case</a>.</p>
<p>*2.6.1, I use Charles Debugging Proxy for measurements.</p>
]]></content:encoded>
			<wfw:commentRss>http://readystate4.com/2011/07/21/older-is-sometimes-better-or-why-i-use-an-old-version-of-jquery/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Nginx, Apache, and Node all living harmony.</title>
		<link>http://readystate4.com/2011/07/15/nginx-apache-and-node-all-living-harmony/</link>
		<comments>http://readystate4.com/2011/07/15/nginx-apache-and-node-all-living-harmony/#comments</comments>
		<pubDate>Fri, 15 Jul 2011 22:28:00 +0000</pubDate>
		<dc:creator>Mauvis</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[node]]></category>

		<guid isPermaLink="false">http://readystate4.com/?p=367</guid>
		<description><![CDATA[So here&#8217;s two problems you want to solve: You want to optimize static content You have an Apache install that&#8217;s hosting a bunch of sites and friend&#8217;s sites through vhosts. One of your blogs is getting a lot of hits and you want to optimize it&#8217;s static content &#8211; or even the static content of [...]]]></description>
			<content:encoded><![CDATA[<p>So here&#8217;s two problems you want to solve:</p>
<h3>You want to optimize static content</h3>
<p>You have an Apache install that&#8217;s hosting a bunch of sites and friend&#8217;s sites through vhosts. One of your blogs is getting a lot of hits and you want to optimize it&#8217;s static content &#8211; or even the static content of all sites. You&#8217;re not quite ready for a CDN-type deal, just to place the content outside of Apache and into something more lighter-weight so it&#8217;s not running through WordPress / Apache and unnecessarily using up threads (at roughly 2mb a thread).</p>
<h3>You want all your web apps on port 80!</h3>
<p>You started really getting into Node (or Ruby on Rails or Django) but every web app needs to be binded to it&#8217;s own port and port 80 is taken by your Apache which is hosting a lot. You don&#8217;t want to be giving out the url: http://mycoolnewapp.com:81.</p>
<p>Sure you can use Apache&#8217;s <a href="http://httpd.apache.org/docs/1.3/mod/mod_proxy.html">proxypass</a> but you&#8217;re gaining overhead and, in case of Node (or Ruby&#8217;s <a href="http://rubyeventmachine.com/">EventMachine</a> or Python&#8217;s <a href="http://twistedmatrix.com/trac/">Twisted</a>), you&#8217;re losing the whole point of having an optimized, non-blocking / non-threaded, web app.</p>
<h3>The solution</h3>
<p><a href="http://wiki.nginx.org/">Nginx</a>! Nginx is a web server, <a href="http://en.wikipedia.org/wiki/Reverse_proxy">reverse-proxy</a>, load balancer, and mail server all in one. Like Node, it was built with the concept of the event loop, not threads so it&#8217;s highly optimized for high concurrency. The idea is to setup Nginx to be a reverse-proxy for all your other services.</p>
<p>I&#8217;ll skip over how to install Nginx as it&#8217;s pretty straightforward and you can google it. I&#8217;ll go over the main steps to getting Apache to work through Nginx &#8211; it&#8217;s truly easy, I did it on my first try. The only problem that I encountered is that since the user only interfaces with Nginx &#8211; it&#8217;s Nginx that is making the requests to Apache / Node. So from Apache&#8217;s perspective, all requests are coming from 127.0.0.1. We also fix this in the steps below.</p>
<ol>
<li>Once Nginx is installed, edit your /etc/httpd/conf/httpd.conf so that it listens on another port. Say 127.0.0.1:8080.</li>
<li>Switch all your vhosts to also listen on this port.</li>
<li>Edit your /etc/nginx/nginx.conf file. Make sure it&#8217;s set to listen on port 80 and add a server entry per each apache vhost. Here&#8217;s an example:
<pre>
    server {
           listen       80;
           server_name  mysite.com;

	   location / {
                    proxy_pass http://127.0.0.1:8080;
                    include /etc/nginx/conf.d/proxy.conf;
           }
    }
</pre>
</li>
<li>Next we&#8217;ll add that proxy.conf reference by creating /etc/nginx/conf.d/proxy.conf:
<pre>
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 8m;
client_body_buffer_size 256k;
proxy_connect_timeout 60;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffer_size 4k;
proxy_buffers 32 256k;
proxy_busy_buffers_size 512k;
proxy_temp_file_write_size 256k;
</pre>
</li>
<li>At his point you need to install <a href="http://stderr.net/apache/rpaf/">mod-rpaf</a> for Apache. This enable Apache to use the extra headers Nginx is passing in the request. If you&#8217;re using a flavor of Linux that uses apt-get you&#8217;re in luck. Just run: sudo apt-get install libapache2-mod-rpaf. If you&#8217;re using a system that uses Yum, you&#8217;ll have to compile it yourself. Just follow the steps <a href="http://binarysushi.com/blog/2009/aug/19/CentOS-5-3-python-2-5-virtualevn-mod-wsgi-and-mod-rpaf/">here</a>.
</li>
</ol>
<p>As for serving static content. Inside each &#8220;server&#8221; declaration you can add the following (modified to your taste):</p>
<pre style="overflow: auto;">
       location ~* ^.+\.(jpg|jpeg|gif|png|ico|tgz|gz|pdf|rar|bz2|exe|ppt|txt|tar|mid|midi|wav|bmp|rtf) {
            root /folder/to/static/files;
            expires 90d;
       }
       location ~* ^.+\.(css|js)$ {
            root /folder/to/static/files;
            expires 30d;
      }
</pre>
<p><br ><br />
Ad that&#8217;s it you&#8217;re done!</p>
<h3>Additional reading</h3>
<p><a href="http://blog.martinfjordvald.com/2010/07/nginx-primer/">Nginx Primer</a><br />
<a href="http://blog.martinfjordvald.com/2011/02/nginx-primer-2-from-apache-to-nginx/">Nginx Primer 2: From Apache to Nginx</a><br />
<a href="http://kbeezie.com/view/apache-with-nginx/">Apache with Nginx</a><br />
<a href="http://kbeezie.com/view/nginx/">Really solid config samples</a></p>
]]></content:encoded>
			<wfw:commentRss>http://readystate4.com/2011/07/15/nginx-apache-and-node-all-living-harmony/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Docco: cool JS documentation generator</title>
		<link>http://readystate4.com/2011/06/27/docco-cool-js-documentation-generator/</link>
		<comments>http://readystate4.com/2011/06/27/docco-cool-js-documentation-generator/#comments</comments>
		<pubDate>Tue, 28 Jun 2011 05:33:30 +0000</pubDate>
		<dc:creator>Mauvis</dc:creator>
				<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://readystate4.com/?p=364</guid>
		<description><![CDATA[I noticed both backbone.js and spine.js are using it: http://jashkenas.github.com/docco/ Creates pages like this: http://documentcloud.github.com/backbone/docs/todos.html]]></description>
			<content:encoded><![CDATA[<p>I noticed both <a href="http://documentcloud.github.com/backbone/">backbone.js</a> and <a href="http://maccman.github.com/spine/">spine.js</a> are using it:</p>
<p>http://jashkenas.github.com/docco/</p>
<p>Creates pages like this:</p>
<p>http://documentcloud.github.com/backbone/docs/todos.html</p>
]]></content:encoded>
			<wfw:commentRss>http://readystate4.com/2011/06/27/docco-cool-js-documentation-generator/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Notes on setting up Gerrit code review on CentOs</title>
		<link>http://readystate4.com/2011/06/23/notes-on-setting-up-gerrit-code-review-on-centos/</link>
		<comments>http://readystate4.com/2011/06/23/notes-on-setting-up-gerrit-code-review-on-centos/#comments</comments>
		<pubDate>Thu, 23 Jun 2011 17:40:02 +0000</pubDate>
		<dc:creator>Mauvis</dc:creator>
				<category><![CDATA[gerrit]]></category>

		<guid isPermaLink="false">http://readystate4.com/?p=344</guid>
		<description><![CDATA[Gerrit is an open-source code-review system for Git. It gives you a nice web interface for conversing about commits, giving and getting feedback, auto-merging reviewed commits, and even has options for hooking in your automated test. While I don&#8217;t feel like it&#8217;s a perfect solution by any means, and I dislike the way it changes [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://code.google.com/p/gerrit/">Gerrit</a> is an open-source code-review system for Git. It gives you a nice web interface for conversing about commits, giving and getting feedback, auto-merging reviewed commits, and even has options for hooking in your automated test.  While I don&#8217;t feel like it&#8217;s a perfect solution by any means, and I dislike the way it changes the basic way Git works &#8211; these changes were probably necessary in developing a code-review system around Git. I&#8217;d be curious on how other projects like <a href="http://www.atlassian.com/software/crucible/">Crucible</a> (not free), <a href="http://smartbear.com/products/development-tools/code-review/features/">CodeCollaborator</a> (not free), or <a href="http://www.reviewboard.org/docs/manual/dev/users/tools/post-review/">ReviewBoard</a> handle it. (Actual reviews of some of these on <a href="http://buildengineer.org/2011/01/27/code-review-tools/">this</a> blog.)</p>
<p>A few quick things to note:</p>
<ul>
<li>Gerrit is made by guys at Google and is used in well known projects such as the Android platform and is used at companies like digg.com.
<li>I found it fairly easy to setup, just run it&#8217;s .war file and answer a few questions (few prerequisites below).</li>
<li>The Gerrit platform internally, uses a java implementation of git as well as it&#8217;s own java SSH daemon. Wonder why? I did too, and posted in the Gerrit Google Group, and got some <a href="http://groups.google.com/group/repo-discuss/browse_thread/thread/e64d9c2c0e2fee91/6728100b152584e2">helpful answers</a>.</li>
</ul>
<h3>Getting started</h3>
<ul>
<li>Before hand you should have mysql running with an empty database (default: reviewdb)</li>
<li>Decide on which port you want to run the Jetty webserver beforehand, and which port you want to run the SSH daemon (it must be different than your default one). I recommend you not run any SSH daemons on the default port (22) if your server is directly accessibly from the internet.</li>
<li>To be secure, you should prepare a separate unix user that gerrit runs as (container process), as well as a gerrit mysql user with full access to the reviewdb.</li>
<li>You should also have SMTP setup either on the server or through another source &#8211; note that you cannot just use sendmail, as I also <a href="https://groups.google.com/forum/#!topic/repo-discuss/rDakFyII5z8">asked here</a>.</li>
</ul>
<h3>Quick commands:</h3>
<pre style="overflow: auto; overflow-y: none;">
cd /tmp
wget http://gerrit.googlecode.com/files/gerrit-2.2.1.war
 # run the install wizard
sudo java -jar gerrit-2.2.1.war init -d /srv/gerrit
</pre>
<p></p>
<p>During the install, when it asks you if you want to copy the war file, agree.<br />
sudo java -jar gerrit-2.2.1.war daemon -d /srv/gerrit # to test it out</p>
<h3>Other Helpful Info</h3>
<p>gerrit&#8217;s home is:<br />
/srv/gerrit</p>
<p>Create /etc/default/gerritcodereview containing the line:<br />
GERRIT_SITE=/srv/gerrit<br />
so you can use the shell script for turning off / on:
</pre>
<p>As for SMPTP you can just set up a gerrit.yourdomain gmail account. Mark SSL encryption on port 443.</p>
]]></content:encoded>
			<wfw:commentRss>http://readystate4.com/2011/06/23/notes-on-setting-up-gerrit-code-review-on-centos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Convert a file to utf8-encoding via command-line</title>
		<link>http://readystate4.com/2011/06/20/convert-a-file-to-utf8-encoding-via-command-line/</link>
		<comments>http://readystate4.com/2011/06/20/convert-a-file-to-utf8-encoding-via-command-line/#comments</comments>
		<pubDate>Mon, 20 Jun 2011 08:56:50 +0000</pubDate>
		<dc:creator>Mauvis</dc:creator>
				<category><![CDATA[bash]]></category>
		<category><![CDATA[mongodb]]></category>

		<guid isPermaLink="false">http://readystate4.com/?p=333</guid>
		<description><![CDATA[I had an issue importing a large CSV to mongodb using mongoimport. I was getting the error: exception:Invalid UTF8 character detected Use iconv, a program that seems to be on both mac and most unix systems: iconv -f ISO-8859-1 -t utf-8 accounts.csv > accounts-utf8.csv Then continue on your merry way: mongoimport --type csv --headerline --drop [...]]]></description>
			<content:encoded><![CDATA[<p>I had an issue importing a large CSV to mongodb using mongoimport. I was getting the error:</p>
<pre>exception:Invalid UTF8 character detected</pre>
<p>Use iconv, a program that seems to be on both mac and most unix systems:</p>
<pre>iconv -f ISO-8859-1 -t utf-8 accounts.csv > accounts-utf8.csv</pre>
<p>Then continue on your merry way:</p>
<pre style="overflow: auto;">mongoimport --type csv --headerline --drop --port 7777  -d dbname -c collectionname --file accounts-utf8.csv</pre>
]]></content:encoded>
			<wfw:commentRss>http://readystate4.com/2011/06/20/convert-a-file-to-utf8-encoding-via-command-line/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

