<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:posterous="http://posterous.com/help/rss/1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>Andrew Cholakian's Blog</title>
    <link>http://blog.andrewvc.com</link>
    <description>Most recent posts at Andrew Cholakian's Blog</description>
    <generator>posterous.com</generator>
    <link href="http://posterous.com/api/sup_update#d1c9aa85b" type="application/json" xmlns="http://www.w3.org/2005/Atom" rel="http://api.friendfeed.com/2008/03#sup"/>
    <atom:link href="http://blog.andrewvc.com/rss.xml" rel="self"/>
    <atom:link href="http://posterous.superfeedr.com" rel="hub"/>
    <item>
      <pubDate>Sun, 12 Feb 2012 21:30:00 -0800</pubDate>
      <title>Check out the new podcast pydanny and myself just started!</title>
      <link>http://blog.andrewvc.com/check-out-the-new-podcast-pydanny-and-myself</link>
      <guid>http://blog.andrewvc.com/check-out-the-new-podcast-pydanny-and-myself</guid>
      <description>
        <![CDATA[<p>
	<p>Pydanny and I just started a new podcast, Silicon Beach Hackercast. We just released our first episode, feedback would be greatly appreciated!</p>
<p>You can checkout the first episode at&nbsp;<a href="http://www.sbhackercast.com/2012/02/12/episode-1-first-podcast.html">http://www.sbhackercast.com/2012/02/12/episode-1-first-podcast.html</a></p>
	
</p>

<p><a href="http://blog.andrewvc.com/check-out-the-new-podcast-pydanny-and-myself">Permalink</a> 

	| <a href="http://blog.andrewvc.com/check-out-the-new-podcast-pydanny-and-myself#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Thu, 01 Dec 2011 23:01:00 -0800</pubDate>
      <title>Experiences with Noir: Taking Clojure Web-Dev to the Next Level</title>
      <link>http://blog.andrewvc.com/getting-started-with-web-development-with-clo</link>
      <guid>http://blog.andrewvc.com/getting-started-with-web-development-with-clo</guid>
      <description>
        <![CDATA[<p>
	<p>If you're interested in getting started with web development in Clojure there's something wrong with you. It's an elegant, fun, infuriating, and enlightening experience. I've spent some of my spare time in the past few weeks building an abstract rock garden in HTML/Canvas backed by Clojure's <a href="http://webnoir.org/">Noir</a> framework at <a href="http://rocksandsand.com">rocksandsand.com</a>&nbsp;(<a href="https://github.com/andrewvc/rocksandsand">source</a>).</p>
<p>I'm really excited by&nbsp;<a href="http://webnoir.org/">Noir</a>&nbsp;as a framework as it's the first Clojure framework that has a strong opinion about a lot of the things that really matter to a productive web framework.</p>
<p>Let's dive in.</p>
<p>Noir's hello world is what you'd expect in a post-sinatra world:</p>
<p>
<script src="https://gist.github.com/1422042.js?file=hellow-noir.clj"></script>
</p>
<p>Where noir really gets interesting is in the tools, convenience, and opinions it brings.</p>
<p>Here's what you get when you first run `lein noir new`. Right here is Noir's first distinction, there's a lein (clojure's main build tool) plugin that will generate a bare-bones Noir app from scratch for you, much like `rails s`.</p>
<p>Noir actively tries to make a bunch of simple web development tasks easy. It's easily the Clojure framework that has the most 'batteries' included. You get things like automatic code-reloading on page refresh, built in lein commands to start up a server in both production and dev mode, a preset folder structure, and a few other such nice opinionated ways of doing things.</p>
<p>Moving on from there, you'll notice your `src` folder contains two folders 'models' and 'views'. Here's where you'll first notice one of Noir's greatest departures from most other web frameworks. There are no controllers by default (you can read the&nbsp;<a href="https://groups.google.com/d/msg/clj-noir/FxipsTEhVtM/l4zX_lY1J5UJ">mailing list thread</a> on why if interested). You wind up with combinations of controllers, views, and routes that--while initially scary--are actually quite elegant. An example of a more complex Noir view:</p>
<p>
<script src="https://gist.github.com/1422042.js?file=complex-view.clj"></script>
</p>
<p>For a small app like Rocks and Sand, this sort of thing works well, it's more reasonable than splitting such stuff across 3 separate files. Whether it scales up to a large app however, is something I'm still on the fence about.</p>
<p>Views in Noir are not mandated to use any particular language, but <a href="https://github.com/weavejester/hiccup">Hiccup</a>&nbsp;is by far the most popular solution, and is one of my all time favorite template languages. And it's nothing but clojure vectors and maps! Here's a quick example:</p>
<p>
<script src="https://gist.github.com/1422042.js?file=hiccup.clj"></script>
</p>
<p>Models in noir are simply straightforward Clojure namespaces, if you want to, noir ships with a validations library you can use with it.</p>
<p>While my experience with Noir is obviously limited I have a list of praises and recommendations for it:</p>
<ul>
<li>Coupling of Routes -&gt; Controllers -&gt; Views is nice for small stuff, I'd probably decouple them more in a larger app. Luckily, if you really want, there's no reason you can't just do that by your own convention. Noir won't get in your way.</li>
<li>Models are really bare bones, but have a nice little validation library. Not as complete as Rails', but quite easily extended</li>
<li>WebSockets are more and more important these days. Tighter integration with <a href="https://groups.google.com/d/msg/clj-noir/FxipsTEhVtM/l4zX_lY1J5UJ">Aleph</a>&nbsp;(defsocket anyone?) would be great. A&nbsp;clojure framework that supports building combination synchronous / asynchronous apps would be awesome. While this is possible, the sugar that Noir's brought to Compojure could be extended to Aleph.</li>
<li>The integrated util packages (S3, App Engine, Crypt, Etc.) are awkward and should be in separate jars.</li>
<li>The ecosystem is still immature.I can still get more functionality out of Rails per hour due to its great community. However, for side-projects I'll be using noir. Additionally, for data-heavy web-services (like a JSON only backend) something like Noir is great!</li>
<li>I wound up writing my own JSON based configuration package. Config files are part of every real web-app, and I think a good config package (preferably with deployment environment (prod/staging/dev) built in.</li>
</ul>
<p>All in all Noir is exactly what Clojure's been needing to move to the next level in the world of web-apps. It's a beautiful framework, with a few odd opinions, but in generally it's a great way to get a small web-app off the ground. I'd recommend getting started by checking out the <a href="http://webnoir.org/">Noir homepage</a>, and maybe even diving into the <a href="https://github.com/andrewvc/rocksandsand">source</a>&nbsp;my rock garden app.</p>
	
</p>

<p><a href="http://blog.andrewvc.com/getting-started-with-web-development-with-clo">Permalink</a> 

	| <a href="http://blog.andrewvc.com/getting-started-with-web-development-with-clo#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Sat, 26 Nov 2011 10:59:00 -0800</pubDate>
      <title>You Can't Hack Photography</title>
      <link>http://blog.andrewvc.com/you-cant-hack-photography</link>
      <guid>http://blog.andrewvc.com/you-cant-hack-photography</guid>
      <description>
        <![CDATA[<p>
	<p>I hack on code, I don't hack on photography.</p>
<p>Engineers tend to pick photography as a hobby over other art forms because it's so technical, and for this terrible reason it generally it winds up a confused train wreck.</p>
<p>This was motivated to write this by today's <a href="http://posterous.com/posts/new/670799?polyominoes">post</a>&nbsp;on <a href="http://news.ycombinator.com/item?id=3279775">hacker news</a>&nbsp;where Peter Norvig gives an intro to photography. Turning photography into a technical hobby is something I find agonizingly painful to watch.</p>
<p>On a technical level, Peter's photo tutorial's concise, accurate, and extremely clear. I couldn't have written a better one myself, it's a great resource. What it's missing however is perspective.</p>
<p>Engineers who become photographers generally spend an outsized amount of time making their images sharp, have true color, be adequately lit, etc. It's like audiophiles who listen to their stereo system but not the music.</p>
<p>When it comes to photography, engineers spend a disproportionate amount of time following compositional rules, shooting photos with straightforward narratives, and thinking about their photos as bullet points of technique before, during, and after shooting. It's as if the aim is for an acceptable, homogeous pastiche with the consistency of oatmeal.</p>
<p>What makes photos interesting? Well, that's the eternal question, but I'll say this, a perfectly clear, crisp, balanced photo is just a tool. The magic is up to you.</p>
<p>I'm not going to lay out the details like the engineer in me would, because the engineer in me has no idea what he's talking about. He might describe a formula for success in nine steps mentioning fibonacci, the golden ratio, the rule of thirds, etc., but that'd be a lie.</p>
<p>I'm just going to say, go out there and find photos that move you (and don't make yourself be moved, wait for it), and take as many photos as you can till you find a message in your own photos that means something to you.</p>
<p><a href="http://www.andrewvc.com">My own photos</a> aren't that great, but I understand my photos as a reflection of myself, they're deeply personal in terms of representing my point of view, and they give me a tremendous amount of personal satisfaction. That's what motivates me, the effect of my photos, not the SNR of my CCD.</p>
<p>I would say that it's richest to find photography as an experience and a method of communication.</p>
<p><span style="font-size: x-small;">Addendum:</span></p>
<p><span style="font-size: x-small;">Lastly, i'd like to apologize to Peter for being a prick about this. Peter's a brilliant, and inspirational developer, and personally I could only hope to have a fraction of his contribution to humanity throughout my life, but super-technical internet photo tutorials tend to have this effect on me, and this one just happened to catch me when I was sick, at home, with not much else to do.</span></p>
<p><span style="font-size: x-small;">And to be fair, if your aim is simply photos of your kids to look at as time passes, there's nothing wrong there, but it's just not in my DNA to truly understand investing time in an art like photography with such a cold eye toward the medium itself.</span></p>
	
</p>

<p><a href="http://blog.andrewvc.com/you-cant-hack-photography">Permalink</a> 

	| <a href="http://blog.andrewvc.com/you-cant-hack-photography#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Thu, 28 Jul 2011 00:56:00 -0700</pubDate>
      <title>Clockwork from Rake</title>
      <link>http://blog.andrewvc.com/clockwork-from-rake</link>
      <guid>http://blog.andrewvc.com/clockwork-from-rake</guid>
      <description>
        <![CDATA[<p>
	<p>Clockwork's an awesome gem, but using it via its funky wrapper I'm not so nuts about. Here's how to use it from Rake.</p>
<p><div class="data type-ruby">
      <table class="lines" cellspacing="0" cellpadding="0">
        <tr>
          <td>
            <pre class="line_numbers"><span rel="#L1" id="L1">1</span>
<span rel="#L2" id="L2">2</span>
<span rel="#L3" id="L3">3</span>
<span rel="#L4" id="L4">4</span>
<span rel="#L5" id="L5">5</span>
<span rel="#L6" id="L6">6</span>
</pre>
          </td>
          <td width="100%">
                <div class="highlight"><pre /><div class="line" id="LC1"><span class="n">task</span> <span class="ss">:clockwork</span> <span class="o">=&gt;</span> <span class="ss">:environment</span> <span class="k">do</span></div><div class="line" id="LC2">&nbsp;&nbsp;<span class="no">Clockwork</span><span class="o">.</span><span class="n">every</span><span class="p">(</span><span class="mi">10</span><span class="o">.</span><span class="n">seconds</span><span class="p">,</span> <span class="s2">&quot;events.update_viewers&quot;</span><span class="p">)</span> <span class="p">{</span></div><div class="line" id="LC3">&nbsp;&nbsp;&nbsp;&nbsp;<span class="no">Resque</span><span class="o">.</span><span class="n">enqueue</span><span class="p">(</span><span class="no">ViewerCountWorker</span><span class="p">)</span></div><div class="line" id="LC4">&nbsp;&nbsp;<span class="p">}</span></div><div class="line" id="LC5">&nbsp;&nbsp;<span class="no">Clockwork</span><span class="o">.</span><span class="n">run</span></div><div class="line" id="LC6"><span class="k">end</span></div></pre></div>
          </td>
        </tr>
      </table>
  </div></p>
	
</p>

<p><a href="http://blog.andrewvc.com/clockwork-from-rake">Permalink</a> 

	| <a href="http://blog.andrewvc.com/clockwork-from-rake#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Sat, 04 Jun 2011 12:34:00 -0700</pubDate>
      <title>Tackling my first Clojure project, a Graphical HTTP Benchmarker</title>
      <link>http://blog.andrewvc.com/tackling-my-first-jlojure-project-a-graphical</link>
      <guid>http://blog.andrewvc.com/tackling-my-first-jlojure-project-a-graphical</guid>
      <description>
        <![CDATA[<p>
	<p>I've been bits of my free time working on <a href="https://github.com/andrewvc/parbench">parbench</a>&nbsp;over the last month, a visual version of the venerable 'ab' (apache-bench) HTTP load testing tool as a way to get up to speed on clojure. It's been a fun project as far as getting up to speed, and I thuoght I'd share what I've learned about clojure and its ecosystem.</p>
<p>Let's walk through the tool first, basically, you run it against an URL like 'ab', and it shows, in real time, your requests being executed. Each horizontal line is a 'user', and each square is a request, it fills from left to right as each user goes through its requests.<div class='p_embed p_image_embed'>
<a href="http://getfile3.posterous.com/getfile/files.posterous.com/temp-2011-06-04/CiCHvuGmpyqiiBkubJFvEBBAmkmGnzgDjBiFxonciaEsqcyhruDnsblepwHn/Screenshot-Parbench.png.scaled1000.png"><img alt="Screenshot-parbench" height="357" src="http://getfile1.posterous.com/getfile/files.posterous.com/temp-2011-06-04/CiCHvuGmpyqiiBkubJFvEBBAmkmGnzgDjBiFxonciaEsqcyhruDnsblepwHn/Screenshot-Parbench.png.scaled500.png" width="500" /></a>
</div>
</p>
<p><span style="font-size: small;"><strong>Structuring the App</strong></span></p>
<p>I'm a ruby programmer by day, and the structure here was a bit different than I'd structure a ruby app, as classes / objects aren't generally used in Clojure code. Rather, the organizing principle is the namespace, and the philosophy behind Clojure is functions operating on core datastructures, or things like defrecord, which, while POJOs in implementation, mimic the core map type.</p>
<p>Clojure has very strong opinions about concurrency, it hasimmutable (persistent) datastructures, software transactional memory, actors, and much more in its bag of tricks. Nothing is mutable in clojure without a fair amount of explicitness. Rather than being encumbering, its actually refreshing, as you spend less time worrying about contention and race conditions.</p>
<p>To get a better feel for how a Clojure program might be built, lets break down parbench. The overall flow of parbench is split into two parts, the http request engine in <a href="https://github.com/andrewvc/parbench/blob/master/src/parbench/benchmark.clj">benchmark.clj</a>&nbsp;and the console and GUI output functions in <a href="https://github.com/andrewvc/parbench/blob/master/src/parbench/displays.clj">displays.clj</a>. A brief overview follows:</p>
<p><strong>benchmark.clj:</strong></p>
<ul>
<li>Initialize a 2d array (vectors actually) of refs, each representing a request. A 'ref' being a wrapper around a persisent datastructure allowing you to change its state in a transaction. Transactions here work almost exactly like database transactions. This is referred to as the 'grid' in parbench.</li>
<li>Each row in the grid is a simulated user-agent, and should execute one request at a time. Each row gets its own backing thread via a Clojure future, which is basically a fancy Java thread. &nbsp;Since I'm using an asynchronous Netty based http-client from <a href="https://github.com/sonatype/async-http-client">Sonatype</a>&nbsp;it is possible, even optimal, to do this all in a single thread rather than thread per-user, but this was more straightforward.</li>
<li>As requests change state, the hashes representing their current state, nested in the grid, are mutated inside a transaction demarcated using dosync.</li>
<li>There's a weird function, block-till-done, that polls the grid and checks to see if all requests are completed, if they are it stops blocking. While this isn't optimal with a bunch of threads, each of which could simply signal when it complete, I went with this method with a previous concurrency model, and its very flexible letting me try out different concurrency models without worrying about housekeeping.</li>
</ul>
<p><strong>displays.clj:</strong></p>
<ul>
<li>The GUI uses <a href="http://processing.org/">processing</a>&nbsp;for display. The UI is initialized before the benchmarks, this is important, as it blocks until its first full render, letting the JVM and UI get pre-warmed so they don't impact results too much.</li>
<li>Due to clojure's refs, the UI always sees the grid in a consistent state, since all mutations to the request refs are transactional inside those dosyncs we spoke about earlier.</li>
<li>The console output uses a java TaskTimer to regularly print output to the terminal, iterating over the datastructures.</li>
</ul>
<p><span style="font-size: medium;"><strong>Impressions of Clojure and the its ecosystem</strong></span></p>
<ul>
<li><strong>It's an active community</strong> with a vibrant, supportive, and fun group of members, which is good, because there's a lot of work to do.</li>
<li><strong>There's a dearth of documentation for libraries.</strong> A lot of the code you'll need is on github, and a lot of it requires diving into the source to figure out the full API. It's somewhat expected in a community this young, but it's a bit of a drag on productivity.</li>
<li><strong>There aren't enough blog posts about Clojure, </strong>problems just aren't that googleable in clojure at the moment. A lot of the common ones are, but a lot of roadblocks require you to roll up your sleeves and experiment.</li>
<li><strong>Sequences, and the functions around them are elegant and powerful,</strong> though there is a bit of a learning curve, it isn't too bad. There are many powerful tools in Clojure to work with sequences, and they are one of the things that makes clojure an absolute joy to work in.</li>
<li><strong>It's all about the datastructures, </strong>while clojure now has more integrated java objects with defrecord and friends, the core data-structures are extremely powerful and easy to use.</li>
<li><strong>Clojure is concise</strong>, though it can become impenetrable at times. This makes breaking up functions extremely important. The same conciseness that gives it its beauty can be its undoing.</li>
<li><strong>You need to know Java.</strong>&nbsp;I'd hoped to learn clojure without learning any Java, it didn't take long to figure out that was a terrible plan, and I had to spend a while learning some basic java first. Clojure leans heavily on java for its library support, and some libraries don't yet have clojure wrappers. Luckily, java interop is so good in Clojure, it isn't an issue to go back and forth most of the time.</li>
<li><strong>Get the <a href="http://joyofclojure.com/">Joy of Clojure</a>,</strong>&nbsp;it's a great book. The online resources for learning Clojure are scattered and hard to piece together into a consistent whole.</li>
</ul>
<p>Overall, Clojure's becoming my free time language of choice because it's concise, expressive, and elegant. It's also a good departure for those coming from more OO languages, and will definitely work different muscles in your brain.</p>
<p>Lastly, I'm pretty new to Clojure, I'm pretty sure parbench's code sucks in myriad ways. Got some ideas as far as improving it? Let me know!</p>
<ul>
</ul>
	
</p>

<p><a href="http://blog.andrewvc.com/tackling-my-first-jlojure-project-a-graphical">Permalink</a> 

	| <a href="http://blog.andrewvc.com/tackling-my-first-jlojure-project-a-graphical#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
      <media:content type="image/png" height="430" width="602" url="http://getfile7.posterous.com/getfile/files.posterous.com/temp-2011-06-04/CiCHvuGmpyqiiBkubJFvEBBAmkmGnzgDjBiFxonciaEsqcyhruDnsblepwHn/Screenshot-Parbench.png">
        <media:thumbnail height="357" width="500" url="http://getfile1.posterous.com/getfile/files.posterous.com/temp-2011-06-04/CiCHvuGmpyqiiBkubJFvEBBAmkmGnzgDjBiFxonciaEsqcyhruDnsblepwHn/Screenshot-Parbench.png.scaled500.png"/>
      </media:content>
    </item>
    <item>
      <pubDate>Thu, 26 May 2011 11:35:38 -0700</pubDate>
      <title>Stevens TCP state diagram at vokle hq!</title>
      <link>http://blog.andrewvc.com/stevens-tcp-state-diagram-at-vokle-hq</link>
      <guid>http://blog.andrewvc.com/stevens-tcp-state-diagram-at-vokle-hq</guid>
      <description>
        <![CDATA[<p>
	<p><div class='p_embed p_image_embed'>
<a href="http://getfile6.posterous.com/getfile/files.posterous.com/andrewvc/ABcgJtlIorxhibEhtlqaGItirexxEadycFriyaDIkGhlHermfEvpDqiGDnkw/2113458782.jpg.scaled1000.jpg"><img alt="2113458782" height="299" src="http://getfile0.posterous.com/getfile/files.posterous.com/andrewvc/ABcgJtlIorxhibEhtlqaGItirexxEadycFriyaDIkGhlHermfEvpDqiGDnkw/2113458782.jpg.scaled500.jpg" width="500" /></a>
</div>
</p>I had some free time to finally draw this.
	
</p>

<p><a href="http://blog.andrewvc.com/stevens-tcp-state-diagram-at-vokle-hq">Permalink</a> 

	| <a href="http://blog.andrewvc.com/stevens-tcp-state-diagram-at-vokle-hq#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
      <media:content type="image/jpeg" height="488" width="816" url="http://getfile6.posterous.com/getfile/files.posterous.com/andrewvc/ABcgJtlIorxhibEhtlqaGItirexxEadycFriyaDIkGhlHermfEvpDqiGDnkw/2113458782.jpg">
        <media:thumbnail height="299" width="500" url="http://getfile0.posterous.com/getfile/files.posterous.com/andrewvc/ABcgJtlIorxhibEhtlqaGItirexxEadycFriyaDIkGhlHermfEvpDqiGDnkw/2113458782.jpg.scaled500.jpg"/>
      </media:content>
    </item>
    <item>
      <pubDate>Sat, 21 May 2011 13:53:00 -0700</pubDate>
      <title>Why Not MessagePack?</title>
      <link>http://blog.andrewvc.com/why-arent-you-using-messagepack</link>
      <guid>http://blog.andrewvc.com/why-arent-you-using-messagepack</guid>
      <description>
        <![CDATA[<p>
	<p>JSON is a fantastic format, anywhere people in your organization want to reach for XML, it's always a good thing to ask the question "Why not JSON?". The question I'd like you to ask the next time you're reaching for your JSON hammer, is "Why not MessagePack?".&nbsp;</p>
<p><a href="http://msgpack.org/">MessagePack</a> has the following things going for it when compared to JSON.</p>
<ol>
<li><strong>JSON Compatible</strong>: Anything that works with JSON will work with MessagePack.</li>
<li><strong>More space efficient</strong>: MessagePack uses an extremely efficient binary serialization format, for things like numbers and binary data MessagePack can be hugely more efficient. For use in persisting datastructures in something like Redis, where you want to be careful with memory usage, this is quite useful</li>
<li><strong>Faster</strong>: MessagePack is usually much faster to encode / decode than JSON.</li>
<li><strong>Supports Your Language</strong>: Ruby, Python, Perl, Javascript, PHP, Java, C++, C#,Go, Erlang, Haskell, OCaml, Scala, Clojure, and more all support MessagePack.</li>
<li><strong>RPC</strong>: There's a separate MessagePack RPC project that maintains a high performance MessagePack based RPC server and client available in most of the languages above.</li>
</ol>
<p>For the record, I'd probably still use JSON for a public facing API in most cases, but for internal ones, MessagePack generally wins.</p>
<p>The following example, written in Ruby, illustrates the advantages of MessagePack in action:</p>
<p><div class="data type-ruby">
      <table class="lines" cellspacing="0" cellpadding="0">
        <tr>
          <td>
            <pre class="line_numbers"><span rel="#L1" id="L1">1</span>
<span rel="#L2" id="L2">2</span>
<span rel="#L3" id="L3">3</span>
<span rel="#L4" id="L4">4</span>
<span rel="#L5" id="L5">5</span>
<span rel="#L6" id="L6">6</span>
<span rel="#L7" id="L7">7</span>
<span rel="#L8" id="L8">8</span>
<span rel="#L9" id="L9">9</span>
<span rel="#L10" id="L10">10</span>
<span rel="#L11" id="L11">11</span>
<span rel="#L12" id="L12">12</span>
<span rel="#L13" id="L13">13</span>
<span rel="#L14" id="L14">14</span>
<span rel="#L15" id="L15">15</span>
<span rel="#L16" id="L16">16</span>
<span rel="#L17" id="L17">17</span>
<span rel="#L18" id="L18">18</span>
<span rel="#L19" id="L19">19</span>
<span rel="#L20" id="L20">20</span>
<span rel="#L21" id="L21">21</span>
<span rel="#L22" id="L22">22</span>
<span rel="#L23" id="L23">23</span>
</pre>
          </td>
          <td width="100%">
                <div class="highlight"><pre /><div class="line" id="LC1"><span class="c1"># A typical piece of data</span></div><div class="line" id="LC2"><span class="o">&gt;</span> <span class="n">mixed_data</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;id&quot;</span><span class="o">=&gt;</span><span class="mi">18929882</span><span class="p">,</span> <span class="s2">&quot;title&quot;</span><span class="o">=&gt;</span><span class="s2">&quot;Lorem Ipsum&quot;</span><span class="p">,</span> <span class="s2">&quot;author&quot;</span><span class="o">=&gt;</span><span class="s2">&quot;Sit Dolor&quot;</span><span class="p">}</span></div><div class="line" id="LC3"><span class="c1"># JSON stores the data in a reasonable amount of space...</span></div><div class="line" id="LC4"><span class="o">&gt;</span> <span class="n">mixed_data</span><span class="o">.</span><span class="n">to_json</span><span class="o">.</span><span class="n">length</span></div><div class="line" id="LC5"><span class="o">=&gt;</span> <span class="mi">58</span> </div><div class="line" id="LC6"><span class="c1"># But messagepack does much better</span></div><div class="line" id="LC7"><span class="o">&gt;</span> <span class="no">MessagePack</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="n">mixed_data</span><span class="p">)</span><span class="o">.</span><span class="n">length</span></div><div class="line" id="LC8"><span class="o">=&gt;</span> <span class="mi">44</span> </div><div class="line" id="LC9"><span class="c1"># That&#39;s a pretty big difference! But its even more efficient with numbers</span></div><div class="line" id="LC10"><span class="o">&gt;</span> <span class="n">numerical_array</span> <span class="o">=</span> <span class="o">[</span><span class="mi">1223</span><span class="p">,</span> <span class="mi">2190</span><span class="p">,</span> <span class="mi">1980092</span><span class="p">,</span> <span class="mi">8932191892</span><span class="p">,</span> <span class="mi">98321982189</span><span class="o">]</span></div><div class="line" id="LC11"><span class="o">&gt;</span> <span class="n">numerical_array</span><span class="o">.</span><span class="n">to_json</span><span class="o">.</span><span class="n">length</span></div><div class="line" id="LC12"><span class="o">=&gt;</span> <span class="mi">42</span></div><div class="line" id="LC13"><span class="o">&gt;</span> <span class="no">MessagePack</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="n">numerical_array</span><span class="p">)</span><span class="o">.</span><span class="n">length</span></div><div class="line" id="LC14"><span class="o">=&gt;</span> <span class="mi">30</span></div><div class="line" id="LC15"><span class="c1"># Both are pretty fast...</span></div><div class="line" id="LC16"><span class="o">&gt;</span> <span class="no">Benchmark</span><span class="o">.</span><span class="n">measure</span> <span class="p">{</span> <span class="mi">2_000_000</span><span class="o">.</span><span class="n">times</span> <span class="p">{</span> <span class="n">mixed_data</span><span class="o">.</span><span class="n">to_json</span><span class="p">}</span>  <span class="p">}</span></div><div class="line" id="LC17">&nbsp;<span class="o">=&gt;</span>  <span class="mi">12</span><span class="o">.</span><span class="mi">550000</span>   <span class="mi">0</span><span class="o">.</span><span class="mo">040000</span>  <span class="mi">12</span><span class="o">.</span><span class="mi">590000</span> <span class="p">(</span> <span class="mi">12</span><span class="o">.</span><span class="mi">567510</span><span class="p">)</span></div><div class="line" id="LC18"><span class="c1"># But message pack is faster...</span></div><div class="line" id="LC19"><span class="no">Benchmark</span><span class="o">.</span><span class="n">measure</span> <span class="p">{</span> <span class="mi">2_000_000</span><span class="o">.</span><span class="n">times</span> <span class="p">{</span> <span class="no">MessagePack</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="n">mixed_data</span><span class="p">)}</span>  <span class="p">}</span></div><div class="line" id="LC20">&nbsp;<span class="o">=&gt;</span>   <span class="mi">3</span><span class="o">.</span><span class="mi">250000</span>   <span class="mi">0</span><span class="o">.</span><span class="mo">020000</span>   <span class="mi">3</span><span class="o">.</span><span class="mi">270000</span> <span class="p">(</span>  <span class="mi">3</span><span class="o">.</span><span class="mi">253008</span><span class="p">)</span></div><div class="line" id="LC21"><span class="c1"># They&#39;re compatible as well...</span></div><div class="line" id="LC22"><span class="o">&gt;</span> <span class="no">JSON</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">mixed_data</span><span class="o">.</span><span class="n">to_json</span><span class="p">)</span> <span class="o">==</span> <span class="no">MessagePack</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="no">MessagePack</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="n">mixed_data</span><span class="p">))</span></div><div class="line" id="LC23"><span class="c1"># So, use MessagePack!</span></div></pre></div>
          </td>
        </tr>
      </table>
  </div></p>
<p>For more info, check out the <a href="http://msgpack.org/">Message Pack Website</a>.</p>
	
</p>

<p><a href="http://blog.andrewvc.com/why-arent-you-using-messagepack">Permalink</a> 

	| <a href="http://blog.andrewvc.com/why-arent-you-using-messagepack#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Fri, 20 May 2011 11:06:00 -0700</pubDate>
      <title>Byobu is Beautiful!</title>
      <link>http://blog.andrewvc.com/byobu-is-beautiful</link>
      <guid>http://blog.andrewvc.com/byobu-is-beautiful</guid>
      <description>
        <![CDATA[<p>
	<p>Loving byobu terminal for dev at the moment. It's like a super-nice, and sanely configured screen.<div class='p_embed p_image_embed'>
<a href="http://getfile1.posterous.com/getfile/files.posterous.com/temp-2011-05-20/EaszdjwcxbCxsibHBmqJcmpeqvdtuDsHcDgvbAIEsnixikcyurHynjesvolj/byobu.png.scaled1000.png"><img alt="Byobu" height="374" src="http://getfile2.posterous.com/getfile/files.posterous.com/temp-2011-05-20/EaszdjwcxbCxsibHBmqJcmpeqvdtuDsHcDgvbAIEsnixikcyurHynjesvolj/byobu.png.scaled500.png" width="500" /></a>
</div>
</p>
	
</p>

<p><a href="http://blog.andrewvc.com/byobu-is-beautiful">Permalink</a> 

	| <a href="http://blog.andrewvc.com/byobu-is-beautiful#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
      <media:content type="image/png" height="534" width="713" url="http://getfile3.posterous.com/getfile/files.posterous.com/temp-2011-05-20/EaszdjwcxbCxsibHBmqJcmpeqvdtuDsHcDgvbAIEsnixikcyurHynjesvolj/byobu.png">
        <media:thumbnail height="374" width="500" url="http://getfile2.posterous.com/getfile/files.posterous.com/temp-2011-05-20/EaszdjwcxbCxsibHBmqJcmpeqvdtuDsHcDgvbAIEsnixikcyurHynjesvolj/byobu.png.scaled500.png"/>
      </media:content>
    </item>
    <item>
      <pubDate>Wed, 13 Apr 2011 16:49:00 -0700</pubDate>
      <title>Unicode Chalkpoints</title>
      <link>http://blog.andrewvc.com/unicode-chalkpoints</link>
      <guid>http://blog.andrewvc.com/unicode-chalkpoints</guid>
      <description>
        <![CDATA[<p>
	<p><br />We recently moved to a new office here at <a href="http://www.vokle.com">Vokle</a>, and that means brand new, blank, chalk walls!</p>
<p>I've got a giant chalk wall next to my desk now just waiting to be filled. So, since this wall's in the engineering office, I figured we needed something a little geeky, hence Unicode Chalkpoints!</p>
<p><div class='p_embed p_image_embed'>
<a href="http://getfile6.posterous.com/getfile/files.posterous.com/temp-2011-04-13/ChtqeBDafJiJhuBqaCEsyuqnElmjIlqeBqIlsltHwptsInnFxgbmCEpHnkeA/IMAG0274.jpg.scaled1000.jpg"><img alt="Imag0274" height="836" src="http://getfile8.posterous.com/getfile/files.posterous.com/temp-2011-04-13/ChtqeBDafJiJhuBqaCEsyuqnElmjIlqeBqIlsltHwptsInnFxgbmCEpHnkeA/IMAG0274.jpg.scaled500.jpg" width="500" /></a>
<a href="http://getfile2.posterous.com/getfile/files.posterous.com/temp-2011-04-13/HrsajxJiHmDpeBHgyIufpnmIsjGqlqJejgprszChIEpxFyDJghwtFrzmGvpy/IMAG0277.jpg.scaled1000.jpg"><img alt="Imag0277" height="836" src="http://getfile7.posterous.com/getfile/files.posterous.com/temp-2011-04-13/HrsajxJiHmDpeBHgyIufpnmIsjGqlqJejgprszChIEpxFyDJghwtFrzmGvpy/IMAG0277.jpg.scaled500.jpg" width="500" /></a>
<a href="http://getfile4.posterous.com/getfile/files.posterous.com/temp-2011-04-13/lCygIqeuktBwpIBloikaexjaIkfvuegeskhreplyjGCbbdrefswlmtrugiyc/IMAG0276.jpg.scaled1000.jpg"><img alt="Imag0276" height="836" src="http://getfile1.posterous.com/getfile/files.posterous.com/temp-2011-04-13/lCygIqeuktBwpIBloikaexjaIkfvuegeskhreplyjGCbbdrefswlmtrugiyc/IMAG0276.jpg.scaled500.jpg" width="500" /></a>
<a href="http://getfile3.posterous.com/getfile/files.posterous.com/temp-2011-04-13/tIdpnIaJaojjwpfhtfyetEBwGAnbpAAtHbFmnaJbmzrbyHjitzDyyDbCvmuI/IMAG0278.jpg.scaled1000.jpg"><img alt="Imag0278" height="836" src="http://getfile8.posterous.com/getfile/files.posterous.com/temp-2011-04-13/tIdpnIaJaojjwpfhtfyetEBwGAnbpAAtHbFmnaJbmzrbyHjitzDyyDbCvmuI/IMAG0278.jpg.scaled500.jpg" width="500" /></a>
<a href="http://getfile5.posterous.com/getfile/files.posterous.com/temp-2011-04-13/weobpHDwzupmdfwtcnctjJCCFbxuHCEfqdgkgboxtksEcfJcHczbkffxIuIq/IMAG0279.jpg.scaled1000.jpg"><img alt="Imag0279" height="836" src="http://getfile6.posterous.com/getfile/files.posterous.com/temp-2011-04-13/weobpHDwzupmdfwtcnctjJCCFbxuHCEfqdgkgboxtksEcfJcHczbkffxIuIq/IMAG0279.jpg.scaled500.jpg" width="500" /></a>
<div class='p_see_full_gallery'><a href="http://blog.andrewvc.com/unicode-chalkpoints">See the full gallery on Posterous</a></div>
</div>
</p>
<p>So, let's see what we have here:</p>
<ul>
<li>⚝&nbsp;\u269D, the <a href="http://www.google.com/search?sourceid=chrome&amp;ie=UTF-8&amp;q=coat+of+arms+for+morocco">Coat of Arms for Morocco</a>, well at least according to wikipedia's page on <a href="http://en.wikipedia.org/wiki/Miscellaneous_Symbols_(Unicode_block)">Miscellaneous Unicode Symbols</a>.</li>
<li>⚸ \u26B8, the <a href="http://en.wikipedia.org/wiki/Black_Moon_Lilith#Lilith">Black Moon Lilith</a>, the astrological sign for earth's second moon that turned out to not actually exist.</li>
<li>⚆ \u2686, White Circle With Dot Right. I just like the way this one looks</li>
<li>♾ \u267E, Permanent Paper Sign. This means paper is <a href="http://en.wikipedia.org/wiki/Acid-free_paper">acid-free</a>. Which means it can last for up to 1000 years.</li>
</ul>
	
</p>

<p><a href="http://blog.andrewvc.com/unicode-chalkpoints">Permalink</a> 

	| <a href="http://blog.andrewvc.com/unicode-chalkpoints#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
      <media:content type="image/jpeg" height="3264" width="1952" url="http://getfile1.posterous.com/getfile/files.posterous.com/temp-2011-04-13/ChtqeBDafJiJhuBqaCEsyuqnElmjIlqeBqIlsltHwptsInnFxgbmCEpHnkeA/IMAG0274.jpg">
        <media:thumbnail height="836" width="500" url="http://getfile8.posterous.com/getfile/files.posterous.com/temp-2011-04-13/ChtqeBDafJiJhuBqaCEsyuqnElmjIlqeBqIlsltHwptsInnFxgbmCEpHnkeA/IMAG0274.jpg.scaled500.jpg"/>
      </media:content>
      <media:content type="image/jpeg" height="3264" width="1952" url="http://getfile5.posterous.com/getfile/files.posterous.com/temp-2011-04-13/HrsajxJiHmDpeBHgyIufpnmIsjGqlqJejgprszChIEpxFyDJghwtFrzmGvpy/IMAG0277.jpg">
        <media:thumbnail height="836" width="500" url="http://getfile7.posterous.com/getfile/files.posterous.com/temp-2011-04-13/HrsajxJiHmDpeBHgyIufpnmIsjGqlqJejgprszChIEpxFyDJghwtFrzmGvpy/IMAG0277.jpg.scaled500.jpg"/>
      </media:content>
      <media:content type="image/jpeg" height="3264" width="1952" url="http://getfile0.posterous.com/getfile/files.posterous.com/temp-2011-04-13/lCygIqeuktBwpIBloikaexjaIkfvuegeskhreplyjGCbbdrefswlmtrugiyc/IMAG0276.jpg">
        <media:thumbnail height="836" width="500" url="http://getfile1.posterous.com/getfile/files.posterous.com/temp-2011-04-13/lCygIqeuktBwpIBloikaexjaIkfvuegeskhreplyjGCbbdrefswlmtrugiyc/IMAG0276.jpg.scaled500.jpg"/>
      </media:content>
      <media:content type="image/jpeg" height="3264" width="1952" url="http://getfile4.posterous.com/getfile/files.posterous.com/temp-2011-04-13/tIdpnIaJaojjwpfhtfyetEBwGAnbpAAtHbFmnaJbmzrbyHjitzDyyDbCvmuI/IMAG0278.jpg">
        <media:thumbnail height="836" width="500" url="http://getfile8.posterous.com/getfile/files.posterous.com/temp-2011-04-13/tIdpnIaJaojjwpfhtfyetEBwGAnbpAAtHbFmnaJbmzrbyHjitzDyyDbCvmuI/IMAG0278.jpg.scaled500.jpg"/>
      </media:content>
      <media:content type="image/jpeg" height="3264" width="1952" url="http://getfile4.posterous.com/getfile/files.posterous.com/temp-2011-04-13/weobpHDwzupmdfwtcnctjJCCFbxuHCEfqdgkgboxtksEcfJcHczbkffxIuIq/IMAG0279.jpg">
        <media:thumbnail height="836" width="500" url="http://getfile6.posterous.com/getfile/files.posterous.com/temp-2011-04-13/weobpHDwzupmdfwtcnctjJCCFbxuHCEfqdgkgboxtksEcfJcHczbkffxIuIq/IMAG0279.jpg.scaled500.jpg"/>
      </media:content>
    </item>
    <item>
      <pubDate>Sun, 13 Mar 2011 22:17:00 -0700</pubDate>
      <title>Making life easier with GIT SHAs in your HTTP Headers</title>
      <link>http://blog.andrewvc.com/making-life-easier-with-git-shas-in-your-http</link>
      <guid>http://blog.andrewvc.com/making-life-easier-with-git-shas-in-your-http</guid>
      <description>
        <![CDATA[<p>
	<div style="color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; margin: 8px;">
<p style="color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">Do you know what code is running on your servers? Perhaps someone deployed something in a weird way and circumvented your normal deploy-logging process. Maybe you suspect an application server didn't actually restart. Maybe you just want to know quickly because you're lazy.</p>
<p style="color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">My answer to this question has been adding the Git SHA of the currently running code to the HTTP headers of my app. By doing this, figuring out what's actually running is as simple as a:</p>
<p style="color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 13px;"><code> curl -I http://www.example.net | grep X-GitSHA</code></p>
<p style="color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">Accomplishing this is pretty simple, first, you'll want to run and store the output of:</p>
<p style="color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 13px;"><code> git rev-parse HEAD</code></p>
<p style="color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">in whatever directory your deployed code runs in. This is the fastest, and easiest way to determine the current SHA. In Rails this is easily done in an initializer or application.rb using something like:</p>
<p style="color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 13px;"><code> GIT_SHA = `git rev-parse HEAD`.chomp</code></p>
<p style="color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">Then, just make sure the constant gets inserted as a header. Again, in Rails you could do this with a before_filter in controllers/application_controller.rb</p>
<p style="color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 13px;"><code> headers['X-GitSHA'] = MyApp::Application::GIT_SHA </code></p>
<p style="color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">And you're done! It should just work. Of course there's a million ways to actually do this.</p>
<p style="color: #000000; font-family: Arial, Helvetica, sans-serif; font-size: 13px;">Now that you have this info you can see what code is different between what's deployed and what's on say your master branch with a `git diff`:</p>
<p><code>PROD_SHA=`curl -I http://www.example.net | grep X-GitSHA | cut -d':' -f2` git diff $PROD_SHA...master</code></p>
</div>
<p>Or, you can see what the difference is in terms of commits messages rather than actual lines changed with `git show-branch`</p>
<p>&nbsp;<code>PROD_SHA=`curl -I http://www.example.net | grep X-GitSHA | cut -d':' -f2` git show-branch $PROD_SHA master</code></p>
<p>Lastly, if you need the cache on a resource busted between deploys be it in either HTTP or Memcached, having a GIT_SHA constant available in your app makes it pretty easy to do. Note that this isn't great for a lot of situations where a file may NOT have changed between deploys.</p>
	
</p>

<p><a href="http://blog.andrewvc.com/making-life-easier-with-git-shas-in-your-http">Permalink</a> 

	| <a href="http://blog.andrewvc.com/making-life-easier-with-git-shas-in-your-http#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Sat, 05 Mar 2011 16:06:00 -0800</pubDate>
      <title>Before PostgreSQL, Bruce Momjian wrote an SQL in Shell</title>
      <link>http://blog.andrewvc.com/before-postgresql-bruce-momjian-wrote-an-sql</link>
      <guid>http://blog.andrewvc.com/before-postgresql-bruce-momjian-wrote-an-sql</guid>
      <description>
        <![CDATA[<p>
	<p>Bruce Momjian is best known as a member of the PostgreSQL core team, what most people don't know is that in the early '90s, before he was working on Postgres, he wrote another SQL database.</p>
<p>And he wrote it in shell.</p>
<p>The result, <a href="http://momjian.us/download/">SHQL</a> is a pretty damn cool piece of software. I had an informal chat about it with Bruce a couple weeks ago at SCALE, and just had to write about it. The source is definitely a fun browse because not only is it a cool idea, it's the kind of software that belongs to a specific time. Asking Bruce how he picked shell, he mentioned that it was a language he knew, and that Perl just seemed like it was too heavy at the time.</p>
<p>What's immediately striking about SHQL is its completeness given its mere 760 SLOC. It supports,&nbsp;CREATE, DELETE, DROP, INSERT, SELECT, UPDATE, WHERE, PRINT, EDIT as commands, but has surprising completeness, including UNION and DISTINCT. It even supports a rudimentary form of views, through which you can do a basic sort of joining!</p>
<p>SHQL is not pure shell, it makes heavy use of both awk and grep. For instance, updating a table involves filtering the entire table through awk, directing the output to a tmp file, then replacing the current data file with the new one.</p>
<p>The source is definitely a fun browse, I'd recommend you <a href="http://momjian.us/download/">download</a> the file, and check out the <a href="http://momjian.us/download/shql.1.3.README">README</a> and <a href="http://momjian.us/download/shql.1.3.demo.shql">demo</a> as well!</p>
<p>One install note, on my ubuntu system /bin/sh has a few issues with it, I'd definitely use bash proper to run it. Also, be sure to mkdir -p ~/shql/MYDBNAME.</p>
	
</p>

<p><a href="http://blog.andrewvc.com/before-postgresql-bruce-momjian-wrote-an-sql">Permalink</a> 

	| <a href="http://blog.andrewvc.com/before-postgresql-bruce-momjian-wrote-an-sql#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Fri, 11 Feb 2011 23:27:06 -0800</pubDate>
      <title>Quickly Constantize</title>
      <link>http://blog.andrewvc.com/quickly-constantize</link>
      <guid>http://blog.andrewvc.com/quickly-constantize</guid>
      <description>
        <![CDATA[<p>
	Constantizing in ruby without rails isn&#39;t intuitive. This snippet I whipped up does the trick though.<p /><div><div class="data type-ruby">
      <table class="lines" cellspacing="0" cellpadding="0">
        <tr>
          <td>
            <pre class="line_numbers"><span rel="#L1" id="L1">1</span>
</pre>
          </td>
          <td width="100%">
                <div class="highlight"><pre /><div class="line" id="LC1"><span class="s2">&quot;Net::HTTP&quot;</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;::&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">inject</span><span class="p">(</span><span class="no">Object</span><span class="p">)</span> <span class="p">{</span><span class="o">|</span><span class="n">memo</span><span class="p">,</span><span class="nb">name</span><span class="o">|</span> <span class="n">memo</span> <span class="o">=</span>  <span class="n">memo</span><span class="o">.</span><span class="n">const_get</span><span class="p">(</span><span class="nb">name</span><span class="p">);</span> <span class="n">memo</span><span class="p">}</span></div></pre></div>
          </td>
        </tr>
      </table>
  </div></div>
	
</p>

<p><a href="http://blog.andrewvc.com/quickly-constantize">Permalink</a> 

	| <a href="http://blog.andrewvc.com/quickly-constantize#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Sat, 08 Jan 2011 11:06:00 -0800</pubDate>
      <title>Fiction in Fiction</title>
      <link>http://blog.andrewvc.com/39032216</link>
      <guid>http://blog.andrewvc.com/39032216</guid>
      <description>
        <![CDATA[<p>
	<blockquote class="posterous_medium_quote">In the third act of <em>Hamlet</em>, Shakespeare erects a stage on the stage; the fact that the play enacted there&mdash;the poisoning of a king&mdash;in some way mirrors the primary play suffices to suggest the posibility of infinite involutions. (In an 1840 article, De Quincey observes that the stolid, heavy-handed style of this minor play makes the overall drama that includes it appear, by contrast, more  lifelike. I would add that its essential aim is the opposite: to make reality appear unreal to us.)</blockquote>
<p>-- Jorge Luis Borges, From his essay "When Fiction Lives in Fiction"</p>
	
</p>

<p><a href="http://blog.andrewvc.com/39032216">Permalink</a> 

	| <a href="http://blog.andrewvc.com/39032216#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Thu, 06 Jan 2011 07:58:00 -0800</pubDate>
      <title>LA Hacker News January Meetup</title>
      <link>http://blog.andrewvc.com/la-hacker-news-january-meetup</link>
      <guid>http://blog.andrewvc.com/la-hacker-news-january-meetup</guid>
      <description>
        <![CDATA[<p>
	<p>This month's <a href="http://www.meetup.com/Los-Angeles-Hacker-News/">Los Angeles Hacker News</a>&nbsp;meetup is going to be pretty damn fun. We've got a series of excellent talks at coloft in Santa Monica this month from John Buckman, Aman Gupta, and Giles Bowkett. Check out the <a href="http://www.meetup.com/Los-Angeles-Hacker-News/calendar/15839764/">January Meetup Page</a> for details.</p>
<p>Additionally, we'll probably have another drinkup at Biergarten couple weeks after this meetup.</p>
	
</p>

<p><a href="http://blog.andrewvc.com/la-hacker-news-january-meetup">Permalink</a> 

	| <a href="http://blog.andrewvc.com/la-hacker-news-january-meetup#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Sun, 02 Jan 2011 11:34:00 -0800</pubDate>
      <title>A Journey Through fork(2) and clone(2) with strace(1)</title>
      <link>http://blog.andrewvc.com/fork2-is-dead-long-live-fork-i-mean-clone2</link>
      <guid>http://blog.andrewvc.com/fork2-is-dead-long-live-fork-i-mean-clone2</guid>
      <description>
        <![CDATA[<p>
	<p>While browsing Hacker News today I stumbled across an interesting article with one odd factual error. It claimed that fork(2) is not a system call. Now, the fact that &nbsp;it's fork(2), not fork(3) is a dead giveaway that fork&nbsp;<em>is&nbsp;</em>indeed&nbsp;a system call, however, this lead me down an interesting path exploring how fork is actually implemented in the Linux kernel, and enlightened me quite a bit to the distinction between threads and processes in the Linux Kernel.</p>
<p>So, the first thing I discovered is that fork does not in fact fork anymore. Quoting man 2 fork:</p>
<blockquote>
<p style="margin-top: 8px; margin-bottom: 0px;">Since version 2.3.3, rather than invoking the kernel's fork() system call, the glibc fork() wrapper that is provided as part of the NPTL threading implementation invokes clone(2) with flags that provide the same effect as the traditional system call. The glibc wrapper invokes any fork handlers that have been established using pthread_atfork(3).</p>
</blockquote>
<p>We can actually test this out, and see that this is, in-fact, the case. First, I grepped the linux header unistd_64.h to check what the number the fork system call maps to. Since glibc wraps the fork function around clone() instead, we'll have to call it by number, not name.</p>
<p><div class="data type-text">
      <table class="lines" cellspacing="0" cellpadding="0">
        <tr>
          <td>
            <pre class="line_numbers"><span rel="#L1" id="L1">1</span>
<span rel="#L2" id="L2">2</span>
<span rel="#L3" id="L3">3</span>
<span rel="#L4" id="L4">4</span>
<span rel="#L5" id="L5">5</span>
<span rel="#L6" id="L6">6</span>
<span rel="#L7" id="L7">7</span>
<span rel="#L8" id="L8">8</span>
<span rel="#L9" id="L9">9</span>
<span rel="#L10" id="L10">10</span>
<span rel="#L11" id="L11">11</span>
<span rel="#L12" id="L12">12</span>
<span rel="#L13" id="L13">13</span>
<span rel="#L14" id="L14">14</span>
<span rel="#L15" id="L15">15</span>
<span rel="#L16" id="L16">16</span>
</pre>
          </td>
          <td width="100%">
                <div class="highlight"><pre /><div class="line" id="LC1">#See which number the fork(2) system call actually is</div><div class="line" id="LC2">$ grep fork /usr/include/asm/unistd_64.h     </div><div class="line" id="LC3">#define __NR_fork				57</div><div class="line" id="LC4">__SYSCALL(__NR_fork, stub_fork)</div><div class="line" id="LC5">#define __NR_vfork				58</div><div class="line" id="LC6">__SYSCALL(__NR_vfork, stub_vfork)</div><div class="line" id="LC7"><br /></div><div class="line" id="LC8">#strace shows us that fork is indeed not seen anywhere, just as man 2 fork said</div><div class="line" id="LC9">$  strace -f ruby -e &#39;fork&#39; 2&gt;&amp;1 | egrep -A1 &#39;^(fork|clone)&#39;</div><div class="line" id="LC10">clone(Process 4281 attached</div><div class="line" id="LC11">child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f2b01ad89f0) = 4281</div><div class="line" id="LC12"><br /></div><div class="line" id="LC13">#strace shows us that fork(2) can be called if manually specified</div><div class="line" id="LC14">$ strace -f ruby -e &#39;syscall 57&#39; 2&gt;&amp;1 | egrep -A1 &#39;^(fork|clone)&#39;</div><div class="line" id="LC15">fork(Process 4259 attached (waiting for parent)</div><div class="line" id="LC16">Process 4259 resumed (parent 4258 ready)</div></pre></div>
          </td>
        </tr>
      </table>
  </div></p>
<p>Well, that was interesting, I wondered what `man 2 clone` has to say for itself...</p>
<blockquote class="posterous_medium_quote">clone()  creates  a  new  process, in a manner similar to fork(2).  It is actually a library function layered on top of the underlying        clone() system call, hereinafter referred to as sys_clone.  A description of sys_clone is given towards the end of this page.         Unlike fork(2), these calls allow the child process to share parts of its execution context with the calling process, such as the memory  space,  the  table of file descriptors, and the table of signal handlers.  (Note that on this manual page, "calling process" normally corresponds to "parent process".  But see the description of CLONE_PARENT below.)</blockquote>
<p>We can see that clone is called with the args:</p>
<p><code>"child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f2b01ad89f0)</code></p>
<p>and returns the int thread ID of the child process to the parent. Now, we see here that the child_stack is set to 0, something which is ONLY valid for sys_clone, which will then automatically allocate stack space for the child. The rest of the flags automatically perform some housekeeping referencing the child_tidptr as described below:&nbsp;</p>
<p><strong>CLONE_CHILD_CLEARTID</strong>: Erase child thread ID at location ctid in child memory when the child exits, and do a wakeup on the futex at that address.</p>
<p><strong>CLONE_CHILD_SETTID</strong>: Store child thread ID at location ctid in child memory.</p>
<p><strong>SIGCHLD</strong>: the termination signal sent to the parent when the child dies (in this case SIGCHLD).</p>
<p>You may notice that the child_stack is set to 0, which is a reminder that we've actually called sys_clone, which can take zero as a location for child_stack. Sys clone will automatically allocate stack space for you, as well as automatically start execution at the point it was called from, rather than forcing you to point it at the instruction to start at.&nbsp;</p>
<p>As an aside, at this point you may be asking what a futex is (referenced from CLONE_CHILD_CLEARTID). After a little research I discovered that a futex(7) is a Fast Userspace Mutex which can be used to communicate between processes or threads sharing memory. The thing about futex's is, they can run mostly in userspace, except in the case of contention, in which case a syscall to futex(2) is made to arbitrate.</p>
<p>So, with that in mind lets break down what these flags and see what's happening. First lets look at what the three flags that were specifed do:</p>
<ol>
<li>Store the child thread ID at the address specified by child_tidptr</li>
<li>Issuing a wakeup on the futex (possibly for pthread_atfork, but I'm not sure exactly)</li>
<li>Send SIGCHLD to the parent (notifying the parent the child has exited)</li>
</ol>
<p>There are a couple things missing from this picture however. How about copy on write semantics? If clone is used for both threads and processes, then there should be something about CoW in there. For those of you who may not know about CoW, when you fork a process, linux makes a second copy of the process, but doesn't duplicate its memory, the two processes share memory until one of them writes to a segment of memory, at which point the altered memory is allocated new space, that's only visible to the process that wrote to it. So, forking off copies of a program requires very little memory so long as the children don't alter much memory.</p>
<p>So, there's a flag that controls this:</p>
<p><strong>CLONE_VM:&nbsp;</strong>If CLONE_VM is set, the calling process and the child process run in the same memory space.</p>
<p>As we saw above, this option was&nbsp;<em>not</em>&nbsp;set, so the memory space was cloned. If you read further in man clone, you'll see that leaving CLONE_VM unspecified results in CoW semantics.</p>
<p>There's one other thing missing from this puzzle, clone mostly talks about threads, not processes. Why does the call to clone above create a new process, and what's the difference anyway? Well, it turns out that threads and processes aren't that different under Linux post-NPTL anyway (we'll get into NPTL in just a little bit). To see how this works lets look at another omitted flag to clone:</p>
<p><span style="line-height: 19px;"><strong>CLONE_THREAD:&nbsp;</strong>If CLONE_THREAD is set, the child is placed in the same thread group as the calling process.</span></p>
<p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em;"><span style="line-height: 19px;">Apparently a process is just a thread with its own PID/TGID</span>(Thread Group Identifier)&nbsp;in Linux. Threads are just threads that share a process, and are grouped under a TGID, which is the PID of the process that spawned the threads. I was a bit surprised to see that the traditional notion of a UNIX process now shares an implementation with threads.</p>
<p>&nbsp;</p>
<ol> </ol>
<p>The next question I had is, why even use clone instead of fork? Well, according to the clone man-page NPTL (<a href="http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library">Native Posix Thread Library</a>) provides clone so let's read into that. I hadn't heard of NPTL before, so I thought I'd see what Wikipedia had to say:</p>
<blockquote class="posterous_medium_quote">
<p>Before the 2.6 version of the Linux kernel, processes were the schedulable entities, and there was no real support for threads. However, it did support a system call &mdash; clone &mdash; which creates a copy of the calling process where the copy shares the address space of the caller.</p>
</blockquote>
<p>It goes on to say...</p>
<blockquote>NPTL uses a similar approach to LinuxThreads, in that the primary abstraction known by the kernel is still a process, and new threads are created with the clone()&nbsp;<a href="http://en.wikipedia.org/wiki/System_call" title="System call">system call</a>&nbsp;(called from the NPTL library). However, NPTL requires specialized kernel support to implement (for example) the contended case of synchronisation primitives which might require threads to sleep and wake again. The primitive used for this is known as a&nbsp;<a href="http://en.wikipedia.org/wiki/Futex" title="Futex">futex</a></blockquote>
<p><span style="line-height: 20px; font-family: sans-serif;"> </span></p>
<p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em;">If we look a little further, back in man 2 clone we see:</p>
<blockquote>
<p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em;"><span style="line-height: 19px;">&nbsp;Unlike fork(2), these calls allow the child process to share parts of its execution context with the calling process, such as the mem</span><span style="line-height: 19px;">ory &nbsp;space, &nbsp;the &nbsp;table of file descriptors, and the table of signal handlers. &nbsp;(Note that on this manual page, "calling process" nor</span><span style="line-height: 19px;">mally corresponds to "parent process". &nbsp;But see the description of CLONE_PARENT below.)</span></p>
</blockquote>
<p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em;">So, basically fork really only performs a subset of the functionality of clone. clone(2) is the go-to syscall for creating threads, and since processes are basically a special case of a thread in Linux these days, we may as well use clone instead.</p>
	
</p>

<p><a href="http://blog.andrewvc.com/fork2-is-dead-long-live-fork-i-mean-clone2">Permalink</a> 

	| <a href="http://blog.andrewvc.com/fork2-is-dead-long-live-fork-i-mean-clone2#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Thu, 18 Nov 2010 20:56:00 -0800</pubDate>
      <title>How I Host My Site Using Only S3, CloudFront, and a Few Small Tools</title>
      <link>http://blog.andrewvc.com/how-i-switched-to-using-only-s3-and-cloudfron</link>
      <guid>http://blog.andrewvc.com/how-i-switched-to-using-only-s3-and-cloudfron</guid>
      <description>
        <![CDATA[<p>
	<p>Last night I switched my personal website <a href="http://www.andrewvc.com">andrewvc.com</a>&nbsp;over from Rackspace cloud to AWS. Thanks to some new functionality in Amazon's CloudFront I was able to eliminate having a proper server at all. It is now possible to host a site using just S3 and CloudFront, no EC2 required!</p>
<p>Since my site's static, it's perfectly capable of being hosted using nothing but S3 for asset storage and Cloud Front (CF) for content delivery. Doing so I wound up saving money, and improving my site's load times as well.</p>
<div>
<p />
<div>
<div>If you're interested in implementing this yourself you'll need:</div>
<div>
<ul>
<li>An empty S3 Bucket</li>
<li>A CF distribution for that bucket</li>
<li>A Default Root Object (DRO) for your CF distribution, this sets what gets served on requests for '/'</li>
<li>A method of automatically syncing content to your bucket</li>
<li>A method of expiring content in the CF distribution post-sync</li>
</ul>
</div>
<p />
<div>CF is bit of a pain to get into shape, but once you get things automated it's well worth it. Since I've already done a lot of the hard work, you can probably get going by simply tweaking my scripts.</div>
<p />
<div>First, a quick intro to how S3 and CF work together: One could always host content on S3, send traffic via HTTP using a big, ugly URL like:</div>
<p />
<div>&nbsp;<a href="http://s3-us-west-1.amazonaws.com/andrewvc.com/index.html">http://s3-us-west-1.amazonaws.com/andrewvc.com/index.html</a>.</div>
<p />
<div>However, such URLs aren't suitable for a visitor facing page. CF lets you get rid of the bucket name in the file path (the <a href="http://andrewvc.com">andrewvc.com</a> part in the URL above) and use your own domain instead of s3-region.amazonaws.com. Basically, you can have your own domain map to a specific S3 root. The names are mapped using DNS CNAMEs, and can be easily set in the AWS web console for CF. One downside of CNAMEs is that they only work on subdomains, so, I can't host <a href="http://andrewvc.com">http://andrewvc.com</a> on CF, only <a href="http://www.andrewvc.com">http://www.andrewvc.com</a>. I'm currently using <a href="http://www.no-ip.com">no-ip</a> as &nbsp;DNS host, and they provide an HTTP redirect service for <a href="http://andrewvc.com">http://andrewvc.com</a>, sending traffic there over to the www subdomain.</div>
</div>
<p />
<div>Once you have the CNAME pointing at your CF distribution, you'll want to set the distribution's default root object, which will be your site's homepage. This... isn't so straightforward. You can't use the AWS web console to do that at the moment, however, a number of third party tools, including the free <a href="http://cyberduck.ch/">Cyberduck</a> on OSX make this easy. For more info on doing this see Matt Gibson's blog post on <a href="http://gothick.org.uk/2010/10/26/serving-websites-using-s3-and-cloudfronts-default-root-object/">serving websites using the DRO.</a></div>
<p />
<div>Once you've gotten this far, things get easier. You'll probably want a script that does something similar to the&nbsp;<a href="https://github.com/andrewvc/little_hat/blob/master/sync.rb">script</a>&nbsp;I wrote, which:</div>
<p />
<div><ol>
<li>Generates the static files for my site</li>
<li>Syncs the files to S3 (I used the command line tool&nbsp;<a href="http://s3tools.org/s3cmd">s3cmd</a>&nbsp;).&nbsp;</li>
<li>Optionally invalidates the edge versions of the files at CF points of presence.</li>
</ol></div>
<p />
<div>The last part is very important, as by default CF will hold on to cached files at the edge for <strong>24 hours, </strong>which would pretty much ruin any site. However, there are a couple things you can do about this. One, is setting a shorter expire time on your files in S3. You'll notice that my script sets the Expires header for an hour in the future. I chose an hour because CF will not cache files for shorter durations.</div>
<p />
<div>With CF, you must invalidate each file separately. Since the photos on my site never change, I only invalidate the HTML, JS, and CSS explicitly. One downside here is that the purge takes some time, for 5-10 minutes after issuing an invalidation I saw content flapping between states, so be forewarned that it's not an atomic transition. However, for a rarely modified, and incrementally updated site like mine it's not a significant issue.</div>
<p />
<div>Be warned that you can only have 3 simultaneous 'in progress' invalidation requests (as I said before, they take time to run), and if you invalidate more than 1000 objects a month you'll start getting charged for it (though it's a tiny amount). For these reasons I made the cache invalidation optional, as for most of my updates I'm only syncing new content.</div>
<p />
<div><strong>UPDATE: </strong>I may have been testing the invalidation incorrectly, others haven't seen the issue I describe in the following paragraph.&nbsp;As another warning, be careful with updates if you try this system. There are still some aspects of CF's caching behaviour I'm not sure of. It seems that CF will want to wait a full hour after its last invalidation before it'll do another one. That may be a result of me explicitly setting the Expires header, something I still need to test.&nbsp; I'm not absolutely sure of this, but it seems to be the case that invalidations don't always invalidate immediately. If you aren't OK with this, then I'd say reserve CF for hosting assets only, and version asset changes using different URL paths .</div>
</div>
<p />
<div>And that's it! I have to say I find using only S3 + CF to be a rather elegant solution, despite the few ungainly warts regarding invalidation. If you'd like to see the full source for my site, including the S3 scripts, I have <a href="https://github.com/andrewvc/little_hat">the full source for <a href="http://www.andrewvc.com">www.andrewvc.com</a></a> available on GitHub.</div>
<p />
<div><strong>EDIT: </strong>To those who say this is impractical, you're generally correct, but you're missing the point.</div>
<p />
<div>For my own purposes this works fantastically. However, I'd never deploy a system with this caching behavior on behalf of a client. The potential for an embarassing (or costly) mistake is just too high. However, this is my personal site and this is the kind of stuff I love doing, I love the idea of my site being hosted on a high performance CDN with global points of presence. That's awesome.&nbsp;</div>
	
</p>

<p><a href="http://blog.andrewvc.com/how-i-switched-to-using-only-s3-and-cloudfron">Permalink</a> 

	| <a href="http://blog.andrewvc.com/how-i-switched-to-using-only-s3-and-cloudfron#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Tue, 02 Nov 2010 18:27:00 -0700</pubDate>
      <title>Fun with Extra Funky JS Closures</title>
      <link>http://blog.andrewvc.com/fun-with-extra-funky-js-closures</link>
      <guid>http://blog.andrewvc.com/fun-with-extra-funky-js-closures</guid>
      <description>
        <![CDATA[<p>
	<div>I was pleasantly surprised today to see that&nbsp;<a href="http://github.com/wadey">Wade Simmons (wadey)</a>&nbsp;had added sent me a pull request for adding a package.json file to&nbsp;<a href="http://github.com/andrewvc/node-streamlogger">node-streamlogger</a>, a node.js logging library I wrote earlier this year. I was glad because that must mean it still works well, which is impressive to me given the fast rate of change in node.js. I haven't really used node since then, and the code's lay dormant since may. However, it's worked well in production, and is as feature complete as I believe it will ever need to be, so there isn't much to change really (I'm sure I'll eat those words later) (EDIT: looking back through the code, there are some warts, but it works efficiently and well).</div>
<p />
<div>I actually quite liked writing node-streamlogger, it's extremely simple (only 152 lines, including whitespace) and has hooks into just about every piece of it that's possible. It's also easily configurable. The only thing I don't really like about it was that I never wrote specs for it... but I digress.</div>
<p />
<div>One thing I learned writing it, is <a href="http://www.dustindiaz.com/javascript-curry/">currying</a>. I'll freely admit to having to ask a question about how to do this in #javascript on freenode, and I owe those who answered my question a debt of gratitude.</div>
<p />
<div>The code below is responsible for dynamically generating methods for logging. While the simple route would have been to have a simple function that works like "logger.logAtLevel('warn','message')" (and I do indeed provide this function), it's much nicer to be able to say "logger.warn('message')". This would generally be easy, just define a function for each level, but it had to work with runtime customizable route names. The following code, extracted from <a href="http://github.com/andrewvc/node-streamlogger/blob/master/lib/streamlogger.js#L55">lib/streamlogger.js</a> accomplishes this:</div>
<p />
<p><div class="data type-javascript">
      <table class="lines" cellspacing="0" cellpadding="0">
        <tr>
          <td>
            <pre class="line_numbers"><span rel="#L1" id="L1">1</span>
<span rel="#L2" id="L2">2</span>
<span rel="#L3" id="L3">3</span>
<span rel="#L4" id="L4">4</span>
<span rel="#L5" id="L5">5</span>
<span rel="#L6" id="L6">6</span>
<span rel="#L7" id="L7">7</span>
<span rel="#L8" id="L8">8</span>
</pre>
          </td>
          <td width="100%">
                <div class="highlight"><pre /><div class="line" id="LC1"><span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">logLevel</span> <span class="k">in</span> <span class="k">this</span><span class="p">.</span><span class="nx">levelList</span><span class="p">)</span> <span class="p">{</span></div><div class="line" id="LC2">&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">this</span><span class="p">[</span><span class="nx">logLevel</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">logLevel</span><span class="p">)</span> <span class="p">{</span></div><div class="line" id="LC3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">message</span><span class="p">,</span><span class="nx">callback</span><span class="p">)</span> <span class="p">{</span></div><div class="line" id="LC4">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">this</span><span class="p">.</span><span class="nx">logAtLevel</span><span class="p">(</span><span class="nx">message</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">levelList</span><span class="p">[</span><span class="nx">logLevel</span><span class="p">],</span> <span class="nx">callback</span><span class="p">);</span></div><div class="line" id="LC5">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class="line" id="LC6">&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">})(</span><span class="nx">logLevel</span><span class="p">);</span></div><div class="line" id="LC7">&nbsp;&nbsp;<span class="p">}</span></div><div class="line" id="LC8"><span class="p">});</span></div></pre></div>
          </td>
        </tr>
      </table>
  </div></p>
<p />
<div>It takes a minute to wrap your head around, but it's quite rewarding once you do. One thing about it that is confusing, is that the name logLevel is both the parameter to the outermost anonymous function, and the first argument passed into it.</div>
	
</p>

<p><a href="http://blog.andrewvc.com/fun-with-extra-funky-js-closures">Permalink</a> 

	| <a href="http://blog.andrewvc.com/fun-with-extra-funky-js-closures#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Sat, 30 Oct 2010 22:55:40 -0700</pubDate>
      <title>Tonights hacking: DripDrop now supports routing</title>
      <link>http://blog.andrewvc.com/tonights-hacking-dripdrop-now-supports-routin</link>
      <guid>http://blog.andrewvc.com/tonights-hacking-dripdrop-now-supports-routin</guid>
      <description>
        <![CDATA[<p>
	DripDrop now supports routing, a feature sorely needed for more complex apps. It was pretty easy to implement by using ruby&#39;s singleton class. Here&#39;s the entire implementation:<p /><div><div class="data type-ruby">
      <table class="lines" cellspacing="0" cellpadding="0">
        <tr>
          <td>
            <pre class="line_numbers"><span rel="#L1" id="L1">1</span>
<span rel="#L2" id="L2">2</span>
<span rel="#L3" id="L3">3</span>
<span rel="#L4" id="L4">4</span>
<span rel="#L5" id="L5">5</span>
<span rel="#L6" id="L6">6</span>
<span rel="#L7" id="L7">7</span>
<span rel="#L8" id="L8">8</span>
<span rel="#L9" id="L9">9</span>
<span rel="#L10" id="L10">10</span>
<span rel="#L11" id="L11">11</span>
<span rel="#L12" id="L12">12</span>
<span rel="#L13" id="L13">13</span>
<span rel="#L14" id="L14">14</span>
<span rel="#L15" id="L15">15</span>
<span rel="#L16" id="L16">16</span>
<span rel="#L17" id="L17">17</span>
<span rel="#L18" id="L18">18</span>
</pre>
          </td>
          <td width="100%">
                <div class="highlight"><pre /><div class="line" id="LC1"><span class="c1"># From: http://github.com/andrewvc/dripdrop/blob/master/lib/dripdrop/node.rb</span></div><div class="line" id="LC2"><br /></div><div class="line" id="LC3"><span class="c1"># Defines a new route. Routes are the recommended way to instantiate</span></div><div class="line" id="LC4"><span class="c1"># handlers. For example:</span></div><div class="line" id="LC5"><span class="c1">#</span></div><div class="line" id="LC6"><span class="c1">#    route :stats_pub, :zmq_publish, &#39;tcp://127.0.0.1:2200&#39;, :bind</span></div><div class="line" id="LC7"><span class="c1">#    route :stats_sub, :zmq_subscribe, stats_pub.address, :connect</span></div><div class="line" id="LC8"><span class="k">def</span> <span class="nf">route</span><span class="p">(</span><span class="nb">name</span><span class="p">,</span><span class="n">handler_type</span><span class="p">,</span><span class="o">*</span><span class="n">handler_args</span><span class="p">)</span></div><div class="line" id="LC9">&nbsp;&nbsp;<span class="n">handler</span> <span class="o">=</span> <span class="nb">self</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">handler_type</span><span class="p">,</span> <span class="o">*</span><span class="n">handler_args</span><span class="p">)</span></div><div class="line" id="LC10">&nbsp;&nbsp;<span class="vi">@routing</span><span class="o">[</span><span class="nb">name</span><span class="o">]</span> <span class="o">=</span> <span class="n">handler</span></div><div class="line" id="LC11">&nbsp;</div><div class="line" id="LC12">&nbsp;&nbsp;<span class="c1"># Define the route name as a singleton method</span></div><div class="line" id="LC13">&nbsp;&nbsp;<span class="p">(</span><span class="k">class</span> <span class="o">&lt;&lt;</span> <span class="nb">self</span><span class="p">;</span> <span class="nb">self</span><span class="p">;</span> <span class="k">end</span><span class="p">)</span><span class="o">.</span><span class="n">class_eval</span> <span class="k">do</span></div><div class="line" id="LC14">&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">define_method</span><span class="p">(</span><span class="nb">name</span><span class="p">)</span> <span class="p">{</span> <span class="n">handler</span> <span class="p">}</span></div><div class="line" id="LC15">&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC16">&nbsp;&nbsp;&nbsp;</div><div class="line" id="LC17">&nbsp;&nbsp;<span class="n">handler</span></div><div class="line" id="LC18"><span class="k">end</span></div></pre></div>
          </td>
        </tr>
      </table>
  </div></div> <p /><div>I&#39;ve also written a <a href="http://github.com/andrewvc/dripdrop/blob/master/example/combined.rb">full example</a> showing how to use the new routing syntax.</div><div><br />A new minor point release of the gem will be out within the week, once I&#39;ve been able to test the routing out a bit more to make sure I like the style.</div>
	
</p>

<p><a href="http://blog.andrewvc.com/tonights-hacking-dripdrop-now-supports-routin">Permalink</a> 

	| <a href="http://blog.andrewvc.com/tonights-hacking-dripdrop-now-supports-routin#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Thu, 21 Oct 2010 21:01:00 -0700</pubDate>
      <title>DripDrop bump to 0.3.0: Subclassing,Filtering, Consistency, and Specs</title>
      <link>http://blog.andrewvc.com/dripdrop-bump-to-030-subclassingfiltering-con</link>
      <guid>http://blog.andrewvc.com/dripdrop-bump-to-030-subclassingfiltering-con</guid>
      <description>
        <![CDATA[<p>
	<p>Just released <a href="http://github.com/andrewvc/dripdrop">DripDrop</a> v 0.3.0. The big new features in this release are message <a href="http://github.com/andrewvc/dripdrop/blob/master/example/subclass.rb">subclassing</a> and pub/sub topic filtering, both courtesy of John W. Higgins (<a href="http://github.com/wishdev">wishdev</a>), who did a phenomenal job engineering these features cleanly. The other major change is a revamped argument order for xrep and http servers and clients. These are more consistent with the web socket interface (message as first arg) and really clean up the API.</p>
<p />
<div>Message subclassing is especially exciting because now you're able to send messages with much richer behavior. The javascript API doesn't yet support subclasses explicitly (they just come through as plain DD.Message objects), but support should be forthcoming in the next release.</div>
<p />
<div>On top of all this, we now have more spec coverage! I'll admit the test coverage hasn't been great, since it wasn't baked in, but we're adding it in as we go, and when I have time, I'm trying to fill it in as well. Questions? Comments? I'd love to hear them, either here, on github, or on twitter @andrewvc .</div>
<p />
<div>PS.</div>
<p />
<div>My plans for <a href="http://blog.andrewvc.com/next-steps-for-dripdrop-zeromq-distributed-wo">distributed workers</a> in DripDrop are on hold till I feel the reactor code is well spec'd. Additionally, I think a rails routes style DSL for managing all your socket names in larger apps might be more important. Or maybe it's a terrible idea, it's not quite a fully formed idea yet.</div>
<p />
<div>-- Andrew</div>
	
</p>

<p><a href="http://blog.andrewvc.com/dripdrop-bump-to-030-subclassingfiltering-con">Permalink</a> 

	| <a href="http://blog.andrewvc.com/dripdrop-bump-to-030-subclassingfiltering-con#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Fri, 08 Oct 2010 08:27:53 -0700</pubDate>
      <title>Cleaned up DripDrop Syntax</title>
      <link>http://blog.andrewvc.com/cleaned-up-dripdrop-syntax</link>
      <guid>http://blog.andrewvc.com/cleaned-up-dripdrop-syntax</guid>
      <description>
        <![CDATA[<p>
	I finally found the time to make some important small changes to DripDrop. I cleaned up the syntax quite a bit using instance_eval. The main style differences are as follows:<p /><div><div class="data type-ruby">
      <table class="lines" cellspacing="0" cellpadding="0">
        <tr>
          <td>
            <pre class="line_numbers"><span rel="#L1" id="L1">1</span>
<span rel="#L2" id="L2">2</span>
<span rel="#L3" id="L3">3</span>
<span rel="#L4" id="L4">4</span>
<span rel="#L5" id="L5">5</span>
<span rel="#L6" id="L6">6</span>
<span rel="#L7" id="L7">7</span>
<span rel="#L8" id="L8">8</span>
<span rel="#L9" id="L9">9</span>
<span rel="#L10" id="L10">10</span>
<span rel="#L11" id="L11">11</span>
<span rel="#L12" id="L12">12</span>
<span rel="#L13" id="L13">13</span>
<span rel="#L14" id="L14">14</span>
<span rel="#L15" id="L15">15</span>
<span rel="#L16" id="L16">16</span>
<span rel="#L17" id="L17">17</span>
<span rel="#L18" id="L18">18</span>
</pre>
          </td>
          <td width="100%">
                <div class="highlight"><pre /><div class="line" id="LC1"><span class="c1">#New Style:</span></div><div class="line" id="LC2"><br /></div><div class="line" id="LC3"><span class="no">DripDrop</span><span class="o">::</span><span class="no">Node</span><span class="o">.</span><span class="n">new</span></div><div class="line" id="LC4">&nbsp;&nbsp;<span class="n">addr</span> <span class="o">=</span> <span class="s1">&#39;tcp://127.0.0.1:2222&#39;</span><span class="p">;</span></div><div class="line" id="LC5">&nbsp;&nbsp;<span class="n">zmq_sub</span><span class="p">(</span><span class="n">addr</span><span class="p">,</span><span class="ss">:bind</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">message</span><span class="o">|</span></div><div class="line" id="LC6">&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC7">&nbsp;&nbsp;<span class="n">pub</span> <span class="o">=</span> <span class="n">zmq_pub</span><span class="p">(</span><span class="n">addr</span><span class="p">,</span><span class="ss">:connect</span><span class="p">)</span></div><div class="line" id="LC8">&nbsp;&nbsp;<span class="n">pub</span><span class="o">.</span><span class="n">send_message</span><span class="p">(</span><span class="ss">:name</span> <span class="o">=&gt;</span> <span class="s1">&#39;test&#39;</span><span class="p">,</span> <span class="ss">:body</span> <span class="o">=&gt;</span> <span class="s1">&#39;hi&#39;</span><span class="p">)</span></div><div class="line" id="LC9"><span class="k">end</span><span class="o">.</span><span class="n">start!</span></div><div class="line" id="LC10"><br /></div><div class="line" id="LC11"><span class="c1">#Much better than the old style (which should still work)...</span></div><div class="line" id="LC12"><span class="no">DripDrop</span><span class="o">::</span><span class="no">Node</span><span class="o">.</span><span class="n">new</span> <span class="k">do</span> <span class="o">|</span><span class="n">node</span><span class="o">|</span></div><div class="line" id="LC13">&nbsp;&nbsp;<span class="n">addr</span> <span class="o">=</span> <span class="s1">&#39;tcp://127.0.0.1:2222&#39;</span><span class="p">;</span></div><div class="line" id="LC14">&nbsp;&nbsp;<span class="n">node</span><span class="o">.</span><span class="n">zmq_sub</span><span class="p">(</span><span class="n">addr</span><span class="p">,</span><span class="ss">:bind</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">message</span><span class="o">|</span></div><div class="line" id="LC15">&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC16">&nbsp;&nbsp;<span class="n">node</span><span class="o">.</span><span class="n">pub</span> <span class="o">=</span> <span class="n">zmq_pub</span><span class="p">(</span><span class="n">addr</span><span class="p">,</span><span class="ss">:connect</span><span class="p">)</span></div><div class="line" id="LC17">&nbsp;&nbsp;<span class="n">pub</span><span class="o">.</span><span class="n">send_message</span><span class="p">(</span><span class="no">DripDrop</span><span class="o">::</span><span class="no">Message</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">&#39;test&#39;</span><span class="p">,</span> <span class="ss">:body</span> <span class="o">=&gt;</span> <span class="s1">&#39;hi&#39;</span><span class="p">))</span></div><div class="line" id="LC18"><span class="k">end</span><span class="o">.</span><span class="n">start!</span></div></pre></div>
          </td>
        </tr>
      </table>
  </div></div> <p /><div>I&#39;m finally adding specs to it (Bad... I know). Writing specs for ZeroMQ isn&#39;t necessarily easy due to the fact that some sockets like pub/sub, while working fine in practice, don&#39;t exhibit the &#39;perfect&#39; behavior your test framework wants. Shouldn&#39;t be too bad for the other socket types though.</div>
	
</p>

<p><a href="http://blog.andrewvc.com/cleaned-up-dripdrop-syntax">Permalink</a> 

	| <a href="http://blog.andrewvc.com/cleaned-up-dripdrop-syntax#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/284929/self-by-dad-small.jpg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/users/36zEVLHvk4wx</posterous:profileUrl>
        <posterous:firstName>Andrew</posterous:firstName>
        <posterous:lastName>Cholakian</posterous:lastName>
        <posterous:nickName>andrewvc</posterous:nickName>
        <posterous:displayName>Andrew Cholakian</posterous:displayName>
      </posterous:author>
    </item>
  </channel>
</rss>
