<?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>ColonelPanic</title>
	<atom:link href="http://colonelpanic.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://colonelpanic.net</link>
	<description>Dumping our corps so you don&#039;t have to</description>
	<lastBuildDate>Mon, 30 Jan 2012 17:50:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>iOS and iCloud: overcoming &#8220;bad file descriptor&#8221; errors</title>
		<link>http://colonelpanic.net/2012/01/ios-and-icloud-overcoming-bad-file-descriptor-errors/</link>
		<comments>http://colonelpanic.net/2012/01/ios-and-icloud-overcoming-bad-file-descriptor-errors/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 06:49:48 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[General Development]]></category>
		<category><![CDATA[icloud]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[objective-c]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=638</guid>
		<description><![CDATA[Pretty quick one today. I beat my head against this for several hours before I found the obvious solution, so I thought I&#8217;d jot the info down here for reference, and maybe to help someone else out. NOTE: There is now a relevant answer on StackOverflow. Unfortunately, this answer wasn&#8217;t there when I needed it. [...]]]></description>
			<content:encoded><![CDATA[<p>Pretty quick one today. I beat my head against this for several hours before I found the obvious solution, so I thought I&#8217;d jot the info down here for reference, and maybe to help someone else out.</p>
<p><strong>NOTE:</strong> There is now <a href="http://stackoverflow.com/questions/8714525/cannot-sync-simple-text-file-with-icloud-bad-file-descriptor">a relevant answer</a> on StackOverflow. Unfortunately, this answer wasn&#8217;t there when I needed it.</p>
<h3>The problem</h3>
<p>Recently, while adding <a href="http://www.apple.com/icloud/">iCloud</a> support to the <a title="Day One - your premier journaling solution." href="http://dayoneapp.com/">Day One</a> iOS app, I ran into an issue copying files to and from the application&#8217;s Documents directory and its corresponding iCloud directory. Day One can run in one of three modes:</p>
<ol>
<li>Sync entries via iCloud</li>
<li>Sync entries via <a href="https://www.dropbox.com/">Dropbox</a></li>
<li>Don&#8217;t sync entries</li>
</ol>
<p>If you&#8217;ve developed for iCloud at all, you know that iCloud documents live within specific, &#8220;ubiquitous&#8221; directories on the user&#8217;s device (discovered via NSFileManager&#8217;s URLForUbiquityContainerIdentifier: method). So in order to enable iCloud sync, we needed to copy all files into the appropriate ubiquitous container. Conversely, if the user elects to disable iCloud then we need to copy all files from the ubiquitous container into the application&#8217;s Documents directory.</p>
<h3>The assumption</h3>
<p>We wrote a simple method to copy files from one directory to another, either going into or coming out of iCloud. It uses a basic NSDirectoryEnumerator to find all the files in the current source directory, check if they are present in the destination directory, and copy them there if they aren&#8217;t. Here&#8217;s a simplified example:</p>
<div class="wp_syntax">
<div class="code">
<pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSURL</span> <span style="color: #002200;">*</span>sourceDir <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self currentWorkingDir<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// current directory, ie ubiquitous iCloud directory</span>
<span style="color: #400080;">NSURL</span> <span style="color: #002200;">*</span>destDir <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>self destDirForMovingFromDir<span style="color: #002200;">:</span>sourceDir<span style="color: #002200;">&#93;</span>; <span style="color: #11740a; font-style: italic;">// where should we copy to?</span>
<span style="color: #400080;">NSFileManager</span> <span style="color: #002200;">*</span>fm <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSFileManager</span> defaultManager<span style="color: #002200;">&#93;</span>;
<span style="color: #400080;">NSDirectoryEnumerator</span> <span style="color: #002200;">*</span>dirEnum <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>fm enumeratorAtPath<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>sourceDir path<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
&nbsp;
<span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span>mergeError;
<span style="color: #a61390;">while</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>sourceFile <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>dirEnum nextObject<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #400080;">NSURL</span> <span style="color: #002200;">*</span>sourceFileURL <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>sourceDir URLByAppendingPathComponent<span style="color: #002200;">:</span>sourceFile<span style="color: #002200;">&#93;</span>;
    <span style="color: #400080;">NSURL</span> <span style="color: #002200;">*</span>destFileURL <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>destDir URLByAppendingPathComponent<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>sourceFile lastPathComponent<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>fm fileExistsAtPath<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>destFileURL path<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>fm copyItemAtURL<span style="color: #002200;">:</span>sourceFileURL toURL<span style="color: #002200;">:</span>destFileURL error<span style="color: #002200;">:&amp;</span>mergeError<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
            NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;ERROR (copy error): %@ -&gt; %@ - %@&quot;</span>, sourceFileURL, destFileURL, mergeError<span style="color: #002200;">&#41;</span>;
        <span style="color: #002200;">&#125;</span>
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre>
</div>
</div>
<p>I frequently found &#8220;bad file descriptor&#8221; errors being logged out. We were assuming that the NSDirectoryEnumerator would only list files that were actually present on the device. As it turns out, that is not the case when enumerating a ubiquitous directory.</p>
<h3>The solution</h3>
<p>Once you realize that the NSDirectoryEnumerator will list all ubiquitous files that exist on any device, regardless of whether or not they have been downloaded to the current device, the solution becomes pretty obvious:</p>
<p><em>You can&#8217;t copy a file that hasn&#8217;t been downloaded.</em></p>
<p>Adding that check is fairly straight forward. Since our method doesn&#8217;t know if we are going into or out of iCloud, we implemented a pretty general solution. Modifying the above example, it looks something like this:</p>
<div class="wp_syntax">
<div class="code">
<pre class="objc" style="font-family:monospace;">...
<span style="color: #a61390;">while</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span>sourceFile <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>dirEnum nextObject<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    ...
    <span style="color: #11740a; font-style: italic;">// By default, assume all files are able to be copied.</span>
    <span style="color: #400080;">NSNumber</span> <span style="color: #002200;">*</span>ableToBeCopied <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #400080;">NSNumber</span> numberWithBool<span style="color: #002200;">:</span><span style="color: #a61390;">YES</span><span style="color: #002200;">&#93;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// However, ubiquitous items that are not downloaded CANNOT be copied</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>fm isUbiquitousItemAtURL<span style="color: #002200;">:</span>sourceFileURL<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #002200;">&#91;</span>sourceFileURL getResourceValue<span style="color: #002200;">:&amp;</span>ableToBeCopied forKey<span style="color: #002200;">:</span>NSURLUbiquitousItemIsDownloadedKey error<span style="color: #002200;">:</span><span style="color: #a61390;">nil</span><span style="color: #002200;">&#93;</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Now copy the file if it doesn't exist and is able to be copied</span>
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>fm fileExistsAtPath<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>destFileURL path<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span> <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">&#91;</span>ableToBeCopied boolValue<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
        <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>fm copyItemAtURL<span style="color: #002200;">:</span>sourceFileURL toURL<span style="color: #002200;">:</span>destFileURL error<span style="color: #002200;">:&amp;</span>mergeError<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
            NSLog<span style="color: #002200;">&#40;</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;ERROR (copy error): %@ -&gt; %@ - %@&quot;</span>, sourceFileURL, destFileURL, mergeError<span style="color: #002200;">&#41;</span>;
        <span style="color: #002200;">&#125;</span>
    <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre>
</div>
</div>
<h3>Conclusion</h3>
<p>See what I mean? Pretty obvious, and I can&#8217;t believe I lost so much time tracking this down. If the source file is ubiquitous, it might not be downloaded, and thus you might not be able to copy it. So check it first.</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2012/01/ios-and-icloud-overcoming-bad-file-descriptor-errors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The best JavaScript stack I have ever used</title>
		<link>http://colonelpanic.net/2011/12/the-best-javascript-stack-i-have-ever-used/</link>
		<comments>http://colonelpanic.net/2011/12/the-best-javascript-stack-i-have-ever-used/#comments</comments>
		<pubDate>Fri, 23 Dec 2011 07:06:54 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=622</guid>
		<description><![CDATA[JavaScript as a real language Like many, the suggestion that JavaScript could be used in a fully architected system initially left me doubting the sanity of the person with whom I spoke. Over the years I have done several different types of Web Development; I am best known for my work with browser plugins in [...]]]></description>
			<content:encoded><![CDATA[<h1>JavaScript as a real language</h1>
<p>Like many, the suggestion that JavaScript could be used in a fully architected system initially left me doubting the sanity of the person with whom I spoke. Over the years I have done several different types of Web Development; I am best known for my work with browser plugins in general and the <a href="http://firebreath.org">FireBreath framework</a> in particular. What most do not know is that I actually started out doing a lot of PHP and JavaScript development and that it was actually my work with JavaScript that eventually led me to learning about NPAPI and ActiveX plugin technologies.</p>
<p>Throughout all this I experimented with many different types of javascript code; I wrote AJAX applications long before I&#8217;d heard the term coined using a system called <a href="http://www.ashleyit.com/rs/jsrs/test.htm">JSRS</a> &#8212; which is surprisingly still around, or at least the page I got it from. I worked for Move Networks on their JavaScript SDK and I wrote several AJAX heavy websites, such as <a href="http://hamstudy.org">HamStudy.org</a>. Many reading this will scoff when I admit that while I considered myself fairly well versed in JavaScript I still wrote it as if it were a simple scripting language. Others may wonder what is wrong with that? JavaScript more than perhaps any other language I have used gives you <a href="http://www.amazon.com/Enough-Rope-Shoot-Yourself-Foot/dp/0070296898">just enough rope to shoot yourself in the foot with</a>. I have learned over the last few months just how little I knew &#8212; and didn&#8217;t know that I didn&#8217;t know.</p>
<p>My upward climb started off simply enough &#8212; I wanted to learn about some of the new technologies that I had heard about; <a href="http://documentcloud.github.com/backbone/">Backbone</a>, MVC frameworks, client-side template libraries&#8230; I had written my own &#8220;frameworks&#8221; on which to base my websites, all of which were side projects, but I found myself spending much more time than I liked updating and maintaining those frameworks. I thought perhaps I could use someone else&#8217;s system and save myself some trouble.</p>
<p>I purchased a book called <a href="http://shop.oreilly.com/product/0636920018421.do">JavaScript Web Applications</a> which claimed to teach how to write an actual application with JavaScript. The table of contents looked interesting, and besides teaching about the principles used it also had instructions on several different MVC frameworks that I wanted to know about, including Backbone.</p>
<p>This book was the beginning &#8212; as a result of this purchase I soon came to grips with just how comparitively incomptetent my old code had been, and started to actually understand that JavaScript can indeed be a real language. Over the course of a few posts I would like to share with you the stack that has grown out of this system: What the components are, how they help, and why they are integral to the overall solution. I will start out in this post with the basics and my next post will detail the specific tweaks that we have made to them that have made our system so successful.</p>
<h1>Dependency Management</h1>
<p>Having been so long-winded with my earlier explanation, I will now spare you the details of all of the things I tried, researched, or experimented with during my search. One thing quickly became clear to me, though: Perhaps the #1 reason that my previous code had ended up so ugly was the need to avoid creating lots of JavaScript files. These can be difficult to deploy cleanly as it is not a good idea to have too many script includes in your production site and combining them can be an annoying process. The end result of this problem is that I had about 10 JavaScript files &#8212; and felt guilty about it &#8212; and all of my functionality was stuffed in those files. I had page-specific files, site-specific files, and general reuse library files, and all of them tried to register themselves cleanly in the global scope without clobbering each other. In short, it was a mess.</p>
<p>Enter <a href="http://requirejs.org/">require.js</a>. Require.js is a system in which all javascript files are wrapped in a function. This is actually a really common pattern, but with require.js that function is passed into the &#8220;define&#8221; function call along with a list of dependencies. Require will first resolve these dependencies and then when they are all resolved it will call the function you provided, passing in the exports of each dependency as arguments in the order that the dependencies are listed in the define call.</p>
<p>The question left unanswered, then, is what are the exports of the other dependencies? Simply put, each &#8220;module&#8221; exports some value by simply returning that value from the function passed into the define call (See file1.js and file2.js).</p>
<div id="gist-1500557" class="gist">
<div class="gist-file">
<div class="gist-data gist-syntax">
<div class="highlight">
<pre>
<div class='line' id='LC1'><span class="nx">define</span><span class="p">([</span><span class="s2">&quot;backbone&quot;</span><span class="p">,</span> <span class="s2">&quot;./reqfile2&quot;</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">Backbone</span><span class="p">,</span> <span class="nx">File2</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// In this file we do whatever it is we do; we know file2 was loaded first and we can use what it exports</span></div>
<div class='line' id='LC3'><br/></div>
<div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">File2</span><span class="p">.</span><span class="nx">text</span> <span class="o">+</span> <span class="s2">&quot; from two different files&quot;</span><span class="p">;</span></div>
<div class='line' id='LC5'><span class="p">});</span></div>
</pre>
</div></div>
<div class="gist-meta">
            <a href="https://gist.github.com/raw/1500557/40e1484de2bc94b65add80219d87e9dc0104d8f8/reqfile1.js" style="float:right;">view raw</a><br />
            <a href="https://gist.github.com/1500557#file_reqfile1.js" style="float:right;margin-right:10px;color:#666">reqfile1.js</a><br />
            <a href="https://gist.github.com/1500557">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
</p></div>
</div>
<div id="gist-1500557" class="gist">
<div class="gist-file">
<div class="gist-data gist-syntax">
<div class="highlight">
<pre>
<div class='line' id='LC1'><span class="nx">define</span><span class="p">([],</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span></div>
<div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">File2</span> <span class="o">=</span> <span class="p">{};</span></div>
<div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">File2</span><span class="p">.</span><span class="nx">text</span> <span class="o">=</span> <span class="s2">&quot;This is some text&quot;</span><span class="p">;</span></div>
<div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">File2</span><span class="p">;</span></div>
<div class='line' id='LC5'><span class="p">});</span></div>
</pre>
</div></div>
<div class="gist-meta">
            <a href="https://gist.github.com/raw/1500557/c9f3ad81c0dba359d2e61093cfd368b22058dafc/reqfile2.js" style="float:right;">view raw</a><br />
            <a href="https://gist.github.com/1500557#file_reqfile2.js" style="float:right;margin-right:10px;color:#666">reqfile2.js</a><br />
            <a href="https://gist.github.com/1500557">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
</p></div>
</div>
<p>The natural result of so much flexibility is a lot of small files; this is really good for code organization because it makes it easy to seperate things into logical pieces and even to include whole modules consisting of multiple files (because one can depend on multiple others and combine them in its return value). The downside is that with lots of small files your page load time starts to get a bit out of control. Fortunately, require.js has an answer for this problem as well!</p>
<p>Require.js has an optimize phase that will examine the dependencies of your main file and combine all of them into a single file so that they are all loaded at once. The require.js system still makes sure that the functions are called in the correct order, but makes it very easy for your production site to be seamlessly updated to use a combined and minified single javascript file instead of the potentially dozens of small other files.</p>
<p>To me, this was a nearly life-changing WIN.</p>
<h1>JavaScript Templates</h1>
<p>If dependency management became the #1 most useful change in my architecture, a close #2 would have the be JavaScript Templates. The more I did things on the client the more client-side HTML I created in JavaScript; I experimented with several methods but still ended up with really hard to read html mixed in with my JavaScript as strings. When the time came to update one of those sites it was painful; not all of the code was in the same place, it wasn&#8217;t easy to read, it wasn&#8217;t easy therefore to change.</p>
<p>I considered different types of templates but had previously rejected the idea. The problem with templates, you see, is that you still have to include the template code somehow. The most &#8220;traditional&#8221; method would be to pretend you&#8217;re on a backend and just store them one template per file. Of course, then if you have any real number of these files you find yourself making a multitude of AJAX requests to download all of these templates; it&#8217;s clean from a file structure perspective and fairly easy to use, but to me the added complexity of all those requests is not acceptible. Other options include storing the template in javascript strings (same problem as I had before without templates) and storing them in a special script tag on the html page, which had the (to me) serious disadvantage of being nearly impossible to reasonably use on multiple pages. It was a problem.</p>
<p>Enter require.js and the text plugin. The text plugin of require.js is an idea both simple and brilliant; it allows you to specify files that should be loaded and the text of those files will be passed into your page function as the value of that dependency. With the text plugin you can save your templates each in their own file and have require load the text when the page loads. Of course, this doesn&#8217;t solve the problem we mentioned earlier! You still have potentially lots of AJAX requests being made to load those files. Problem? Not at all! Remember the optimize step in require.js; just like the normal dependencies are loaded and combined into one file the text plugin provides a mechanism to serialize those templates into javascript as strings and combine them into that same file. You get the best of both worlds! When you&#8217;re developing you have the flexibility of having each template in an easy-to-read file, but when you deploy those templates are packaged with your javascript.</p>
<div id="gist-1500557" class="gist">
<div class="gist-file">
<div class="gist-data gist-syntax">
<div class="highlight">
<pre>
<div class='line' id='LC1'><span class="nx">define</span><span class="p">([</span><span class="s2">&quot;backbone&quot;</span><span class="p">,</span> <span class="s2">&quot;underscore&quot;</span><span class="p">,</span> <span class="s2">&quot;text!./mytemplate.jst&quot;</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">Backbone</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">tplCode</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">template</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">template</span><span class="p">(</span><span class="nx">tplCode</span><span class="p">);</span></div>
<div class='line' id='LC4'><br/></div>
<div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">function</span> <span class="nx">doSomething</span><span class="p">(</span><span class="nx">val</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;Here is the rendered template: &quot;</span><span class="p">,</span> <span class="nx">tplCode</span><span class="p">({</span><span class="nx">key</span><span class="o">:</span> <span class="nx">val</span><span class="p">}));</span></div>
<div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div>
<div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">doSomething</span><span class="p">;</span></div>
<div class='line' id='LC9'><span class="p">});</span></div>
</pre>
</div></div>
<div class="gist-meta">
            <a href="https://gist.github.com/raw/1500557/e30e9374666998bd5cb309ce8ce1547199e0ffea/reqtpl.js" style="float:right;">view raw</a><br />
            <a href="https://gist.github.com/1500557#file_reqtpl.js" style="float:right;margin-right:10px;color:#666">reqtpl.js</a><br />
            <a href="https://gist.github.com/1500557">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
</p></div>
</div>
<p>Top all of this off with the fact that for several of the most popular template libraries there are already require.js plugins, such as <a href="https://github.com/ZeeAgency/requirejs-tpl">requirejs-tpl</a>. These plugins work like the text plugin, but they compile the template string into an actual template function before passing it back to resolve the dependency. Then, when you optimize, they actually compile your template code into javascript functions and minify them along with the rest of your JS code!</p>
<p>To me, this was a nearly life-changing WIN.</p>
<h1>Deferred Objects</h1>
<p>This may seem like it doesn&#8217;t fit with the other items on this page, but if templates and dependency management have revolutionized the organization of my code then deferred objects have revolutionized the way that I write JavaScript code. One of my coworkers at <a href="http://www.gradecam.com">GradeCam</a>, Robin, has already begun a <a href="http://colonelpanic.net/2011/11/jquery-deferred-objects/">small introductory series on how deferred objects work</a>, so I&#8217;m not going to go into those details, but I do want to explain the conceptual shift in how pieces of the system interact that this led me to. It is both subtle and extremely powerful.</p>
<p>Most JavaScript operations anymore are asynchronous; in other words, they return immediately even though the operation in question hasn&#8217;t been completed. This can make it difficult to handle result cases; the traditional method is to pass a callback into the function to be called when the operation completes. You then perform some other operation once that function is called back and so forth.</p>
<p>The challenge with that is that it is a significant deviation from the patterns that we are all accustomed to. Granted, it&#8217;s important to understand what is <em>actually </em>happening, but often you may want to call a function in a place where you don&#8217;t actually want to handle the results; a good example is when you are requesting data from a model in your controller code, but you will actually be rendering it withing your view and your controller doesn&#8217;t really care what the results are. The view, of course, should not need to know or care where the data came from. In fact, it shouldn&#8217;t really need to know if the data is immediately available or will be available later on &#8212; it should display it <em>when it is available</em> and not worry about the other details.</p>
<p>Code speaks louder than prose, so here is an example of the difference between these two approaches; in both async1.js and async2.js three async operations take place. In async1.js they are handled in a traditional way, and in async2.js they are handled using jQuery.Deferred.</p>
<div id="gist-1500557" class="gist">
<div class="gist-file">
<div class="gist-data gist-syntax">
<div class="highlight">
<pre>
<div class='line' id='LC1'><span class="kd">function</span> <span class="nx">asyncOper1</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span></div>
<div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">callback</span><span class="p">(</span><span class="s2">&quot;One second has passed since &quot;</span> <span class="o">+</span> <span class="nx">value</span><span class="p">);</span></div>
<div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span> <span class="mi">1000</span><span class="p">);</span></div>
<div class='line' id='LC5'><span class="p">}</span></div>
<div class='line' id='LC6'><br/></div>
<div class='line' id='LC7'><span class="kd">function</span> <span class="nx">asyncOper2</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span></div>
<div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">callback</span><span class="p">(</span><span class="s2">&quot;Two seconds were added, then &quot;</span> <span class="o">+</span> <span class="nx">value</span><span class="p">);</span></div>
<div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span> <span class="mi">2000</span><span class="p">);</span></div>
<div class='line' id='LC11'><span class="p">}</span></div>
<div class='line' id='LC12'><br/></div>
<div class='line' id='LC13'><span class="kd">function</span> <span class="nx">asyncOper3</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span></div>
<div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">callback</span><span class="p">(</span><span class="s2">&quot;A long time (3 seconds) went by before &quot;</span> <span class="o">+</span> <span class="nx">value</span><span class="p">);</span></div>
<div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span> <span class="mi">3000</span><span class="p">);</span></div>
<div class='line' id='LC17'><span class="p">}</span></div>
<div class='line' id='LC18'><br/></div>
<div class='line' id='LC19'><span class="kd">function</span> <span class="nx">alertResult</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC20'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">alert</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span></div>
<div class='line' id='LC21'><span class="p">}</span></div>
<div class='line' id='LC22'><br/></div>
<div class='line' id='LC23'><span class="c1">// Call them all; alert the final result</span></div>
<div class='line' id='LC24'><span class="nx">asyncOper1</span><span class="p">(</span><span class="s2">&quot;we started&quot;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">strVal1</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">asyncOper2</span><span class="p">(</span><span class="nx">strVal1</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">strVal2</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">asyncOper3</span><span class="p">(</span><span class="nx">strVal2</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">strVal3</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC27'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">alertResult</span><span class="p">(</span><span class="nx">strVal3</span><span class="p">);</span></div>
<div class='line' id='LC28'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC29'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC30'><span class="p">});</span></div>
</pre>
</div></div>
<div class="gist-meta">
            <a href="https://gist.github.com/raw/1500557/be1fceb3098909ae1d02d0a03a1e6f36169fbbe1/async1.js" style="float:right;">view raw</a><br />
            <a href="https://gist.github.com/1500557#file_async1.js" style="float:right;margin-right:10px;color:#666">async1.js</a><br />
            <a href="https://gist.github.com/1500557">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
</p></div>
</div>
<div id="gist-1500557" class="gist">
<div class="gist-file">
<div class="gist-data gist-syntax">
<div class="highlight">
<pre>
<div class='line' id='LC1'><span class="kd">function</span> <span class="nx">asyncOper1</span><span class="p">(</span><span class="nx">valueDfd</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">$</span><span class="p">.</span><span class="nx">when</span><span class="p">(</span><span class="nx">valueDfd</span><span class="p">).</span><span class="nx">pipe</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">dfd</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">$</span><span class="p">.</span><span class="nx">Deferred</span><span class="p">()</span></div>
<div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span></div>
<div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">dfd</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="s2">&quot;One second has passed since &quot;</span> <span class="o">+</span> <span class="nx">value</span><span class="p">);</span></div>
<div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span> <span class="mi">1000</span><span class="p">);</span></div>
<div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">dfd</span><span class="p">.</span><span class="nx">promise</span><span class="p">();</span></div>
<div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC9'><span class="p">}</span></div>
<div class='line' id='LC10'><br/></div>
<div class='line' id='LC11'><span class="kd">function</span> <span class="nx">asyncOper2</span><span class="p">(</span><span class="nx">valueDfd</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">$</span><span class="p">.</span><span class="nx">when</span><span class="p">(</span><span class="nx">valueDfd</span><span class="p">).</span><span class="nx">pipe</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">dfd</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">$</span><span class="p">.</span><span class="nx">Deferred</span><span class="p">()</span></div>
<div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span></div>
<div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">dfd</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="s2">&quot;Two seconds were added, then &quot;</span> <span class="o">+</span> <span class="nx">value</span><span class="p">);</span></div>
<div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span> <span class="mi">2000</span><span class="p">);</span></div>
<div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">dfd</span><span class="p">.</span><span class="nx">promise</span><span class="p">();</span></div>
<div class='line' id='LC18'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC19'><span class="p">}</span></div>
<div class='line' id='LC20'><br/></div>
<div class='line' id='LC21'><span class="kd">function</span> <span class="nx">asyncOper3</span><span class="p">(</span><span class="nx">valueDfd</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">$</span><span class="p">.</span><span class="nx">when</span><span class="p">(</span><span class="nx">valueDfd</span><span class="p">).</span><span class="nx">pipe</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">dfd</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">$</span><span class="p">.</span><span class="nx">Deferred</span><span class="p">()</span></div>
<div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span></div>
<div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">dfd</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="s2">&quot;A long time (3 seconds) went by before &quot;</span> <span class="o">+</span> <span class="nx">value</span><span class="p">);</span></div>
<div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span> <span class="mi">3000</span><span class="p">);</span></div>
<div class='line' id='LC27'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">dfd</span><span class="p">.</span><span class="nx">promise</span><span class="p">();</span></div>
<div class='line' id='LC28'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC29'><span class="p">}</span></div>
<div class='line' id='LC30'><br/></div>
<div class='line' id='LC31'><span class="kd">function</span> <span class="nx">alertResult</span><span class="p">(</span><span class="nx">valueDfd</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC32'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">$</span><span class="p">.</span><span class="nx">when</span><span class="p">(</span><span class="nx">valueDfd</span><span class="p">).</span><span class="nx">done</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC33'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">alert</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span></div>
<div class='line' id='LC34'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC35'><span class="p">}</span></div>
<div class='line' id='LC36'><br/></div>
<div class='line' id='LC37'><span class="kd">var</span> <span class="nx">res1</span><span class="p">,</span> <span class="nx">res2</span><span class="p">,</span> <span class="nx">res3</span><span class="p">;</span></div>
<div class='line' id='LC38'><br/></div>
<div class='line' id='LC39'><span class="nx">res1</span> <span class="o">=</span> <span class="nx">asyncOper1</span><span class="p">(</span><span class="s2">&quot;we started&quot;</span><span class="p">);</span></div>
<div class='line' id='LC40'><span class="nx">res2</span> <span class="o">=</span> <span class="nx">asyncOper2</span><span class="p">(</span><span class="nx">res1</span><span class="p">);</span></div>
<div class='line' id='LC41'><span class="nx">res3</span> <span class="o">=</span> <span class="nx">asyncOper3</span><span class="p">(</span><span class="nx">res2</span><span class="p">);</span></div>
<div class='line' id='LC42'><br/></div>
<div class='line' id='LC43'><span class="nx">alertResult</span><span class="p">(</span><span class="nx">res3</span><span class="p">);</span></div>
<div class='line' id='LC44'><br/></div>
</pre>
</div></div>
<div class="gist-meta">
            <a href="https://gist.github.com/raw/1500557/75a294c8603e678d91db660c5e0c2e6060aa1636/async2.js" style="float:right;">view raw</a><br />
            <a href="https://gist.github.com/1500557#file_async2.js" style="float:right;margin-right:10px;color:#666">async2.js</a><br />
            <a href="https://gist.github.com/1500557">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
</p></div>
</div>
<p>As you can see, the Deferred object method is slightly more complex at first; however, the complexity is where it belongs. Each method need know nothing about the others &#8212; they all assume that the input value *might* be Deferred. They return a Deferred object, and so they use the Deferred.pipe method, which makes it easy to chain deferred objects. Because each of the methods returns a Deferred object and is aware that it may receive a Deferred object, you can call one after the other as though they were happening synchronously &#8212; because indeed they will end up doing so, in all practical purposes. However, you shouldn&#8217;t think of this as hiding the fact that it is asynchronous, but rather as returning asynchronous return values.</p>
<p>Because we used $.when, you can pass a regular parameter in to any of those methods as well and chain them as much as you want. It will handle them all perfectly.</p>
<p>To me, this was a completely life-changing WIN.</p>
<h1>This is just the beginning</h1>
<p>I have a lot more to talk about here; this is just the foundation. If you know nothing more about our stack, you should understand these things. Next time, though, I&#8217;ll talk about how we tie this together using Backbone.js Routers, Views, and Models, how those tie into our templates, and how Deferred objects allowed us to add data cacheing to our data models completely transparently &#8212; without changing a line of code outside of the model classes.</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/12/the-best-javascript-stack-i-have-ever-used/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>jQuery Deferred Objects &#8211; Part 2</title>
		<link>http://colonelpanic.net/2011/12/jquery-deferred-objects-part-2/</link>
		<comments>http://colonelpanic.net/2011/12/jquery-deferred-objects-part-2/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 16:47:58 +0000</pubDate>
		<dc:creator>Robin</dc:creator>
				<category><![CDATA[General Development]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=603</guid>
		<description><![CDATA[Deferred Objects &#8211; Part II As you recall from the first part jQuery Deferred Objects &#8211; Part I, deferred objects give you a way to organize asynchronous blocks of code in to a self-managed callback queue, while allowing you to attach 1..* callbacks. Also, you&#8217;ll recall that the basics of using jQuery deferred objects include [...]]]></description>
			<content:encoded><![CDATA[<h1> Deferred Objects &#8211; Part II</h1>
<p>As you recall from the first part <a href="http://colonelpanic.net/2011/11/jquery-deferred-objects/" target="_blank">jQuery Deferred Objects &#8211; Part I</a>, deferred objects give you a way to organize asynchronous blocks of code in to <a href="http://www.erichynds.com/jquery/using-deferreds-in-jquery/" target="_blank">a self-managed callback queue</a>, while allowing you to attach 1..* callbacks. Also, you&#8217;ll recall that the basics of using jQuery deferred objects include essentially the following &#8220;simplified&#8221; steps:<br />
1. Created a deferred object<br />
2. Attached .done and .fail callbacks<br />
3. Called resolve or reject, thereby triggering the appropriate respective callbacks</p>
<h2> Promises</h2>
<p>This was fine as a first step in understanding what&#8217;s going on, but in all likelyhood you&#8217;ll use a slightly different approach. What&#8217;s wrong with returning a deferred object itself? It gives the caller access to resolve or reject directly, and that means other callers could be affected as a result. What we really want to do is return a &#8220;promise&#8221;. From the <a href="http://api.jquery.com/Types/#Promise">jQuery Promise Documentation</a> we learn:<br />
&#8220;This object provides a subset of the methods of the Deferred object (then, done, fail, always, pipe. isResolved, and isRejected) to prevent users from changing the state of the Deferred.&#8221;</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span>
    $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&quot;/push_to_twitter&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&quot;/push_to_facebook&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&quot;/push_to_linkedin&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
    $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&quot;/generate_report&quot;</span> <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">then</span><span style="color: #009900;">&#40;</span> it_succeeded<span style="color: #339933;">,</span> it_failed<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> it_succeeded<span style="color: #009900;">&#40;</span>report_data<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Now do something with the report data e.g. show</span>
    <span style="color: #006600; font-style: italic;">// an awesome summary with pretty bars and graphs!</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #003366; font-weight: bold;">function</span> it_failed<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Treat user's depression, OCD and other ailments</span>
    <span style="color: #006600; font-style: italic;">// Prescribe prozac, etc., etc...</span>
<span style="color: #009900;">&#125;</span></pre>
</div>
</div>
<h2>Possible Uses</h2>
<p>Possible use cases are endless but here are some examples:<br />
1. You need to make multiple asynchronous Ajax requests &#8211; with Deferred objects you can handle the results together without concern for which order they finish in.<br />
2. You want to be able to make the call in one region of code, then pass the result as an argument to a different part, but the call may be asynchronous.<br />
3. Easily return data from a modal dialog<br />
4. Caching &#8211; an API properly supporting Deferred objects can implement caching <em>without any changes to the consumer of the API</em>.</p>
<h2>An Example: Caching</h2>
<p>For caching, jQuery&#8217;s when .. then provides us the tools we need to return both fresh and cached data from one interface. Take the following code:</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> cacheA <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">function</span> fetch_some_objectA<span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>cacheA<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> cacheA<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">return</span> cacheA<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/fooEndpoint'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// ajax options here</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">done</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>res<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        cacheA<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> res<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #003366; font-weight: bold;">var</span> cacheB <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">function</span> fetch_some_objectB<span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>cacheB<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> cacheB<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">return</span> cacheB<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/barEndpoint'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// ajax options here</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">done</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>res<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        cacheB<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> res<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
$.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span>fetch_some_objectA<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'foo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> fetch_some_objectB<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'bar'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">done</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>dataA<span style="color: #339933;">,</span> dataB<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Do whatever you want with said data</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fail</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>errA<span style="color: #339933;">,</span> errB<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Deal with error handling</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
<h3> The basics of caching with Deferred objects</h3>
<p>There are a couple of cases to consider here; the first case is that you are requesting object(&#8216;foo&#8217;) for the first time. In this case, cacheA["foo"] will not exist and so an ajax call is created. $.ajax returns a deferred object, which is saved in the cache. The reason this is important is that thereafter, future requests will get that same deferred object, thus preventing two requests from being made to the same endpoint. Once the ajax call completes the done handler we set updates the cache with the actual object. Any calls that ran fetch<em>some</em>objectA(&#8216;foo&#8217;) while the request was &#8220;in progress&#8221; will be notified with the data once the deferred is resolved. Calls made after the request has resolved will get the actual data straight away. So, how do you tell if you have a deferred or the real data? The answer is simple: you don&#8217;t need to.</p>
<p>This is where <a href="http://api.jquery.com/jQuery.when/">jQuery.when</a> neatly ties everything together. jQuery.when ($.when) accepts any number of arguments and returns a jquery.Deferred object. That object will be resolved once all of the arguments are resolved; however, if those objects are not jQuery.Deferred objects then they will be considered resolved immediately. From the documentation, jQuery.when takes either a Deferred or object: &#8220;If a single argument is passed to jQuery.when and it is not a Deferred, it will be treated as a resolved Deferred and any doneCallbacks attached will be executed immediately.&#8221;</p>
<p>After passing through a jQuery.when, a Deferred object that resolves to a string &#8220;A&#8221; and the string &#8220;A&#8221; become functionally equivalent &#8212; no matter which you passed in, you&#8217;ll still get the same thing:</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;fdsafdsa&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">done</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
<p>This will immediately alert &#8220;fdsafdsa&#8221;. Now essentially the same using the deferred resolve idiom:</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> dfd <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> $.<span style="color: #660066;">Deferred</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
$.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span>dfd<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">done</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
dfd.<span style="color: #660066;">resolve</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;fdsafdsa&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
<p>This will also alert the same thing; it doesn&#8217;t matter if it&#8217;s a real object or a deferred, once you make it into the when it&#8217;ll be a real object. This makes caching really slick because you don&#8217;t need to care if you have the object yet or not, you just let jQuery.when figure that out and tell it what should happen once it does.</p>
<h3>One small problem&#8230;</h3>
<p>If you actually copy in this code and play with it long enough, you&#8217;ll notice something that doesn&#8217;t quite work how you expect. When the jQuery.ajax call returns you&#8217;ll actually get a slightly different object in the jQuery.when callback; this actually makes sense if you look at it closer. From the jQuery codebase, when the ajax call completes it is either resolved or rejected with the following lines:</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Success/Error</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> isSuccess <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    deferred.<span style="color: #660066;">resolveWith</span><span style="color: #009900;">&#40;</span> callbackContext<span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span> success<span style="color: #339933;">,</span> statusText<span style="color: #339933;">,</span> jqXHR <span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
    deferred.<span style="color: #660066;">rejectWith</span><span style="color: #009900;">&#40;</span> callbackContext<span style="color: #339933;">,</span> <span style="color: #009900;">&#91;</span> jqXHR<span style="color: #339933;">,</span> statusText<span style="color: #339933;">,</span> error <span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre>
</div>
</div>
<p>Notice that there are actually three arguments in either case; this may surprise you, since most examples you&#8217;ll see of the callbacks accept just one, like the above code. Most don&#8217;t need the other two, but jQuery.when isn&#8217;t going to discard those extra values and yet it still needs to keep one argument per input in the callback function. Therefore, in the $.when block above you&#8217;ll actually have both dataA and dataB resolve to an array with three values (success, statusText, jqXHR); however, we normally would only cache one of those values (success) so when reading from the cache we don&#8217;t get that array. The solution is to make our functions a little bit more complicated by using the jquery pipe method to restructure the result a little bit:</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> cacheA <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">function</span> fetch_some_objectA<span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>cacheA<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> cacheA<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">return</span> cacheA<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/fooEndpoint'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// ajax options here</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">pipe</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>res<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> cacheA<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> res<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #003366; font-weight: bold;">var</span> cacheB <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">function</span> fetch_some_objectB<span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>cacheB<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> cacheB<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">return</span> cacheB<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/barEndpoint'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// ajax options here</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">pipe</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>res<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">return</span> cacheB<span style="color: #009900;">&#91;</span>key<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> res<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
$.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span>fetch_some_objectA<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'foo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> fetch_some_objectB<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'bar'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">done</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>dataA<span style="color: #339933;">,</span> dataB<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Do whatever you want with said data</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fail</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>errA<span style="color: #339933;">,</span> errB<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// Deal with error handling</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
<p>You may notice the assignment of the result to the cache happens twice. The reason is that you first want to assign the deferred object to the cache when you start the request &#8212; otherwise if you call the function again before the ajax request finishes it&#8217;ll start a new request rather than reusing the old one. </p>
<p>With this new object (the result of the .pipe) the resolved value will be as we expect it. This relatively simple pattern can get a little more complex if you&#8217;re doing a lot with pipe, but for the consumer the interface is really simple.</p>
<p>Admittedly, there is some complexity to using this pattern but the &#8220;win&#8221; is that your interface now has a &#8220;Single Point of Contact&#8221; (<a href="http://en.wikipedia.org/wiki/Point_of_contact">SPOC</a>)<br />
Let&#8217;s look at a convenient analogy&#8230;</p>
<h2>An Example: Placing a Special Order</h2>
<p>Let&#8217;s imagine that, as an active supporter of your local community businesses, you make it a point to go to your favorite little &#8220;mom and pop&#8221; bookstore to place orders for books. The lady at the counter asks for your phone number or email, and says she&#8217;ll contact you as soon as your books come in. Now obviously, there&#8217;s the small chance that, after the fact, the wholesaler, manufacturer, etc., will have ran out of the ordered book(s). Should this happen, you&#8217;d probably feel it was acceptable for the bookstore to contact you and give you the option to wait or cancel your order. However, you would not want to here directly from the wholesaler or manufacturer directly. This would probably confuse you and you may even complain to the bookstore that they should manage their purchases better should this happen! The expectation you have as a customer in this example is that you only have to deal with a single point of contact. In code, we can have a similar convenience using deferred objects:</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Contrived ajax and random failure stubs so we can</span>
<span style="color: #006600; font-style: italic;">// pretend to have &quot;mostly successful&quot; requests</span>
<span style="color: #003366; font-weight: bold;">function</span> randomTrueFalse<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> r <span style="color: #339933;">=</span> Math.<span style="color: #660066;">round</span><span style="color: #009900;">&#40;</span>Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span><span style="color: #CC0000;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>r<span style="color: #339933;">%</span>9 <span style="color: #339933;">!==</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> ajaxStub<span style="color: #009900;">&#40;</span>endpoint<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> dfdResult <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> $.<span style="color: #660066;">Deferred</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> bool <span style="color: #339933;">=</span> randomTrueFalse<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    setTimeout<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>bool<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            dfdResult.<span style="color: #660066;">resolve</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'success: '</span><span style="color: #339933;">+</span>endpoint<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
            dfdResult.<span style="color: #660066;">reject</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'fail: '</span><span style="color: #339933;">+</span>endpoint<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">100</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> dfdResult.<span style="color: #660066;">promise</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> manufacturer <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        orderBook<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>bookName<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">return</span> $.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span>ajaxStub<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/book/'</span><span style="color: #339933;">+</span>bookName<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">pipe</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>respObj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Manufacturer-DONE: &quot;</span><span style="color: #339933;">,</span> respObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">return</span> respObj<span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>errObj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Manufacturer-FAIL: &quot;</span><span style="color: #339933;">,</span> errObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">return</span> errObj<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> wholesaler <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> m <span style="color: #339933;">=</span> manufacturer<span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#123;</span>
        orderBook<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>bookName<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">return</span> $.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span>m.<span style="color: #660066;">orderBook</span><span style="color: #009900;">&#40;</span>bookName<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">pipe</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>respObj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Wholesaler-DONE: &quot;</span><span style="color: #339933;">,</span> respObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">return</span> respObj<span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>errObj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Wholesaler-FAIL: &quot;</span><span style="color: #339933;">,</span> errObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">return</span> errObj<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> retailer <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> w <span style="color: #339933;">=</span> wholesaler<span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#123;</span>
        orderBook<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>bookName<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">return</span> $.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span>w.<span style="color: #660066;">orderBook</span><span style="color: #009900;">&#40;</span>bookName<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">pipe</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>respObj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Retailer-DONE: &quot;</span><span style="color: #339933;">,</span> respObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                dfdResult.<span style="color: #660066;">resolve</span><span style="color: #009900;">&#40;</span>respObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>errObj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Retailer-FAIL: &quot;</span><span style="color: #339933;">,</span> errObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000066; font-weight: bold;">return</span> errObj<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Notice that, although we have multiple potential points of failure above (e.g.</span>
<span style="color: #006600; font-style: italic;">// Manufacturer, Wholesaler, Retailer, the customer only needs to deal with the</span>
<span style="color: #006600; font-style: italic;">// retailer directly.)</span>
<span style="color: #003366; font-weight: bold;">function</span> makePurchase<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">// Place an order for two books</span>
    <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i<span style="color: #339933;">=</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span><span style="color: #CC0000;">3</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        $.<span style="color: #660066;">when</span><span style="color: #009900;">&#40;</span>retailer.<span style="color: #660066;">orderBook</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Great Book - Part &quot;</span> <span style="color: #339933;">+</span> i<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">done</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>respObj<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Purchaser-DONE... respObj: &quot;</span><span style="color: #339933;">,</span> respObj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">fail</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>err<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            console.<span style="color: #660066;">log</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Purchaser-FAIL... err: &quot;</span><span style="color: #339933;">,</span> err<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
makePurchase<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">/*
Random output for placing order of two books might look like:
Manufacturer-FAIL: fail: /book/Great Book - Part 1
Wholesaler-FAIL: fail: /book/Great Book - Part 1
Retailer-FAIL: fail: /book/Great Book - Part 1
Purchaser-FAIL... err: fail: /book/Great Book - Part 1
Manufacturer-DONE: success: /book/Great Book - Part 2
Wholesaler-DONE: success: /book/Great Book - Part 2
Retailer-DONE: success: /book/Great Book - Part 2
Purchaser-DONE... respObj: success: /book/Great Book - Part 2
*/</span></pre>
</div>
</div>
<p>Start at the bottom at the makePurchase() call and you should see that we&#8217;ve essentially modeled our story of a customer (purchaser) placing an order for two books. Should the purchase succeed or fail, the purchaser will only ever have to deal with the retailer directly (as expected), because the fact that deferred promises can sort of &#8220;bubble back up&#8221; the call chain. This keeps the interface quite clean, and the caller&#8217;s required knowledge of inner working to a minimum.</p>
<h2> Conclusion</h2>
<p>I&#8217;ve purposely kept the examples contrived so you can focus on the principles of deferred objects. If you&#8217;d like to see a variety of other example implementations, <a href="http://jaubourg.net/">Julian Aubourg</a> and <a href="http://addyosmani.com/">Addy Osmani</a> have written a <a href="http://msdn.microsoft.com/en-us/scriptjunkie/gg723713">wonderful article</a> you should definitey have a look at. jQuery deferred objects take a bit to get used to, but provide some very compelling advantages for web applications that require heavy ajax or graphics.</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/12/jquery-deferred-objects-part-2/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>jQuery Deferred Objects</title>
		<link>http://colonelpanic.net/2011/11/jquery-deferred-objects/</link>
		<comments>http://colonelpanic.net/2011/11/jquery-deferred-objects/#comments</comments>
		<pubDate>Fri, 18 Nov 2011 18:46:48 +0000</pubDate>
		<dc:creator>Robin</dc:creator>
				<category><![CDATA[General Development]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=575</guid>
		<description><![CDATA[If you&#8217;re a web developer, you may be asking yourself, &#8216;what are these &#8220;deferred objects&#8221; I keep hearing about?&#8217; Hopefully, this article will help explain that. Given the asynchronous nature of the web, and specifically JavaScript, a general asynchronous callback pattern has proliferated. So you have something you need to defer a bit so you [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re a web developer, you may be asking yourself, &#8216;what are these &#8220;deferred objects&#8221; I keep hearing about?&#8217; Hopefully, this article will help explain that.</p>
<p>Given the asynchronous nature of the web, and specifically JavaScript, a general asynchronous callback pattern has proliferated. So you have something you need to defer a bit so you use a timeout or an interval and you&#8217;re good to go&#8230;what&#8217;s the issue you may be asking? Well&#8230;web applications have become more and more complex, and what was once a nested callback or two, is turning into a hairy beast of nested callbacks.</p>
<p>The Deferred pattern addresses this nested nightmare by using using an idiom much like publish/subscribe (Observer) or Notifications (if you come from the land of iOS development). However, notification is a bit different because the caller has access to the Deferred object itself and can determine whether to call success or fail callbacks. This is sort of a forward reference, but will hopefully be clearer further down in this article. That said, let&#8217;s dig in&#8230;</p>
<p>If you&#8217;re familiar with stacks and queues then the underlying concept should be pretty straight forward. Essentially, the Deferred object implementation keeps a stack of callback function objects (similar to subscribers) for success or failure. Conventionally, these are called done callbacks or fail callbacks. Specifically, these function objects get pushed on the Deferred object when you call .then(myfunc), .done(myfunc), or .fail(myfunc):</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> deferred <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Deferred<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
deferred.<span style="color: #660066;">done</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>message<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>message<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
setTimeout<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">3000</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  deferred.<span style="color: #660066;">resolve</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Hey buddy!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
<p>First we create a deferred object. Immediately, the deferred object goes in to the &#8220;Pending&#8221; state. </p>
<p>Next, and here&#8217;s the important part to &#8220;grok&#8221;, by calling .done(&#8230; on the Deferred object, we are essentially asking it to add our function object to its array of callback functions. </p>
<p>Ok, so now we have 1..* functions queued (or stacked depending on implementation details) on the deferred object. Now one of two things will happen (at some point):<br />
1. We call deferred.resolve (or one of it&#8217;s variants)<br />
2. We call deferred.reject</p>
<p>If we do 1., this will &#8220;trigger&#8221; the deferred object to call all of the queued resolve category functions. These are the .done, .then, variant callbacks.</p>
<p>If we do 2., this will &#8220;trigger&#8221; the deferred object call all of the queued fail variant functions.</p>
<p>There are some semantic details to all of this, but that drives to the essence of the pattern. If you&#8217;re still not clear, I&#8217;ve drawn this extremely ugly diagram to help to visualize the essence of the deferred pattern (as described in both the <a href="http://api.jquery.com/category/deferred-object/">jQuery API docs</a> and <a href="http://wiki.commonjs.org/wiki/Promises/A">CommonJS Promises page)</a>. Open your browser wide and start on the left and work to the right:</a></p>
<p><img src="http://colonelpanic.net/wp-content/uploads/2011/11/Deferred.png" alt="Deferred Object Pattern" /></p>
<p>Cool! So how is this Deferred object doing it&#8217;s magic internally? Here&#8217;s a simplified example of how it may be implemented:</p>
<div class="wp_syntax">
<div class="code">
<pre class="javascript" style="font-family:monospace;">&nbsp;
<span style="color: #339933;">&lt;</span>h1<span style="color: #339933;">&gt;</span>JavaScript Deferred Objects Example<span style="color: #339933;">&lt;/</span>h1<span style="color: #339933;">&gt;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> Deferred<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> callbacks <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">done</span> <span style="color: #339933;">=</span>  <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>cb<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        callbacks.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>cb<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">resolve</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>arg<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> callbacks.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            callbacks<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#40;</span>arg<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Now we use the deferred object</span>
<span style="color: #003366; font-weight: bold;">var</span> deferred <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Deferred<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
deferred.<span style="color: #660066;">done</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>message<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span>message<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
setTimeout<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  deferred.<span style="color: #660066;">resolve</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>quot<span style="color: #339933;">;</span>Hey buddy<span style="color: #339933;">!&amp;</span>quot<span style="color: #339933;">;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>
</div>
</div>
<p>What&#8217;s interesting about this pattern is that the owner of the deferred object determines whether we go in to the resolved or rejected state not the deferred object itself. This is slightly different from how a traditional Pub/Sub pattern would work, where the Publishing object itself would likely determine who/when to callback it&#8217;s subscribers. Because of this, it&#8217;s common to see usage where an intermediary function that is supplying some service (e.g. fetchResource, hitDatabase, etc.), will negotiate the initialization of the deferred object, determine whether to call resolve or reject, etc., and simply return the deferred object. So it looks like:</p>
<p><img src="http://colonelpanic.net/wp-content/uploads/2011/11/Deferred_Brokered.png" alt="Deferred Pattern using a Broker" /></p>
<p>The above diagram only shows part of the picture. Once the Broker object calls resolve or reject, the original caller&#8217;s respective .done, .fail, etc., will get called.</p>
<p>All of this is possible because of JavaScript&#8217;s ability to treat functions as first class citizens (a fancy way of saying you can pass functions around and call them later and treat them like good ol&#8217; objects!).</p>
<p>I hope this posting was somewhat helpful and revealed the magic behind Deferred Objects.</p>
<p><strong>EDIT</strong></p>
<p>My good friend Richard Bateman offers a point of clarification. There is actually a difference between .then and .done; .then allows you to provide two callbacks, the first for done and the second for fail.</p>
<h3>Next part</h3>
<p>For more on jquery deferred objects, see <a href="http://colonelpanic.net/2011/12/jquery-deferred-objects-part-2/">part 2 of this series</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/11/jquery-deferred-objects/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>backbone.js attaching multiple Routers to the same route</title>
		<link>http://colonelpanic.net/2011/09/backbone-js-attaching-multiple-routers-to-the-same-route/</link>
		<comments>http://colonelpanic.net/2011/09/backbone-js-attaching-multiple-routers-to-the-same-route/#comments</comments>
		<pubDate>Sat, 17 Sep 2011 00:00:46 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=562</guid>
		<description><![CDATA[Recently I had need to attach multiple backbone.js Router objects to the same route; the purpose was to create a page which could have multiple sections that were unaware of each other, since the path gave them all the information they needed. This allowed a much looser form of coupling and gave us a bit [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I had need to attach multiple backbone.js Router objects to the same route; the purpose was to create a page which could have multiple sections that were unaware of each other, since the path gave them all the information they needed. This allowed a much looser form of coupling and gave us a bit more of a MVP feel rather than a traditional MVC.</p>
<p>However, after a lot of discussion we ended up scrapping this plan for a slightly different one.  I had already written a patch to make backbone.js routers support multiple route handlers, though, and I didn&#8217;t think it made sense to just throw it out, so I&#8217;ll provide it here.  Keep in mind that this may not work with future versions of backbone.js!</p>
<p>So, without further ado, here it is:</p>
<div id="gist-1223417" class="gist">
<div class="gist-file">
<div class="gist-data gist-syntax">
<div class="highlight">
<pre>
<div class='line' id='LC1'><span class="nx">define</span><span class="p">([</span><span class="s2">&quot;require&quot;</span><span class="p">,</span> <span class="s2">&quot;./underscore&quot;</span><span class="p">,</span> <span class="s2">&quot;./backbone&quot;</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">require</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">Backbone</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Backbone.js doesn&#39;t quite do what we want it to, but it almost does;</span></div>
<div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// we can modify it so that it does do what we want pretty easily, thanks</span></div>
<div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// to the eminent hackability of javascript.</span></div>
<div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">//</span></div>
<div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// We may need to update this when backbone.js updates! :-/</span></div>
<div class='line' id='LC7'><br/></div>
<div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">patched_methods</span> <span class="o">=</span> <span class="p">{</span></div>
<div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Save and rename the old route function, modified to work with the new</span></div>
<div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">override_route</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">route</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">this</span><span class="p">.</span><span class="nx">handlers</span><span class="p">.</span><span class="nx">unshift</span><span class="p">({</span><span class="nx">route</span> <span class="o">:</span> <span class="nx">route</span><span class="p">,</span> <span class="nx">callback</span> <span class="o">:</span> <span class="p">[</span><span class="nx">callback</span><span class="p">]});</span></div>
<div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span></div>
<div class='line' id='LC13'><br/></div>
<div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Add a route to be tested when the fragment changes.</span></div>
<div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// RB 9/15/2011: We don&#39;t want routes added later to</span></div>
<div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">//               override previous routes; we want</span></div>
<div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">//               routes added later to get called as well.</span></div>
<div class='line' id='LC18'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">//</span></div>
<div class='line' id='LC19'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">//               With this change, callback becomes an array</span></div>
<div class='line' id='LC20'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">//               of callbacks instead of just one.</span></div>
<div class='line' id='LC21'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">route</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">route</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">appended</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">any</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">handlers</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">handler</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC23'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="p">(</span><span class="nx">handler</span><span class="p">.</span><span class="nx">route</span><span class="p">.</span><span class="nx">toString</span><span class="p">()</span> <span class="o">==</span> <span class="nx">route</span><span class="p">.</span><span class="nx">toString</span><span class="p">())</span> <span class="p">{</span></div>
<div class='line' id='LC24'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">handler</span><span class="p">.</span><span class="nx">callback</span><span class="p">.</span><span class="nx">unshift</span><span class="p">(</span><span class="nx">callback</span><span class="p">);</span></div>
<div class='line' id='LC25'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="kc">true</span><span class="p">;</span></div>
<div class='line' id='LC26'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div>
<div class='line' id='LC27'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC28'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">appended</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC29'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">this</span><span class="p">.</span><span class="nx">handlers</span><span class="p">.</span><span class="nx">unshift</span><span class="p">({</span><span class="nx">route</span> <span class="o">:</span> <span class="nx">route</span><span class="p">,</span> <span class="nx">callback</span> <span class="o">:</span> <span class="p">[</span><span class="nx">callback</span><span class="p">]});</span></div>
<div class='line' id='LC30'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div>
<div class='line' id='LC31'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span></div>
<div class='line' id='LC32'><br/></div>
<div class='line' id='LC33'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Add a feature to remove a route, since we no longer override them</span></div>
<div class='line' id='LC34'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">unroute</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">route</span><span class="p">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC35'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">found_and_removed</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">any</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">handlers</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">handler</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC36'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="p">(</span><span class="nx">handler</span><span class="p">.</span><span class="nx">route</span> <span class="o">==</span> <span class="nx">route</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC37'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">idx</span> <span class="o">=</span> <span class="nx">handler</span><span class="p">.</span><span class="nx">callback</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">callback</span><span class="p">);</span></div>
<div class='line' id='LC38'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="p">(</span><span class="nx">idx</span> <span class="o">&gt;</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC39'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">handler</span><span class="p">.</span><span class="nx">callback</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="nx">idx</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span></div>
<div class='line' id='LC40'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="kc">true</span><span class="p">;</span></div>
<div class='line' id='LC41'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span> <span class="k">else</span> <span class="p">{</span></div>
<div class='line' id='LC42'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="kc">false</span><span class="p">;</span></div>
<div class='line' id='LC43'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div>
<div class='line' id='LC44'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div>
<div class='line' id='LC45'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC46'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">},</span></div>
<div class='line' id='LC47'><br/></div>
<div class='line' id='LC48'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// Attempt to load the current URL fragment. If a route succeeds with a</span></div>
<div class='line' id='LC49'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// match, returns `true`. If no defined routes matches the fragment,</span></div>
<div class='line' id='LC50'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// returns `false`.</span></div>
<div class='line' id='LC51'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1">// RB 9/15/2011: overriding this function</span></div>
<div class='line' id='LC52'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">loadUrl</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">fragmentOverride</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC53'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">fragment</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">fragment</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">getFragment</span><span class="p">(</span><span class="nx">fragmentOverride</span><span class="p">);</span></div>
<div class='line' id='LC54'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kd">var</span> <span class="nx">matched</span> <span class="o">=</span> <span class="nx">_</span><span class="p">.</span><span class="nx">any</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">handlers</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">handler</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC55'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="p">(</span><span class="nx">handler</span><span class="p">.</span><span class="nx">route</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">fragment</span><span class="p">))</span> <span class="p">{</span></div>
<div class='line' id='LC56'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">handler</span><span class="p">.</span><span class="nx">callback</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="p">{</span></div>
<div class='line' id='LC57'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">callback</span><span class="p">(</span><span class="nx">fragment</span><span class="p">);</span></div>
<div class='line' id='LC58'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC59'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="kc">true</span><span class="p">;</span></div>
<div class='line' id='LC60'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div>
<div class='line' id='LC61'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">});</span></div>
<div class='line' id='LC62'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">matched</span><span class="p">;</span></div>
<div class='line' id='LC63'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div>
<div class='line' id='LC64'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">};</span></div>
<div class='line' id='LC65'><br/></div>
<div class='line' id='LC66'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">_</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="nx">Backbone</span><span class="p">.</span><span class="nx">History</span><span class="p">.</span><span class="nx">prototype</span><span class="p">,</span> <span class="nx">patched_methods</span><span class="p">);</span></div>
<div class='line' id='LC67'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="nx">Backbone</span><span class="p">;</span></div>
<div class='line' id='LC68'><span class="p">});</span></div>
<div class='line' id='LC69'><br/></div>
</pre>
</div></div>
<div class="gist-meta">
            <a href="https://gist.github.com/raw/1223417/97e8eb2209011f0f342de56664a7b44df3f7d59b/backbone-multihash.js" style="float:right;">view raw</a><br />
            <a href="https://gist.github.com/1223417#file_backbone_multihash.js" style="float:right;margin-right:10px;color:#666">backbone-multihash.js</a><br />
            <a href="https://gist.github.com/1223417">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
</p></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/09/backbone-js-attaching-multiple-routers-to-the-same-route/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>UPDATED: Terminal Nirvana with TotalTerminal (Snow Leopard, Lion)</title>
		<link>http://colonelpanic.net/2011/08/updated-terminal-nirvana-with-totalterminal-snow-leopard-lion/</link>
		<comments>http://colonelpanic.net/2011/08/updated-terminal-nirvana-with-totalterminal-snow-leopard-lion/#comments</comments>
		<pubDate>Tue, 30 Aug 2011 05:08:30 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[General Development]]></category>
		<category><![CDATA[Systems Administration]]></category>
		<category><![CDATA[terminal]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[visor]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=537</guid>
		<description><![CDATA[It&#8217;s been a while since I wrote up how I achieved Terminal Nirvana on Snow Leopard using SIMBL and Visor. Since then, some things have changed: TotalTerminal has replaced Visor Mac OS X Lion has been released TotalTerminal changes up the way it launches Terminal &#8212; instead of being automatically injected via SIMBL, it manually [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I wrote up how I achieved <a title="Terminal Nirvana on Snow Leopard with SIMBL + Visor" href="http://colonelpanic.net/2010/07/terminal-nirvana-on-snow-leopard-with-simbl-visor/">Terminal Nirvana on Snow Leopard using SIMBL and Visor</a>. Since then, some things have changed:</p>
<ul>
<li><a href="http://totalterminal.binaryage.com/">TotalTerminal</a> has replaced Visor</li>
<li>Mac OS X Lion has been released</li>
</ul>
<p>TotalTerminal changes up the way it launches Terminal &#8212; instead of being automatically injected via SIMBL, it manually injects the plugin into Terminal.app. Well, I wasn&#8217;t going to let this deter me.</p>
<p>Getting back to Nirvana after installing TotalTerminal is not all that bad. Most of the steps haven&#8217;t changed from my original post so I will only go into detail about the new steps here. Briefly, here are the steps I followed.</p>
<ol>
<li>Remove TerminalColours.bundle SIMBL plugin &#8212; per the <a href="http://totalterminal.binaryage.com/#faq">TotalTerminal FAQ</a>, it injects its own version and having TerminalColours.bundle installed creates a conflict. (~/Library/Application\ Support/SIMBL/Plugins)</li>
<li>Fix the Home / End keys (see original post)</li>
<li>Copy Terminal.app to VisorTerminal.app (see original post)</li>
<li>Install TotalTerminal</li>
<li>Modify TotalTerminal to use VisorTerminal.app instead of Terminal.app</li>
</ol>
<h3>That&#8217;s right, there&#8217;s really only one thing to change, and it&#8217;s very simple</h3>
<p>TotalTerminal.app has a simple, compiled AppleScript which launches Terminal and injects itself. The compiled file is located at /Applications/TotalTerminal.app/Contents/Resources/Scripts/main.scpt. But, we don&#8217;t want the compiled binary version, we want the original so we can make it use VisorTerminal.app.</p>
<p>Fortunately the <a href="https://raw.github.com/binaryage/totalterminal-installer/master/TotalTerminal.app/Contents/Resources/Scripts/main.applescript">uncompiled source file</a> is available in the <a href="https://github.com/binaryage/totalterminal-installer">TotalTerminal repo on Github</a>.</p>
<p>Only one change is necessary.</p>
<div class="wp_syntax">
<div class="code">
<pre class="diff" style="font-family:monospace;"><span style="color: #888822;">--- TotalTerminal.app/Contents/Resources/Scripts/main.applescript</span>
<span style="color: #888822;">+++ TotalTerminal.app/Contents/Resources/Scripts/main.applescript</span>
<span style="color: #440088;">@@ -1,4 +1,4 @@</span>
<span style="color: #991111;">-tell application &quot;Terminal&quot;</span>
<span style="color: #00b000;">+tell application &quot;VisorTerminal&quot;</span>
        delay <span style="">1</span> -- this delay is important to prevent random &quot;Connection is Invalid -<span style="">609</span>&quot; AppleScript errors
        try
                event BATTinit</pre>
</div>
</div>
<p>Once that is done, you just need to compile the script and replace the one that shipped with TotalTerminal.</p>
<div class="wp_syntax">
<div class="code">
<pre class="bash" style="font-family:monospace;">$ osacompile <span style="color: #660033;">-o</span> main.scpt main.applescript
$ <span style="color: #c20cb9; font-weight: bold;">mv</span> main.scpt <span style="color: #000000; font-weight: bold;">/</span>Applications<span style="color: #000000; font-weight: bold;">/</span>TotalTerminal.app<span style="color: #000000; font-weight: bold;">/</span>Contents<span style="color: #000000; font-weight: bold;">/</span>Resources<span style="color: #000000; font-weight: bold;">/</span>Scripts</pre>
</div>
</div>
<h3>That&#8217;s it.</h3>
<p>You should be good to go. Put TotalTerminal.app into your user startup applications if you wish (I do), or launch it manually by launching TotalTerminal.app.</p>
<p>Enjoy the restoration of terminal nirvana.</p>
<h3>For the lazy&#8230;</h3>
<p>My modified and compiled main.applescript is <a href="http://colonelpanic.net/wp-content/uploads/2011/08/modified-applescript-compiled.zip">available for download</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/08/updated-terminal-nirvana-with-totalterminal-snow-leopard-lion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing VMWare ESXi 4.1.0 on an i7 3.4Ghz and Asus P8Q67-M</title>
		<link>http://colonelpanic.net/2011/07/installing-vmware-esxi-4-1-0-on-i7-and-p8q67-m/</link>
		<comments>http://colonelpanic.net/2011/07/installing-vmware-esxi-4-1-0-on-i7-and-p8q67-m/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 05:28:58 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=530</guid>
		<description><![CDATA[I&#8217;m not going to go into the many reasons why you might want to do this; basically I find myself in need of more computers at my home office than I can conveniently store the boxes for, and I am not doing anything graphics related, so I started looking at how to set up my [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m not going to go into the many reasons why you might want to do this; basically I find myself in need of more computers at my home office than I can conveniently store the boxes for, and I am not doing anything graphics related, so I started looking at how to set up my own VPS system; unfortunately, the tools I found were for the most part lacking.</p>
<p>I tried VMWare server for awhile, but found that every time I updated my system everything broke and I had to recompile drivers.</p>
<p>I tried VirtualBox in headless mode, which worked much better; still, it was hard to keep things running well since something always seemed to go wrong if the server got restarted for any reason.</p>
<p>Finally, I decided to invest in a machine to dedicate to the task. I did some research and decided on VMWare ESXi as the host platform &#8212; the free version is plenty for what I need.</p>
<h2>Finding &#8220;Supported&#8221; Hardware</h2>
<p>The list of supported hardware that I found was filled with things outside of my price range; okay, I admit it, I&#8217;m a bit cheap. I&#8217;ll save you the sob story of the time it took me to piece together a system that I thought might work and just give you the list of what I settled on. This is not a &#8220;supported&#8221; setup, but it does work (with a little tinkering with the setup file):</p>
<ul>
<li>$179.99 &#8211; <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16820231442">G.SKILL 16GB of ram</a> &#8211; I wanted a little more performance, so I got the faster set.</li>
<li>2 x $139.99 &#8211; <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16822148506">Seagate Barracuda XT 2TB 7200 RPM SATA 6.0GB/s hard drive</a> &#8211; My goal was to mirror these; that hasn&#8217;t turned out to be directly possible, but I have ideas for workarounds.</li>
<li>$29.99 (+$9.99 shipping) <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16811147112">Rosewill R101-P-BK Mid Tower case</a> &#8211; Just about anything would work, but this case seems adequate so far</li>
<li>$59.99 <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16817182200">Rosewill Green Series 630W Power supply</a> &#8211; Again, I wasn&#8217;t really picky, but this one looked decent and specifically says it works for i7 cpus</li>
<li>$299.99 <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16819115071">Intel Core i7-2600 3.4Ghz quad core CPU</a> &#8211; Note that this is the 2600, not the 2600k. There are virtualization features missing on the 2600k.</li>
<li>$139.99 <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16813131766">Asus P8Q67-M LGA 1155 Intel Q67 Motherboard</a> &#8211; This one is where it really got scary and dicy. The new CPUs (like the 2600, not the 2600k) support something called VT-D. Now, I don&#8217;t have this fully working yet, but the Q67 boards are supposed to support it as well; mine says it does, and I have enabled it, but I haven&#8217;t seen it work in VMWare yet, so I&#8217;m not 100% sure if this is working or not.  However, since most of the hardware needing support is on this board, which motherboard you get matters a lot.</li>
</ul>
<p>Total cost of the system after shipping: $1,007.25</p>
<h2>Installing VMWare ESXi</h2>
<p>The first thing I tried, of course, was to install from the ISO I downloaded from VMWare.  Unfortunately, that gave me an ugly python error message; I forget exactly what it said. A little constructive googling turned up that it meant that ESXi couldn&#8217;t find a valid network card.  DRAT! I knew I was right to be worried about the motherboard choice; it has an Intel chipset, but the NIC is not supported by VMWare ESXi. I was quite put out and even started looking to see if any local computer stores had a NIC that was supported so I could get things going today. However, I found something better!</p>
<h2>Customizing the install disk</h2>
<p>As it turns out, there is a <a href="http://vm-help.com/">website (vm-help.com)</a> for people who are running ESXi on hardware other than the &#8220;official supported&#8221; hardware. It took me awhile to find what I needed, but it turns out someone else has already had the issue I did (probably on a different motherboard) and created a driver customization archive (oem.tgz) with the drivers I need!</p>
<p>Here are the steps:</p>
<ol>
<li>Download the latest VMWare ESXi install iso; the one I got was called &#8220;VMware-VMvisor-Installer-4.1.0.update1-348481.x86_64.iso&#8221;</li>
<li>Found and downloaded <a href="http://www.vm-help.com/forum/viewtopic.php?f=12&amp;t=2194&amp;p=11181#p11181">the oem.tgz file (2 rar files that I extracted) that supports the Intel 82579 Gigabit ethernet card</a></li>
<li>Followed <a href="http://www.vm-help.com/forum/viewtopic.php?f=16&amp;t=4">these instructions</a> to use the <a href="http://code.google.com/p/mkesxiaio/">mkesxiaio shell script</a> (on a linux machine) to customize my ISO</li>
<li>Burned the new ISO and installed</li>
</ol>
<p>That was it! It works now! I did of course have to turn on all the virtualization features in the motherboard BIOS settings; I also set the SATA controller to AHCI mode. Really, though, everything seems to work perfectly and I&#8217;m now in the process of adding virtual machines.</p>
<p>Life is good =]</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/07/installing-vmware-esxi-4-1-0-on-i7-and-p8q67-m/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Building a firefox plugin &#8211; part four</title>
		<link>http://colonelpanic.net/2011/07/building-a-firefox-plugin-part-four/</link>
		<comments>http://colonelpanic.net/2011/07/building-a-firefox-plugin-part-four/#comments</comments>
		<pubDate>Tue, 05 Jul 2011 03:41:01 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Browser Plugin Development]]></category>
		<category><![CDATA[FireBreath]]></category>
		<category><![CDATA[NPAPI]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=520</guid>
		<description><![CDATA[The traffic going to my &#8220;Building a firefox plugin&#8221; series over the last year or two has been incredible. Granted, I knew that the other documenation was poor, but in recent times I have encountered links to my previous posts in all sorts of strange places &#8212; even in the comments in a project I [...]]]></description>
			<content:encoded><![CDATA[<p>The traffic going to my &#8220;Building a firefox plugin&#8221; series over the last year or two has been incredible. Granted, I knew that the other documenation was poor, but in recent times I have encountered links to my previous posts in all sorts of strange places &#8212; even in the comments in a project I ended up reviewing for an employer where the original author had not previously met me. I never inteded those to be the end of the series, but it has been quite some time since I last posted an update.  The main reason for this is that for all but a few uses &#8212; android in particular &#8212; I no longer recommend anyone write a NPAPI plugin from scratch. The reason for this is that the popular <a href="http://www.firebreath.org">FireBreath</a> framework makes all of this so easy and fixes so many edge cases in different browser versions that it isn&#8217;t worth doing it by hand anymore.</p>
<p>Yes, I wrote <a href="http://www.firebreath.org">FireBreath</a>. A lot of others have contributed.</p>
<h2>A different approach to learning NPAPI</h2>
<p>Now that I have a good example already up and running, it seems pointless to keep trying to describe things with words and code snippets when I can simply walk you through what I have done &#8212; what is in use and works well. To that end, and in hopes that it will foster more capable NPAPI developers to help with FireBreath development (we still don&#8217;t support printing, for example), I have created a series of 5 minute screencasts providing a brief overview of FireBreath&#8217;s NPAPI framework.</p>
<p>I don&#8217;t expect that this is as comprehensive as it should be; I&#8217;m hoping that comments will help me see what future segments I should create.  I have posted these screencasts on youtube and will link to them from here. You can also find a more complete series that includes this one <a href="http://www.firebreath.org/display/documentation/FireBreath+development+video+tutorials">on the FireBreath website</a>.</p>
<p><iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/ehHfsxj2xSk" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/VbHW4HvitIg" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/RtPyEpiTFxY" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/c17kvVxoNGU" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/SQtduyKCAZ8" frameborder="0"><br />
</iframe><br />
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/4NxLMDUHufE" frameborder="0"><br />
</iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/07/building-a-firefox-plugin-part-four/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Jenkins on Mac OS X; git w/ ssh public key</title>
		<link>http://colonelpanic.net/2011/06/jenkins-on-mac-os-x-git-w-ssh-public-key/</link>
		<comments>http://colonelpanic.net/2011/06/jenkins-on-mac-os-x-git-w-ssh-public-key/#comments</comments>
		<pubDate>Wed, 15 Jun 2011 20:22:08 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=514</guid>
		<description><![CDATA[Jenkins on Mac OS X I just finished setting up a build server on Mac OS X using Jenkins (formerly Hudson). The company I&#8217;m working for (GradeCam) uses git and gitolite for our source control and so I expected no trouble using Jenkins to build our tools using the git plugin. However, I quickly ran [...]]]></description>
			<content:encoded><![CDATA[<h1>Jenkins on Mac OS X</h1>
<p>I just finished setting up a build server on Mac OS X using Jenkins (formerly Hudson). The company I&#8217;m working for (<a href="http://www.gradecam.com" target="_blank">GradeCam</a>) uses git and gitolite for our source control and so I expected no trouble using Jenkins to build our tools using the git plugin.</p>
<p>However, I quickly ran into a snag: the source control server is on a public address and so our source code is not available except via ssh, and gitolite ssh access uses private key authentication.  Well, I&#8217;m an experience unix sysadmin, so that didn&#8217;t sound like a big issue &#8212; after all, setting up public key authentication is childs play, right?</p>
<h2>Default install</h2>
<p>The default installation of Jenkins on Mac OS X (at the time of this writing) installs a Launch Agent plist to /Library/LaunchAgents/org.jenkins-ci.plist. This plist file causes Jenkins to load as user &#8220;daemon&#8221;, which sounds fine &#8212; except that the home directory for the &#8220;daemon&#8221; user is /var/root, same as for user root.  This means that the .ssh dir in there will never have the right permissions for a private key to be used.</p>
<h2>Creating a new hidden user</h2>
<p>My solution was to create a new &#8220;hidden&#8221; user for Jenkins to run under. Following instructions I found on a <a href="http://hints.macworld.com/article.php?story=20080127172157404" target="_blank">blog post</a>, I created a user &#8220;jenkins&#8221; with a home directory &#8220;/Users/Shared/Jenkins/Home&#8221;:</p>
<pre>sudo dscl . create /Users/jenkins
sudo dscl . create /Users/jenkins PrimaryGroupID 1
sudo dscl . create /Users/jenkins UniqueID 300   
sudo dscl . create /Users/jenkins UserShell /bin/bash
sudo dscl . passwd /Users/jenkins $PASSWORD
sudo dscl . create /Users/jenkins home /Users/Shared/Jenkins/Home/</pre>
<p>I then stopped Jenkins: &#8220;sudo launchctl unload -w /Library/LaunchAgents/org.jenkins-ci.plist&#8221; and <a href="https://gist.github.com/1028036">edited the plist file</a> to set the username to jenkins instead of daemon.  &#8220;chown -R jenkins: /Users/Shared/Jenkins/Home&#8221; sets the permissions how they need to be, and then &#8220;sudo launchctl load -w /Library/LaunchAgents/org.jenkins-ci.plist&#8221; should get you up and running!</p>
<p>To get git over ssh running, &#8220;sudo su &#8211; jenkins&#8221; to get a console as the jenkins user and set up the ssh keys and such. Make sure you can ssh to where you want to go (or even do a test git clone) because you need to save the keys so it doesn&#8217;t ask for them when jenkins tries to do the clone.</p>
<p>That should do you! Hope it helps someone.</p>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/06/jenkins-on-mac-os-x-git-w-ssh-public-key/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Enabling git access via password authentication with gitolite</title>
		<link>http://colonelpanic.net/2011/03/enabling-git-access-via-password-authentication-with-gitolite/</link>
		<comments>http://colonelpanic.net/2011/03/enabling-git-access-via-password-authentication-with-gitolite/#comments</comments>
		<pubDate>Fri, 04 Mar 2011 23:46:17 +0000</pubDate>
		<dc:creator>Ben</dc:creator>
				<category><![CDATA[General Development]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[gitolite]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://colonelpanic.net/?p=486</guid>
		<description><![CDATA[We recently started using gitolite at my workplace. Our previous git hosting setup involved manually managing linux users and groups on the Ubuntu server, which was needlessly time consuming and painful. There were times when file permissions got out of sync because the repo was deployed by user X from his workstation (where group permissions [...]]]></description>
			<content:encoded><![CDATA[<p>We recently started using <a title="gitolite" href="https://github.com/sitaramc/gitolite">gitolite</a> at my workplace. Our previous git hosting setup involved manually managing linux users and groups on the Ubuntu server, which was needlessly time consuming and painful. There were times when file permissions got out of sync because the repo was deployed by user X from his workstation (where group permissions were not setup correctly for a shared git repository), and other headaches.</p>
<p>We needed something easier. We did not want to go to a workflow where there is one git user on the system, every employee authenticates with their own public key to that user, and everyone with a key has access to everything. We wanted more granular control, but also an easier management workflow. While gitolite does use a single system user under the covers, it provides per-user access control (governed by public keys), easy repo management, and a couple other nice features like wildcard repositories and branch-level access restrictions.</p>
<p>However, one of our developers is in the habit of accessing a random server, cloning a repo (using his password), and pushing from environments other than his development environment. Obviously, his private key is not going to be on each of the machines he does this from. Gitolite does not allow password-based access for obvious reasons &#8212; it needs to know who you are to determine permissions &#8212; so gitolite was cramping his style.</p>
<p><span id="more-486"></span></p>
<p>There are a couple ways around this:</p>
<ol>
<li>Add a public key for each system he pushes changes from. Since he often logs in as &#8220;administrator&#8221; or &#8220;root&#8221; on individual systems, this obviously is not a good solution.</li>
<li>Have the developer enable SSH Agent Forwarding from his machine. This works well, as long as the user does not chain sessions (connect to server A, from there to server B, and clone on B) or is willing / able / allowed to enable Agent Forwarding on each system in the chain. (NOTE: on Mac OS X Snow Leopard, enabling SSH Agent Forwarding is as simple as running ssh-add and adding two lines to your ~/.ssh/config file:
<div class="wp_syntax">
<div class="code">
<pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># add key to agent (I do this in ~/.profile)</span>
<span style="color: #c20cb9; font-weight: bold;">ssh-add</span> <span style="color: #007800;">$HOME</span><span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa
&nbsp;
<span style="color: #666666; font-style: italic;"># ~/.ssh/config</span>
Host <span style="color: #000000; font-weight: bold;">*</span>
    ForwardAgent <span style="color: #c20cb9; font-weight: bold;">yes</span></pre>
</div>
</div>
</li>
<li>Come up with something else.</li>
</ol>
<p>What we really wanted was a way to allow password-based access to the repositories. Since gitolite does not support this itself, we had to come up with another way. As it turns out, doing so is not too bad, though it does involve a little bash shell black magic.</p>
<p>What we came up with is creating a system user on the git server for each developer who wants password access to git repositories, using a custom script as their defined shell (instead of /bin/sh or /bin/bash). Don&#8217;t forget to make your new script executable.</p>
<p>This script needs to look at what the user is trying to do (git action, gitolite ADC, some random shell command, nothing&#8230;) and act accordingly. Here&#8217;s the script we came up with, which will be dissected below to explain what each part does in more detail than the inline doc (<a href="https://gist.github.com/847755">gist</a>).</p>
<div class="wp_syntax">
<div class="code">
<pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #7a0874; font-weight: bold;">shift</span> <span style="color: #666666; font-style: italic;"># get rid of -c</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># if no commands, just open a shell</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$#</span> <span style="color: #660033;">-eq</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">bash</span> <span style="color: #660033;">-l</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># if the first arg is a git- command, that means it is something like git-push, etc... so forward it</span>
<span style="color: #000000; font-weight: bold;">elif</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$1</span> == git-<span style="color: #000000; font-weight: bold;">*</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #660033;">-q</span> <span style="color: #660033;">-o</span> <span style="color: #007800;">UserKnownHostsFile</span>=<span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null <span style="color: #660033;">-o</span> <span style="color: #007800;">StrictHostKeyChecking</span>=no <span style="color: #c20cb9; font-weight: bold;">git</span><span style="color: #000000; font-weight: bold;">@</span>localhost <span style="color: #007800;">$*</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># if the first arg is SET_ENV_ONLY, we sourced this file in order to set up the gitolite function</span>
<span style="color: #000000; font-weight: bold;">elif</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$1</span> == <span style="color: #ff0000;">&quot;SET_ENV_ONLY&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
        gitolite <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
                <span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #660033;">-q</span> <span style="color: #660033;">-o</span> <span style="color: #007800;">UserKnownHostsFile</span>=<span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null <span style="color: #660033;">-o</span> <span style="color: #007800;">StrictHostKeyChecking</span>=no <span style="color: #c20cb9; font-weight: bold;">git</span><span style="color: #000000; font-weight: bold;">@</span>localhost <span style="color: #007800;">$*</span>
        <span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># if there is at least one non-git command, source this file in a new shell and create the 'gitolite' function</span>
<span style="color: #000000; font-weight: bold;">else</span>
        <span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">bash</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;source $0 shiftme SET_ENV_ONLY; $*&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre>
</div>
</div>
<p>If the user is not trying to <em>do</em> anything (just wants to open a shell), then there are no arguments and we should just open a bash prompt:</p>
<div class="wp_syntax">
<div class="code">
<pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$#</span> <span style="color: #660033;">-eq</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">bash</span> <span style="color: #660033;">-l</span></pre>
</div>
</div>
<p>Okay, the simple bit is out of the way. Now on to the black magic.</p>
<p>If the user is trying to perform a git command (via git push, etc.) then we create a new SSH session to localhost (remember, this is running on the same server as gitolite) and pass along the commands ($*). Since the user has already logged in, this ssh command will run from their account using their private / public key. The git commands are things like git-receive-pack, git-upload-pack, etc, so we match the first script argument against &#8220;git-&#8221;.</p>
<p>Finally, we don&#8217;t care about validating the host&#8217;s fingerprint (we are already on the host) and there can be no man in the middle (since we are going to localhost), so we can turn off StrictHostKeyChecking. We also don&#8217;t want to print out the various fingerprint messages that SSH will generate when you ignore host keys, so we make the new SSH connection quiet. That&#8217;s it for this block:</p>
<div class="wp_syntax">
<div class="code">
<pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">elif</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$1</span> == git-<span style="color: #000000; font-weight: bold;">*</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #660033;">-q</span> <span style="color: #660033;">-o</span> <span style="color: #007800;">UserKnownHostsFile</span>=<span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null <span style="color: #660033;">-o</span> <span style="color: #007800;">StrictHostKeyChecking</span>=no <span style="color: #c20cb9; font-weight: bold;">git</span><span style="color: #000000; font-weight: bold;">@</span>localhost <span style="color: #007800;">$*</span></pre>
</div>
</div>
<p>I am going to go over the last two pieces in reverse order, because it is easier to follow.</p>
<p>If the user sent some SSH commands that were <strong>not</strong> native git commands, we need to process those commands. So, we will execute the remaining commands in a new bash process.</p>
<p>BUT, what if the user is trying to perform a gitolite command (such as <em>expand</em> or an ADC), what should we do? We can&#8217;t just trust that all commands the user sends will either be a git command or a gitolite command, so we need to set up some more black magic to handle that for us. So the first thing we will do when we open a new bash process to handle the remaining commands is source <strong>this custom script</strong> ($0) with a custom value we made up (SET_ENV_ONLY). That way, if this script executes again we will know it was done by ourselves and we can set up some more magic.</p>
<div class="wp_syntax">
<div class="code">
<pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">else</span>
        <span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">bash</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;source $0 shiftme SET_ENV_ONLY; $*&quot;</span></pre>
</div>
</div>
<p>Finally for the last block.</p>
<p>If our new script is being executed, and the first argument is SET_ENV_ONLY (after <em>shift</em>ing), then it is because we sourced it from our new bash process from the previous step. What we do now is set up a <em>gitolite</em> command which does something very similar to what happens if the user is performing a native git command: it opens an SSH connection to git@host and performs the gitolite commands.</p>
<p>After this has been done, &#8220;gitolite expand&#8221; is the same as &#8220;ssh git@git.company.com expand&#8221;. This makes it so the developer can still run gitolite commands and ADCs, he just has to prefix each command with <em>gitolite</em>. Something like this:</p>
<div class="wp_syntax">
<div class="code">
<pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>DEVELOPER<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">@</span>git.company.com <span style="color: #ff0000;">&quot;gitolite expand; echo <span style="color: #007800;">$PATH</span>; gitolite info&quot;</span></pre>
</div>
</div>
<p>is equivalent to this:</p>
<div class="wp_syntax">
<div class="code">
<pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #c20cb9; font-weight: bold;">git</span><span style="color: #000000; font-weight: bold;">@</span>git.company.com expand
$ <span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>DEVELOPER<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">@</span>git.company.com <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$PATH</span>
$ <span style="color: #c20cb9; font-weight: bold;">ssh</span> <span style="color: #c20cb9; font-weight: bold;">git</span><span style="color: #000000; font-weight: bold;">@</span>git.company.com info</pre>
</div>
</div>
<p>Now you just need to create accounts that use this script as their shell. Each user can add whatever public keys they want to their authorized_keys file, or they can authenticate solely with their password. The only requirement is that their server account has a private / public key generated, and that the public key is added to gitolite.</p>
<div class="wp_syntax">
<div class="code">
<pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">ssh</span> root<span style="color: #000000; font-weight: bold;">@</span>git.company.com
$ useradd <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>custom_gitbash.sh <span style="color: #660033;">-m</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>DEVELOPER<span style="color: #7a0874; font-weight: bold;">&#93;</span>
$ <span style="color: #c20cb9; font-weight: bold;">su</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>DEVELOPER<span style="color: #7a0874; font-weight: bold;">&#93;</span>
$ <span style="color: #c20cb9; font-weight: bold;">ssh-keygen</span> <span style="color: #660033;">-t</span> rsa
$ <span style="color: #c20cb9; font-weight: bold;">cp</span> ~<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>id_rsa.pub ~<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">&#91;</span>DEVELOPER<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">@</span>git.company.com.pub
<span style="color: #666666; font-style: italic;"># add the new public key to the gitolite keydir</span></pre>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://colonelpanic.net/2011/03/enabling-git-access-via-password-authentication-with-gitolite/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

