<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Paperless Post Dev Blog]]></title>
  <link href="http://paperlesspost.github.com/atom.xml" rel="self"/>
  <link href="http://paperlesspost.github.com/"/>
  <updated>2013-05-17T12:09:02-04:00</updated>
  <id>http://paperlesspost.github.com/</id>
  <author>
    <name><![CDATA[The Paperless Post Engineering Team]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Ricon|East 2013]]></title>
    <link href="http://paperlesspost.github.com/blog/2013/05/17/ricon-east-2013/"/>
    <updated>2013-05-17T11:43:00-04:00</updated>
    <id>http://paperlesspost.github.com/blog/2013/05/17/ricon-east-2013</id>
    <content type="html"><![CDATA[<p>Earlier this week, <a href="http://twitter.com/mrb_bk">MRB</a> and <a href="http://twitter.com/aq">I</a> attended <a href="http://ricon.io/east.html">Ricon East</a> not that far from Paperless HQ. It was advertised as a &#8220;Distributed Systems Conference&#8221; and that&#8217;s really what it was. It was an awesome experience; The talks were of an extremely high quality and the crowd was full of smart and friendly people. More than anything, I was overwhelmed with all the brilliance and made to feel like a distributed noob (Personally, I love this feeling and it left me with a strong desire to level up). There were a lot of great talks, but here were our favorites:</p>

<h3>Call Me Maybe - Kyle Kingsbury on Partition Tolerance</h3>

<p><a href="http://aphyr.com/media/talk.pdf">Slides</a></p>

<p><a href="http://twitter.com/aphyr">Kyle</a> did an insane amount of work on <a href="https://github.com/aphyr/jepsen">tooling specifically for this talk</a> to simulate network partitions against a number of databases and then calculate data recovery/healing (or lack thereof). The talk highlighted some tightly held misconceptions and really emphasized how databases often ignore the P in CAP in favor of CA.</p>

<h3>Bloom - Neil Conway</h3>

<p><a href="https://dl.dropboxusercontent.com/u/3135088/ricon_bloom.pdf">Slides</a></p>

<p><a href="https://twitter.com/neil_conway">Neil</a> presented the work that he and his colleagues are doing at UC Berkeley on creating a language for writing &#8220;disorderly distributed programs&#8221;. The culmination of the work is <a href="http://www.bloom-lang.net/">Bloom</a> a language embedded in a Ruby gem DSL that allows easy construction of complex distributed programs. Wether or not Bloom is &#8220;production ready&#8221; is irrelevant - the beauty is in how simply it can render these normally very large distributed programs.</p>

<h3>Smarter Caching - Neha Narula</h3>

<p><a href="https://speakerdeck.com/neha/smarter-caching">Slides</a></p>

<p><a href="https://twitter.com/neha">Neha</a> showed off Pequod, an intelligent caching system she has been developing with colleagues at MIT and Harvard. The central idea was moving the idea of joins from the DB layer up into the caching layer. With a Twitter-like system as an example, she showed how simple range GETs into Pequod could be used to fetch and collate data at the cache level without touching the database. Though Pequod is not open source yet, the concepts are very interesting and I&#8217;m sure well see similar implementations in OSS soon.</p>

<h3>Just open a Socket - Sean Cribbs</h3>

<p><a href="https://speakerdeck.com/seancribbs/just-open-a-socket-connecting-applications-to-distributed-systems">Slides</a></p>

<p><a href="https://twitter.com/seancribbs">Sean</a> gave a detailed rundown of how he improved some common problems in TCP client libraries, specifically for the Riak Ruby client. The primary solution/idea was putting load balancing in the client itself. This spoke directly to me as we&#8217;ve been doing a bunch of work on this at PP and Sean&#8217;s ideas were novel and very straight-forward.</p>

<h3>MORE!</h3>

<p>There were so many mind blowing talks at Ricon, I feel bad that I&#8217;m not writing them all out. I&#8217;m sure Basho will publish the videos soon and we&#8217;ll all have a field day. My biggest takeaway from the two days was that, at least in this community, researchers and developers are really starting to work more closely together and the rate at which research is being implemented and integrated into production systems is speeding up. As an implementer, this makes me extremely excited. We have an insane thirst for ideas in this field, and the faster we can test those ideas, the sooner we can solve bigger problems.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[When I Ship]]></title>
    <link href="http://paperlesspost.github.com/blog/2013/03/15/when-i-ship/"/>
    <updated>2013-03-15T12:02:00-04:00</updated>
    <id>http://paperlesspost.github.com/blog/2013/03/15/when-i-ship</id>
    <content type="html"><![CDATA[<p>Lets be clear that as a team we have many theme songs. They range from MOP to Boyz || Men to Culture club to …. I know of few that have struck such a cord (especially with the ops team) as <a href="http://www.youtube.com/watch?v=dZPQdZLyHYE">Da Dip</a>.</p>

<p>I gave a talk a couple of weeks ago where I tried to explain the methodology of Paperless Post&#8217;s culture of shipping. It is sung to the tune of Da Dip: <em>when I ship you ship we ship</em>. You can check out the slides and video below:</p>

<iframe src="http://player.vimeo.com/video/57927630?byline=0&amp;portrait=0" width="500" height="281" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>


<p> <p><a href="http://vimeo.com/57927630">Automate or Die - Aaron Quint</a> from <a href="http://vimeo.com/user9086015">devopsdays</a> on <a href="http://vimeo.com">Vimeo</a>.</p></p>

<script async class="speakerdeck-embed" data-id="f01b9c2043c1013099bd22000a1d0205" data-ratio="1.2994923857868" src="http://paperlesspost.github.com//speakerdeck.com/assets/embed.js"></script>


<p><strong>Also be sure to check out <a href="https://speakerdeck.com/skymob/from-nachos-to-sushi-a-monitoring-love-story">Bethany&#8217;s Talk about Sensu</a></strong></p>

<p>I wanted to explain a little further about our process and why I think it&#8217;s been successful. You don&#8217;t have to look far to see or hear people talk about continuous delivery and deployment these days. While I fully believe in the tenants and real benefits of all of these practices and systems, I also feel like everyone is missing the point a bit. When I&#8217;ve talked to people at conferences, meetups, etc, a lot (definitely the majority in my very small and unscientific test group) are excited about the <em>ideas</em> and potential results of implementing any kind of automated deployment system but are frankly lost as to where to begin. Worse, the effort that has to go into building or implementing such a huge system seems insurmountable. I want to say that this shouldn&#8217;t be the case and I think we&#8217;ve proved that at Paperless Post.</p>

<h2>Iterative Devops</h2>

<p>The first assumption that is incorrect about these kind of projects is that it has to be all or nothing. We, and a lot of other teams, when working on our product are most comfortable and successful when taking an iterative approach to shipping features. We split big projects into small deployable steps, look for the 80% solution, and ship one thing at a time. Why then, on the Ops side are we obsessed with silver bullets? Why are we doing large rewrites and replacements of existing infrastructure? For our case we&#8217;ve been able to take the same iterative approach with our developer infrastructure. What I was trying to show in the presentation above was that we didn&#8217;t get to where we are today overnight. Rather, it&#8217;s taken years, and most importantly, each step was worthwhile and an improvement. We&#8217;ve been benefiting since the beginning with even the most simple layer of automation that we added years ago. Don&#8217;t wait for the ultimate solution.</p>

<h2>Pick the right problems</h2>

<p>Of course we all want the &#8216;push a button&#8217; ideal of an infrastructure. One click deploys, scaling, beer delivery. However, as DevOps Engineers and Leaders that might not be what is actually needed <em>now</em>. While the end result of all that kind of automation can not be argued with, that doesn&#8217;t mean it&#8217;s the most important problem for your team to solve. At PP, we started with the whining.</p>

<p>It turned out that our developer setup process and our git workflow were actually the most difficult and slow parts of our daily process, and hence what was taking the majority of our dev and ops time. So instead of doing what we wanted first (one click deploys), we focused on the pain points one at a time and made them better. It&#8217;s important to remember what I see a the real goal of DevOps - to support the developers and the product they build. In the talk, I presented a &#8216;DevOps Oath&#8217;:</p>

<blockquote><p>I, [YOU], Do solemnly swear to help developers solve their problems, quickly and without [too many] yak-shaves and make their lives easier, so they can ship code, so that the company can improve, so that we all can be successful. I will do what it takes to avoid repeated tasks, help unblock the blocked, and generally make things work better.</p></blockquote>

<h2>Every team is different</h2>

<p>A big question I get whenever I talk about our devtools or other internal tools is &#8216;is this open source?&#8217; To me that brings up a fundamental point of how I hope people can think about deploying automation into their workflow - every team is different. Even though a lot of people see this as a given, they have no problem grabbing and forcing tools and workflows from other companies and team into their own. This isn&#8217;t to say that OSS isn&#8217;t valuable and doesn&#8217;t have a place in Ops. I really believe, however, that in order to really have a process and tools that work, you need to start with how your team works organically, and then gently apply the tools to that process. Teams are living and breathing organisms, and applying solutions that are too abstract or worse too specific (but in the wrong direction) can be disastrous.</p>

<h2>Keep moving</h2>

<p>Our process and tools continue to evolve as we run into new blockers or new problems. We&#8217;re proud of how far we come, but we know that this is a moving target. Our key to success in this realm has been to just acknowledge that fact, and work with it.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[VDAY 13: A Post Mortem]]></title>
    <link href="http://paperlesspost.github.com/blog/2013/02/17/vday-13-a-post-mortem/"/>
    <updated>2013-02-17T18:46:00-05:00</updated>
    <id>http://paperlesspost.github.com/blog/2013/02/17/vday-13-a-post-mortem</id>
    <content type="html"><![CDATA[<p>Paperless Post does business year round, but we are a company whose traffic and usage patterns are driven by holidays and seasons. This past week included Valentine&#8217;s Day, which historically is one of our busiest days of the year. The interesting thing about Valentine&#8217;s Day for us, compared to other holidays, is that the traffic pattern is completely unique. Our other busiest days are the ones leading up to Christmas, and those are characterized by very high overall traffic and a large number of cards sent to average numbers of people (~60 guests per event). Valentine&#8217;s, however, is a single day with a very high number of senders and only a slightly higher number of receivers &#8211; Valentine&#8217;s cards are predominantly 1-to-1. This means that, while during the rest of the year, most of our infrastructure is dedicated to serving receivers (they make up > 99% of our daily traffic), Valentine&#8217;s puts a huge amount of pressure on our <em>sending</em> infrastructure, more specifically on the creating and rendering of Paperless Post cards.</p>

<p>This Valentine&#8217;s Day, we saw an unpredicted growth in sender traffic and that, combined with some issues I&#8217;ll describe below, led to a cascading series of problems that affected many of our users on a very important day. For most of the day, users were unable to get through the full process of creating and sending a card and, as a company (and a Dev, Ops, and Support Team), we couldn&#8217;t be more apologetic and sorry for how this affected our users.</p>

<p><img src="http://ppgraphiti.s3.amazonaws.com/snapshots/ace4a81ef5a/1360878492220.png" alt="The Raw Magnitude" /></p>

<h3>The Problem</h3>

<p>By 7:25am EST, when our team began to come online, we immediately noticed that cards were taking a longer-than-average time to render, preventing users from sending. This manifests itself to users as &#8220;eternal spinny&#8221; (as users often call it), which is on the page after you&#8217;ve completed designing your card. We poll the server to see if the images for your card have completed rendering. If they have, we show you a sample of the e-mail that will be sent (usually an envelope with the recipient&#8217;s name) with a link to a preview of the card the way a recipient will see it. If the images are not ready, you will see a loading GIF that will refresh once the cards are ready. On a normal day, most users will never see the &#8220;spinny&#8221; as card rendering takes less than 4 seconds total, on average. On this morning, however, cards seemed to never appear. To the user, this perceived &#8220;eternal spinny&#8221; was actually a failure on a number of levels, and that continued through to the late afternoon, resulting in most cards not going out until much later in the day.</p>

<h4>A little background on &#8220;Rendering&#8221;</h4>

<p>When a user saves a card in our design tool, it goes through a multi-step process before the recipient of the card receives it in their inbox and then sees it as a recipient. The basic workflow is as follows:</p>

<ul>
<li>User saves card in design tool</li>
<li>JSON is sent to the server and is serialized into different PostgreSQL tables and relationships</li>
<li>A JSON representation is stored in Redis and enqueued in Redis for &#8220;rendering&#8221;</li>
<li>A server-side &#8220;Renderer&#8221; process picks jobs off the queue and turns the JSON into a visual representation of the card (an image)</li>
<li>The image is put back into a Resque/Redis queue as a Base64-encoded PNG</li>
<li>Resque picks up the image, writes it to a shared NFS storage and writes a pointer to it (called a MediaFile record) to Postgres &#8211; this enqueues another job called &#8220;MediaFileConversion&#8221;</li>
<li>MediaFileConversion takes the rendered PNG and, using ImageMagick, turns the image into a series of differently-sized and -shaped thumbnails and JPGs used across the site and on mobile web</li>
<li>Eventually (about 1 hour later) a &#8220;DiskCleaner&#8221; process comes around and uploads the on-disk files to Amazon S3, marks them as uploaded in Postgres, and then clears the local files from NFS</li>
</ul>


<p>We arrived at this multi-step process over the years and, though it has some faults and slow areas, under normal usage it is more than fast enough. By making different parts of the worfklow have different jobs and responsibilities, we&#8217;ve been able to scale each as needed.</p>

<h4>The Initial Failure</h4>

<p>When we came online on 2/14, the Renderer queue was already backed up, with over 1000 jobs in the queue. Worse, it seemed like it was growing much faster than it was processing. Initially, we worked on bringing up more Renderer processes/boxes (we run a number of these within our datacenter and a number in EC2), but even this was not helping. Something was wrong with the Renderer processes themselves &#8211; even though they were running, they appeared &#8220;red&#8221; in our dashboard. On examination, the processes were indeed still running but, at some point, they stopped picking up jobs. A restart turned them all green again, but one by one they quickly turned back to red and the queue continued to grow. This was almost definitely happening throughout the week and the day before, but we never noticed because 1) our daily # of renders is small comparatively and 2) we alert when the queue grows large and when the processes die but not when they &#8220;disconnect&#8221; in this way.</p>

<p>We began messaging our users through a site-wide alert that creating cards was taking longer than normal. Part of the team divided off and started working feverishly to try to fix the Renderer code that seemed to be causing the disconnections. Unfortunately, before we were able to deploy any changes and because of the way we recently started storing the JSON for the cards in Redis, the queue grew so large that Redis itself filled up and ran out of memory. At 9:48am, it was OOM-killed (by Linux &#8220;out of memory&#8221; process), bringing the entire site down for a few minutes. Because of an issue with our Redis saving/backup strategy when the process auto-restarted, it came up with an older backup, losing our existing queue and a bunch of other realtime data. We deployed a change to our queueing strategy to take the JSON data out of Redis and have the Renderers instead fetch through our HTTP API, but before the deploy finished, the queue filled up again and Redis was OOM-killed again. This time, before we allowed it to restart, we doubled its memory.</p>

<p><img src="http://ppgraphiti.s3.amazonaws.com/snapshots/065632785bc/1361142215241.png" alt="Production Redis Memory Usage" /></p>

<p>At this point, the Renderers were still not staying connected, but we continued to bring up more Resque workers going from our day-to-day scale of 28 processes to 178. We deployed a number of fixes to the Renderer that put layers of rescuing in place so that no matter what part of the process was failing, it would always continue to request the next job. When the last of these was deployed at 3:26pm, the Renderers finally started to pull off jobs quickly and without disconnecting.</p>

<p>Up until then, we continued to deploy a number of changes to our main app to try to reduce the amount of work the Renderers and other workers were doing. We stopped creating thumbnails only used by certain applications and turned down the amount of polling that clients were doing to check for Renderers. We also noticed that API response times were high and increased our Postgres max connections to account for the higher number of worker connections.</p>

<h4>Second Wave</h4>

<p>Now that Renderers were staying alive and quickly pushing through the backlog, the next process to get bogged down was the Resque job/queue responsible for saving the images to disk. We brought up more and more workers to try to deal with the backlog, but noticed diminishing returns because they were all operating on shared storage. The process of bringing up and reassigning new workers, though involving very little actual work/effort from the Ops team (thanks to Chef), unexpectedly consumed a bunch of time. We had to pull resources from other sources (our staging clusters). Also, changing the queue distribution required a HUP/restart of the workers, which meant the queues weren&#8217;t draining as fast as we hoped.</p>

<p>We continued to make changes to try to get the cards to show up faster (changing what images/steps were required for viewing/sending/previewing) &#8211; however, the queue continued to grow. Because, again, we were storing full/large data as part of the queue (this time the rendered images), Redis continued to have problems/get close to capacity. To stem the tide, we stopped the Renderers themselves so that the queue did not continue to grow past Redis&#8217;s capacity.</p>

<p><img src="http://ppgraphiti.s3.amazonaws.com/snapshots/b4c1e5441bb/1360883351625.png" alt="Renderer Queue Size" /></p>

<h4>Third Wave</h4>

<p>By 7pm, we were back to showing cards within a couple of minutes but the third part of the process, the resizing/thumbnailing queue, had over 30K jobs in it. This meant that the number of files were growing on disk because we had diverted resources from our uploading/cleanup queue to the resizing queue. We started to receive alerts for our shared storage as it approached 100%.</p>

<p>We worked quickly to modify our disk cleaner script to be able to work in parallel over multiple boxes. Unfortunately, at 7:50pm, we ran out of disk space on our shared storage, and the jobs to save/render images began to fail. We had to temporarily stop all workers. Once we got the parallelized disk cleaner running, we were able to reclaim enough space to start the workers again. The key was that the (50) disk cleaners were reclaiming space faster then the media jobs were filling it.</p>

<p><img src="http://ppgraphiti.s3.amazonaws.com/snapshots/8b3d4b53560/1360901475285.png" alt="Disk Cleaning" /></p>

<h4>Finally</h4>

<p>By 10:00pm, we were back to &#8220;normal&#8221; and we started to re-enqueue cards/emails/etc. that had not yet been processed or were lost when Redis went down. This took a little over 2 hours and, at 11:30pm, we were able to send out an apology email to our affected users. After a very rough day (to say the least), we were gratified with the general response from our users:</p>

<blockquote><p>&#8220;That is the nicest apology I&#8217;ve ever received. Happy Valentine&#8217;s Day!&#8221;</p>

<p>&#8220;Thank you so much for your kind response. I am very impressed with your customer service. You offer the best in email stationary and I will continue to be a big fan and customer!!&#8221;</p>

<p>&#8220;Thank you. Admirable response. I already knew you provided a good, user friendly service. And now it&#8217;s clear you follow good business practices. How refreshing!!&#8221;</p>

<p>&#8220;Thank you for the coins. I am a loyal customer and I appreciate the indication that you prize excellent customer experience.&#8221;</p></blockquote>

<h3>Root Cause</h3>

<p>We like to think of ourselves as an ego-less team, and this day really proved it. Wherever you want to point the blame based on the details above, every member of the team clearly felt responsible. We worked together, constantly communicating and trying to keep emotion out of it. Our Support team took the brunt of the user complaints and issues, but at no point did that reflect on how the Dev or Ops teams were treated. Similarly, the Dev/Ops teams were under a huge amount of pressure to &#8220;fix it&#8221; but this pressure was self-inflicted and we did our best to communicate the current status throughout the day.</p>

<p>It&#8217;s hard to point at a real root cause with something like this. We clearly had a number of early failures that took the rest of the day to recover from. The biggest failure, though, was really in planning. We knew this day was coming, but were so focused on shipping all the things that we didn&#8217;t step back to adequately test or prepare. Lesson learned.</p>

<h3>Post-Mortems</h3>

<p>We had two separate post-mortems the day after, one going over the accounts of the day in detail with the Ops and Dev teams, and the other with the management team going over the events at a high level. Both were positive and left us with a large number of next-steps and ways to improve every part of our process.</p>

<h3>Next Steps</h3>

<p>We have a lot to do to ensure something like this never happens again. We&#8217;ve organized the main work under three categories:</p>

<ul>
<li><em>Load and configuration testing</em>

<ul>
<li>We need ways to have automated load tests, because currently we are only really ever testing production load in production.</li>
<li>We also had issues with broken chef recipes that could have been caught earlier by Chef integration testing.</li>
</ul>
</li>
<li><em>Faster deploys/configuration changes</em>

<ul>
<li>Bootstrapping should only take a couple minutes and nodes should &#8220;come up swinging&#8221; without an additional deploy.</li>
<li>Current deploys are O(N), meaning that the more nodes we add, the slower deploys get.</li>
<li>We should be able to reassign/reorganize queues without redeploying Chef or restarting the workers.</li>
</ul>
</li>
<li><em>Optimizing the Renderer pipeline</em>

<ul>
<li>Getting off of shared storage.</li>
<li>Moving other classes of workers (besides Renderers) to EC2.</li>
<li>Giving the renderer more/less responsibility in a live, configurable way.</li>
<li>Moving to a more durable queueing system.</li>
</ul>
</li>
</ul>


<p>On days like this, we&#8217;re thankful not only for our team, but for our users. Having scaling problems like this is generally a good problem to have, and it&#8217;s up to the entire company to improve and rise to the occasion. We knew about some of the problematic areas in our architecture before Valentine&#8217;s, but a crush like this exposed them (as well as new issues) in a clearer way. It&#8217;s our job to catch and fix these before our users do and we continue to make steps toward this goal.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Fast test feedback for Rails 2 with Spin]]></title>
    <link href="http://paperlesspost.github.com/blog/2013/02/12/fast-test-feedback-for-rails-2-with-spin/"/>
    <updated>2013-02-12T18:51:00-05:00</updated>
    <id>http://paperlesspost.github.com/blog/2013/02/12/fast-test-feedback-for-rails-2-with-spin</id>
    <content type="html"><![CDATA[<p>A couple times a year Paperless Post has a <em>Stampy Day</em> (in honor of Stampy &mdash; that&#8217;s him right there in the top-right corner), where the entire company works together to hack on silly, useful, inspiring, experimental (or ideally, all of the above) things. For a recent Stampy Day, I attempted to add the <a href="https://github.com/jstorimer/spin/issues/8">missing Rails 2 support</a> to the <a href="https://github.com/jstorimer/spin">Spin gem</a>.</p>




<p>If you&#8217;re not familiar with Spin, it&#8217;s a great example of how UNIX fundamentals (namely, <code>fork(2)</code>, sockets, and signals) can be applied in Ruby to cleanly and elegantly solve a modern web development problem: making unit testing fast and fun. It does this by starting a Rails process, then forking off each time you wish to run a test. When your test is finished running in the fork and exits, you get to start again with the original and pristine Rails process, ready for your next test.</p>




<p>The gem I developed is named <strong>Rails2Preload</strong>, and is now available on <a href="https://github.com/paperlesspost/rails-2-preload">GitHub</a> and on <a href="https://rubygems.org/gems/rails_2_preload">RubyGems.org</a>. The gem uses Spin&#8217;s hook system to patch the Rails 2 initialization method into two phases: <em>preload</em> and <em>postload</em>. We hope you find it useful! Bug reports, fixes, and contributions are welcome.</p>




<p><em>The author of the Spin gem is <a href="http://www.jstorimer.com/">Jesse Storimer</a>, who&#8217;s also (by no coincidence, I&#8217;m sure!) the author of <a href="http://workingwithunixprocesses.com/">Working With Unix Processes</a>. If you happen to feel like you missed UNIX 101 like me, I&#8217;d recommend it.</em></p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Paperless Post Tech Talks: Mathias Meyer]]></title>
    <link href="http://paperlesspost.github.com/blog/2013/01/02/mathias-meyer-tech-talk/"/>
    <updated>2013-01-02T13:40:00-05:00</updated>
    <id>http://paperlesspost.github.com/blog/2013/01/02/mathias-meyer-tech-talk</id>
    <content type="html"><![CDATA[<p>Today we&#8217;re happy to announce that we&#8217;re starting out our 2013 Tech Talk season with a bang, as we&#8217;re joined by <a href="http://paperplanes.de">Mathias &#8220;@roidrage&#8221; Meyer</a>. Mathias is the author of the Riak Handbook and the Infrastructure Head Honcho at Travis CI, in addition to being one of our favorite technical writers/bloggers in the web operations space right now.</p>

<p><img src="http://farm6.staticflickr.com/5030/5653514417_94976350b9.jpg"></p>

<p>Space is limited and <em>RSVP&#8217;s are required</em>. <a href="http://paperless.ly/YpLazi">Please RSVP here: http://paperless.ly/YpLazi</a></p>

<p>Continue reading for details on his talk, &#8220;Coffee and the Art of Software Maintenance.&#8221;</p>

<!-- more -->


<h3>Coffee and the Art of Software Maintenance</h3>

<p>Coffee is all about two things: simplicity and passion for your craft. I spent a lot of time in coffee shops, talking and listening to baristas about their passion, their craft, about coffee, getting lots of inspiration for my daily work.</p>

<p>Coffee involves two things: building reproducable results, as every coffee brewed should taste just as great as the previous and the next one. The other is getting the customer excited about that precious cup of caffeine-induced ooze and how it came about.</p>

<p>This talk is an exploration of what makes for a great cup of coffee and how really caring about getting the next cup at least just as great makes you a better developer and even better at making customers happy.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[2012: A Year of Lessons]]></title>
    <link href="http://paperlesspost.github.com/blog/2012/12/26/2012-a-year-of-lessons/"/>
    <updated>2012-12-26T13:26:00-05:00</updated>
    <id>http://paperlesspost.github.com/blog/2012/12/26/2012-a-year-of-lessons</id>
    <content type="html"><![CDATA[<p>On all fronts it’s been a great year for Paperless Post and we’re really proud of the way we’ve grown our team, our product, and our business.  We thought we’d wrap up 2012 by sharing some lessons we’ve learned, along with a dose of some fun numbers we dug up during our end-of-the year retrospectives.</p>

<!-- more -->


<h2>Ops is Dev and Dev is Ops</h2>

<p>This was our first full year with a subteam of Operations developers on our Engineering team. Johnny, Bethany, Dan, Alex, and Vipul have tackled some gigantic projects in 2012, including a data center migration aided by the automation framework they have been building for over a year. Other highlights of their hard work include the full automation of our development environment with Vagrant, an amazingly solid and scalable metrics infrastructure with Sensu and Graphite, and, perhaps most importantly, a collaborative workflow for Operations work that looks and feels very similar to how we develop Product features for our web application. Our Ops team members write Ruby and shell code, participate in Code Reviews with Pull Requests, maintain Issues on GitHub for long running projects, and manage features with great aplomb.</p>

<p>As a consequence of the insane gravitational force of our Ops team&#8217;s awesomeness, Engineers on other subteams are taking Operational concerns into consideration when developing features. They are making changes to the Chef repo for configuration file changes, coordinating after-hours data migrations, and generally sharing the responsibilities that have traditionally been Ops-team-only burdens. This is both a reflection of the excellence of our Engineers and the great work Ops has pulled off. Major props.</p>

<h2>Internal Feedback Rules</h2>

<p>Besides an investment in a full Operations team in 2012, one of our other biggest bets was on a suite of internal tools that our CTO Aaron Quint started writing basically as soon as he started working at Paperless Post in 2010. The approach we have taken will be covered in some detail as some members of our Ops team present at <a href="http://devopsdays.org/events/2012-newyork/program/">DevOps Days 2013 in NYC</a>, but the big lesson is pretty simple, and our statement of it here is hardly novel: Internal Feedback Rules. Do whatever you need to do to shape the data that your application and its environment generate in order to make it more consumable. If your logs are too verbose, fix your logs. If your alerting system is broken, fix it. If you can&#8217;t find the right one, fix your process, or write a new one that fits.</p>

<p>During the last weeks of 2012, we now have alerts in our Development Campfire room if our acceptance tests aren&#8217;t passing in a given browser, alerts in our Operations room if the latency on key pages exceeds a certain threshold, and daily emails sent containing graphs and KPI numbers to anyone in the company who is interested. Our management and Product leadership rely on our developers to record the right numbers, and our developers trust management and Product leadership to help them interpret the results. Data is our common ground, and as we all work together to record, present, and understand it, the entire process improves.</p>

<h2>Community Involvement Works</h2>

<p>Working hard on awesome internal tools is more fun if you can share the outcomes. We have been really happy to be able to send our Engineers to great conferences such as Strange Loop, Rocky Mountain Ruby Conf, JSConf, GoRuCo, RubyConf, and more. We encourage our developers to submit proposals and  we send people to conferences whether they&#8217;re speaking or not. The result has been a lot of information sharing, some great networking, and a chance for us to spread the word about our Engineering team.</p>

<p>Besides sending our team all over the place, we have been using our office space as a meeting ground for groups like <a href="http://www.meetup.com/NYC-Ruby-Women/">NYC Ruby Women</a>, the NYC Chef meetup, and a variety of our own internal tech talks. Having people come to our office for beer and pizza to hear people we admire talk about whatever they want has been an awesome experience. Since we are a group of insanely passionate and dedicated developers our enthusiasm rubs off. It&#8217;s been a lot of fun to see young developers learn from our guests, and we’re psyched that people now think of us as a company that gives back to the dev community.</p>

<h2>Interns Do Not Fetch Coffee</h2>

<p>Our third annual summer internship program helped reinforce what is hopefully by now accepted wisdom: hire interns and get them to actually do things, and both parties will benefit greatly. In addition to travelling to recruit interns, we spend a lot of time putting together the program that they go through once they get here. It&#8217;s easy to grind on the recruiting aspect and say, &#8220;eh, we&#8217;ll figure it out when they get here” but that’s simply a waste of your early investment in finding good interns. Having a program ready that involves as much of your company (yes, not just your engineering team) as possible is the easiest way to reach a productive place as quickly as possible. We find promising, passionate students, teach them as much as we can, give them as many chances to be successful as they can, and then sit back and watch them ship. <a href="http://dev.paperlesspost.com/blog/2012/09/27/paperless-post-summer-intern-recap/">We blogged about the interns experiences here</a> and we can&#8217;t wait to get our new crop in in early Summer 2013.</p>

<h2>Embrace New Languages and Frameworks</h2>

<p>Our main web application codebase celebrated its 4th birthday this year (oh commit 65ac5ab, you seem so long ago). Since four internet years equals around 400 human years, a lot has changed in the interim. Frameworks change, traffic changes, products change, developers change. One of the most important lessons we re-learned in 2012 was that new is not bad. We&#8217;ve tried to embrace technologies that will make it easier for us to maneuver our way towards our goals in 2013. This year we&#8217;ve introduced a network service using the Go programming language, moved towards Grunt and other modern JS frameworks for managing our JavaScript code, employed KSS and other modern style frameworks for our CSS, and of course hacked lovingly on our Campfire bot that is written in Node.js. We&#8217;ve managed to avoid &#8216;the big rewrite&#8217; by integrating new tools as they are necessary, and it has paid off. Do yourself a favor and kill that three-year-old code that is causing you and your team a lot of stress. It will pay off in the end.</p>

<h2>2012: The Year In Some Numbers</h2>

<p>Finally, here are some great figures that sum up our awesome year. Thanks for reading our Engineering blog this year, we hope to hear from you soon!</p>

<ul>
<li>Unique animated gifs posted in Campfire: 3,208</li>
<li>Unique metrics stored in Graphite: ~250,000</li>
<li>Most individual user-generated cards sent in a single week: ~2 million</li>
<li>Registered user growth over December 2011: 211% (3.1x)</li>
<li>Revenue growth over December 2011: 135% (2.3x)</li>
<li>Number of commits to main app git repo: 44,545</li>
<li>Number of commits to chef git repo: 4,447</li>
<li>Peak traffic served: ~300 Mbps</li>
<li>Number of production deploys across applications: 1,631</li>
<li>Number of staging deploys accross applications: 10,600</li>
</ul>


<p><em>Thanks to David Stamm, Michael Hansen, Tarun Chakravorty, and Alexa Hirschfeld for help with the above numbers</em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Paperless Post Tech Talks: Alex Payne]]></title>
    <link href="http://paperlesspost.github.com/blog/2012/10/09/alex-payne-tech-talk-october-2012/"/>
    <updated>2012-10-09T16:03:00-04:00</updated>
    <id>http://paperlesspost.github.com/blog/2012/10/09/alex-payne-tech-talk-october-2012</id>
    <content type="html"><![CDATA[<p>Paperless Post&#8217;s series of tech talks will continue at the end of October with a talk by programmer, blogger, and tech leader <a href="http://al3x.net/about.html">Alex &#8220;al3x&#8221; Payne</a>, formerly of Simple and Twitter.</p>

<p><img src="http://files.paperlesspost.com/img/289896666789209127_1860664-20121009-160753.jpg"></p>

<p>Tuesday, October 30th at 7PM</p>

<p>Paperless Post, 151 W. 25th St, 9th Floor, New York, NY</p>

<p>Space is limited and <em>RSVP&#8217;s are required</em>. <a href="http://paperless.ly/VXuyAn">Please RSVP here: http://paperless.ly/VXuyAn</a></p>

<!-- more -->


<p>Alex will be joining us to discuss, in his own words, &#8220;Architectural patterns for bridging multiple languages. In a world where we have an increasing number of highly specialized programming languages, how do we let programmers use the best tool for the job while working in/across teams?&#8221;</p>

<h3>About Alex</h3>

<p>Alex is a programmer, writer, angel investor, and an advisor to several startups. He recently helped launch Simple, an online banking service with a focus on better technology, design, and customer service. Previously, he was Platform Lead at Twitter, and has worked on projects ranging from online campaigns to information security. Alex organizes the annual Emerging Languages conference, a showcase of new programming languages. He co-authored O&#8217;Reilly&#8217;s Programming Scala (2009), and has been writing online for over a decade.</p>

<h3>About Paperless Post Tech Talks</h3>

<p>Paperless Post Tech Talks are our chance to bring developers and artists whom we admire into our New York office to talk and share knowledge about their work with our team and the larger New York tech community. They are open to the public but RSVP is required as space is limited. There will be time to talk and mingle with the other attendees and the speakers over craft beer and snacks.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Summer Intern Recap]]></title>
    <link href="http://paperlesspost.github.com/blog/2012/09/27/paperless-post-summer-intern-recap/"/>
    <updated>2012-09-27T11:31:00-04:00</updated>
    <id>http://paperlesspost.github.com/blog/2012/09/27/paperless-post-summer-intern-recap</id>
    <content type="html"><![CDATA[<p>One of my favorite parts of working at Paperless Post is being involved in our internship program. Each summer for the past three years, we&#8217;ve brought on an increasing number of students who are at various points in their college careers, but have one important thing in common: they want to see how a startup works from the inside. We do everything we can to get these students in front of real work as soon as possible, starting off with a &#8220;bootcamp&#8221; that introduces them to our process and technology stack, and then immediately assigning them to one of our internal teams. We asked two of our interns to talk a bit about what they worked on. They were excited to share and so are we!</p>

<!--more-->


<h3>Caio Lima</h3>

<p>My name is <em>Caio Lima</em>, and I recently finished a four month co-op placement here at Paperless Post. I study Mathematics at the University Waterloo in Canada (birthplace of the frail Blackberry) and I make mobile apps.</p>

<p>Besides learning various ways of making coffee, I have learned an astounding amount of new practices and concepts in software design, all while meeting really cool people and watching the company grow. I have had a few different roles as a member of the PP dev team. For the first month of my co-op term I learned about the architecture and internal workings of their large scale web application and was able to contribute to the project by fixing bugs, streamlining our administrative package creation tool, and ‘JSHint-ing’ part of the code base. For the remaining three months, I learned about design patterns for developing Cocoa applications. The main feature I worked on is the new activity page on the iOS app.</p>

<p>The activity page is where users can view an event’s ‘activity’ and acts as a centralized hub for media and interactivity with your Paperless Post invitation. The page layout differs depending if the viewer is a host or a guest. Hosts and guests can see up to four most recently replied guests, ordered by status, and post comments, but the guest’s view can be limited to the permissions set by the host.</p>

<p>The idea is that this page will eventually get more features or modules and that the layout could change as well, so one of the biggest challenges was setting up the page so that it dynamically generates the UITableView’s data source to make it more malleable and easier for future features to be added. When the UIViewController is loaded, there is a data source array that is constructed to hold the layout of the entire view. It holds arrays of the different data cell types that will go in each slot.</p>

<p><img src="http://files.paperlesspost.com/img/Intern_Blog_Post_draft_-_Google_Docs-20121001-110621.jpg"></p>

<p>Now maybe this was already familiar to some of you, but to me this was new and I think it is pretty darn cool. This feature allows us to generate the structure of the table view with only an array of integers. It is modular, easy to reorganize, and doesn&#8217;t require as much data. When there are many simultaneous tasks, this feature could make a big difference in end user performance.  Kudos to Paperless Post&#8217;s iOS Developer Sal Randazzo for helping me out. This design pattern has really motivated me to look for other ways of implementing designs in Cocoa and I have learned a bunch of cool features in Objective-C. You can also use the activity page feature to post comments to events, which has been successful so far.</p>

<p>Overall, I’m pretty satisfied with how it turned out, happy with how much I learned and pleased with the amount of ‘real stuff’ I accomplished during this co-op term. Time well spent.</p>

<h3>Ryder Moody</h3>

<p>Hey! I&#8217;m <em>Ryder Moody</em>, and I&#8217;m a rising junior at Columbia University in New York City. My work at Paperless Post is on the Accounts/Site Structure team, which means that I get to dig into vastly different parts of the codebase. My background is mostly in Rails and Ruby, but because of my position I&#8217;ve been able to play with tech like Sammy.js, Redis, our API, and Twitter/Facebook integration.</p>

<p>Much of what goes into making a successful web based company is knowing what the users want before they do. While user facing features often get all the attention, some of the most interesting projects I&#8217;ve undertaken at Paperless Post have been things that users would never see or even think about. How do we give them what they want before they ask? At Paperless Post we do lots of analytics, and the more we know about what every user does on the site, the better we can tailor the experience to them. For instance, we know that we need designers to create more cards for wine tastings, yet we&#8217;ve never received an email or phone call expressing this. We know this because I worked on an admin dashboard that gives us the ability to track and see what users are searching for, how many results they get, and when they ran the search. This ensures that our designers don&#8217;t waste their time making cards that nobody is looking for, and that existing cards get tagged with all the appropriate phrases that people search for.</p>

<p>I&#8217;ve also done a lot of work with Google Analytics. We have a robust system that makes it as easy as possible to add tracking to any element of the site. That&#8217;s cool, but figuring out exactly what is tracked and what isn&#8217;t would be cumbersome without a nice interface, so I created the &#8220;Admin Goggles.&#8221;</p>

<p>With one click of a bookmarklet, every tracked element of the site is outlined in red, and by rolling over a link you can see the information that is sent to Google. This removes the guessing from finding Google&#8217;s nice graphs for a particular button, and helps us in our goal of gaining more insight into what users do or don&#8217;t do around the site.</p>

<hr />

<p><em>If you think you&#8217;d be a good fit for our Internship program, get in touch! jobs@paperlesspost.com</em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Metrics Driven]]></title>
    <link href="http://paperlesspost.github.com/blog/2012/09/04/metrics-driven/"/>
    <updated>2012-09-04T10:10:00-04:00</updated>
    <id>http://paperlesspost.github.com/blog/2012/09/04/metrics-driven</id>
    <content type="html"><![CDATA[<p>Over the summer, I&#8217;ve been traveling around a bit speaking at meetups and conferences sharing how Paperless Post thinks about metrics. Its been a fun and interesting experience and not only have I gotten some great feedback, it&#8217;s helped me formulate my thoughts to bring back to the team.</p>

<!--more-->


<p>Most recently, I gave a (more technical) version of the talk at the SF Metrics Meetup which you can watch here:</p>

<iframe src="http://player.vimeo.com/video/45834014?byline=0&amp;portrait=0" width="500" height="281" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>


<p> <p><a href="http://vimeo.com/45834014">Aaron Quint (@aq) talks about metrics at Paperless Post and Graphiti.</a> from <a href="http://vimeo.com/librato">Librato</a> on <a href="http://vimeo.com">Vimeo</a>.</p></p>

<p>and heres just the slides:</p>

<script async class="speakerdeck-embed" data-id="4fedf31c7bd4db001f003f5b" data-ratio="1.299492385786802" src="http://paperlesspost.github.com//speakerdeck.com/assets/embed.js"></script>


<h1>Moving the needle</h1>

<p>At Paperless Post our business is very driven by holidays and seasons. For the past 3 years the months between Sept-Dec are our biggest traffic months by far. Last year we set some very large goals for ourselves and our team. The biggest goal, that we talked about loudly throughout the company was expressed as a big number - N Million Cards sent in December 2011. We got close, really close, but we didn&#8217;t meet the goal. Though we still had a very successful holiday season, the fact that we promised something and failed was really painful. In January, we looked back and tried to analyze what the real failure was and came to some interesting conclusions about the way we were setting goals.</p>

<p>The clearest failure was that everyone felt very little connection to the goal. Though everyone worked their asses off, it was really hard to see how their work was or wasn&#8217;t affecting this big number. No one felt truly empowered to move the needle. The second problem was that the big number itself was actually a conglomeration of a lot of different smaller changes in our numbers and no one change could have produced that goal. Moreover, there were two very different very separate processes at work that would drive total success. We realized if we started to separate them out, they could give so much more clarity to our process.</p>

<h3>Quantity vs Quality</h3>

<p>The two main categories of metrics as we saw them were separated by <em>how</em> and <em>where</em> they changed our totals. If the end goal was growth of the business in general, we realized that we needed to improve in two distinct areas.</p>

<p>Quality metrics measure the quality of the product. This is often what most startups focus on: Adding and refining features and supporting new and existing users. For us, over the past year, it has also been removing and simplifying. Quality metrics are measured in averages of X per Y. For example average Events created by an Account, or average Coins used per Event. Changes to our product, like simplifying the process of creating events can have a great affect on these numbers. We like to think of this as the velocity of our growth.</p>

<p>However, to grow exponentially (as many companies would like to do) you need to add another factor we call Quantity. Quantity is driven by the sheer volume of people going through the product. Quantity metrics are really growth metrics, they are measured in deltas % of X. For example: % of guests registering for accounts, % of visitors to the homepage creating a card. These aren&#8217;t numbers that directly effect our bottom line, instead they drive people <em>into</em> the Quality metrics and the multiplication of the two are what produce the big numbers that let us meet our goals.</p>

<h3>Metrics Driven</h3>

<p>We&#8217;ve tried to shift our process to match these ideas. We want not only the management but <em>everyone</em> to really think about these metrics and push them forward. After breaking down the goals in terms of these smaller consumable deltas in &#8216;rates&#8217; (as opposed to big numbers), we can attach the metrics we want to change to feature specs and issues. This allows us to have clear, measurable goals attached to features.</p>

<h3>Measuring</h3>

<p>Once the goals are set up and the development process begins, we measure throughout the process. We have a ton of different tools for measuring and we like to think about it in two separate categories: Accounting vs Trending. The differences between these two are really stark.</p>

<p>Accounting are raw numbers that are exact and not-real time. They come from our production data and they are used for making decisions and measuring our progress in very specific ways. We have internal scripts to pull our data out of PostgreSQL into what we call <em>The KPIs</em> (Key Performance Indicators). We also use a data-warehousing tool called <a href="http://www.rjmetrics.com/">RJ Metrics</a> to get cohort and other deeper analysis.</p>

<p>Trending is relative data, it is completely devoid of real numbers and is all about deltas and changes over time. It <em>is</em> real time and lets us get feedback directly after deploying new code. We have some custom built dashboards for this and then also use Graphite and <a href="http://github.com/paperlesspost/graphiti">Graphiti</a> (which we have <a href="http://dev.paperlesspost.com/blog/categories/graphiti/">blogged about here</a>).</p>

<p>The difference is we <em>watch</em> the trends, and we <em>study</em> the KPIs.</p>

<h3>Constantly improving</h3>

<p>For this upcoming holiday season, we are going to attempt to still drive our team to put out their truly best effort without setting everyone up to fail. We&#8217;re going to do this by using these different categories of metrics and tools to set smaller achievable goals that each team can actually change. When combined the goal is all the small changes in our growth rates will make this a very successful year.</p>

<p>We&#8217;ve been changing our process continuously over the past couple years and some things have worked and some haven&#8217;t. The point is that we are converging on something that truly works and its exciting. We hope to continue to share our learnings with everyone as we improve.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Paperless Post: Now With Machine Learning!]]></title>
    <link href="http://paperlesspost.github.com/blog/2012/08/31/paperless-post-now-with-machine-learning/"/>
    <updated>2012-08-31T14:34:00-04:00</updated>
    <id>http://paperlesspost.github.com/blog/2012/08/31/paperless-post-now-with-machine-learning</id>
    <content type="html"><![CDATA[<p>Our interface designers came up with several registration form views, but didn&#8217;t know which view would perform the best and wanted to compare them in the field. A/B testing with Google Website Optimizer was kicked around as a solution, but I stumbled across <a href="http://stevehanov.ca/blog/index.php?id=132">this excellent article</a> by Steve Hanov explaining how to easily implement a &#8220;multi-armed bandit&#8221; library (we used more than 20 lines). This article is excellent, and I encourge you to implement something similar on your website if you have multiple UIs and doubts about which is the best.</p>

<!-- more -->


<p>Let&#8217;s say you design three pages. You want to make an objective decision about which page is most likely to cause a user that visits it to take an action that you like. You think all the pages are great, but sadly, there is no magic algorithm or application you can send pictures of your great designs to be graded for performance. That&#8217;s where multi-armed bandit testing comes in. <a href="http://en.wikipedia.org/wiki/Multi-armed_bandit">Wikipedia says</a>: &#8220;The multi-armed bandit problem models an agent that simultaneously attempts to acquire new knowledge and to optimize its decisions based on existing knowledge.&#8221;</p>

<p>We could run an A/B to determine the success rate of the different registration forms. However, we&#8217;d need to leave these views up on our site for a long time to gather data, and probably the results would be inconclusive. Also, we&#8217;d be showing a large portion of our users something that doesn&#8217;t work well. Instead, we decided to use a machine learning algorithm that exploits the results of the test while the test is still being run.</p>

<p>Multi-armed bandit testing works by choosing the &#8220;lever&#8221; with the highest expectation of reward. This means that the registration form with the highest probablity of converting a visitor to a registered user is shown the majority of the time. However, we also stir things up a bit and show a random view 10% of the time. This prevents the test from getting trapped at a local maximum (and also guarantees that we don&#8217;t only show whichever view first converted a visitor).</p>

<p>This strategy has two benefits. First and foremost, we lose the fewest amount of users to UI that isn&#8217;t optimal. After a short initial learning phase, 90% of users are seeing what is currently the best thing you got. Secondly, this serves to verify that the view the system thinks is the best IS actually the best. The test is still running, and gathering data for that particular choice, and it&#8217;s gathering the most data around the best choice. You get a high degree of certainty that your registration form works.</p>

<p>Additionally, if after running the test for a while you want to throw another choice into the mix, you can do so without ruining your results because the data you have gathered for each choice are independent of each other.</p>

<p>We hope to use this more widely across the site. In addition to building a library that makes it easy to store trial and reward data in Redis, we also put the data right on our internal dashboard, so that product owners can place bets on which horse is going to win the race.</p>

<p><img src="http://files.paperlesspost.com/img/bandit-20120904-180235.jpg"></p>

<p>Here are some of the results for the test running on our splash page. In this test we have three choices, &#8220;email&#8221;, &#8220;facebook&#8221;, and &#8220;email_form&#8221;, which represent three different views we&#8217;re displaying to the user. Our implementation yields two statistics for each choice. The first is &#8220;successes&#8221;, which measures the number of times a choice has been rewarded, meaning in this case that a user registered with that view. The second is &#8220;trials&#8221;, which is the total number of times that particular choice has been displayed to a user. Percentage is just a measure of successes over trials, giving us the conversion rate for each individual view.</p>

<p>In this case, &#8220;email&#8221; is the most successful, with a conversion rate of 2.34%. Because it&#8217;s currently the most successful view, it&#8217;s being shown 90% of the time, which accounts for the large number of trials relative to the number of trials for &#8220;facebook&#8221;. Looking at these results, we can tell that at some point in recent history &#8220;email_form&#8221; was the most successful, amassing about 130k trials. This highlights one of the benefits of running multi-armed bandit testing: since &#8220;email_form&#8221; was the most successful, it was subject to increased scrutiny by the system through more trials and ended up not being the best choice after all.</p>

<p>You may work for a big company, but you couldn&#8217;t possibly get your UI in front of more eyeballs without testing like this. 300k users can&#8217;t be wrong!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Paperless Post Tech Talks: David Nolen]]></title>
    <link href="http://paperlesspost.github.com/blog/2012/08/08/paperless-post-tec-talks-david-nolen/"/>
    <updated>2012-08-08T16:42:00-04:00</updated>
    <id>http://paperlesspost.github.com/blog/2012/08/08/paperless-post-tec-talks-david-nolen</id>
    <content type="html"><![CDATA[<p>For our next talk we found one of our favorite NYC developers and technologists, <a href="http://dosync.posterous.com/">David Nolen</a> aka <a href="http://twitter.com/swannodette">@swannodette</a>. We saw David <a href="http://blip.tv/jsconf/jsconf2012-david-nolen-6141386">speak at this year&#8217;s JS Conf</a> and were nodding our heads the entire time. Since then, we&#8217;ve been following his recent forays into logic programming, Lisp, and ClojureScript with great admiration. With that in mind, we&#8217;re very excited to have him share his latest ideas with us.</p>

<p>Thursday, August 23rd 2012 at 7PM</p>

<p>Paperless Post, <br/>
151 W. 25th St., 9th Floor, <br/>
New York, NY</p>

<p>Space is limited and <em>RSVP&#8217;s are required</em>. <a href="http://paperless.ly/S4UhlH">Please RSVP here: http://paperless.ly/S4UhlH</a></p>

<!-- more -->


<h3>Tiny Code</h3>

<p>Alan Kay famously described a half page of code in the Lisp 1.5 Programmer&#8217;s manual as &#8220;Maxwell&#8217;s equations of software&#8221;. If you&#8217;ve ever built a small Lisp interpreter the amount of semantic power is pretty surprising. But the question remains does &#8220;small&#8221; equate with &#8220;toy&#8221;? As engineers we&#8217;re consistently fighting complexity - much complexity comes from the sheer amount of code that we&#8217;re required to manage. Is it inevitable that code loses clarity as it evolves? I&#8217;ve spent nearly two years understanding two pages of code - while I have no definitive conclusions perhaps some of the principles and approaches I&#8217;ve discovered can be applied to software development.</p>

<h3>About David</h3>

<p>David Nolen is a musician and curious programmer living in Brooklyn and currently employed at The New York Times. He has been writing JavaScript applications for nearly seven years, past projects include work for Princeton University, <a href="http://platial.com/" data-bitly-type="bitly_hover_card">platial.com</a>, The Modern Museum of Art, and <a href="http://shiftspace.org" data-bitly-type="bitly_hover_card">shiftspace.org</a>. JavaScript brought him to Lisp and he&#8217;s been closely involved in the Clojure community for about three years. When he has a free moment he gleefully fixes bugs and improves the <a href="http://clojurescriptone.com/" data-bitly-type="bitly_hover_card">ClojureScript</a> compiler in hopes that he can give back something fun to JavaScript.</p>

<h3>About Paperless Post Tech Talks</h3>

<p>Paperless Post Tech Talks are our chance to bring developers and artists whom we admire into our New York office to talk and share knowledge about their work with our team and the larger New York tech community. They are open to the public but RSVP is required as space is limited. There will be time to talk and mingle with the other attendees and the speakers over craft beer and snacks.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Graphiti Tips: Why We <3 S3]]></title>
    <link href="http://paperlesspost.github.com/blog/2012/05/25/graphiti-tips-why-we-love-s3/"/>
    <updated>2012-05-25T12:03:00-04:00</updated>
    <id>http://paperlesspost.github.com/blog/2012/05/25/graphiti-tips-why-we-love-s3</id>
    <content type="html"><![CDATA[<p>We first blogged about <a href="http://github.com/paperlesspost/graphiti">Graphiti</a>, our open source alternate front end to Graphite <a href="http://dev.paperlesspost.com/blog/2011/12/16/introducing-graphiti-an-alternate-frontend-for-graphite/">back in December of 2011</a>, and have been happily using it in production at Paperless Post for about 6 months now. We get a lot of great feedback about Graphiti, mostly positive, but one question comes up a lot about a design choice we made when writing the library: &#8220;Why the dependency on Amazon S3?&#8221;</p>

<p>At first we was a bit confused that people didn&#8217;t understand what was so cool about it, until we realized that we never took the time to explain it. In this quick post, we&#8217;ll reveal three awesome ways we use Graphiti that wouldn&#8217;t be possible without Amazon&#8217;s Simple Storage Service (S3) or an equivalent place to serve and store image snapshots.</p>

<!-- more -->


<h3>Several Points in Time</h3>

<p>It becomes clear very quickly when you start using Graphite to record data that although it&#8217;s straightforward to get information relative to NOW, point in time graphs are harder to come by. Instead of building an extra Javascript or Ruby layer that could interpolate this information for us, we decided to take a somewhat low-tech approach, and added this route to the Sinatra application that powers Graphiti&#8217;s backend:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">post</span> <span class="s1">&#39;/snapshot&#39;</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">filename</span> <span class="o">=</span> <span class="no">Graph</span><span class="o">.</span><span class="n">snapshot</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:uuid</span><span class="o">]</span><span class="p">)</span>
</span><span class='line'>  <span class="n">json</span> <span class="ss">:filename</span> <span class="o">=&gt;</span> <span class="n">filename</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p><a href="https://github.com/paperlesspost/graphiti/blob/master/lib/graph.rb#L23-36">The implementation of Graph.snapshot</a> shows what&#8217;s going on here: we&#8217;re grabbing the Graphite URL, saving the body of the response (the image) as a file, and then uploading it to S3. This allows us to provide each graph with the following dropdown menu:</p>

<p><img src="https://img.skitch.com/20120525-g5m5wera2c7nwu3uua79m2y4h5.jpg"></p>

<p>which lets you recall, view, and share &#8220;frozen&#8221; point in time graphs that represent what you&#8217;d expect them to represent. This way whenever a graph is interesting for some reason, and we want to share it, it is also automatically persisted: a record of it is saved in Redis, and the image is uploaded to an external service. We have a historical record, as above, of interesting graphs. It&#8217;s been extremely helpful to see what the differences are between a graph saved a few weeks or months ago and one saved today.</p>

<p>Another obvious benefit to graph snapshotting became clear as soon as we implemented them: we&#8217;d be able to view them in places where we didn&#8217;t have access to the VPN that our Graphiti instance sits behind. This gave us the opportunity to implement one of our favorite Graphiti related features - daily emailed graph summaries.</p>

<h3>Email Reports</h3>

<p>Every morning any Paperless Post employee who is subscribed to the Graphiti email list we&#8217;ve set up gets an inbox full of graphy goodness:</p>

<p><img src="https://img.skitch.com/20120525-bjwdra5pyji9rwygjrb9p2sh6e.jpg"></p>

<p>Each of these emails represents a Graphiti Dashboard, and contains snapshots from that morning of each of the graphs in the dashboard:</p>

<p><img src="https://img.skitch.com/20120525-1rqp4xx6hjge1kur3j1f4dibi7.jpg"></p>

<p>This has been very valuable for us across a wide swath of our company. People following product numbers check out product-related graphs, Operations people follow systems-related graphs, and developers who have created dashboards to track data for features can follow graphs they&#8217;ve implemented. We all have a common discusion point for the large variety of metrics we collect, and email inbox delivery is appropriately more passive than actively having to visit the site to see the graphs. It&#8217;s become a part of many of our morning rituals to check in on our graphs and bring up any issues that might pop up. It greatly aids in correlating seemingly disparate events, and gives us more information, which is always what we&#8217;re striving for.</p>

<h3>Sensible Chat Logs</h3>

<p>The final point here is sort of a humorous one. Immediately after getting data flowing into Graphite, of course we wanted to share our graphs in Campfire. The first time we ever went back into our history to look at a graph we had pasted, we noticed that the graph was strange. It was now relative to the time we were checking Campfire logs, not relative to the time it was first created. So now instead of pasting Graphite links, we post snapshot links:</p>

<p><img src="https://img.skitch.com/20120525-f9hdsignyqp1mi1b9ngsakn4g5.jpg"></p>

<p>and when we review Campfire history, the graph history is preserved. This saves us a lot of confusion and keeps Campfire&#8217;s narrative history straight.</p>

<h3>…but we&#8217;re flexible</h3>

<p>There is an open issue on Github to remove the S3 dependency from Graphiti. The reason we&#8217;ve been hesitant to do this is simply that while having S3 credentials in a config file is a requirement to run the application, they don&#8217;t need to be &#8220;real.&#8221; You can insert some dummy credentials, and then just not use the snapshotting features as outlined above. Our hope is that we&#8217;ve been able to explain a little bit better why the decision to include a connection to this service was made, and that you&#8217;ll think they&#8217;re cool enough to try out. Regardless, we hope you enjoy using Graphiti, and if anyone wants to finish up the patch open on Github to provide alternate storage backends for the images, we&#8217;re flexible.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Paperless Post Tech Talks: Zach Holman]]></title>
    <link href="http://paperlesspost.github.com/blog/2012/05/07/paperless-post-tech-talks-zach-holman/"/>
    <updated>2012-05-07T16:42:00-04:00</updated>
    <id>http://paperlesspost.github.com/blog/2012/05/07/paperless-post-tech-talks-zach-holman</id>
    <content type="html"><![CDATA[<p>We&#8217;re very excited to announce another tech talk, this time with the illustrious <a href="http://zachholman.com">Zach Holman</a> of our favorite code collaboration platform, <a href="http://github.com">GitHub</a>.  Zach will talk about the awesome things GitHub does to work better.</p>

<p><img src="http://www.quirkey.com/skitch/zachhomanheader-20120507-170500.jpg" alt="Octobirdonit" /></p>

<p>Thursday, May 24th 2012 at 7PM</p>

<p>Paperless Post, 151 W. 25th St., 9th Floor, New York, NY</p>

<p>Space is limited and <em>RSVP&#8217;s are required</em>. <a href="http://paperless.ly/JVA8eG">Please RSVP here: http://paperless.ly/JVA8eG</a></p>

<!-- more -->


<p>Sure everyone knows how great and useful github.com is, and all the awesome features and team members that go into making it what it is. But we only see the surface and inside of GitHub an amazing amount of work goes into internal hacks and tools to make the daily lives and work of its team fun and extra-productive. We&#8217;re putting Zach to the challenge of showing off some of both the well known and completely unknown hacks, how they work, how GitHub uses them, and how we can learn from their experiments.</p>

<h3>About Zach</h3>

<p>A Ruby developer with sound fundamentals, firm grasp on the industry, and innovative development approaches are all phrases inapplicable to Zach Holman. He works at <a href="https://github.com">GitHub</a>, and hacks on <a href="https://github.com/holman/spark">sparkline generators</a>, <a href="https://github.com/holman/play">robot music DJs</a>, and ethically frightening <a href="http://facelette.com">FaceTime + Chatroulette</a> mashups. He <a href="http://zachholman.com">blogs</a>, he <a href="https://twitter.com/holman">tweets</a>, he evades his taxes.</p>

<h3>About Paperless Post Tech Talks</h3>

<p>Paperless Post Tech Talks are our chance to bring developers and artists whom we admire into our New York office to talk and share knowledge about their work with our team and the larger New York tech community. They are open to the public but RSVP is required as space is limited. There will be time to talk and mingle with the other attendees and the speakers over craft beer and snacks.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How We Added Time Travel to Paperless Post]]></title>
    <link href="http://paperlesspost.github.com/blog/2012/05/01/how-we-added-time-travel-to-paperless-post/"/>
    <updated>2012-05-01T11:38:00-04:00</updated>
    <id>http://paperlesspost.github.com/blog/2012/05/01/how-we-added-time-travel-to-paperless-post</id>
    <content type="html"><![CDATA[<p>Our designers make our cards beautiful, but our users make them unique. To help
them, we&#8217;ve built a card editing tool that allows extensive customization. And
customize they do: over and over, we&#8217;ve seen our users stretch the limits of the
design system. In fact, we&#8217;ve seen them stretch it, bend it, twist it, crush it,
and sometimes even break it—as our customer support team can attest. They
experiment, they tweak, they twiddle, and they turn out cards, from the artistic
to the bizarre, that we as designers and programmers could never have
anticipated. This is a major strength of our site, even when our customers&#8217;
creativity fills up the bug tracker, and so editing features have always been a
priority. In the past few months, after withstanding a huge holiday rush, we had
breathing room to tackle a major new editing feature: a fully reversible undo
history.</p>

<!-- more -->


<h2>The History of History</h2>

<p>We have not been sleeping for the last three years, of course. Undo history has
been in the app, off and on, in various forms, for a long time. Until recently,
text input could be undone with Ctrl-Z, although it wasn&#8217;t redoable. We switched
from per-character undo to batched input undo over the summer, with a little
help from the <code>_.debounce</code> feature of
<a href="http://www.github.com/amacdougall/underscore.as">underscore.as</a>.</p>

<p>Meanwhile, on the JavaScript side of the application, we had a state-based undo
system, which handled every other kind of user action. Two undo systems—odd,
but emblematic of one of the key design decisions behind the card creation app.</p>

<h3>The Hybrid</h3>

<p>Early in the summer of 2011, we switched over from our original pure-Flash card
creation app to a new approach we call &#8220;the hybrid&#8221;: a JavaScript UI wrapping a
Flash viewport. Visually, JavaScript handles all the HTML controls outside the
viewport, while the Flash viewport renders the card and handles UI interaction
that happens within it, such as dragging a photo. More importantly, our
JavaScript code can be said to drive the app: it has modules which interact with
the server to maintain a canonical card state, and it relays that state to Flash
as needed. In turn, it interprets events from Flash and updates the server when
necessary. Flash and JavaScript sync constantly, since local communication is
cheap; but JavaScript hits the server only when necessary.</p>

<p>Our goal for this separation was to permit advanced Flash rendering techniques
such as fast photo filters and high-quality fonts, while doing most UI elements
in HTML. JavaScript, HAML, and Sass make UI updates a snap. What&#8217;s more, we can
easily replace the Flash viewport with a pure HTML5 solution where
appropriate&#8230; but that&#8217;s another blog post.</p>

<h3>State Snapshots</h3>

<p>When implementing an undo history, having two codebases on two runtimes
makes life harder. Crucial state is split across runtimes. Even though
JavaScript is the canonical source of model data on the client side, plenty of
other state is segregated, including things you might not think of as &#8220;state&#8221;:
object references, event handlers, the starting values of in-progress slider
interactions.</p>

<p>When we first tried to implement an undo history, we assumed these issues could
be brushed aside. We need to restore object references and event handlers upon
undoing a delete? Recreate them! We need to get a delta (a single change amount)
from a slider drag (dozens and dozens of little events)? Assign the drag a
transaction id! JavaScript should be the sole source of <em>all</em> app data, not just
raw model information, and so we should be able to revert to any previous state
by loading a snapshot we&#8217;ve stored as a JavaScript string.</p>

<p>This may sound cumbersome, but it worked pretty well in practice. Many actions
could be undone just by piping model updates from JavaScript to Flash. But
although this system showed promise, and its outstanding bugs could have been
resolved, we knew we wanted a much more incremental and flexible approach.
Instead of serializing the entire application state on every user action, and
rewriting the entire application state on undo, why not store only the relevant
delta? This would use fewer resources and isolate the effects of each undo step.</p>

<h3>Design Patterns to the Rescue</h3>

<p>After some internal discussion, we settled on the classic undo implementation:
the <a href="http://en.wikipedia.org/wiki/Command_pattern">Command pattern</a>. I first
used the Command pattern in Java land, and although I respected its power, I
dreaded the tedium of defining customized command classes. In the traditional
Command implementation, there might be one for every possible user action, each
containing copies of the state necessary to reverse and repeat the action. As I
thought about it, however, I realized that JavaScript and its more straitlaced
cousin ActionScript 3 were well-suited to the pattern—considerably more so
than Java and C++, where the pattern accumulated its original mindshare.</p>

<h2>Commands for Controls</h2>

<p>There are a few immediate motivations for the pattern in UI programming. One is to
attach a single procedure to multiple UI elements—a menu item, a toolbar
button, and a keyboard shortcut, for example—with more flexibility than event
handlers, such as runtime remapping. In a language with first-class functions,
such as JavaScript, this handles itself; so do many other behavioral patterns,
such as Strategy&#8230; up to a point.</p>

<p>Another is to modify a button&#8217;s action bit by bit in response to other factors.
Add a Command to a form&#8217;s submit button, and alter the command state as the user
plays with the form. Sure, the button handler could just read the form, but if
you want to divorce command execution from the form code entirely, this is a
good architectural choice.</p>

<p>But the overriding reason to use the Command pattern is to implement undo and
redo.</p>

<h3>Alternatives to Commands: A Chilling Dystopian Hellscape</h3>

<p>Without the Command pattern—without a way to visualize actions as storable
objects—only two sensible approaches remain. You can save coded representations
of the actions to be performed and revoked, such as strings to be interpreted
later; or you can save snapshots of the entire state of your app.</p>

<p>Both approaches can be effective. An array of simple action codes such as
&#8220;element 123abc color = #ff0000&#8221;, or more computer-readable data objects such as
<code>{targetID: "123abc", action: "move", x: 120, y: 0}</code>, will work for a long time,
especially if you write a simple interpreter for such commands. But once you
need to undelete a complex object, your undelete command must suddenly contain
all the commands necessary to rebuild the object from scratch; or you begin to
cache deleted objects for potential resurrection, and must perforce remember to
purge them when discarding a history branch.</p>

<p>Keeping a snapshot of the whole state is simple enough, as long as your model is
amenable to serialization in the first place. But unless you&#8217;re restoring a
whole VM state, or rebuilding a purely noninteractive document, it becomes a
real task to ensure functionality in all situations. You need a strong canonical
source of state data—which we had, in the JavaScript session state. The
snapshot approach had legs. But it lacked the one thing we really wanted:
<em>isolation</em>. A history event involving text should be replayable even if an
unrelated photo has been changed elsewhere; but with a snapshot approach, this
was impossible.</p>

<h3>The Simplest Command</h3>

<p>The classic approach, we decided, was best. A Command, in this pattern, is just
that: an object representing a command to be executed—or reversed—by the
application. Commands are not UI actions: a click is not a Command, but a click
can trigger a command. Commands are not controller or model methods:
<code>record.delete()</code> is not a Command, but a Command can invoke that method. At
minimum, a Command is an object which has a single <code>execute</code> method. For our
purposes, it must also have <code>undo</code>. This is especially simple in JavaScript,
where we don&#8217;t even need to make a class:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">command</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">execute</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">releaseTheHounds</span><span class="p">();</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">undo</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">deployDogCatcher</span><span class="p">();</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Making Dumb Commands Smarter</h2>

<p><em>&#8220;It&#8217;s like undo is smarter than do&#8221;</em> —overheard on Campfire</p>

<p>Of course, in this example, we assume that <code>releaseTheHounds</code> and
<code>deployDogCatcher</code> are global functions that take no parameters. In any real
application, we will have commands which alter the program state. Their <code>undo</code>
implementation must know what state to revert to. In Java, it was common to
write subclasses for each type of command, like this:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="kd">class</span> <span class="nc">ColorChangeCommand</span> <span class="kd">extends</span> <span class="n">Command</span> <span class="o">{</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">private</span> <span class="n">Potato</span> <span class="n">potato</span><span class="o">;</span>
</span><span class='line'>  <span class="kd">private</span> <span class="kt">int</span> <span class="n">oldColor</span><span class="o">;</span>
</span><span class='line'>  <span class="kd">private</span> <span class="kt">int</span> <span class="n">newColor</span><span class="o">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">public</span> <span class="nf">ColorChangeCommand</span><span class="o">(</span><span class="n">Potato</span> <span class="n">potato</span><span class="o">,</span> <span class="kt">int</span> <span class="n">newColor</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'>    <span class="k">this</span><span class="o">.</span><span class="na">potato</span> <span class="o">=</span> <span class="n">potato</span><span class="o">;</span>
</span><span class='line'>    <span class="k">this</span><span class="o">.</span><span class="na">oldColor</span> <span class="o">=</span> <span class="n">potato</span><span class="o">.</span><span class="na">getColor</span><span class="o">();</span>
</span><span class='line'>    <span class="k">this</span><span class="o">.</span><span class="na">newColor</span> <span class="o">=</span> <span class="n">newColor</span><span class="o">;</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">execute</span><span class="o">()</span> <span class="o">{</span>
</span><span class='line'>    <span class="n">potato</span><span class="o">.</span><span class="na">setColor</span><span class="o">(</span><span class="n">newColor</span><span class="o">);</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">undo</span><span class="o">()</span> <span class="o">{</span>
</span><span class='line'>    <span class="n">potato</span><span class="o">.</span><span class="na">setColor</span><span class="o">(</span><span class="n">oldColor</span><span class="o">);</span>
</span><span class='line'>  <span class="o">}</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Then we would use it in an event handler like this:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="kt">void</span> <span class="nf">handleColorClick</span><span class="o">(</span><span class="n">ClickEvent</span> <span class="n">event</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'>  <span class="n">Command</span> <span class="n">command</span> <span class="o">=</span> <span class="k">new</span> <span class="n">ColorChangeCommand</span><span class="o">(</span>
</span><span class='line'>    <span class="n">PP</span><span class="o">.</span><span class="na">getApplication</span><span class="o">().</span><span class="na">getCurrentPotato</span><span class="o">(),</span>
</span><span class='line'>    <span class="n">event</span><span class="o">.</span><span class="na">target</span><span class="o">.</span><span class="na">getColor</span><span class="o">());</span>
</span><span class='line'>  <span class="n">command</span><span class="o">.</span><span class="na">execute</span><span class="o">();</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This subclass is simple, but as you start doing more complicated things,
subclasses proliferate, and things get out of hand in a hurry. There are tricks
to manage that complexity, but once you start using extra patterns or even
full-fledged frameworks, well, <a href="http://regex.info/blog/2006-09-15/247">&#8220;now you have two
problems&#8221;</a>.</p>

<p>JavaScript and ActionScript 3 sidestep the whole issue. Functions in those
languages are <em>closures</em>, which means that they retain references to everything
that was in scope when they were defined. All you need is a simple hash to hold
a couple of closures, and you&#8217;re done. Here&#8217;s the above example, as we might
write it for Paperless Post.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">function</span> <span class="nx">handleColorClick</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">potato</span> <span class="o">=</span> <span class="nx">PP</span><span class="p">.</span><span class="nx">Current</span><span class="p">.</span><span class="nx">potato</span><span class="p">;</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">newColor</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="s2">&quot;data-color&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">oldColor</span> <span class="o">=</span> <span class="nx">potato</span><span class="p">.</span><span class="nx">color</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">command</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">execute</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">potato</span><span class="p">.</span><span class="nx">color</span> <span class="o">=</span> <span class="nx">newColor</span><span class="p">;</span>
</span><span class='line'>    <span class="p">},</span>
</span><span class='line'>    <span class="nx">undo</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">potato</span><span class="p">.</span><span class="nx">color</span> <span class="o">=</span> <span class="nx">oldColor</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>  <span class="p">};</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">command</span><span class="p">.</span><span class="nx">execute</span><span class="p">();</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>In this case, all the information we need is defined within the scope of
<code>handleColorClick</code>; and since that scope is available to the nested functions
<code>execute</code> and <code>undo</code>, it remains available to those functions whenever they
happen to run. Already you can see a gain in simplicity. As long as you have a
good grasp of function scope and closure mechanics, which should be natural for
any JavaScript programmer these days, the simplicity stays even when you&#8217;re
storing complex objects in those closures.</p>

<h2>Undo, Redo, Unredo, Reunredo, and Unreunredo</h2>

<p>JavaScript and ActionScript make it easy to create a command object along with
all its state. The history of the app state—assuming it is entirely
user-driven, or that a user-driven component can easily be separated—can be
expressed simply as a linked chain of commands. The obvious and correct approach
is to embody history as an array, which is used as a stack: push an executed
command, pop a command in order to undo it. Push undone commands onto a redo
stack; pop those commands one by one to replay history, pushing each redone
command onto the undo stack.</p>

<p>To put it another way, as we travel forward through time, we leave behind us a
series of Commands: crystals of solidified intent. When we hit Undo, we take a
step back, pick up that crystal, give it a solid rap with our magic wand, and
time goes backward. Then we set it back down in front of us, on the redo stack.
If we go forward again, we tap the crystal and it repeats our undone action for
us, making time whole again. But if we do something else, instead, every crystal
ahead of us—our redo stack—disappears in the proverbial puff of logic.</p>

<h2>Cross-Runtime Issues</h2>

<p>This stack-based approach is obvious and correct&#8230; until you start dealing with
two codebases on two runtimes. That&#8217;s when things get tricky. A lot of
interactions involve JavaScript simply sending model updates to the Flash
viewport, which duly renders them; but when an action originates within Flash,
such as a photo drag or text input, JavaScript simply doesn&#8217;t have enough
information. Text input must be stored as commands holding sophisticated state
such as text patches and formatting object fragments. Sending that kind of data
to JavaScript would add complexity we don&#8217;t need, since we&#8217;d need code on the
JavaScript side to incorporate fragmentary data into the model. Why implement
text patching in JavaScript when the text is only visible in Flash?</p>

<p>My second thought was to give each runtime its own history, with special
commands used to hand over control of the undo and redo buttons—literally
swapping event handlers, actually, depending on which runtime was &#8220;up&#8221; to undo
the next command. I was thinking of coroutines: the entire command history could
be visualized as cooperative multitasking. This quickly led to the approach I
actually used.</p>

<p>I didn&#8217;t write code for bad approaches, just notes. Never underestimate the
debugging power of a notepad!</p>

<h2>Main and Subordinate Command Stores</h2>

<p>JavaScript was already the canonical source of model information on the client
side, the anointed speaker to the database. It made perfect sense to canonize
its command store as well, making it the sole keeper of application history.
At the same time, we wanted to handle Flash commands within Flash: a photo
resize, for instance, involves factors JavaScript should not be aware of, such
as the boundary contraints which keep an image in its frame during resizing.
User actions performed entirely within Flash should be undone <em>by</em> Flash, even
though JavaScript knows the score and calls the tune.</p>

<p>The solution was simple: keep two command stores. On the JavaScript side, the
twin undo and redo stacks; on the Flash side, a hash of commands. Commands
originating in Flash now do this:</p>

<ol>
<li>User performs action.</li>
<li>Flash creates a command which can undo/redo the action.</li>
<li>Flash calls <code>historyUpdate</code> on JavaScript, passing the command as an
argument.</li>
<li>JavaScript creates a command which calls <code>undo(uuid)</code> and <code>redo(uuid)</code> on Flash.</li>
<li>JavaScript assigns a new uuid to that command.</li>
<li>JavaScript adds the command to its undo stack.</li>
<li>JavaScript returns the uuid to Flash; this all took place during execution of
<code>historyUpdate</code>.</li>
<li>Flash sets the uuid on its own command object.</li>
<li>Flash stores that command in its own command hash, keyed by uuid.</li>
</ol>


<p>In effect, JavaScript maintains the entire command history, but some of the
commands delegate directly to commands on the Flash side. Flash stores the
commands as an unordered hash, relying upon JavaScript to maintain the sequence.</p>

<h2>Breaking with the Past</h2>

<p>Sometimes we need to &#8220;break&#8221; history: destroy some of our stored commands and
start over. Any time the user performs a new action, for instance, our redo
stack must be cast into the void. Your application might have actions that
cannot be undone; when the user opens that door, her history shatters. Depending
on your application&#8217;s demands, executing a history break can be complex: you
need to purge those commands, make them all available for garbage collection,
and along with them, any object references and event listeners that might still
hold some obscure yet tenacious tie to the outer world. Orphaned event listeners
are like samurai ghosts, locked in this world past their time, forever waiting
to fulfill an obligation that does not come.</p>

<p>And sometimes, adding history will break your app. If you design with the naive
assumption that time travels in only one direction, you will paint yourself into
a corner. Adding undo history to our application was not just a matter of
wrapping UI handlers in command generators. Every one-way state transition had
to become reversible; every act of creation had to contain the blueprint for its
own destruction. But by the same token, no object could be deleted without
provision for its recovery. In the end, we touched nearly every aspect of the
application to implement an undo history, and turned up dozens of new and
interesting bugs in the process. If you&#8217;re writing a new app that might benefit
from undo/redo, I strongly advise building it in at the start.</p>

<h2>The Future of History</h2>

<p>Undo/redo has gone live, but development is not over. Undo history is an ongoing
commitment: every new feature has to tie into the system, and every change to
the application can alter the resource usage of the command stacks. But it will
be worth it. Undo history is hard to get right, but it&#8217;s a huge usability
improvement our card senders will notice and appreciate.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Functional Concepts for Practical Coders]]></title>
    <link href="http://paperlesspost.github.com/blog/2012/04/18/functional-concepts-for-practical-coders/"/>
    <updated>2012-04-18T14:05:00-04:00</updated>
    <id>http://paperlesspost.github.com/blog/2012/04/18/functional-concepts-for-practical-coders</id>
    <content type="html"><![CDATA[<p>ActionScript and JavaScript support a lot of fancy concepts like closures,
partial application, filter chaining, and function composition. Without a
background in functional programming, it might not be clear to you what those
things are, or why you&#8217;d want to use any of it. Wikipedia is too dense,
functional programming language tutorials are too mathematical, Haskell is too
weird-looking, and more to the point, why would you <em>want</em> to use any of this
stuff instead of clear and simple loops, variables, and inheritance? Why make
your code more complicated? Why confuse your fellow coders with weird
programming paradigms? Why write functions that make functions that make
functions when you could just, you know, write a function?</p>

<p>I&#8217;ve written a blog series to convince you otherwise.</p>

<!-- more -->


<p>These concepts <em>can</em> be added to everyday code without twisting it into some
confusing recursive sculpture, and they <em>can</em> make common tasks easier, faster,
and even produce more readable code. The first four posts use examples written
in ActionScript, but the concepts are precisely identical in JavaScript; they
even use the same library, <a href="http://documentcloud.github.com/underscore/">underscore.js</a>
and my AS3 port <a href="https://github.com/amacdougall/underscore.as">underscore.as</a>.</p>

<p>Read <a href="http://www.alanmacdougall.com/functional-series/">the whole series</a> here.
If you find it helpful (or confusing), let me know.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Paperless Post In The Wild, Wild West: JSConf 2012]]></title>
    <link href="http://paperlesspost.github.com/blog/2012/04/05/paperless-post-in-the-wild/"/>
    <updated>2012-04-05T18:26:00-04:00</updated>
    <id>http://paperlesspost.github.com/blog/2012/04/05/paperless-post-in-the-wild</id>
    <content type="html"><![CDATA[<p>Yee haw! Paperless Post sent three people to the cowboy-themed JSConf in Scottsdale, Arizona recently, and now that we&#8217;re back from the <a href="http://2012.jsconf.us/">Wild, Wild West</a>, I thought I&#8217;d share some of my conference experiences.</p>

<p><img src="https://github.com/voodootikigod/logo.js/raw/master/js.png" width = 300></p>

<!-- more -->


<p>Though I&#8217;ve been using JavaScript professionally for quite some time, and I keep up with the community at large, I have never been to a JSConf before, and many of the people at the conference were new to me. Traveling with Paperless Post CTO and JSConf Alumnus <a href="http://twitter.com/aq">@aq</a> certainly helped, but the openness and accessibility of the conference venue and its participants certainly would have made this conference approachable and fun for anyone.</p>

<p>Instead of attempting to recap the entire experience, which isn&#8217;t possible, or even trying to cover all of the amazing talks, which would also be difficult, I thought I&#8217;d highlight a few of my favorite moments which I think will properly speak to the quality and success of the two-day conference.</p>

<h3>The Return of Play and a Standing Ovation</h3>

<p>The community of developers who congregate a few times a year to celebrate JavaScript and all of its incarnations is a thoroughly modern bunch. They are creating cutting edge web application architecture stacks, trying to overthrow the hegemony of native mobile software, and writing 3D graphics simulations in fewer characters than I&#8217;ve used in this sentence. While this penchant for the <em>next</em> leads to a lot of innovation and progress, it can also manifest itself in a repetitive way when presented in the conference setting: &#8220;Here&#8217;s this cool thing I did! It doesn&#8217;t really work, but check it out, I did it!&#8221; or &#8220;Here&#8217;s this thing that will certainly be the best thing ever!&#8221; are all too common.</p>

<p>Two talks were stark contrasts to this theme, in that they presented ideas that rooted themselves firmly in the trajectory of computing history, and tried to focus as much on ideas as implementation. <strong>David Nolen</strong>&#8217;s talk about <strong>Jelly Stains</strong> was a <em>trip</em> through the history of his various programming language love affairs, and  <strong><a href="http://whatsup-di.blogspot.com/">Daniel Henry Holmes Ingalls, Jr.</a></strong>&#8217;s presentation on <strong>The Lively Kernel</strong> was a hilarious and surprising retelling of the manifestation of a lifetime&#8217;s worth of work.</p>

<p><strong>Jelly Stains</strong> was a talk about how <a href="http://dosync.posterous.com/">David Nolen</a>, a JavaScript developer at the New York Times, by chance stumbled upon a series of Computer Science books which manages to share two qualities not often found in the same text: playfulness and denseness. <em>The Little Schemer,</em> <em>The Seasoned Schemer,</em> and <em>The Reasoned Schemer</em> take the reader through a conversational and philosophical journey through the Scheme programming language, a &#8220;minimalist LISP&#8221; that is also the <em>deus ex machina</em> of another hallmark Computer Science text, <em>The Structure and Interpretation of Computer Programs</em>. Nolen talked about how a relatively unknown &#8220;third paradigm&#8221; of Programming Languages, Relational or Logic Programming, changed the way he thought about problem solving, and the defining role that the freedom to play had in his transformation. He then took us on a trip back in time, sharing with us the notorious <em>Zebra Puzzle</em>, and illustrated with ease the stark contrasts between Functional, Object Oriented, and Logic Programming. Nolen showed some recent experiments with ClojureScript, which brings Clojure syntax to the JS runtime, and talked about implementing a logic engine in Clojure called <code>core.logic.</code> A trip that started with Javascript and ended with Nolen working alongside his idols was routed heavily through playful terrains that were radically disconnected from the work he was doing in a professional context. This is a lesson we can all use.</p>

<p><strong>The Lively Kernel</strong> is &#8220;a new approach to web programming&#8221; that was founded at Sun Microsystems in 2006 by Dan Ingalls and Antero Taivalsaari. In case Ingall&#8217;s name isn&#8217;t familiar, read up about his history with the Smalltalk programming language and advances in Virtual Machine technology <a href="http://en.wikipedia.org/wiki/Daniel_Henry_Holmes_Ingalls,_Jr.">here</a>. During his talk, Ingalls took the JSConf audience through a tour of the Kernel, which is quite aptly named. Illustrating that every aspect of the system is &#8220;alive,&#8221; and that it exists in order to make other connections possible, Ingalls used it to make pianos play, elephants dance, and graphs fill with data. His ease at the podium was highlighted by several exhortations that &#8220;that&#8217;s how it should be,&#8221; noting that he has spent a large part of his career trying to make live systems <em>de rigeur</em>, and that our pleasure at seeing things &#8220;just work&#8221; should be a catalyst for us to actually get up and make them work. I was very impressed that the JSConf community overlooked the lack of visual polish in this presentation and that everyone seemed to gain easy delight from the fact that the simple interactivity obviously rested on a deeply complex and well implemented kernel. Ingalls gave the crowd the gift of vision, and the crowd returned the favor with a well-deserved standing ovation.</p>

<h3>Embracing the Low-Level</h3>

<p>In addition to the fanciful-but-technical talks, there were a few technical-but-fanciful talks which also went beyond the stereotypical areas of interest for JavaScript programmers. In fact it should be noted that after JSConf it&#8217;s no longer worthwhile to harbor stereotypes about &#8220;JavaScript programmers&#8221; at all &#8211; they&#8217;re doing all kinds of things you&#8217;d never expect. Blowing straight past frameworks, libraries, and even browsers, these talks focused on the Virtual Machines that make JavaScript run so ubiquitously. <strong><a href="http://herhut.eu/">Stephan Herhut</a></strong> from Intel gave a presentation on <strong>Parallel Extensions for JavaScript</strong>, while <strong><a href="http://blog.mrale.ph/">Vyacheslav &#8220;Slava&#8221; Egorov</a></strong> asked the question <strong>Can V8 Do That?</strong></p>

<p>Each of these talks were particularly interesting in how they walked the audience through the process of looking at code in JavaScript and seeing how it manifested itself by the time it got to the assembler code that the Virtual Machines use to &#8220;speak&#8221; to the host OS. Herhut demonstrated the <strong>River Trail parallel data structures</strong> that Intel is experimenting with, which could allow for the design of concurrent JavaScript applications that didn&#8217;t rely on process concurrency. The idea that a JavaScript developer could look at code that needs to be written and reason about it in terms of data concurrency semantics is a very encouraging one. It means that parallel execution of code paths could be a reality in modern JavaScript implementations, and that developers could write code to execute this way without having to do more than choose the right data structure and model their algorithms accordingly.</p>

<p><strong>Can V8 Do That?</strong> gave the audience a chance to peer into the mind of one of the hackers doing work most relevant to modern JavaScript implementations, as presenter <strong>Slava Egorov</strong> is a member of the V8 team in Aarhus, Denmark. V8 is the JavaScript runtime that both Google Chrome and node.js use to interpret JavaScript code. Egorov took a gentle approach with the audience, encouraging us to not be afraid of the assembler code he displayed on slides, instead telling us that the patterns we saw and explanations he give could lead us to logical conclusions. The basic question is one that is common to developers in any language - to optimize now, or to optimize later? The twist here is that V8 does a lot to optimize our code for us, and Egorov used this fact to debunk some common optimization strategies (such as caching <code>array.length()</code>) and to show us other areas where V8 doesn&#8217;t optimize as successfully. The message was a clear and hopeful one - write your code, reason about it, and read up on what V8 can do - it can make you a more confident programmer who writes more efficient code.</p>

<h3>Standing in Circles and Nodding</h3>

<p>The one thing that I had heard about JSConfs that proved to be very true was that the experiences outside of the conference rooms would be as valuable as the talks themselves. The conference in general has an air of accessibility and in general doesn&#8217;t take itself too seriously, and this lends itself to lots of casual conversation. I cannot stress enough how many of the most fun and enlightening moments from the two day conference came from standing in circles with people and chatting. At one point I found myself standing around with beers or coffees in hand  with Brian Ford of Rubinius, Slava Egorov, Rick Hudson of Intel, and David Nolen, chatting about the cutting edge Garbage Collection technology used by Rubinius, the JVM and V8. All I could do was smile and nod, knowing that I was in the company of brilliance, and feeling lucky enough to get a glimpse.</p>

<p>What&#8217;s even cooler is that when you looked around at JSConf, these kinds of conversations were happening everywhere &#8211; speakers made themselves available after their talks or at the sponsored parties, and in general, a congenial air of collaboration amongst peers dominated.</p>

<h3>Hope for &#8220;the language with a bad upbringing&#8221;</h3>

<p>After Dan Ingall&#8217;s rousing demonstration of the Lively Kernel, I asked him a question about something he hadn&#8217;t addressed &#8211; what are his opinions and thoughts about working with JavaScript as a language? Since I know he was involved in the implementation of Virtual Machines and was obviously a deep thinker with regard to evaluating Programming Languages, I thought he would have some brilliant insights. His response was more or less that he obviously loved it or he wouldn&#8217;t be working with it, and that although JavaScript &#8220;had a bad upbringing,&#8221; Brendan (referring to Brendan Eich, credited as the creator of the language) had &#8220;done a great job with it.&#8221;</p>

<p>At first I wanted him to dig some dirt and maybe get a little controversial, but upon reflection, Mr. Ingall&#8217;s words depict a hopeful future for the language. I showed up at the conference expecting a lot of whizz-bang, and ended up with a lot of deep ideas. People continue to do astounding things with JavaScript, despite it being a language that is not without its warts and technological and political constraints. Between these speakers and others, the atmosphere, the voracious minds of the community&#8211; it&#8217;s difficult to leave this conference not convinced that there is a strong foundation and a bright adulthood ahead for JavaScript.</p>

<p><em>If you&#8217;re interested in Paperless Post&#8217;s commitment to professional development, we&#8217;ve <a href="http://blog.paperlesspost.com/2011/05/confin-it/">posted about</a>  <a href="http://blog.paperlesspost.com/2011/06/goruco-2011/">going to conferences</a> before, and keep in mind:
<a href="http://www.paperlesspost.com/jobs">we&#8217;re looking for more talented people in NYC and SF</a>.</em></p>

<h4>Some Resources</h4>

<ul>
<li><a href="https://www.cs.indiana.edu/~dfried/">Daniel Friedman&#8217;s Work</a>, including the Reasoned Schemer</li>
<li><a href="http://en.wikipedia.org/wiki/Zebra_Puzzle">The Zebra Puzzle</a> that David Nolen spoke of</li>
<li><a href="http://www.lively-kernel.org/">The Lively Kernel</a> that Dan Ingalls demonstrated</li>
<li><a href="http://www.github.com/rivertrail/rivertrail/wiki/">Intel&#8217;s River Trail</a> as provided by Intel</li>
<li><a href="http://code.google.com/p/v8/">Google&#8217;s V8</a>: an overview</li>
</ul>


<p><em>Update 04/18/2012 - The photos from the booth sponsored by Paperless Post are up! <a href="http://www.flickr.com/photos/voodootikigod/sets/72157629478505680/">Check them out here!</a></em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Paperless Post Tech Talks: Greg Borenstein]]></title>
    <link href="http://paperlesspost.github.com/blog/2012/03/15/paperless-post-tech-talks-greg-borenstein/"/>
    <updated>2012-03-15T15:12:00-04:00</updated>
    <id>http://paperlesspost.github.com/blog/2012/03/15/paperless-post-tech-talks-greg-borenstein</id>
    <content type="html"><![CDATA[<p>We&#8217;re happy to announce that this month we&#8217;ll be hosting a talk with the very talented technologist Greg Borenstein.  You can check out Greg&#8217;s recent work at <a href="http://gregborenstein.com/">http://gregborenstein.com/</a></p>

<p><img src="http://gregborenstein.com/assets/c4d_self_portrait_small.jpg" alt="" /></p>

<p>Wednesday, March 28th at 7:00 PM</p>

<p>Paperless Post, 151 W. 25th St., 9th Floor, New York, NY</p>

<p>Space is limited and <em>RSVP&#8217;s are required</em>. <a href="http://paperless.ly/z9TpVo">Please RSVP here</a></p>

<p><em>04/18/2012 Update: <a href="http://speakerdeck.com/u/gregab/p/paperless-post-tech-talk">Greg&#8217;s Slides are now online!</a></em></p>

<!-- more -->


<h3><em>About Greg</em>:</h3>

<p>Greg Borenstein is an artist and teacher in New York. After years as a web developer and musician he quit to attend grad school at the NYU Interactive Telecommunications Program where he is now a Resident Researcher. His artistic work explores the use of special effects as an artistic medium. He is fascinated by how special effects techniques cross the boundary between images and the physical objects that make them: miniatures, motion capture, 3D animation, animatronics, and digital fabrication. Greg is the author of Making Things See: 3D Vision with Kinect, Processing, Arduino, and Makerbot, published by O&#8217;Reilly.</p>

<h3><em>From Greg</em>:</h3>

<p>I&#8217;ll present a survey of some of my recent work with the Kinect and then talk about two active projects in my current research. The first project explores the use of face tracking and recognition to substitute for QR codes and other fiducial markers in computer vision applications. QR codes are ugly and unusable and replacing them with images of the human face offers a number of interesting design and interaction possibilities. Secondly I&#8217;ll talk about a new project I&#8217;m undertaking called Makematics. With the rise of 3D scanning, digital fabrication, and advanced computer graphics the field of creative coding requires more and more knowledge of mathematical fields such as linear algebra, differential equations, and topology. There are few resources available for competent programmers (let alone artists and designers) to learn the parts of these fields they increasingly need to do interesting and original work. I&#8217;ll talk about some ideas for how to improve this situation and why I think it&#8217;s important for the future of art and interactivity.</p>

<h3>About Paperless Post Tech Talks</h3>

<p>Paperless Post Tech Talks are our chance to bring developers and artists who we admire into our New York office to talk and share knowledge about their work with our team and the larger New York tech community. They are open to the public but RSVP is required as space is limited. There will be time to talk and mingle with the other attendees and the speakers over craft beer and snacks.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Paperless Post at JSConf 2012]]></title>
    <link href="http://paperlesspost.github.com/blog/2012/03/09/paperless-post-at-jsconf-2012/"/>
    <updated>2012-03-09T10:18:00-05:00</updated>
    <id>http://paperlesspost.github.com/blog/2012/03/09/paperless-post-at-jsconf-2012</id>
    <content type="html"><![CDATA[<p>Some events you look forward to for an entire year. <a href="http://2012.jsconf.us">JSConf</a> is one of those events.
Last year, <a href="http://blog.paperlesspost.com/2011/05/confin-it/">we had a great time in Portland</a>. This year, we&#8217;ll not only be there, we&#8217;re very excited to be sponsoring a really fun suprise for everyone.
If you&#8217;re coming to the conference or are attending any of the parties, <a href="http://twitter.com/aq">@aq</a>, <a href="http://twitter.com/talltyler">@talltyler</a>, and <a href="http://twitter.com/mrb_bk">@mrb_bk</a> will be there, so make sure you say hello.</p>

<p>Looking forward to seeing everyone in Scottsdale!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Metallic Text Shaders]]></title>
    <link href="http://paperlesspost.github.com/blog/2012/03/07/metallic-text-shaders/"/>
    <updated>2012-03-07T11:50:00-05:00</updated>
    <id>http://paperlesspost.github.com/blog/2012/03/07/metallic-text-shaders</id>
    <content type="html"><![CDATA[<p><img src="http://paperlesspost.github.com/images/posts/metallictxt.jpg"></p>

<p>Text customization is a big part of our card creation process here at Paperless
Post. We want to enable users to easily create beautiful and unique cards. One
feature we thought would be cool would be for the user to be able to foil stamp
or gold emboss text, which would give text a texturized silver or gold effect.</p>

<!-- more -->


<p>When assessing how to implement these text effects, we needed a solution that
wouldn&#8217;t interfere with any existing customization functionality and would also
fit easily into our pipeline without slowing everything down. Essentially, our
goal was to color the text with the gold or silver texture images, or mask the
images with the text.</p>

<p>Currently we are using a simple Flash text field to render all of the text
within a card. Flash supports a wide array of options for graphical
customization and bitmap filters. One possibility was to add the image to the
stage, put the text over it, and either make the text a mask or change the blend
mode of the text field. The issue with a solution like this was that it
prevented us from having gold, silver and plain text within a single text field.
There didn&#8217;t seem to be a way to achieve the effect we wanted using a technique
like this without overcomplicating everything with duplicate text layers and
strange layering hacks.</p>

<p>What we needed was a way to intelligently replace certain text with the texture,
while ignoring other parts of the text field. A graphical effect with logic?
Sounds like a job for a <a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Shader.html">shader</a>.
Flash supports pixel shaders using their proprietary <a href="http://www.adobe.com/devnet/pixelbender.html">Pixel Bender</a> software. In order to
apply a shader written using Pixel Bender, you need to import the
shader byte code, create a shader object with the byte code, create a shader
filter from that shader object, and finally pass that filter into the filters
property of a Flash display object.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='actionscript'><span class='line'>  <span class="p">[</span><span class="nx">Embed</span><span class="p">(</span><span class="s2">&quot;myShader.pbj&quot;</span><span class="o">,</span> <span class="nx">mimeType</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">)]</span>
</span><span class='line'>  <span class="kd">private</span> <span class="kd">static</span> <span class="k">var</span> <span class="nx">MyShader</span><span class="o">:</span><span class="nb">Class</span><span class="o">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="p">...</span>
</span><span class='line'>  <span class="k">var</span> <span class="nx">shader</span><span class="o">:</span><span class="nx">Shader</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Shader</span><span class="p">(</span><span class="k">new</span> <span class="nx">MyShader</span><span class="p">()</span> <span class="nx">as</span> <span class="nb">ByteArray</span><span class="p">);</span>
</span><span class='line'>  <span class="c1">// Set shader parameters here if there are any.</span>
</span><span class='line'>  <span class="k">var</span> <span class="nx">shaderFilter</span><span class="o">:</span><span class="nx">ShaderFilter</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ShaderFilter</span><span class="p">(</span><span class="nx">shader</span><span class="p">);</span>
</span><span class='line'>  <span class="nx">aDisplayObject</span><span class="p">.</span><span class="nx">filters</span> <span class="o">=</span> <span class="p">[</span><span class="nx">shaderFilter</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>This code loads the byte code for the pixel shader &#8216;myShader.pbj&#8217; and then
passes it into the shader constructor, which creates the executable shader object
<code>shader</code>. The shader filter is then created with the executable shader. This
shader can then be passed to the filters array of any display object, which will
cause the pixel shader to operate on the display object.</p>

<p>The way we implemented our gold and silver text effects was by choosing certain
colors that we did not use in our card creation app. When the user selects the
gold and silver text effects for a segment of text, that segment of text is
assigned a certain color that corresponds to a gold or silver effect. The shader
we wrote only targets these colors, and if it is able to find the colors, it
replaces that pixel with a sampled pixel from the texture image. This is
essentially a smart mask or intelligent blend filter.</p>

<p>Our shader takes in colors and texture images, with each color corresponding
respectively to the texture image. So if the pixel shader finds a <code>color1</code> it will
replace it with a sampled pixel from <code>textureImage1</code>. We sample from the image
using a 3x3 grid, from an input image called <code>foreground</code>.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'>  <span class="n">float4</span> <span class="n">c00</span> <span class="o">=</span> <span class="n">sampleNearest</span><span class="p">(</span><span class="n">foreground</span><span class="p">,</span> <span class="n">float2</span><span class="p">(</span><span class="n">pos</span><span class="p">.</span><span class="n">x</span> <span class="o">-</span> <span class="mf">1.0</span><span class="p">,</span> <span class="n">pos</span><span class="p">.</span><span class="n">y</span> <span class="o">-</span> <span class="mf">1.0</span><span class="p">));</span>
</span><span class='line'>  <span class="n">float4</span> <span class="n">c01</span> <span class="o">=</span> <span class="n">sampleNearest</span><span class="p">(</span><span class="n">foreground</span><span class="p">,</span> <span class="n">float2</span><span class="p">(</span><span class="n">pos</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">pos</span><span class="p">.</span><span class="n">y</span> <span class="o">-</span> <span class="mf">1.0</span><span class="p">));</span>
</span><span class='line'>  <span class="n">float4</span> <span class="n">c02</span> <span class="o">=</span> <span class="n">sampleNearest</span><span class="p">(</span><span class="n">foreground</span><span class="p">,</span> <span class="n">float2</span><span class="p">(</span><span class="n">pos</span><span class="p">.</span><span class="n">x</span> <span class="o">+</span> <span class="mf">1.0</span><span class="p">,</span> <span class="n">pos</span><span class="p">.</span><span class="n">y</span> <span class="o">-</span> <span class="mf">1.0</span><span class="p">));</span>
</span><span class='line'>  <span class="n">float4</span> <span class="n">c10</span> <span class="o">=</span> <span class="n">sampleNearest</span><span class="p">(</span><span class="n">foreground</span><span class="p">,</span> <span class="n">float2</span><span class="p">(</span><span class="n">pos</span><span class="p">.</span><span class="n">x</span> <span class="o">-</span> <span class="mf">1.0</span><span class="p">,</span> <span class="n">pos</span><span class="p">.</span><span class="n">y</span><span class="p">));</span>
</span><span class='line'>  <span class="n">float4</span> <span class="n">c11</span> <span class="o">=</span> <span class="n">sampleNearest</span><span class="p">(</span><span class="n">foreground</span><span class="p">,</span> <span class="n">pos</span><span class="p">);</span>    <span class="c1">// center pixel</span>
</span><span class='line'>  <span class="n">float4</span> <span class="n">c12</span> <span class="o">=</span> <span class="n">sampleNearest</span><span class="p">(</span><span class="n">foreground</span><span class="p">,</span> <span class="n">float2</span><span class="p">(</span><span class="n">pos</span><span class="p">.</span><span class="n">x</span> <span class="o">+</span> <span class="mf">1.0</span><span class="p">,</span> <span class="n">pos</span><span class="p">.</span><span class="n">y</span><span class="p">));</span>
</span><span class='line'>  <span class="n">float4</span> <span class="n">c20</span> <span class="o">=</span> <span class="n">sampleNearest</span><span class="p">(</span><span class="n">foreground</span><span class="p">,</span> <span class="n">float2</span><span class="p">(</span><span class="n">pos</span><span class="p">.</span><span class="n">x</span> <span class="o">-</span> <span class="mf">1.0</span><span class="p">,</span> <span class="n">pos</span><span class="p">.</span><span class="n">y</span> <span class="o">+</span> <span class="mf">1.0</span><span class="p">));</span>
</span><span class='line'>  <span class="n">float4</span> <span class="n">c21</span> <span class="o">=</span> <span class="n">sampleNearest</span><span class="p">(</span><span class="n">foreground</span><span class="p">,</span> <span class="n">float2</span><span class="p">(</span><span class="n">pos</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">pos</span><span class="p">.</span><span class="n">y</span> <span class="o">+</span> <span class="mf">1.0</span><span class="p">));</span>
</span><span class='line'>  <span class="n">float4</span> <span class="n">c22</span> <span class="o">=</span> <span class="n">sampleNearest</span><span class="p">(</span><span class="n">foreground</span><span class="p">,</span> <span class="n">float2</span><span class="p">(</span><span class="n">pos</span><span class="p">.</span><span class="n">x</span> <span class="o">+</span> <span class="mf">1.0</span><span class="p">,</span> <span class="n">pos</span><span class="p">.</span><span class="n">y</span> <span class="o">+</span> <span class="mf">1.0</span><span class="p">));</span>
</span></code></pre></td></tr></table></div></figure>


<p>We sample using a 3x3 grid because we want to replace antialiased pixels that
may not have the same color value that we are looking for, but should still be
replaced. Because antialiased pixels will be adjacent to the true color of the
text, we check whether any color in the 3x3 grid is the target color. We then
check to see which sampled pixel is closest to the target color.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'>  <span class="kt">float</span> <span class="n">color1Dist</span> <span class="o">=</span> <span class="n">min</span><span class="p">(</span><span class="n">distance</span><span class="p">(</span><span class="n">c00</span><span class="p">.</span><span class="n">rgb</span><span class="p">,</span> <span class="n">color1</span><span class="p">),</span> <span class="n">min</span><span class="p">(</span><span class="n">distance</span><span class="p">(</span><span class="n">c01</span><span class="p">.</span><span class="n">rgb</span><span class="p">,</span> <span class="n">color1</span><span class="p">),</span> <span class="n">min</span><span class="p">(</span><span class="n">distance</span><span class="p">(</span><span class="n">c02</span><span class="p">.</span><span class="n">rgb</span><span class="p">,</span> <span class="n">color1</span><span class="p">),</span>
</span><span class='line'>    <span class="n">min</span><span class="p">(</span><span class="n">distance</span><span class="p">(</span><span class="n">c10</span><span class="p">.</span><span class="n">rgb</span><span class="p">,</span> <span class="n">color1</span><span class="p">),</span> <span class="n">min</span><span class="p">(</span><span class="n">distance</span><span class="p">(</span><span class="n">c11</span><span class="p">.</span><span class="n">rgb</span><span class="p">,</span> <span class="n">color1</span><span class="p">),</span> <span class="n">min</span><span class="p">(</span><span class="n">distance</span><span class="p">(</span><span class="n">c12</span><span class="p">.</span><span class="n">rgb</span><span class="p">,</span> <span class="n">color1</span><span class="p">),</span>
</span><span class='line'>    <span class="n">min</span><span class="p">(</span><span class="n">distance</span><span class="p">(</span><span class="n">c20</span><span class="p">.</span><span class="n">rgb</span><span class="p">,</span> <span class="n">color1</span><span class="p">),</span> <span class="n">min</span><span class="p">(</span><span class="n">distance</span><span class="p">(</span><span class="n">c21</span><span class="p">.</span><span class="n">rgb</span><span class="p">,</span> <span class="n">color1</span><span class="p">),</span> <span class="n">distance</span><span class="p">(</span><span class="n">c22</span><span class="p">.</span><span class="n">rgb</span><span class="p">,</span> <span class="n">color1</span><span class="p">)))))))));</span>
</span></code></pre></td></tr></table></div></figure>


<p>If this distance is lower than our target threshold, we set the output pixel to
a sampled texture value. Otherwise, we set it to the center of the sampled input
matrix.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'>  <span class="n">float2</span> <span class="n">pos</span> <span class="o">=</span> <span class="n">outCoord</span><span class="p">();</span>
</span><span class='line'>  <span class="n">float4</span> <span class="n">texture1</span> <span class="o">=</span> <span class="n">sampleNearest</span><span class="p">(</span><span class="n">textureImg1</span><span class="p">,</span> <span class="n">pos</span><span class="p">);</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">color1Dist</span> <span class="o">&lt;=</span> <span class="n">thresholds</span><span class="p">[</span><span class="mi">0</span><span class="p">]){</span>
</span><span class='line'>    <span class="n">dst</span> <span class="o">=</span> <span class="n">float4</span><span class="p">(</span><span class="n">texture1</span><span class="p">.</span><span class="n">r</span><span class="p">,</span> <span class="n">texture1</span><span class="p">.</span><span class="n">g</span><span class="p">,</span> <span class="n">texture1</span><span class="p">.</span><span class="n">b</span><span class="p">,</span> <span class="n">c11</span><span class="p">.</span><span class="n">a</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="k">else</span><span class="p">{</span>
</span><span class='line'>    <span class="n">dst</span> <span class="o">=</span> <span class="n">c11</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>You can see here that we use the alpha value of the original sampled center
pixel for the output pixel. This is to ensure that if the text was originally
blending with something in the background, so will the gold or silver text
effect.</p>

<p>After trying a variety of other methods of applying these types of effects, this
really seems to be the only way to achieve this quality of effect without
drastically slowing down the runtime. You can <a href="http://www.paperlesspost.com/cards#/cards/card/6436?q=6436">try it out on a card here</a>. Try changing
different parts of the text to different metallic colors. All of these metallics
are applied with a single shader that is sent a new texture for each metallic
color you choose.</p>

<p>If you want to learn more about Pixel Bender, Adobe <a href="http://www.adobe.com/cfusion/exchange/index.cfm?event=productHome&amp;exc=26&amp;loc=en_us">keeps a list of shaders here</a>;
or you can come work/intern with us! Most of this shader work was done by Nick
Schaubeck, one of our very talented interns. <em><a href="http://www.paperlesspost.com/jobs">We&#8217;re looking for more talented people in NYC and SF</a>.</em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Why We Patched node.js]]></title>
    <link href="http://paperlesspost.github.com/blog/2012/01/17/why-we-patched-node-dot-js/"/>
    <updated>2012-01-17T15:26:00-05:00</updated>
    <id>http://paperlesspost.github.com/blog/2012/01/17/why-we-patched-node-dot-js</id>
    <content type="html"><![CDATA[<p>At a company that relies on open source software, every day is an adventure. This week: how a memory fragmentation issue in node.js tempted me into the wilds of the V8 JavaScript Engine and C++.</p>

<!-- more -->


<p>As our fearless leader and CTO Aaron Quint mentioned in <a href="http://dev.paperlesspost.com/blog/2011/12/16/introducing-graphiti-an-alternate-frontend-for-graphite/">our previous blog post</a>, we are completely addicted to metrics. One of the cornerstones of this new mindset is <a href="http://github.com/etsy/statsd">statsd</a>, a node.js server for aggregating and sending information to a Graphite server. If you don&#8217;t know what statsd or Graphite are, read the above blog post. If you don&#8217;t know what <a href="http://github.com/joyent/node">node.js</a> or <a href="http://code.google.com/p/v8/">V8</a> are, you should check them both out as they are very interesting projects!</p>

<p>As a consequence of a big push to automate our software infrastructure, we have tried to tie as many of our dependencies as possible to pre-compiled packages for our current deployment platform of choice, CentOS. The <a href="http://nodejs.tchol.org/">only available packages</a> for our version of CentOS were for the 0.6.x stable branch of node. Even though we were running the 0.4.x branch (compiled by hand) up until that point, we decided to give it a shot.</p>

<p>After our upgrade, we noticed that the node statsd process on our isolated statsd box would balloon in memory usage, measured by resident set size, from a manageable number in the tens of megabytes to upwards of a gigabyte. Eventually, the process would consume so much memory that it would get shut down by the OS, and for the time that the process was down, we would miss out on our stats getting transmitted properly to Graphite. Besides making us aware that we should try to find a way to improve the availability of our statsd, we were very suspicious.</p>

<p>At first we assumed that we had accidentally created a memory leak in the statsd process, because we are actively maintaining our own fork at this point and we couldn&#8217;t find many other mentions of similar issues. After some serious head scratching and investigation, Aaron tracked it down to node itself, by stripping away the extraneous bits and observing how node handles sending and receiving UDP packets.</p>

<p>Here&#8217;s the client test code, commented for your convenience:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">// Require the necessary node modules</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">util</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;util&#39;</span><span class="p">),</span>
</span><span class='line'>    <span class="nx">dgram</span>  <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;dgram&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Set up the UDP client, create a dummy message, and zero out a counter</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">client</span> <span class="o">=</span> <span class="nx">dgram</span><span class="p">.</span><span class="nx">createSocket</span><span class="p">(</span><span class="s2">&quot;udp4&quot;</span><span class="p">);</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">message</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Buffer</span><span class="p">(</span><span class="s2">&quot;stats.counters.test|1&quot;</span><span class="p">);</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">sent</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Define a send function that will be executed in a timed loop.</span>
</span><span class='line'><span class="kd">function</span> <span class="nx">send</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">process</span><span class="p">.</span><span class="nx">nextTick</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">client</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">message</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">message</span><span class="p">.</span><span class="nx">length</span><span class="p">,</span> <span class="mi">8125</span><span class="p">,</span> <span class="s2">&quot;localhost&quot;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">sent</span><span class="o">++</span><span class="p">;</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'>    <span class="nx">send</span><span class="p">();</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'><span class="nx">send</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Set up an interval timer that will periodically send the number of sent</span>
</span><span class='line'><span class="c1">// packets to the console</span>
</span><span class='line'><span class="nx">setInterval</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Sent &#39;</span><span class="p">,</span> <span class="nx">sent</span><span class="p">);</span>
</span><span class='line'><span class="p">},</span> <span class="mi">1000</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Output the client start to the console</span>
</span><span class='line'><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Started sending to&#39;</span><span class="p">,</span> <span class="nx">port</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>And the server, equally simple but also commented:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">// Require the necessary node modules</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">util</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;util&#39;</span><span class="p">),</span>
</span><span class='line'>    <span class="nx">dgram</span>  <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;dgram&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Set up the server and a counter for the number of received packets, and</span>
</span><span class='line'><span class="c1">// define a callback function to be executed when a packet is received.</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">packets</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">receive</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">msg</span><span class="p">,</span> <span class="nx">rinfo</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">packets</span><span class="o">++</span><span class="p">;</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">server</span> <span class="o">=</span> <span class="nx">dgram</span><span class="p">.</span><span class="nx">createSocket</span><span class="p">(</span><span class="s1">&#39;udp4&#39;</span><span class="p">,</span> <span class="nx">receive</span><span class="p">);</span>
</span><span class='line'><span class="nx">server</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="mi">8125</span><span class="p">);</span>
</span><span class='line'><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Listening for UDP packets on&quot;</span><span class="p">,</span> <span class="nx">port</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// Print out the process memory usage, the number of packets received,</span>
</span><span class='line'><span class="c1">// and force a GC run every 2 seconds</span>
</span><span class='line'><span class="nx">setInterval</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;\n*** RSS: &quot;</span><span class="p">,</span> <span class="nx">process</span><span class="p">.</span><span class="nx">memoryUsage</span><span class="p">().</span><span class="nx">rss</span> <span class="o">/</span> <span class="mi">1024</span> <span class="o">/</span> <span class="mi">1024</span><span class="p">,</span> <span class="s2">&quot;mb&quot;</span><span class="p">)</span>
</span><span class='line'>  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;packets:&quot;</span><span class="p">,</span> <span class="nx">packets</span><span class="p">);</span>
</span><span class='line'>  <span class="c1">// A hook to force gc through V8&#39;s --expose_gc option</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="nx">gc</span><span class="p">)</span> <span class="nx">gc</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
</span><span class='line'><span class="p">},</span> <span class="mi">2000</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>This simple client/server set up lets us observe what happens when we throw a bunch of UDP packets at a node server, and do nothing else with them. When we ran the above client and server code against the 0.6.x stable version of node, we got the following output (note that this is a sample from the &#8220;middle&#8221; of the log, you can note by the number of packets sent):</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="o">***</span> <span class="nx">RSS</span><span class="o">:</span>  <span class="mf">64.64453125</span> <span class="nx">mb</span>
</span><span class='line'><span class="nx">packets</span><span class="o">:</span> <span class="mi">95354</span>
</span><span class='line'>
</span><span class='line'><span class="o">***</span> <span class="nx">RSS</span><span class="o">:</span>  <span class="mf">93.68359375</span> <span class="nx">mb</span>
</span><span class='line'><span class="nx">packets</span><span class="o">:</span> <span class="mi">113610</span>
</span><span class='line'>
</span><span class='line'><span class="o">***</span> <span class="nx">RSS</span><span class="o">:</span>  <span class="mf">56.98046875</span> <span class="nx">mb</span>
</span><span class='line'><span class="nx">packets</span><span class="o">:</span> <span class="mi">114268</span>
</span><span class='line'>
</span><span class='line'><span class="o">***</span> <span class="nx">RSS</span><span class="o">:</span>  <span class="mf">55.50390625</span> <span class="nx">mb</span>
</span><span class='line'><span class="nx">packets</span><span class="o">:</span> <span class="mi">114278</span>
</span><span class='line'>
</span><span class='line'><span class="o">***</span> <span class="nx">RSS</span><span class="o">:</span>  <span class="mf">74.39453125</span> <span class="nx">mb</span>
</span><span class='line'><span class="nx">packets</span><span class="o">:</span> <span class="mi">131329</span>
</span><span class='line'>
</span><span class='line'><span class="o">***</span> <span class="nx">RSS</span><span class="o">:</span>  <span class="mf">60.00390625</span> <span class="nx">mb</span>
</span><span class='line'><span class="nx">packets</span><span class="o">:</span> <span class="mi">131329</span>
</span><span class='line'>
</span><span class='line'><span class="o">***</span> <span class="nx">RSS</span><span class="o">:</span>  <span class="mf">58.69140625</span> <span class="nx">mb</span>
</span><span class='line'><span class="nx">packets</span><span class="o">:</span> <span class="mi">132717</span>
</span><span class='line'>
</span><span class='line'><span class="o">***</span> <span class="nx">RSS</span><span class="o">:</span>  <span class="mf">100.3359375</span> <span class="nx">mb</span>
</span><span class='line'><span class="nx">packets</span><span class="o">:</span> <span class="mi">147266</span>
</span></code></pre></td></tr></table></div></figure>


<p>This simple UDP client/server implementation leaked memory profusely. Even more damning is the fact that after the client was killed and packets stopped being transmitted to the server, the RSS did not drop significantly, even after many cycles. After we had proof of some memory weirdness in the node process and verified that this issue didn&#8217;t exist in the 0.4.x branch of node, we did the next natural thing: opened an issue on GitHub.</p>

<p>Thanks to the transparency and activeness of node&#8217;s development process, we were able to get the direct attention of the maintainers to explain our issues. It turns out that the 0.6.x branches introduced major changes in node&#8217;s entire networking layer via the adoption of a new library called <a href="https://github.com/joyent/libuv">libuv</a>. Ryan Dahl described libuv on the <a href="http://blog.nodejs.org/2011/09/23/libuv-status-report/">node.js blog</a>:</p>

<blockquote><p>libuv&#8217;s purpose is to abstract platform-dependent code in Node into one place where it can be tested for correctness and performance before bindings to V8 are added. Since Node is totally non-blocking, libuv turns out to be a rather useful library itself: a BSD-licensed, minimal, high-performance, cross-platform networking library.</p></blockquote>


<p>The 0.5.x branch of node.js had given the node community the opportunity to test these changes with an unstable release, but since UDP isn&#8217;t used as commonly as TCP by node.js users, its datagram functionality was sort of lost in the shuffle. More &#8220;important&#8221; and oft-used protocols were covered first, and first class memory management was one of the features that TCP got that datagrams didn&#8217;t.</p>

<p>It turned out that the node core team <a href="https://github.com/joyent/node/blob/c123ac05dc37311d3dfb37ed6f22baef58280379/src/udp_wrap.cc#L336">knew that datagrams needed some love</a>, and they were happy to have some help. The TCP strategy for memory management made it much easier to avoid memory fragmentation because it used slab allocation. For an excellent, illustrative explanlation of memory fragmentation, see <a href="http://stackoverflow.com/a/3770593/761975">this Stackoverflow answer</a>. Slab allocation solves fragmentation issues by allocating larger chunks of memory at once, to be used only by objects of the same type and size, alleviating memory gaps of different sizes being created by deallocation.</p>

<p>Because we had committed to using node in production, and we try as hard as possible to be good open source citizens, I decided to challenge myself to make this change. Mind you I haven&#8217;t touched C++ in years, I have zero familiarity with the V8 C++ interface, and I&#8217;m not an avid user of node.js, but I still really wanted to do it. If you&#8217;re wondering why, I was motivated by my desire to give back to the open source community, and by my dedication to keep Paperless Post&#8217;s operational overhead to a minimum. I was presented with a clear path, and was ready for the adventure. Plus, we needed our stats!</p>

<p>I started to dig in, read some materials online, and got a good sense at how the interactions worked between V8, libuv, and node.js. Because the Internet is awesome, I was able to continue the conversation from GitHub on Twitter and then on IRC with a few of the node and libuv maintainers. They patiently explained some of the crucial pieces I needed to know, and after some major head-banging, a lot of rubber duck programming, and some heavy testing, my patch was ready.</p>

<p>After all of that, it turns out that:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="mi">1</span> <span class="nx">files</span> <span class="nx">changed</span><span class="p">,</span> <span class="mi">59</span> <span class="nx">insertions</span><span class="p">(</span><span class="o">+</span><span class="p">),</span> <span class="mi">9</span> <span class="nx">deletions</span><span class="p">(</span><span class="o">-</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<p>could result in a change from the above log to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="o">***</span> <span class="nx">RSS</span><span class="o">:</span>  <span class="mf">14.59375</span> <span class="nx">mb</span>
</span><span class='line'><span class="nx">packets</span><span class="o">:</span> <span class="mi">4074145</span>
</span><span class='line'>
</span><span class='line'><span class="o">***</span> <span class="nx">RSS</span><span class="o">:</span>  <span class="mf">17.60546875</span> <span class="nx">mb</span>
</span><span class='line'><span class="nx">packets</span><span class="o">:</span> <span class="mi">4081558</span>
</span><span class='line'>
</span><span class='line'><span class="o">***</span> <span class="nx">RSS</span><span class="o">:</span>  <span class="mf">17.64453125</span> <span class="nx">mb</span>
</span><span class='line'><span class="nx">packets</span><span class="o">:</span> <span class="mi">4081568</span>
</span></code></pre></td></tr></table></div></figure>


<p>If you&#8217;re interested in the specifics of the patch, you can <a href="https://github.com/joyent/node/pull/2522">see them here along with the pull request</a>. The patch isn&#8217;t that exciting - I simply ported the slab allocation code from libuv&#8217;s <code>stream_wrap.cc</code> file which handles streaming networking connections to the <code>udp_wrap.cc</code> file which specifically pertains to datagrams. I&#8217;m happy to report that the next stable version of node, v0.6.8 (<a href="https://github.com/joyent/node/blob/d18cebaf8a7ac701dabd71a3aa4eb0571db6a645/ChangeLog#L19">changelog here</a>) shipped with my patch, and that the memory usage of the node process under heavy datagram load shows a stable memory profile.</p>

<p>There have been many times where I have not bothered to get involved in a project, and instead settled for suboptimal performance or degraded functionality in a software library. I wanted to share this example of when I decided to step up, and I hope that reading this story reminds people like me who have made a career out of using open source software that it&#8217;s possible to get involved in projects of any size – you just need to be persistent, patient, and highly tolerant to pain.</p>

<p><em>Want to be patching, shipping, and learning every day? <a href="http://www.paperlesspost.com/jobs">We&#8217;re hiring in NYC and SF</a>.</em></p>
]]></content>
  </entry>
  
</feed>
