<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Paul Gross's Blog</title>
	
	<link>http://www.pgrs.net</link>
	<description />
	<lastBuildDate>Mon, 01 Apr 2013 05:30:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/pgrs" /><feedburner:info uri="pgrs" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>High Availability at Braintree</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/FNTLKlt7Tjk/</link>
		<comments>http://www.pgrs.net/2013/02/21/high-availability-at-braintree/#comments</comments>
		<pubDate>Fri, 22 Feb 2013 02:54:41 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pgrs.net/?p=22515</guid>
		<description><![CDATA[Update (3/31/13): The video of the talk is online: High Availability at Braintree The slides from my RubyConf Australia talk are now online: High Availability at Braintree. The slides were generated using showoff.]]></description>
			<content:encoded><![CDATA[<p><strong>Update (3/31/13):</strong> The video of the talk is online: <a href="http://vimeo.com/61255649">High Availability at Braintree</a></p>
<p>The slides from my <a href="http://www.rubyconf.org.au">RubyConf Australia</a> talk are now online: <a href='http://www.pgrs.net/wp-content/uploads/2013/02/rubyconf_australia_high_availability.pdf'>High Availability at Braintree</a>.</p>
<p>The slides were generated using <a href="https://github.com/schacon/showoff">showoff</a>.</p>
<img src="http://feeds.feedburner.com/~r/pgrs/~4/FNTLKlt7Tjk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2013/02/21/high-availability-at-braintree/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2013/02/21/high-availability-at-braintree/</feedburner:origLink></item>
		<item>
		<title>Scaling PostgreSQL at Braintree: Four Years of Evolution</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/uMZj5FPikxU/</link>
		<comments>http://www.pgrs.net/2012/10/16/scaling-postgresql-at-braintree-four-years-of-evolution/#comments</comments>
		<pubDate>Tue, 16 Oct 2012 18:37:25 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pgrs.net/?p=22505</guid>
		<description><![CDATA[This post is cross-posted at Scaling PostgreSQL at Braintree: Four Years of Evolution. We love PostgreSQL at Braintree. Although we use many different data stores (such as Riak, MongoDB, Redis, and Memcached), most of our core data is stored in PostgreSQL. It&#8217;s not as sexy as the new NoSQL databases, but PostgreSQL is consistent and <a href='http://www.pgrs.net/2012/10/16/scaling-postgresql-at-braintree-four-years-of-evolution/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>This post is cross-posted at <a href="https://www.braintreepayments.com/braintrust/scaling-postgresql-at-braintree-four-years-of-evolution">Scaling PostgreSQL at Braintree: Four Years of Evolution</a>.</p>
<p>We love <a href="http://www.postgresql.org/">PostgreSQL</a> at Braintree. Although we use many different data stores (such as <a href="http://basho.com/products/riak-overview/">Riak</a>, <a href="http://www.mongodb.org/">MongoDB</a>, <a href="http://redis.io/">Redis</a>, and <a href="http://memcached.org/">Memcached</a>), most of our core data is stored in PostgreSQL. It&#8217;s not as sexy as the new NoSQL databases, but PostgreSQL is consistent and incredibly reliable, two properties we value when storing payment information.</p>
<p>We also love the ad-hoc querying that we get from a relational database. For example, if our traffic looks fishy, we can answer questions like &#8220;What is the percentage of Visa declines coming from Europe?&#8221; without having to pre-compute views or write complex map/reduce queries.</p>
<p>Our PostgreSQL setup has changed a lot over the last few years. In this post, I&#8217;m going to walk you through the evolution of how we host and use PostgreSQL. We&#8217;ve had a lot of help along the way from the very knowledgeable people at <a href="http://www.commandprompt.com/">Command Prompt</a>.</p>
<h3>2008: The beginning</h3>
<p>Like most <a href="http://rubyonrails.org/">Ruby on Rails</a> apps in 2008, our gateway started out on <a href="https://www.mysql.com/">MySQL</a>. We ran a couple of app servers and two database servers replicated using <a href="http://www.drbd.org/">DRBD</a>. DRBD uses block level replication to mirror partitions between servers. This setup was fine at first, but as our traffic started growing, we began to see problems.</p>
<h3>2010: The problems with MySQL</h3>
<p>The biggest problem we faced was that schema migrations on large tables took a long time with MySQL. As our dataset grew, our deploys started taking longer and longer. We were iterating quickly, and our schema was evolving. We couldn&#8217;t keep affording to take downtime while we upgraded or even added a new index to a large table.</p>
<p>We explored various options with MySQL (such as <a href="https://openarkkit.googlecode.com/svn/trunk/openarkkit/doc/html/oak-online-alter-table.html">oak-online-alter-table</a>), but decided that we would rather move to a database that supported it directly. We were also starting to see deadlock issues with MySQL, which were on operations we felt shouldn&#8217;t deadlock. PostgreSQL solved this problem as well.</p>
<p>We migrated from MySQL to PostgreSQL in the fall of 2010. You can read more about the migration on the <a href="http://www.pgrs.net/wp-content/uploads/2011/03/pgeast_presentation.pdf">slides from my PgEast talk</a>. PostgreSQL 9.0 was recently released, but we chose to go with version 8.4 since it had been out longer and was more well known.</p>
<h3>2010 &#8211; 2011: Initial PostgreSQL</h3>
<p>We ran PostgreSQL on modest hardware, and we kept DRBD for replication. This worked fine at first, but as our traffic continued to grow, we needed some upgrades. Unlike most applications, we are much heavier on writes than reads. For every credit card that we charge, we store a lot of data (such as customer information, raw responses from the processing networks, and table audits).</p>
<p>Over the next year, we performed the following upgrades:</p>
<ul>
<li>Tweaked our configs around checkpoints, shared buffers, work_mem and more (this is a great start: <a href="https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server">Tuning Your PostgreSQL Server</a>)</li>
<li>Moved the Write Ahead Log (WAL) to its own partition (so fsyncs of the WAL don&#8217;t flush all of the dirty data files)</li>
<li>Moved the WAL to its own pair of disks (so the sequential writes of the WAL are not slowed down by the random read/write of the data files)</li>
<li>Added more RAM</li>
<li>Moved to better servers (24 cores, 16 disks, even more RAM)</li>
<li>Added more RAM again (kept adding to keep the working set in RAM)</li>
</ul>
<h3>Fall 2011: Sharding</h3>
<p>These incremental improvements worked great for a long time, and our database was able to keep up with our ever increasing volume. In the summer of 2011, we started to feel like our traffic was going to outgrow a single server. We could keep buying better hardware, but we knew there was a limit.</p>
<p>We talked about a lot of different solutions, and in the end, we decided to horizontally shard our database by merchant. A merchant&#8217;s traffic would all live on one shard to make querying easier, but different merchants would live on different shards.</p>
<p>We used <a href="https://github.com/bpot/data_fabric">data_fabric</a> to introduce sharding into our Rails app. data_fabric lets you specify which models are sharded, and gives you methods for activating a specific shard. In conjunction with data_fabric, we also wrote a fair amount of custom code for sharding. We sharded every table except for a handful of global tables, such as merchants and users. Since almost every URL has the merchant id in it, we were able to activate shards in application_controller.rb for 99% of our traffic with code that looked roughly like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> ApplicationController <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActionController::Base</span>
  around_filter <span style="color:#ff3333; font-weight:bold;">:activate_shard</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> activate_shard<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
    merchant = Merchant.<span style="color:#9900CC;">find_by_public_id</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:merchant_id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    DataFabric.<span style="color:#9900CC;">activate_shard</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:shard</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> merchant.<span style="color:#9900CC;">shard</span>, <span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Making our code work with sharding was only half the battle. We still had to migrate merchants to a different shard (without downtime). We did this with <a href="https://github.com/markokr/skytools">londiste</a>, a statement-based replication tool. We set up the new database servers and used londiste to mirror the entire database between the current cluster (which we renamed to shard 0) and the new cluster (shard 1).</p>
<p>Then, we paused traffic<a href="#footnote-1">[1]</a>, stopped replication, updated the shard column in the global database, and resumed traffic. The whole process was automated using <a href="https://github.com/capistrano/capistrano">capistrano</a>. At this point, some requests went to the new database servers, and some to the old. Once we were sure everything was working, we removed the shard 0 data from shard 1 and vice versa.</p>
<p>The final cutover was completed in the fall of 2011.</p>
<h3>Spring 2012: DRBD Problems</h3>
<p>Sharding took care of our performance problems, but in the spring of 2012, we started running into issues with our DRBD replication:</p>
<ul>
<li>DRBD made replicating between two servers very easy, but more than two required complex stacked resources that were harder to orchestrate. It also required more moving pieces, like <a href="https://www.linbit.com/products-services/drbd-proxy/">DRBD Proxy</a> to prevent blocking writes between data centers.</li>
<li>DRBD is block level replication, so the filesystem is shared between servers. This means it can never be unmounted and checked (fsck) without taking downtime. We become increasingly concerned that filesystem corruption would go unnoticed and corrupt all servers in the cluster.</li>
<li>The filesystem can only be mounted on the primary server, so the standby servers sit idle. It is not possible to run read-only queries on them.</li>
<li>Failover required unmounting and remounting filesystems, so it was slower than desired. Also, since the filesystem was unmounted on the target server, once mounted, the filesystem cache was empty. This meant that our backup PostgreSQL was slow after failover, and we would see slow requests and sometimes timeouts.</li>
<li>We saw a couple of issues in our sandbox environment where DRBD issues on the secondary prevented writes on the primary node. Thankfully, these never occurred in production, but we had a lot of trouble tracking down the issue.</li>
<li>We were still using manual failover because we were scared of the horror stories with <a href="http://www.clusterlabs.org/">Pacemaker</a> and DRBD causing split brain scenarios and data corruption. We wanted to get to automated failover, however.</li>
<li>DRBD required a kernel module, so we had to build and test a new module every time we upgraded the kernel.</li>
<li>One upgrade of DRBD caused a huge degradation of write performance . Thankfully, we discovered the issue in our test environment, but it was another reason to be wary of kernel level replication.</li>
</ul>
<p>Given all of these concerns, we decided to leave DRBD replication and move to PostgreSQL streaming replication (which was new in PostgreSQL 9). We felt like it was a better fit for what we wanted to do. We could replicate to many servers easily, standby servers were queryable letting us offload some expensive queries, and failover was very quick.</p>
<p>We made the switch during the summer of 2012.</p>
<h3>Summer 2012: PostgreSQL 9.1</h3>
<p>We updated our code to support PostgreSQL 9.1 (which involved very few code changes). Along with the upgrade, we wanted to move to fully automated failover. We decided to use Pacemaker and these great open source scripts for managing PostgreSQL streaming replication: <a href="https://github.com/t-matsuo/resource-agents/wiki">https://github.com/t-matsuo/resource-agents/wiki</a>. These scripts handle promotion, moving the database IPs, and even switching from sync to async mode if there are no more standby servers.</p>
<p>We set up our new database clusters (one per shard). We used two servers per datacenter, with synchronous replication within the datacenter and asynchronous replication between our datacenters. We configured Pacemaker and had the clusters ready to go (but empty). We performed extensive testing on this setup to fully understand the failover scenarios and exactly how Pacemaker would react.</p>
<p>We used londiste again to copy the data. Once the clusters were up to date, we did a similar cutover: we paused traffic, stopped londiste, updated our database.yml, and then resumed traffic. We did this one shard at a time, and the entire procedure was automated with capistrano. Again, we took no downtime.</p>
<h3>Fall 2012: Today</h3>
<p>Today, we&#8217;re in a good state with PostgreSQL. We have fully automated failover between servers (within a datacenter). Our cross datacenter failover is still manual since we want to be sure before we give up on an entire datacenter. We have automated capistrano tasks to orchestrate controlled failover using Pacemaker and traffic pausing. This means we can perform database maintenance with zero downtime.</p>
<p>One of our big lessons learned is that we need to continually invest in our PostgreSQL setup. We&#8217;re always watching our PostgreSQL performance and making adjustments where needed (new indexes, restructuring our data, config tuning, etc). Since our traffic continues to grow and we record more and more data, we know that our PostgreSQL setup will continue to evolve over the coming years.</p>
<p id="footnote-1">
  [1] For more info on how we pause traffic, check out <a href="https://www.braintreepayments.com/braintrust/switching-datacenters">How We Moved Our Data Center 25 Miles Without Downtime</a> and <a href="http://drewolson.org/braintree_ha/presentation.html">High Availability at Braintree</a></p>
<img src="http://feeds.feedburner.com/~r/pgrs/~4/uMZj5FPikxU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2012/10/16/scaling-postgresql-at-braintree-four-years-of-evolution/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2012/10/16/scaling-postgresql-at-braintree-four-years-of-evolution/</feedburner:origLink></item>
		<item>
		<title>Testing Interactions with a State Based Approach</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/RhYj1-igPas/</link>
		<comments>http://www.pgrs.net/2012/07/07/testing-interactions-with-a-state-based-approach/#comments</comments>
		<pubDate>Sun, 08 Jul 2012 00:08:38 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pgrs.net/?p=22492</guid>
		<description><![CDATA[There are two main types of unit tests: state based and interaction based. State based tests rely on the verification of state. These tests typically perform some operation and then check the state of the resulting object: user = User.new :title =&#62; 'manager' user.promote! user.title.should == 'senior manager' In contrast, interaction based tests rely on <a href='http://www.pgrs.net/2012/07/07/testing-interactions-with-a-state-based-approach/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>There are two main types of unit tests: state based and interaction based. State based tests rely on the verification of state. These tests typically perform some operation and then check the state of the resulting object:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">user = User.<span style="color:#9900CC;">new</span> <span style="color:#ff3333; font-weight:bold;">:title</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'manager'</span>
user.<span style="color:#9900CC;">promote</span>!
user.<span style="color:#9900CC;">title</span>.<span style="color:#9900CC;">should</span> == <span style="color:#996600;">'senior manager'</span></pre></div></div>

<p>In contrast, interaction based tests rely on verification of the interaction between objects. This is generally done with mocks or stubs:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">user = User.<span style="color:#9900CC;">new</span>
Mailer.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:send_email</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">with</span><span style="color:#006600; font-weight:bold;">&#40;</span>user<span style="color:#006600; font-weight:bold;">&#41;</span>
user.<span style="color:#9900CC;">activate</span>!</pre></div></div>

<p>This test ensures that the <code>activate!</code> method interacts with the <code>Mailer</code>, without actually sending an email.</p>
<p>Interaction based testing has its uses, but in general, I prefer state based testing. I think that tests full of mocks are brittle and hard to read. Furthermore, when they fail, it can be difficult to understand why.</p>
<p>In my testing, I try to replace interaction based testing with state based when possible. I&#8217;m going to walk through an example where a typical test would use mocks, but I&#8217;m going to use a state based approad instead.</p>
<p>Say I have a Rails 3 application that accepts social security numbers. These are sensitive, so I want to make sure I don&#8217;t log them to the application log. A simple testing approach (using <a href="https://www.relishapp.com/rspec/">rspec</a>) might look like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'spec_helper'</span>
&nbsp;
describe MyController <span style="color:#9966CC; font-weight:bold;">do</span>
  describe <span style="color:#996600;">&quot;create&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    it <span style="color:#996600;">&quot;filters sensitive data from the log&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      Rails.<span style="color:#9900CC;">logger</span>.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:info</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">with</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>message<span style="color:#006600; font-weight:bold;">|</span> message.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;123-45-6789&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">never</span> 
      post <span style="color:#ff3333; font-weight:bold;">:create</span>, <span style="color:#ff3333; font-weight:bold;">:myobj</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:social_security_number <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;123-45-6789&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>One problem with this test is that it&#8217;s a negative test. It can pass for the wrong reasons. For example, if the controller action blows up before it would normally log, the test may pass even though it would log under normal circumstances. It&#8217;s generally better to write a possitive test:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'spec_helper'</span>
&nbsp;
describe MyController <span style="color:#9966CC; font-weight:bold;">do</span>
  describe <span style="color:#996600;">&quot;create&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    it <span style="color:#996600;">&quot;filters sensitive data from the log&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      Rails.<span style="color:#9900CC;">logger</span>.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:info</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">with</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#9966CC; font-weight:bold;">include</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'&quot;social_security_number&quot;=&gt;&quot;[FILTERED]&quot;'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      post <span style="color:#ff3333; font-weight:bold;">:create</span>, <span style="color:#ff3333; font-weight:bold;">:myobj</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:social_security_number <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;123-45-6789&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>This test is better, but still not great. One problem is that <code>Rails.logger.info</code> is now mocked out, so there will be no logging which can make debugging a failing test more difficult. Another problem is that if the test fails, the test output only says expectation not met. It does not show you what was actually logged:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span> MyController create filters sensitive data from the log
     Failure<span style="color:#006600; font-weight:bold;">/</span>Error: Rails.<span style="color:#9900CC;">logger</span>.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:info</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">with</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#9966CC; font-weight:bold;">include</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'&quot;social_security_number&quot;=&gt;&quot;[FILTERED]&quot;'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
       <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#008000; font-style:italic;">#&lt;ActiveSupport::TaggedLogging:0x007fcf39201a10&gt;).info(include &quot;\&quot;social_security_number\&quot;=&gt;\&quot;[FILTERED]\&quot;&quot;)</span>
           expected: <span style="color:#006666;">1</span> time
           received: <span style="color:#006666;">0</span> times
     <span style="color:#008000; font-style:italic;"># ./spec/controllers/my_controller_spec.rb:7:in `block (3 levels) in &lt;top (required)&gt;'</span></pre></div></div>

<p>Here is the state based test I prefer:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'spec_helper'</span>
&nbsp;
describe MyController <span style="color:#9966CC; font-weight:bold;">do</span>
  describe <span style="color:#996600;">&quot;create&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    it <span style="color:#996600;">&quot;filters sensitive data from the log&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      post <span style="color:#ff3333; font-weight:bold;">:create</span>, <span style="color:#ff3333; font-weight:bold;">:myobj</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:social_security_number <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;123-45-6789&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
      log_line = Rails.<span style="color:#9900CC;">logger</span>.<span style="color:#9900CC;">log_history</span>.<span style="color:#9900CC;">grep</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>Parameters:<span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">first</span>
      log_line.<span style="color:#9900CC;">should</span> <span style="color:#9966CC; font-weight:bold;">include</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'&quot;social_security_number&quot;=&gt;&quot;[FILTERED]&quot;'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>This test actually grabs the log line from a log history. If we don&#8217;t find the log line, it will be obvious. If we do find the line, we can compare the expected output with the actual one.</p>
<p>Now, the test failure contains both the expected and actual:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span> MyController create filters sensitive data from the log
     Failure<span style="color:#006600; font-weight:bold;">/</span>Error: log_line.<span style="color:#9900CC;">should</span> <span style="color:#9966CC; font-weight:bold;">include</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'&quot;social_security_number&quot;=&gt;&quot;[FILTERED]&quot;'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
       expected <span style="color:#996600;">&quot;  Parameters: {<span style="color:#000099;">\&quot;</span>myobj<span style="color:#000099;">\&quot;</span>=&gt;{<span style="color:#000099;">\&quot;</span>social_security_number<span style="color:#000099;">\&quot;</span>=&gt;<span style="color:#000099;">\&quot;</span>123-45-6789<span style="color:#000099;">\&quot;</span>}}&quot;</span> to <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#996600;">&quot;<span style="color:#000099;">\&quot;</span>social_security_number<span style="color:#000099;">\&quot;</span>=&gt;<span style="color:#000099;">\&quot;</span>[FILTERED]<span style="color:#000099;">\&quot;</span>&quot;</span>
     <span style="color:#008000; font-style:italic;"># ./spec/controllers/my_controller_spec.rb:9:in `block (3 levels) in &lt;top (required)&gt;'</span></pre></div></div>

<p>We can monkey patch <code>Rails.logger</code> to record the log lines in <code>spec_helper.rb</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">module</span> LogHistory
  <span style="color:#9966CC; font-weight:bold;">def</span> add<span style="color:#006600; font-weight:bold;">&#40;</span>_, _, message = <span style="color:#0000FF; font-weight:bold;">nil</span>, <span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
    log_history <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> message
    <span style="color:#9966CC; font-weight:bold;">super</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> log_history
    <span style="color:#0066ff; font-weight:bold;">@log_history</span> <span style="color:#006600; font-weight:bold;">||</span>= <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> clear_log_history
    log_history.<span style="color:#9900CC;">clear</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
RSpec.<span style="color:#9900CC;">configure</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>config<span style="color:#006600; font-weight:bold;">|</span>
  config.<span style="color:#9900CC;">before</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:suite</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    Rails.<span style="color:#9900CC;">logger</span>.<span style="color:#9900CC;">extend</span><span style="color:#006600; font-weight:bold;">&#40;</span>LogHistory<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  config.<span style="color:#9900CC;">before</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    Rails.<span style="color:#9900CC;">logger</span>.<span style="color:#9900CC;">clear_log_history</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now, every log line is recorded per test and cleared out in between. This pattern also works well for other external dependencies, such as database statements or queries sent to a search tool. They can be recorded and asserted against directly.</p>
<img src="http://feeds.feedburner.com/~r/pgrs/~4/RhYj1-igPas" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2012/07/07/testing-interactions-with-a-state-based-approach/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2012/07/07/testing-interactions-with-a-state-based-approach/</feedburner:origLink></item>
		<item>
		<title>Automate statement downloading with statement_hoarder</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/DysDwxrtcOc/</link>
		<comments>http://www.pgrs.net/2012/06/03/automate-statement-downloading-with-statement_hoarder/#comments</comments>
		<pubDate>Mon, 04 Jun 2012 00:55:45 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pgrs.net/?p=22484</guid>
		<description><![CDATA[If you&#8217;re like me, you&#8217;ve switched all of your websites to paperless statements. No more bank, credit card, or utility statements arrive in the mail. But you would still like to have copies of these important documents, so you log in to each website and download the PDF statements. Downloading these statements is tedious and <a href='http://www.pgrs.net/2012/06/03/automate-statement-downloading-with-statement_hoarder/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re like me, you&#8217;ve switched all of your websites to paperless statements. No more bank, credit card, or utility statements arrive in the mail. But you would still like to have copies of these important documents, so you log in to each website and download the PDF statements.</p>
<p>Downloading these statements is tedious and time consuming. That&#8217;s where <a href="https://github.com/pgr0ss/statement_hoarder">statement_hoarder</a> comes in. It automates this process across many different sites.</p>
<p>To get started, follow the instructions on GitHub: <a href="https://github.com/pgr0ss/statement_hoarder">statement_hoarder</a></p>
<p>If you are interested in contributing (for example, adding support for new websites), please help out on Github. Feel free to open issues, submit pull requests, and help make it better.</p>
<img src="http://feeds.feedburner.com/~r/pgrs/~4/DysDwxrtcOc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2012/06/03/automate-statement-downloading-with-statement_hoarder/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2012/06/03/automate-statement-downloading-with-statement_hoarder/</feedburner:origLink></item>
		<item>
		<title>How Braintree Builds a Platform for Developers</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/Np7yENuGGRg/</link>
		<comments>http://www.pgrs.net/2012/05/02/how-braintree-builds-a-platform-for-developers/#comments</comments>
		<pubDate>Thu, 03 May 2012 01:34:35 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pgrs.net/?p=22468</guid>
		<description><![CDATA[The slides from my Intuit CTOF (&#8220;Create The Offering Forum&#8221;) talk are now online: How Braintree Builds a Platform for Developers. The slides were generated using showoff.]]></description>
			<content:encoded><![CDATA[<p>The slides from my <a href="http://ctof.intuit.com">Intuit CTOF</a> (&#8220;Create The Offering Forum&#8221;) talk are now online: <a href='http://www.pgrs.net/wp-content/uploads/2012/05/intuit_presentation.pdf'>How Braintree Builds a Platform for Developers</a>.</p>
<p>The slides were generated using <a href="https://github.com/schacon/showoff">showoff</a>.</p>
<img src="http://feeds.feedburner.com/~r/pgrs/~4/Np7yENuGGRg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2012/05/02/how-braintree-builds-a-platform-for-developers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2012/05/02/how-braintree-builds-a-platform-for-developers/</feedburner:origLink></item>
		<item>
		<title>Data Migrations for NoSQL with Curator</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/F8xSYJvFnb4/</link>
		<comments>http://www.pgrs.net/2012/03/08/data-migrations-for-nosql-with-curator/#comments</comments>
		<pubDate>Thu, 08 Mar 2012 15:41:55 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pgrs.net/?p=22458</guid>
		<description><![CDATA[This post is cross-posted at Data Migrations for NoSQL with Curator. The NoSQL movement has brought us a wave of new data stores beyond the traditional relational databases. These data stores come with their own tradeoffs, but they provide some incredible benefits. At Braintree, we are moving in the direction of using Riak as our <a href='http://www.pgrs.net/2012/03/08/data-migrations-for-nosql-with-curator/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>This post is cross-posted at <a href="http://www.braintreepayments.com/devblog/data-migrations-for-nosql-with-curator">Data Migrations for NoSQL with Curator</a>.</p>
<p>The NoSQL movement has brought us a wave of new data stores beyond the traditional relational databases. These data stores come with their own tradeoffs, but they provide some incredible benefits. At <a href="http://www.braintreepayments.com/">Braintree</a>, we are moving in the direction of using <a href="http://basho.com/products/riak-overview/">Riak</a> as our next generation data store. We love its focus on scalability and availability. Servers can fail without causing any downtime, and we can add more capacity by simply adding more servers to the cluster.</p>
<p>One great feature of relational databases, however, is the consistency in the shape of the data. You know if you have a <code>people</code> table, every row has the same columns. Some fields might be null, but there won&#8217;t be any surprises. Furthermore, if you want to rename or modify a column, it&#8217;s a simple operation. In the case of <a href="http://www.postgresql.org/">PostgreSQL</a> and other databases, a rename is nearly instantaneous. We lose this ability with Riak and most NoSQL databases. We can easily add attributes (columns), but we cannot easily rename them or change the data within each document (row).</p>
<p>Since our apps are always evolving at Braintree, we needed a way for our data to keep up with our code. Our solution is something we&#8217;re calling lazy data migrations, and we&#8217;ve built it into our repository and model framework, <a href="https://github.com/braintree/curator">curator</a>. You can read more about curator on our blog at <a href="http://www.braintreepayments.com/devblog/untangle-domain-and-persistence-logic-with-curator">Untangle Domain and Persistence Logic with Curator</a>.</p>
<h3>The problem</h3>
<p>Say we have a collection of <code>people</code> in Riak. This is analogous to a <code>people</code> table in a relational database. When we first built the app, we added fields for <code>first_name</code> and <code>last_name</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">person = Person.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:first_name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Joe&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:last_name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Smith&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Some time has passed, our app has data, and we now realize that names are a pain. What do we do with middle names? What about people with multiple first or last names? We want to just simplify the system and collect only a name. We no longer care about a separate first and last name. The problem is we have a ton of data in the old format. How do we handle that old records have a <code>first_name</code> and <code>last_name</code>, but going forward, we want just <code>name</code>?</p>
<p>In a relational database, we would simply write a database migration that looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span> people <span style="color: #993333; font-weight: bold;">ADD</span> <span style="color: #993333; font-weight: bold;">COLUMN</span> name <span style="color: #993333; font-weight: bold;">VARCHAR</span>;
<span style="color: #993333; font-weight: bold;">UPDATE</span> people <span style="color: #993333; font-weight: bold;">SET</span> name <span style="color: #66cc66;">=</span> first_name <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">' '</span> <span style="color: #66cc66;">||</span> last_name;
<span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span> people <span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">COLUMN</span> first_name<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">COLUMN</span> last_name;</pre></div></div>

<p>This migration might take a while to run, but once it&#8217;s done, we know that all data has been migrated. We can then change all of our code to only deal with <code>name</code>, knowing we no longer have <code>first_name</code> or <code>last_name</code>.</p>
<p>In a NoSQL database like Riak, we cannot simply change the schema. We have to come up with a different solution. Here are the steps we went through in trying to come up with the solution that made its way into <a href="https://github.com/braintree/curator">curator</a>:</p>
<h3>Solution attempt 1: Scattered conditionals</h3>
<p>The first solution is to make the <code>Person</code> class smart enough to handle both cases.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Person
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:first_name</span>, <span style="color:#ff3333; font-weight:bold;">:last_name</span>, <span style="color:#ff3333; font-weight:bold;">:name</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>We can populate whatever fields we get back from the data store. Then, when we want to do something with the <code>name</code>, we have to use code like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">if</span> person.<span style="color:#9900CC;">name</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Name is #{person.name}&quot;</span>
<span style="color:#9966CC; font-weight:bold;">else</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Name is #{person.first_name} #{person.last_name}&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>The problem with this approach is that we have to use branching code like this whenever we want to use the <code>name</code>. It quickly gets messy.</p>
<h3>Solution attempt 2: Gathered conditionals</h3>
<p>The second solution is to move this logic to the place where we read the Person out of the data store:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">attributes = fetch_from_riak
<span style="color:#9966CC; font-weight:bold;">if</span> attributes<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:name</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  person = Person.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> attributes<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:name</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">else</span>
  person = Person.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;#{attributes[:first_name]} #{attributes[:last_name]}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now, we only have to do it once and we can change our <code>Person</code> class to only know about <code>name</code>.</p>
<p>This solution works well, but what happens a year down the road when we&#8217;ve made lots of data changes to many different models? We don&#8217;t want a bunch of conditionals all over our persistence code.</p>
<h3>Our solution: Lazy data migrations</h3>
<p>We pulled the idea from solution 2 into the idea of a migration (similar to ActiveRecord migrations). Migrations target a given collection at a given version. They look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> ConsolidateName <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">Curator::Migration</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> migrate<span style="color:#006600; font-weight:bold;">&#40;</span>attributes<span style="color:#006600; font-weight:bold;">&#41;</span>
    first_name = attributes.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:first_name</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    last_name = attributes.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:last_name</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    attributes.<span style="color:#9900CC;">merge</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;#{first_name} #{last_name}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>This migration is stored in <code>db/migrate/people/0001_consolidate_name.rb</code>. We&#8217;ve also added the concept of a version to each Model. By default, models start at version 0. When they are read from the Repository, the attributes are run through any migrations that are a greater version (based on the version in the filename):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">person = PersonRepository.<span style="color:#9900CC;">find_by_key</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;person_id&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
person.<span style="color:#9900CC;">version</span> <span style="color:#008000; font-style:italic;">#=&gt; 1</span></pre></div></div>

<p>Now, the migration logic is isolated from the rest of the application. The rest of the app can safely assume that all <code>Person</code> objects have only a <code>name</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Person
  current_version <span style="color:#006666;">1</span>
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:name</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>We mark the <code>Person</code> class with <code>current_version 1</code> to signify that new instances start at version 1, since they have a <code>name</code> attribute rather than <code>first_name</code>/<code>last_name</code>. </p>
<p>These migrations run when models are read, so they are lazy. Data will migrate as it&#8217;s used, and update when saved. This means that, unlike with relational databases, the website can be up and serving requests while the data is migrated.</p>
<p>If you want to force the data to migrate (and not wait for all data to be used), you can simply find models who haven&#8217;t been migrated and save them. The <code>version</code> attribute is indexed by default:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">PersonRepository.<span style="color:#9900CC;">find_by_version</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>person<span style="color:#006600; font-weight:bold;">|</span>
  PersonRepository.<span style="color:#9900CC;">save</span><span style="color:#006600; font-weight:bold;">&#40;</span>person<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<h3>Testing</h3>
<p>Unlike ActiveRecord migrations, curator migrations have no side effects. They simply accept a hash and return a new hash. This makes them easy to call from a unit test:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'spec_helper'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'db/migrate/people/0001_consolidate_name'</span>
&nbsp;
describe ConsolidateName <span style="color:#9966CC; font-weight:bold;">do</span>
  describe <span style="color:#996600;">&quot;migrate&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    it <span style="color:#996600;">&quot;concatenates first_name and last_name&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      attributes = <span style="color:#006600; font-weight:bold;">&#123;</span>:first_name <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Joe&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:last_name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Smith&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
      ConsolidateName.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">migrate</span><span style="color:#006600; font-weight:bold;">&#40;</span>attributes<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:name</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">should</span> == <span style="color:#996600;">&quot;Joe Smith&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<h3>Limitations</h3>
<p>Curator migrations are lazy, so at any given time you might have documents with different versions in the data store. This is not normally a problem since the migrations will run as soon as the objects are read. However, if you add a migration that changes an indexed field, you cannot rely on that index to return all of the correct values until you migrate them all. In this case, you might want to force migration by reading and saving all of the documents.</p>
<h3>Next Steps</h3>
<p>You can see these migrations in action in the <a href="https://github.com/braintree/curator_rails_example">curator_rails_example</a>.</p>
<p>Let us know what you think about lazy data migrations in <a href="https://github.com/braintree/curator">curator</a>. Feel free to open issues on GitHub, submit pull requests, and help us make it better.</p>
<img src="http://feeds.feedburner.com/~r/pgrs/~4/F8xSYJvFnb4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2012/03/08/data-migrations-for-nosql-with-curator/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2012/03/08/data-migrations-for-nosql-with-curator/</feedburner:origLink></item>
		<item>
		<title>Untangle Domain and Persistence Logic with Curator</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/JLNxWUkp5uo/</link>
		<comments>http://www.pgrs.net/2012/02/21/untangle-domain-and-persistence-logic-with-curator/#comments</comments>
		<pubDate>Tue, 21 Feb 2012 15:46:14 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pgrs.net/?p=22449</guid>
		<description><![CDATA[This post is cross-posted at http://www.braintreepayments.com/devblog/untangle-domain-and-persistence-logic-with-curator. The problem Ruby on Rails is a great web framework, and we use it extensively at Braintree to build web apps. One criticism of Rails, however, is that it encourages tight coupling of domain and persistence layers. The convention in Ruby on Rails is for domain objects to extend <a href='http://www.pgrs.net/2012/02/21/untangle-domain-and-persistence-logic-with-curator/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>This post is cross-posted at <a href="http://www.braintreepayments.com/devblog/untangle-domain-and-persistence-logic-with-curator">http://www.braintreepayments.com/devblog/untangle-domain-and-persistence-logic-with-curator</a>.</p>
<h3>The problem</h3>
<p><a href="http://rubyonrails.org/">Ruby on Rails</a> is a great web framework, and we use it extensively at <a href="http://www.braintreepayments.com/">Braintree</a> to build web apps. One criticism of Rails, however, is that it encourages tight coupling of domain and persistence layers. The convention in Ruby on Rails is for domain objects to extend <code>ActiveRecord::Base</code> and directly gain persistence. This makes building small apps easy, but as applications grow, the tight coupling starts to make things more difficult.</p>
<p>Domain objects in more complicated systems no longer have a simple mapping into a database row. For example, money might be represented as cents and currency in the database, but as a Money object in the domain layer. Now, the domain objects have to handle both the money logic and the money persistence. Even if the code is abstracted away by a gem, it still lives in the domain object. Take a look at the methods on a brand new model in Rails:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&gt;&gt;</span> <span style="color:#9966CC; font-weight:bold;">class</span> Bar <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> <span style="color:#006600; font-weight:bold;">&#40;</span>Bar.<span style="color:#9900CC;">methods</span>.<span style="color:#9900CC;">sort</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#CC00FF; font-weight:bold;">Object</span>.<span style="color:#9900CC;">methods</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">count</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">391</span></pre></div></div>

<p>These methods are in addition to anything you add to the model.</p>
<h3>The solution</h3>
<p>There&#8217;s nothing in Rails that says you have to tie your domain objects to persistence. It&#8217;s merely a convention. At <a href="http://www.braintreepayments.com/">Braintree</a>, we&#8217;re using a new convention for new projects. Our domain objects do not contain any persistence logic. Instead, we&#8217;ve introduced a <a href="http://domaindrivendesign.org/node/123">repository</a> layer which is in charge of the persistence of these domain objects. This pattern is well-documented in <a href="http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215">Domain Driven Design</a>.</p>
<p>Introducing a Repository layer into our applications has a number of benefits. The main benefit is that it separates out different kinds of logic. Domain logic goes into the domain objects, and can be tested in isolation without any persistence. Persistence logic goes into the repository objects, which only deal with saving and retrieving objects.</p>
<p>The second big benefit is that abstracting persistence logic into a repository allows us to swap persistence back-ends without much trouble. The most notable case is that we can swap in an in-memory data store for testing (or for most tests), but use Riak for the real application. Since the repository interacts with the back-end data store, the application code is the same regardless of back-end. It also allows us to use different back-ends for different kinds of data but still have a consistent pattern around persistence.</p>
<p>We&#8217;ve extracted this model and repository framework from our current applications and released it as <a href="https://github.com/braintree/curator">curator</a>. Curator currently supports <a href="http://basho.com/">Riak</a> as the persistence back-end, but more back-ends are coming soon.</p>
<p>Domain objects include <code>Curator::Model</code>, which just gives helper methods like an initialize that sets instance variables. It also adds some helper methods for Rails.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Note
  <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">Curator::Model</span>
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:id</span>, <span style="color:#ff3333; font-weight:bold;">:title</span>, <span style="color:#ff3333; font-weight:bold;">:description</span>, <span style="color:#ff3333; font-weight:bold;">:user_id</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
note = Note.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:title</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;My Note&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:description</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;My description&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> note.<span style="color:#9900CC;">description</span></pre></div></div>

<p>These model classes don&#8217;t have a lot of extra stuff:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&gt;&gt;</span> <span style="color:#9966CC; font-weight:bold;">class</span> Bar
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span>   <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">Curator::Model</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> Bar.<span style="color:#9900CC;">methods</span>.<span style="color:#9900CC;">sort</span> <span style="color:#006600; font-weight:bold;">-</span> <span style="color:#CC00FF; font-weight:bold;">Object</span>.<span style="color:#9900CC;">methods</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:_to_partial_path</span>, <span style="color:#ff3333; font-weight:bold;">:current_version</span>, <span style="color:#ff3333; font-weight:bold;">:model_name</span>, <span style="color:#ff3333; font-weight:bold;">:version</span><span style="color:#006600; font-weight:bold;">&#93;</span></pre></div></div>

<p>Repositories include the <code>Curator::Repository</code> module:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> NoteRepository
  <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">Curator::Repository</span>
  indexed_fields <span style="color:#ff3333; font-weight:bold;">:user_id</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Repositories have <code>save</code>, <code>find_by_id</code>, and <code>find_by</code> methods for indexed fields:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">note = Note.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:user_id</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;my_user&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
NoteRepository.<span style="color:#9900CC;">save</span><span style="color:#006600; font-weight:bold;">&#40;</span>note<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
NoteRepository.<span style="color:#9900CC;">find_by_id</span><span style="color:#006600; font-weight:bold;">&#40;</span>note.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#41;</span>
NoteRepository.<span style="color:#9900CC;">find_by_user_id</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;my_user&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>As persistence gets more complicated, repositories can implement their own serialize and deserialize methods to handle any case. For example, suppose our note object contains a PDF:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> NoteRepository
  <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">Curator::Repository</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">serialize</span><span style="color:#006600; font-weight:bold;">&#40;</span>note<span style="color:#006600; font-weight:bold;">&#41;</span>
    attributes = <span style="color:#9966CC; font-weight:bold;">super</span><span style="color:#006600; font-weight:bold;">&#40;</span>note<span style="color:#006600; font-weight:bold;">&#41;</span>
    attributes<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:pdf</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#CC00FF; font-weight:bold;">Base64</span>.<span style="color:#9900CC;">encode64</span><span style="color:#006600; font-weight:bold;">&#40;</span>note.<span style="color:#9900CC;">pdf</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> note.<span style="color:#9900CC;">pdf</span>
    attributes
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">deserialize</span><span style="color:#006600; font-weight:bold;">&#40;</span>attributes<span style="color:#006600; font-weight:bold;">&#41;</span>
    note = <span style="color:#9966CC; font-weight:bold;">super</span><span style="color:#006600; font-weight:bold;">&#40;</span>attributes<span style="color:#006600; font-weight:bold;">&#41;</span>
    note.<span style="color:#9900CC;">pdf</span> = <span style="color:#CC00FF; font-weight:bold;">Base64</span>.<span style="color:#9900CC;">decode64</span><span style="color:#006600; font-weight:bold;">&#40;</span>attributes<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:pdf</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> attributes<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:pdf</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    note
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>As you can see, all persistence logic around PDFs lives in the Repository. The Note class does not care how PDFs are stored.</p>
<h3>Curator in action</h3>
<p>If you want to see a simple, fully functional Rails application using curator, check out <a href="https://github.com/braintree/curator_rails_example">curator_rails_example</a>. I will detail the relevant bits below.</p>
<p>Thanks to Rails 3.x, you can include <code>ActiveModel::Validations</code> in any class to get validations. So if you want your note class to validate, it would look like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"> <span style="color:#9966CC; font-weight:bold;">class</span> Note
   <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">Curator::Model</span>
   <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">ActiveModel::Validations</span>
   attr_accessor <span style="color:#ff3333; font-weight:bold;">:id</span>, <span style="color:#ff3333; font-weight:bold;">:title</span>, <span style="color:#ff3333; font-weight:bold;">:description</span>
   validates <span style="color:#ff3333; font-weight:bold;">:title</span>, <span style="color:#ff3333; font-weight:bold;">:presence</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
 <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>You can also build forms from these objects. new.html.erb would look like:</p>

<div class="wp_syntax"><div class="code"><pre class="erb" style="font-family:monospace;">&lt;%= form_for @note do |f| %&gt;                                  
  &lt;%= f.error_messages %&gt;                                     
  &lt;dl&gt;                                                        
    &lt;dt&gt;&lt;%= f.label :title %&gt;&lt;/dt&gt;                            
    &lt;dd&gt;&lt;%= f.text_field :title %&gt;&lt;/dd&gt;                       
    &lt;dt&gt;&lt;%= f.label :description %&gt;&lt;/dt&gt;                      
    &lt;dd&gt;&lt;%= f.text_area :description, :size =&gt; &quot;60x12&quot; %&gt;&lt;/dd&gt;
  &lt;/dl&gt;                                                       
  &lt;%= f.submit &quot;Create&quot; %&gt;                                    
&lt;% end %&gt;</pre></div></div>

<p>And the controller looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> NotesController <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActionController::Base</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> new
    <span style="color:#0066ff; font-weight:bold;">@note</span> = Note.<span style="color:#9900CC;">new</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> create
    <span style="color:#0066ff; font-weight:bold;">@note</span> = Note.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>request.<span style="color:#9900CC;">POST</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:note</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@note</span>.<span style="color:#9900CC;">valid</span>?
      NoteRepository.<span style="color:#9900CC;">save</span><span style="color:#006600; font-weight:bold;">&#40;</span>@note<span style="color:#006600; font-weight:bold;">&#41;</span>
      redirect_to notes_path
    <span style="color:#9966CC; font-weight:bold;">else</span>
      render <span style="color:#ff3333; font-weight:bold;">:new</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>That&#8217;s it. Rails makes it really easy to build forms and validate against our models.<br />
Next Steps</p>
<p>Please check out the <a href="https://github.com/braintree/curator">curator</a> code and let us know what you think. Like all software, <a href="https://github.com/braintree/curator">curator</a> is a work in progress, so feel free to open issues on Github, submit pull requests, and help us make it better.</p>
<img src="http://feeds.feedburner.com/~r/pgrs/~4/JLNxWUkp5uo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2012/02/21/untangle-domain-and-persistence-logic-with-curator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2012/02/21/untangle-domain-and-persistence-logic-with-curator/</feedburner:origLink></item>
		<item>
		<title>Setting up a Zotac ZBOX with XBMC as a home theater PC</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/qS3OdxZlbiQ/</link>
		<comments>http://www.pgrs.net/2011/12/23/setting-up-a-zotac-zbox-with-xbmc-as-a-home-theater-pc/#comments</comments>
		<pubDate>Fri, 23 Dec 2011 21:14:20 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pgrs.net/?p=22427</guid>
		<description><![CDATA[I have wanted a Home theater PC for awhile to play movies, music, Hulu, and more through my TV. I thought briefly about buying a prebuilt device (like a Roku), but I decided to hack one together myself. My main motivation was flexibility and the fact that I like to tinker. Furthermore, I wanted a <a href='http://www.pgrs.net/2011/12/23/setting-up-a-zotac-zbox-with-xbmc-as-a-home-theater-pc/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I have wanted a <a href="http://en.wikipedia.org/wiki/Home_theater_PC">Home theater PC</a> for awhile to play movies, music, <a href="http://www.hulu.com">Hulu</a>, and more through my TV. I thought briefly about buying a prebuilt device (like a <a href="http://www.roku.com/">Roku</a>), but I decided to hack one together myself. My main motivation was flexibility and the fact that I like to tinker. Furthermore, I wanted a device with a hard drive that I could load up with files and play directly to a TV.</p>
<p>I asked around for recommendations, and several of my coworkers recommended <a href="http://www.zotac.com">Zotac</a>. After looking through their options, I decided on a <a href="http://www.zotac.com/index.php?page=shop.product_details&#038;flypage=flypage_images-SRW.tpl&#038;product_id=336&#038;category_id=118&#038;option=com_virtuemart&#038;Itemid=100170&#038;lang=en">Zotac ZBOX ID41</a> (here it is on <a href="http://www.amazon.com/gp/product/B004WO8OBC/ref=as_li_ss_tl?ie=UTF8&#038;camp=1789&#038;creative=390957&#038;creativeASIN=B004WO8OBC&#038;linkCode=as2&#038;tag=bablis-20">Amazon</a>).</p>
<h3>Setting up Ubuntu</h3>
<p>I decided to run <a href="https://wiki.ubuntu.com/OneiricOcelot">Ubuntu 11.10 Oneiric Ocelot</a> for the operating system. The Zotac ZBOX has no CD drive, so I downloaded the Ubuntu ISO from the website, and I used <a href="http://unetbootin.sourceforge.net">UNetbootin</a> to make a bootable USB drive. </p>
<p>I plugged an HDMI cable from the Zotac into my TV, and I plugged a wired USB keyboard and mouse in the Zotac. I inserted the USB drive and booted it up. It automatically booted from the drive, and I selected Install.</p>
<p>Once the installation was finished, I had to go to Settings -> Sound and choose the HDMI output. Then, sound correctly played through my TV.</p>
<h3>Setting up XMBC</h3>
<p>There is a lot of software for home theater PCs. I chose <a href="http://xbmc.org">XBMC</a> since it seems very polished and has a lot of plugins for different video sources (such as <a href="http://www.youtube.com">Youtube</a>). It&#8217;s also optimized for a remote instead of requiring a full keyboard.</p>
<p>I had to add an extra apt repository in order to install the latest version of XMBC (11.0 beta1). Here are the commands I ran:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> add-apt-repository ppa:nathan-renniewaldock<span style="color: #000000; font-weight: bold;">/</span>xbmc-stable
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> update
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> xbmc</pre></div></div>

<p>Then, I launched XBMC from Ubuntu. I was greeted with a screen that looked like:</p>
<p><a href="http://www.pgrs.net/wp-content/uploads/2011/12/xbmc-eden.jpg"><img src="http://www.pgrs.net/wp-content/uploads/2011/12/xbmc-eden-300x179.jpg" alt="" title="xbmc-eden" width="300" height="179" class="alignnone size-medium wp-image-22442" /></a></p>
<p>I went to Settings and changed my region to where I live. I also told XBMC to update my library on start. Then, I went to Weather and entered my zip code to get local weather. Next I went to Videos -> Add ons and installed a bunch of video add ons (such as Youtube, HGTV, etc).</p>
<p>At this point, I had to manually run XBMC whenever I restarted the computer. There are many strategies to boot directly into XBMC. I decided to just add XBMC as a Startup Item in Ubuntu. I also allowed Ubuntu to boot without a password. So Ubuntu boots up and then runs XBMC when it&#8217;s finished. If I need to go back to Ubuntu, I can just exit from XBMC.</p>
<h3>Uploading media</h3>
<p>XMBC uses filenames to figure out which movie or TV show a file represents. For example, with default settings, episodes of a TV show need to be named in one of the following formats:</p>
<pre>
foo.s01e01.*
foo.s01.e01.*
foo.s01_e01.*
foo_[s01]_[e01]_*
foo.1x01.*
foo.101.*
</pre>
<p>These files should be in a folder with the name of the show. The full set of instructions can be found on the XBMC website at <a href="http://wiki.xbmc.org/?title=TV_Shows_%28Video_Library%29">TV Shows (Video Library)</a>.</p>
<p>I created a Movies directory and a TV Shows directory under /home/paul/Videos and uploaded my media. Then, I added these directories to XMBC and set the content type to Movies and TV Shows respectively (see <a href="http://wiki.xbmc.org/index.php?title=Media_sources">Media Sources</a>).</p>
<p>Finally, I quit XBMC and restarted it. It scanned my directories and added the movies and TV shows to the library.</p>
<h3>Hulu</h3>
<p>Unfortunately, there are no officially supported Hulu plugins for XBMC. I managed to get an unoffical plugin working with some extra effort using <a href="http://forum.xbmc.org/showthread.php?t=79148">Bluecop&#8217;s beta video plugin repository</a>.</p>
<p>I downloaded the zip file from the site above and saved it to the Zotac. Then, in XBMC, I went to Settings -> Add ons and chose to install add ons from a zip file. At this point, the Hulu plugin appeared in the list of available plugins to install. I installed the plugin, but it still didn&#8217;t work.</p>
<p>By looking in the XBMC log (~/.xbmc/temp/xbmc.log), I discovered that Hulu requires a newer version of <a href="http://rtmpdump.mplayerhq.hu">rtmpdump</a> than Ubuntu ships with.</p>
<p>I built the latest rtmpdump from source with the following commands:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> libssl-dev
<span style="color: #c20cb9; font-weight: bold;">git</span> clone <span style="color: #c20cb9; font-weight: bold;">git</span>:<span style="color: #000000; font-weight: bold;">//</span>git.ffmpeg.org<span style="color: #000000; font-weight: bold;">/</span>rtmpdump
<span style="color: #7a0874; font-weight: bold;">cd</span> rtmpdump
<span style="color: #c20cb9; font-weight: bold;">make</span> <span style="color: #007800;">sys</span>=posix
<span style="color: #c20cb9; font-weight: bold;">cp</span> librtmp<span style="color: #000000; font-weight: bold;">/</span>librtmp.so.0 <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>i386-linux-gnu<span style="color: #000000; font-weight: bold;">/</span>librtmp.so.0</pre></div></div>

<p>The last step copies the new librtmp on top of the existing one, which isn&#8217;t great. Unfortunately, XBMC runs with a specified library path, so I couldn&#8217;t find an easy way to add a different directory to the path.</p>
<p>Now, Hulu works. Unfortunately, I have to browse for videos to play. If I search for a video, and then play it, I get the following error in the xbmc.log:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">ERROR: Error Type: <span style="color: #66cc66;">&lt;</span>type <span style="color: #483d8b;">'exceptions.AttributeError'</span><span style="color: #66cc66;">&gt;</span>
ERROR: Error Contents: _Info instance has no attribute <span style="color: #483d8b;">'videoid'</span>
ERROR: Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
                      File <span style="color: #483d8b;">&quot;/home/paul/.xbmc/addons/plugin.video.hulu/default.py&quot;</span>, line <span style="color: #ff4500;">56</span>, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
                        modes <span style="color: black;">&#40;</span> <span style="color: black;">&#41;</span>
                      File <span style="color: #483d8b;">&quot;/home/paul/.xbmc/addons/plugin.video.hulu/default.py&quot;</span>, line <span style="color: #ff4500;">36</span>, <span style="color: #ff7700;font-weight:bold;">in</span> modes
                        stream_media.<span style="color: black;">Main</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
                      File <span style="color: #483d8b;">&quot;/home/paul/.xbmc/addons/plugin.video.hulu/resources/lib/stream_hulu.py&quot;</span>, line <span style="color: #ff4500;">148</span>, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #0000cd;">__init__</span>
                        <span style="color: #008000;">self</span>.<span style="color: black;">queueAD</span><span style="color: black;">&#40;</span>video_id,<span style="color: #ff4500;">2</span>,<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
                      File <span style="color: #483d8b;">&quot;/home/paul/.xbmc/addons/plugin.video.hulu/resources/lib/stream_hulu.py&quot;</span>, line <span style="color: #ff4500;">420</span>, <span style="color: #ff7700;font-weight:bold;">in</span> queueAD
                        u += <span style="color: #483d8b;">'&amp;videoid=&quot;'</span>+<span style="color: #dc143c;">urllib</span>.<span style="color: black;">quote_plus</span><span style="color: black;">&#40;</span>common.<span style="color: black;">args</span>.<span style="color: black;">videoid</span><span style="color: black;">&#41;</span>+<span style="color: #483d8b;">'&quot;'</span>
                    <span style="color: #008000;">AttributeError</span>: _Info instance has no attribute <span style="color: #483d8b;">'videoid'</span></pre></div></div>

<p>Browsing works just fine, though, so I only browse for videos.</p>
<h3>Next Steps</h3>
<p>I&#8217;m still using a wired USB keyboard and mouse, but I&#8217;m planning to get a home theater friendly wireless keyboard/mouse combo. Something along the lines of a <a href="http://www.amazon.com/Wireless-Keyboard-Built-TouchPad-Pointer/dp/B003UE52ME">Rii Mini Wireless Keyboard</a>.</p>
<p>There are also hundreds of XBMC plugins I haven&#8217;t checked out yet, as well as other ways to customize XBMC.</p>
<img src="http://feeds.feedburner.com/~r/pgrs/~4/qS3OdxZlbiQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2011/12/23/setting-up-a-zotac-zbox-with-xbmc-as-a-home-theater-pc/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2011/12/23/setting-up-a-zotac-zbox-with-xbmc-as-a-home-theater-pc/</feedburner:origLink></item>
		<item>
		<title>Running multiple ruby projects with foreman and subcontractor</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/Mcrqk6OJNs0/</link>
		<comments>http://www.pgrs.net/2011/12/15/running-multiple-ruby-projects-with-foreman-and-subcontractor/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 03:11:50 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pgrs.net/?p=22422</guid>
		<description><![CDATA[We have a suite of ruby applications at Braintree. There are many times when we need to run more than one of these apps at the same time. For example, we might need to run our login app in addition to whichever app we are working on. We use foreman as our process launcher, but <a href='http://www.pgrs.net/2011/12/15/running-multiple-ruby-projects-with-foreman-and-subcontractor/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>We have a suite of ruby applications at <a href="http://www.braintreepayments.com">Braintree</a>. There are many times when we need to run more than one of these apps at the same time. For example, we might need to run our login app in addition to whichever app we are working on.</p>
<p>We use <a href="https://github.com/ddollar/foreman">foreman</a> as our process launcher, but foreman does not handle running other projects in other rvm gemsets (and possibly ruby versions). One of my fellow developers, <a href="http://tony.pitluga.com">Tony Pitluga</a>, released a gem called <a href="https://github.com/pitluga/subcontractor">subcontractor</a> that handles these cases.</p>
<p>For example, our Procfile looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">app: rails server
login: subcontract <span style="color:#006600; font-weight:bold;">--</span>rvm <span style="color:#996600;">&quot;--with-rubies rvmrc&quot;</span> <span style="color:#006600; font-weight:bold;">--</span>chdir ..<span style="color:#006600; font-weight:bold;">/</span>login <span style="color:#006600; font-weight:bold;">--</span>signal INT <span style="color:#006600; font-weight:bold;">--</span> rails server <span style="color:#006600; font-weight:bold;">-</span><span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#006666;">4000</span></pre></div></div>

<p>This runs the current app on port 3000 and the login app on port 4000 with a different home folder, ruby and gemset. The login line is roughly equivalent to running <code>cd ../login &#038;&#038; rvm --with-rubies rvmrc exec rails server -p 4000</code> The option <code>--with-rubies rvmrc</code> tells rvm to use the .rvmrc file to load the correct ruby and gemset. If a project doesn&#8217;t have an .rvmrc file, you can specify the ruby version:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">another_app: subcontract <span style="color:#006600; font-weight:bold;">--</span>rvm ruby<span style="color:#006600; font-weight:bold;">-</span>1.8.7<span style="color:#006600; font-weight:bold;">-</span>p249@another_app <span style="color:#006600; font-weight:bold;">--</span>chdir ..<span style="color:#006600; font-weight:bold;">/</span>another_app <span style="color:#006600; font-weight:bold;">--</span>signal INT <span style="color:#006600; font-weight:bold;">--</span> rails server <span style="color:#006600; font-weight:bold;">-</span><span style="color:#CC0066; font-weight:bold;">p</span> <span style="color:#006666;">4000</span></pre></div></div>

<img src="http://feeds.feedburner.com/~r/pgrs/~4/Mcrqk6OJNs0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2011/12/15/running-multiple-ruby-projects-with-foreman-and-subcontractor/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2011/12/15/running-multiple-ruby-projects-with-foreman-and-subcontractor/</feedburner:origLink></item>
		<item>
		<title>speclj-growl 1.0 released</title>
		<link>http://feedproxy.google.com/~r/pgrs/~3/bhRRkdwUfRQ/</link>
		<comments>http://www.pgrs.net/2011/12/06/speclj-growl-1-0-released/#comments</comments>
		<pubDate>Wed, 07 Dec 2011 05:46:27 +0000</pubDate>
		<dc:creator>Paul Gross</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.pgrs.net/?p=22389</guid>
		<description><![CDATA[I just released version 1.0 of speclj-growl. This is a plugin for the speclj test framework for clojure which adds Growl popups for each spec run. For those unfamiliar with Growl, it is a notification system for Mac OS X which allows applications to show custom messages in system popups. speclj comes with autotest built <a href='http://www.pgrs.net/2011/12/06/speclj-growl-1-0-released/' class='excerpt-more'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I just released version 1.0 of <a href="https://github.com/pgr0ss/speclj-growl">speclj-growl</a>. This is a plugin for the <a href="https://github.com/slagyr/speclj">speclj</a> test framework for clojure which adds <a href="http://growl.info">Growl</a> popups for each spec run. For those unfamiliar with <a href="http://growl.info">Growl</a>, it is a notification system for Mac OS X which allows applications to show custom messages in system popups.</p>
<p><a href="https://github.com/slagyr/speclj">speclj</a> comes with autotest built in. You can start an autotest process which will monitor the filesystem for changes. When tests or code change, the tests will be automatically run again. <a href="https://github.com/pgr0ss/speclj-growl">speclj-growl</a> adds to this process by showing the test results in a growl popup, so you can stay within your editor, glance at the corner of the screen, and see whether your tests passed or failed.</p>
<p>For example, say you have a clojure project using both speclj and speclj-growl (in my example, the speclj-growl project itself). The command <code>lein spec -a -f growl</code> will start autotest <code>(-a)</code> and add the growl formatter <code>(-f growl)</code>:</p>
<pre>
% lein spec -a -f growl

----- Tue Dec 06 23:03:32 CST 2011 -------------------------------------------------------------------
took 0.89041 seconds to determine file statuses.
reloading files:
  /Users/paul/speclj-growl/spec/speclj/report/growl_spec.clj

Growl Reporter
  report-runs
  - growls summary information for no test runs
  - growls a successful run
  - growls an unsuccessful run

Finished in 0.02542 seconds
3 examples, 0 failures
</pre>
<p>A growl message also appears on screen when the specs finish:</p>
<p><a href="http://www.pgrs.net/wp-content/uploads/2011/12/growl_success.png"><img src="http://www.pgrs.net/wp-content/uploads/2011/12/growl_success-300x95.png" alt="" title="growl_success" width="300" height="95" class="alignnone size-medium wp-image-22402" /></a></p>
<p>Now, if I change a spec to intentionally break it, the terminal automatically updates with the new spec output and a new growl message appears:</p>
<pre>
----- Tue Dec 06 23:04:58 CST 2011 -------------------------------------------------------------------
took 0.00414 seconds to determine file statuses.
reloading files:
  /Users/paul/speclj-growl/spec/speclj/report/growl_spec.clj

Growl Reporter
  report-runs  - growls summary information for no test runs (FAILED)
  - growls a successful run
  - growls an unsuccessful run

Failures:

  1) Growl Reporter report-runs growls summary information for no test runs     Expected: <"Failure">
          got: <"Success"> (using =)
     /Users/paul/speclj-growl/spec/speclj/report/growl_spec.clj:28

Finished in 0.00705 seconds
3 examples, 1 failures
</pre>
<p><a href="http://www.pgrs.net/wp-content/uploads/2011/12/growl_failure.png"><img src="http://www.pgrs.net/wp-content/uploads/2011/12/growl_failure-300x95.png" alt="" title="growl_failure" width="300" height="95" class="alignnone size-medium wp-image-22396" /></a></p>
<p>This cycle continues every time the source or spec files change.</p>
<p>Check out the code and installation instructions on github: <a href="https://github.com/pgr0ss/speclj-growl">https://github.com/pgr0ss/speclj-growl</a></p>
<p>Thanks to <a href="https://github.com/slagyr">Micah Martin</a> for both speclj and help with speclj-growl.</p>
<img src="http://feeds.feedburner.com/~r/pgrs/~4/bhRRkdwUfRQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.pgrs.net/2011/12/06/speclj-growl-1-0-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.pgrs.net/2011/12/06/speclj-growl-1-0-released/</feedburner:origLink></item>
	</channel>
</rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk: basic
Database Caching using disk: basic
Object Caching 531/650 objects using disk: basic

Served from: www.pgrs.net @ 2013-06-18 13:16:59 -->
