<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <id>tag:code.isdangero.us,2005:/posts</id>
  <link type="text/html" rel="alternate" href="http://code.isdangero.us"/>
  <link type="application/atom+xml" rel="self" href="http://code.isdangero.us/posts.atom"/>
  <title>code.isdangero.us</title>
  <updated>2013-02-25T19:22:34+00:00</updated>
  <entry>
    <id>tag:code.isdangero.us,2005:Post/31</id>
    <published>2013-02-25T19:08:31+00:00</published>
    <updated>2013-02-25T19:22:34+00:00</updated>
    <link type="text/html" rel="alternate" href="http://code.isdangero.us/posts/Announcing-rspec-fire-roles"/>
    <title>Announcing rspec-fire-roles</title>
    <content type="html">&lt;p&gt;&lt;em&gt;TL;DR: The &lt;a href="https://github.com/cvincent/rspec-fire-roles"&gt;&lt;code&gt;rspec-fire-roles&lt;/code&gt; gem&lt;/a&gt; can allow for more flexible design and better, more useful failures in your specs. For use with &lt;a href="https://github.com/xaviershay/rspec-fire"&gt;&lt;code&gt;rspec-fire&lt;/code&gt;&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;After having read &lt;a href="http://amzn.to/VWOwyA"&gt;Growing Object-Oriented Software Guided by Tests&lt;/a&gt; and &lt;a href="http://amzn.to/VWOHtP"&gt;Practical Object-Oriented Design in Ruby&lt;/a&gt;, the benefits of the so-called &amp;#8220;London school&amp;#8221; or &amp;#8220;&lt;a href="http://martinfowler.com/articles/mocksArentStubs.html" title="Mocks aren&amp;#39;t stubs"&gt;mockist style&lt;/a&gt;&amp;#8221; of &lt;span class="caps"&gt;TDD&lt;/span&gt; finally crystalized in my mind. I began reaping the benefits of interface discovery through mocks to design more flexible software organically.&lt;/p&gt;
&lt;p&gt;If you are having trouble understanding the advantages of mockist testing, I highly recommend the first book linked above (commonly known as &amp;#8220;&lt;span class="caps"&gt;GOOS&lt;/span&gt;&amp;#8221;). It may be written with Java and therefore a bit of a pain to read for those of us spoiled by Ruby&amp;#8217;s clean syntax, but it&amp;#8217;s more than worth the effort. It dispelled misgivings and misunderstandings about mockist testing that I&amp;#8217;d harbored for years, and as a result I have a significantly leveled up as an engineer. &lt;em&gt;(Disclosure: Them be affiliate links.)&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;The problem with mocks in Ruby&lt;/h3&gt;
&lt;p&gt;Due to Ruby&amp;#8217;s dynamic, duck-typed nature, tests focused on interaction using mocks do have one big weakness. Since mock objects are standing in for real collaborator objects, and since Ruby doesn&amp;#8217;t have interfaces defined at the language level, your mock-based tests are liable to report false positives if the real collaborator objects in production aren&amp;#8217;t compatible with the interfaces specified by the mocks. This isn&amp;#8217;t a problem in Java, of course, because it&amp;#8217;s a typed language with language-level interfaces, which allows the compiler to catch such situations. Here&amp;#8217;s an example of the problem:&lt;/p&gt;
&lt;script src="https://gist.github.com/cvincent/1649054363b9cb077f6c.js"&gt;&lt;/script&gt;&lt;p&gt;One approach to this issue is to write additional integration tests to ensure the objects plug into each other correctly, but the &lt;a href="http://blog.thecodewhisperer.com/2010/10/16/integrated-tests-are-a-scam/" title="Integration Tests Are A Scam"&gt;combinatorial explosion&lt;/a&gt; inherent in integration testing makes this a weak solution at best.&lt;/p&gt;
&lt;h3&gt;Enter rspec-fire&lt;/h3&gt;
&lt;p&gt;An alternative approach is offered by the &lt;a href="https://github.com/xaviershay/rspec-fire"&gt;&lt;code&gt;rspec-fire&lt;/code&gt; gem&lt;/a&gt;. This gem allows the name of a real class to be specified when creating a mock object. If a test is run in isolation (awesome for writing &lt;a href="http://blog.leshill.org/blog/2011/10/23/fast-specs.html"&gt;fast specs&lt;/a&gt;), the mock behaves just like any other mock. However, if the test is run as part of the entire suite, thus with the named class having been loaded, the tests will fail if expectations on the mock do not have a matching implementation defined on the given class.&lt;/p&gt;
&lt;p&gt;This is a great approach which largely solves the problem. However, part of the problem still remains. When using mocks for test-driven design, you want to &lt;a href="http://jmock.org/oopsla2004.pdf"&gt;mock roles, rather than concrete objects&lt;/a&gt;. Thinking in terms of roles results in more flexible software. A given concrete class might play multiple roles. Furthermore, a given role might be played by more than one class. Ruby&amp;#8217;s duck-typed nature makes it an ideal language for this type of design thinking, allowing what is probably the most flexible possible application of polymorphism. &lt;span class="caps"&gt;POODR&lt;/span&gt; (the second book linked above) goes into further detail on this topic.&lt;/p&gt;
&lt;p&gt;This approach is already halfway doable in &lt;code&gt;rspec-fire&lt;/code&gt;. Define a class named after your role with an empty implementation of that role&amp;#8217;s interface, require it in your specs (which should even be fast enough in isolation), then pass in the name of that role for your &lt;code&gt;rspec-fire&lt;/code&gt; mocks rather than the name of a concrete class. Like this:&lt;/p&gt;
&lt;script src="https://gist.github.com/cvincent/ed219b05010468492522.js"&gt;&lt;/script&gt;&lt;p&gt;This works well enough, but there still isn&amp;#8217;t an easy way to ensure that every concrete class playing the &lt;code&gt;Notifier&lt;/code&gt; role is implementing the correct interface. If the role changes, the &lt;code&gt;BatchSender&lt;/code&gt; spec will fail, but the specs for &lt;code&gt;EmailNotifier&lt;/code&gt;, &lt;code&gt;SmsNotifier&lt;/code&gt;, and any other concrete class which is supposed to be implementing the role will continue to report false positives.&lt;/p&gt;
&lt;h3&gt;Enter rspec-fire-roles&lt;/h3&gt;
&lt;p&gt;The new &lt;code&gt;rspec-fire-roles&lt;/code&gt; gem does something really simple: it adds an &lt;code&gt;implements_role&lt;/code&gt; macro for use with RSpec. That, and it includes a &lt;code&gt;README&lt;/code&gt; which recommends using &lt;code&gt;rspec-fire&lt;/code&gt; with roles rather than concrete classes, as explained above. Here&amp;#8217;s how you would use it, continued from the above example:&lt;/p&gt;
&lt;script src="https://gist.github.com/cvincent/c85ecca407e591e90dd9.js"&gt;&lt;/script&gt;&lt;p&gt;There. We&amp;#8217;ve closed the loop. If the &lt;code&gt;Notifier&lt;/code&gt; role changes, whether it be from the standpoint of the role itself, any classes implementing the role, or any classes dependent upon the role, the specs will now fail in all of the right places.&lt;/p&gt;
&lt;p&gt;See the &lt;a href="https://github.com/cvincent/rspec-fire-roles"&gt;&lt;code&gt;rspec-fire-roles&lt;/code&gt; gem on GitHub&lt;/a&gt; for installation, usage, and more waxing on the topic of mocking roles. Feedback and discussion is welcome. See &amp;#8220;Future improvements&amp;#8221; for ideas on where to start if you&amp;#8217;d like to contribute. It is my hope that this gem is useful, and results in faster, better tests, higher quality software, and happier engineers.&lt;/p&gt;</content>
    <author>
      <name>Chris Vincent</name>
    </author>
  </entry>
  <entry>
    <id>tag:code.isdangero.us,2005:Post/29</id>
    <published>2012-07-18T03:47:57+00:00</published>
    <updated>2012-07-18T05:35:14+00:00</updated>
    <link type="text/html" rel="alternate" href="http://code.isdangero.us/posts/Optimizing-Rails-and-Unicorn-on-EC2"/>
    <title>Optimizing Rails and Unicorn on EC2</title>
    <content type="html">&lt;p&gt;In a recent project, we had the challenge of ensuring the scalability of our app up-front, as the client would be sending tons of people to the app after launch via their Facebook Page fans and their marketing mailing list. We needed to make sure that the app would withstand the load and scale out effectively if needed. We extensively tested a number of configurations of our fairly standard Nginx + &lt;a href="http://unicorn.bogomips.org/"&gt;Unicorn&lt;/a&gt; setup. I thought I would share our optimizations and findings, including the type of EC2 instance we found to be most cost-effective for our app servers.&lt;/p&gt;
&lt;h3&gt;Optimize for request length&lt;/h3&gt;
&lt;p&gt;This seems almost too obvious to point out, but the level of concurrency your app can handle is largely limited by how long it takes your requests to complete on average, so much of the work you put into scalability should be focused on speeding up any slow requests. If your app takes 1000ms to serve up an average request, you&amp;#8217;re not going to gain much by horizontally scaling out multiple instances of your app. A few milliseconds&amp;#8217; difference in request time isn&amp;#8217;t much to worry about in most cases, but a good rule of thumb is to try and keep the total request time under 250ms. Keeping it under 100ms is even better.&lt;/p&gt;
&lt;p&gt;There are two great tools out there for helping to diagnose slow requests. &lt;a href="http://newrelic.com/"&gt;New Relic&lt;/a&gt; is the heavy-hitter in this arena, however &lt;a href="https://scoutapp.com/"&gt;Scout&lt;/a&gt; just recently began offering a more lightweight version of what New Relic does, and at a more appealing price point. And, as of today, &lt;a href="https://github.com/scoutapp/scout_rails"&gt;the scout_rails gem&lt;/a&gt; has a beta release which supports Unicorn; I&amp;#8217;ve been running it in production and it&amp;#8217;s working splendidly. It doesn&amp;#8217;t offer the same level of detail yet that New Relic offers, but they seem to be iterating quickly on it. I recommend checking out both tools to see what fits your needs and budget.&lt;/p&gt;
&lt;h3&gt;Background as much as you can&lt;/h3&gt;
&lt;p&gt;Any time your request does any significant work for which it does not require the result to proceed, background it, especially if that work could take a variable amount of time. This could be something like mailers, which are safe to fire and forget. In our case, we were creating analytics summaries at the end of each request, which ended up taking far more time than we anticipated. We moved that work into a &lt;a href="https://github.com/mperham/sidekiq"&gt;Sidekiq&lt;/a&gt; job, and our average request time fell dramatically.&lt;/p&gt;
&lt;h3&gt;Cache as much as you can&lt;/h3&gt;
&lt;p&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt; caching is the holy grail, with page caching coming in second, because both of these methods completely avert the need for requests to even hit your app. However, if your app is highly dynamic, these methods won&amp;#8217;t help you much unless you use Ajax to pull in dynamic content after the initial page load; such an approach may or may not be worth the extra effort, depending on your app. They also make it difficult or impossible to restrict access to parts of your app based on the user&amp;#8217;s session.&lt;/p&gt;
&lt;p&gt;Action caching is more likely what you&amp;#8217;ll be able to use when you can, and when that&amp;#8217;s not granular enough, use fragment caching. Use self-expiring keys everywhere so you don&amp;#8217;t have to sweep caches manually or rely on cheap time-based expiration. Use Russian doll caching with your fragments where appropriate to keep everything nice and tight.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Don&amp;#8217;t take this lightly!&lt;/strong&gt; Even for simple views, &lt;span class="caps"&gt;ERB&lt;/span&gt; can take a surprising amount of time to render. I had some requests where view rendering was actually the bottleneck, with ActiveRecord being a distant second. If you can cache it, do it.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://37signals.com/svn/posts/3113-how-key-based-cache-expiration-works"&gt;37signals does a great job of explaining&lt;/a&gt; the techniques of Russian doll caching and auto-expiring keys. And &lt;a href="http://broadcastingadam.com/2011/05/advanced_caching_in_rails/"&gt;this article has a thorough overview&lt;/a&gt; of all the different types of caching available out of the box in Rails, which I highly recommend reading if you&amp;#8217;ve never used Rails caching or need a refresher on it.&lt;/p&gt;
&lt;h3&gt;Make Nginx take advantage of the asset pipeline&lt;/h3&gt;
&lt;p&gt;First off, make sure that Nginx, not Unicorn, is actually serving up your static files. We realized we forgot this when we saw requests for assets in our logs. Fixing this drastically increased our app&amp;#8217;s throughput. Second off, make sure Nginx is serving the pre-gzipped versions of your assets generated when you precompile them. &lt;a href="http://guides.rubyonrails.org/asset_pipeline.html#precompiling-assets"&gt;This section of the Rails Guide to the Asset Pipeline&lt;/a&gt; explains precompiling assets and properly configuring Nginx to serve them.&lt;/p&gt;
&lt;p&gt;Note that when you do this, you will need to make sure that you&amp;#8217;re using Rails helpers wherever your assets are referenced, such as linking to your &lt;span class="caps"&gt;CSS&lt;/span&gt; and JavaScript files or generating image tags. Also, in your &lt;span class="caps"&gt;SASS&lt;/span&gt;, &lt;code&gt;url("style/active.png")&lt;/code&gt; should be rewritten as &lt;code&gt;image-url("style/active.png")&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This step alone made a great difference in how quickly our app served requests, and therefore to how many users it would be able to handle at once.&lt;/p&gt;
&lt;h3&gt;Configure Unicorn for one worker per core&lt;/h3&gt;
&lt;p&gt;Having deployed Mongrel before, the natural conclusion when configuring the number of Unicorn workers is to take advantage of your &lt;span class="caps"&gt;RAM&lt;/span&gt; and have as many as possible. This is not the case with Unicorn, as we discovered. In our testing, we found that just one Unicorn worker per core far outperformed even a single additional worker. We were really surprised by the difference. You may want to test this yourself with your own configuration, of course, as the Unicorn &lt;a href="http://unicorn.bogomips.org/TUNING.html"&gt;tuning documentation&lt;/a&gt; does state that additional workers &lt;em&gt;may&lt;/em&gt; help in certain cases, but we found that exactly one worker per core was optimum for our application.&lt;/p&gt;
&lt;h3&gt;Do your own load testing&lt;/h3&gt;
&lt;p&gt;This brings me to one of the last tips, which is do your own load testing! One of the beautiful things about on-demand EC2 instances is that it&amp;#8217;s cheap and easy to duplicate your production environment and try different types of instances and configurations and then discard them when you&amp;#8217;re done. We took full advantage of this fact. Indeed, we ended up spinning up and tearing down so many instances that we took a little extra time to write a script to help automate this process using the &lt;a href="https://github.com/appoxy/aws/"&gt;&lt;span class="caps"&gt;AWS&lt;/span&gt; gem&lt;/a&gt;, which will of course pay dividends in future productivity as well.&lt;/p&gt;
&lt;p&gt;For the actual load testing, there are many routes to go, from as simple as &lt;a href="http://httpd.apache.org/docs/2.0/programs/ab.html"&gt;the Apache benchmark tool&lt;/a&gt; to more elaborate, distributed setups. For our fairly simple app, we found &lt;a href="http://blitz.io/bbV4y1TEhhA4ad3h34INmuB"&gt;Blitz.io&lt;/a&gt; to be very fast and easy to get started with, and just better at simulating actual load than we would be able to from our laptops. It&amp;#8217;s also really affordable, and in our case, most of the load testing we did was actually free. I recommend giving it a try! &lt;em&gt;Disclaimer: If you sign up for Blitz.io after clicking that link, our limits on free usage will be bumped up slightly. :)&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Use c1.medium instances&lt;/h3&gt;
&lt;p&gt;Okay, this isn&amp;#8217;t exactly divine law, but our testing found that the c1.medium instance type gave us the best bang-for-buck as far as pushing the limits of concurrent users our app servers could handle. Rails and Unicorn, it seems, are &lt;span class="caps"&gt;CPU&lt;/span&gt;-hungry, and the more you can give them, the better. We also tested the other high-&lt;span class="caps"&gt;CPU&lt;/span&gt; instance type, the c1.xlarge, and while fewer instances were needed to achieve the same level of concurrency, we found that each concurrent user was more expensive than with the c1.medium instances.&lt;/p&gt;
&lt;p&gt;Ultimately, we did reach a point where adding new app servers gave us fast-diminishing returns. In fact, we found that having six c1.xlarge instances, averaging at about 530 concurrent users in Blitz.io before the app began serving error 502, performed &lt;em&gt;worse&lt;/em&gt; than just three of the same instance type, which would start crapping out at 562 concurrent users. This would seem to indicate that, at this point, our app servers were no longer the bottleneck, but that probably our database (MySQL on an m1.large instance) was. However, our optimization had gotten our app to the point where we were most likely exceeding the speed we actually needed, so we were happy.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Hopefully this helps someone else out there who might be thinking about deploying a similar configuration to EC2, or who might have an existing deployment but is mystified as to how to get more performance out of it. If you have any other tips I may have missed, please feel free to add them here so I can add them to our app as well! :)&lt;/p&gt;</content>
    <author>
      <name>Chris Vincent</name>
    </author>
  </entry>
  <entry>
    <id>tag:code.isdangero.us,2005:Post/28</id>
    <published>2012-04-13T03:04:17+00:00</published>
    <updated>2012-04-13T03:25:09+00:00</updated>
    <link type="text/html" rel="alternate" href="http://code.isdangero.us/posts/DRY-specs-with-ProgressiveRequirements"/>
    <title>DRY specs with ProgressiveRequirements</title>
    <content type="html">&lt;p&gt;Anyone who has spent significant time crafting automated tests with RSpec or Shoulda knows context nesting hell. This seems to be a common idiom with specs which are building up toward a successful scenario while testing failing scenarios along the way. This makes sense, because you&amp;#8217;re testing different layers of requirements which seems perfectly suited to nesting contexts. That is, until you need to read the resulting spec, or make modifications to it down the road.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s what I&amp;#8217;m talking about:&lt;/p&gt;
&lt;script src="https://gist.github.com/2373155.js?file=gistfile1.rb"&gt;&lt;/script&gt;&lt;p&gt;Note that I&amp;#8217;m using a regular method for &lt;code&gt;request_params&lt;/code&gt; rather than &lt;code&gt;let&lt;/code&gt; or &lt;code&gt;let!&lt;/code&gt;. This is necessary so I can use &lt;code&gt;super&lt;/code&gt; and keep the requirements &lt;span class="caps"&gt;DRY&lt;/span&gt;. You can&amp;#8217;t access the parent context with &lt;code&gt;let&lt;/code&gt; (&lt;a href="https://github.com/rspec/rspec-core/issues/294"&gt;at least not yet&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Now, this isn&amp;#8217;t half bad. But imagine if you had more than just three requirements to satisfy, and each one had its own consequence for not being met. Now imagine you wanted to also share these requirements so they could be reused, mixed and matched for different controller actions. Now you have to extract them into shared examples or shared contexts. Now you&amp;#8217;re in nesting hell.&lt;/p&gt;
&lt;p&gt;After lots of head-banging (and not in the musical sense), I came up with a different approach and a helper to make it easily repeatable. It lets me rewrite the above example like this:&lt;/p&gt;
&lt;script src="https://gist.github.com/2373218.js?file=gistfile1.rb"&gt;&lt;/script&gt;&lt;h3&gt;What sorcery is this?!&lt;/h3&gt;
&lt;p&gt;First we declare our requirements and how they are added to the spec. Then, in our spec, we include the requirements one at a time, including what should happen if the requirement is not met. Finally, we spec what should happen with all requirements met.&lt;/p&gt;
&lt;p&gt;Note that the order matters. In the &lt;code&gt;on_failure&lt;/code&gt; block for &lt;code&gt;requirement_3&lt;/code&gt;, the changes made by &lt;code&gt;requirement_1&lt;/code&gt; and &lt;code&gt;requirement_2&lt;/code&gt; have been added, but not the changes for &lt;code&gt;requirement_3&lt;/code&gt;. And after all the &lt;code&gt;include_progressive_requirement&lt;/code&gt; declarations have been made, and all the requirements are met, so you can define what should happen at that point.&lt;/p&gt;
&lt;p&gt;This also makes them reusable. Because each requirement makes an atomic change to your scenario, you can mix and match them or use them in a different order if necessary for other specs. In my opinion, the resulting spec is also easier to read since the nesting is simply not an issue. I would rather write and modify the spec using this approach than the highly-nested spec.&lt;/p&gt;
&lt;h3&gt;How does it work?&lt;/h3&gt;
&lt;p&gt;Just include this module:&lt;/p&gt;
&lt;script src="https://gist.github.com/2373332.js?file=gistfile1.rb"&gt;&lt;/script&gt;&lt;p&gt;Note that you can also include &lt;code&gt;on_failure&lt;/code&gt; in the requirement definitions if you&amp;#8217;d like default failure examples every time the requirement is included. If you would like &lt;code&gt;on_success&lt;/code&gt;, it would be easy enough to add as well.&lt;/p&gt;
&lt;p&gt;Possible improvements would be to allow &lt;code&gt;add_requirement&lt;/code&gt; to do more than just override existing methods, but add &lt;code&gt;before&lt;/code&gt; blocks as well to do things like stub out &lt;span class="caps"&gt;API&lt;/span&gt; requests with required responses. This would also require defining a &lt;code&gt;remove_requirement&lt;/code&gt; block to undo such a change in the failure context. I&amp;#8217;m going to continue using this and see how useful such additions might be.&lt;/p&gt;
&lt;p&gt;In the meantime, any input on this approach is greatly appreciated! I know I&amp;#8217;m not the only one on a quest for DRYer, more maintainable specs, and this is just one approach I came up with which I think is unique. Suggestions on alternative approaches are greatly appreciated!&lt;/p&gt;</content>
    <author>
      <name>Chris Vincent</name>
    </author>
  </entry>
  <entry>
    <id>tag:code.isdangero.us,2005:Post/26</id>
    <published>2012-02-09T02:16:21+00:00</published>
    <updated>2012-02-09T05:16:03+00:00</updated>
    <link type="text/html" rel="alternate" href="http://code.isdangero.us/posts/The-Command-Pattern-A-Lightweight-Alternative-to-DCI"/>
    <title>The Command Pattern: A Lightweight Alternative to DCI</title>
    <content type="html">&lt;p&gt;Recently the Rails community has seen a &lt;a href="http://www.rubyflow.com/search/dci"&gt;flurry of activity&lt;/a&gt; regarding a new approach to encapsulating business logic in Rails called &lt;em&gt;Data, Context, Interaction&lt;/em&gt;, or, &lt;em&gt;&lt;span class="caps"&gt;DCI&lt;/span&gt;&lt;/em&gt;. And rightfully so! The old mantra of &amp;#8220;fat models, skinny controllers&amp;#8221; has cracked with wisdom as models in larger and more complicated applications have become not just fat but in fact rather &lt;em&gt;obese&lt;/em&gt;. Furthermore, the question of &lt;em&gt;which&lt;/em&gt; model some piece of business logic should live in has always been vague regarding operations involving multiple models of different kinds.&lt;/p&gt;
&lt;p&gt;It is a problem. The results have been &lt;strong&gt;sub-optimal design, testability, and readability&lt;/strong&gt;, coupled with &lt;strong&gt;huge model files&lt;/strong&gt; bloating into &lt;em&gt;thousands&lt;/em&gt; of lines of code. The &lt;span class="caps"&gt;DCI&lt;/span&gt; approach has been explored at length as a possible solution. Mike Pack wrote a &lt;a href="http://mikepackdev.com/blog_posts/24-the-right-way-to-code-dci-in-ruby"&gt;great article&lt;/a&gt; both explaining the benefits of &lt;span class="caps"&gt;DCI&lt;/span&gt; and an example implementation.&lt;/p&gt;
&lt;h3&gt;The &lt;span class="caps"&gt;DCI&lt;/span&gt; Pattern: Pros and Cons&lt;/h3&gt;
&lt;p&gt;There are some clear benefits of the &lt;span class="caps"&gt;DCI&lt;/span&gt; approach, especially compared to the old way of just shoving business logic into the nearest relevant model:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Skinny models.&lt;/strong&gt; &lt;span class="caps"&gt;DCI&lt;/span&gt; effectively cleans up your models, and should leave them with nothing but declarative associations, validations, and callbacks, plus any convenient accessor methods and query scopes. Models are left dealing strictly with the access and persistence of your data. In this way, they are &lt;em&gt;dumb&lt;/em&gt;, knowing nothing about the business logic beyond how to find, validate, and persist the data for which they are responsible.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Explicit definition of user roles.&lt;/strong&gt; In the Agile development methodology, user stories are defined as being the goal a user who represents a given &amp;#8220;role&amp;#8221;, such as a &amp;#8220;Customer&amp;#8221;, &amp;#8220;Client&amp;#8221;, or &amp;#8220;Administrator&amp;#8221;. In &lt;span class="caps"&gt;DCI&lt;/span&gt;, abilities tied to these roles are defined explicitly in their own Role modules which extend the actor instances at runtime.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Clarity.&lt;/strong&gt; As mentioned before, when working with the fat models approach, it&amp;#8217;s often ambiguous as to which model a given set of business logic should live in, especially when that business logic involves manipulating a number of different kinds of models. With &lt;span class="caps"&gt;DCI&lt;/span&gt;, each business goal lives in its own Context class, regardless of the types of models it requires, so there is no confusion.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Testability.&lt;/strong&gt; With the clean separation of logic, it&amp;#8217;s very easy to test each user story in isolation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sounds great, right? It turns out that &lt;span class="caps"&gt;DCI&lt;/span&gt; is just the kind of scalpel Rails needs to divvy up responsibilities around complicated business logic, and its nearly lock-step fit with Agile user stories is a great extra feature. That said, here are some of the drawbacks that I can see:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Performance.&lt;/strong&gt; One of the main bogeymen regarding &lt;span class="caps"&gt;DCI&lt;/span&gt; right now is performance. The &amp;#8220;correct&amp;#8221; approach to &lt;span class="caps"&gt;DCI&lt;/span&gt; is to extend the actors with their appropriate Roles at runtime, which can be a significant performance hit if done enough times. In larger applications with a high request volume, this can be significant. Mike Pack has written &lt;a href="http://mikepackdev.com/blog_posts/26-dci-role-injection-in-ruby"&gt;another article&lt;/a&gt; addressing different approaches to injecting Roles into actors, each with its own trade-offs of performance and purity. It&amp;#8217;s definitely worth a look.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Extra classes/modules and boilerplate.&lt;/strong&gt; Each Role requires its own Module, and each Context must begin by extending the given actors with their appropriate Roles. It&amp;#8217;s just additional overhead during development.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;More moving parts.&lt;/strong&gt; Each Context requires an intimate knowledge of the actions available to the Roles involved.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I still think &lt;span class="caps"&gt;DCI&lt;/span&gt; is an excellent solution, but it occurs to me that it might be a little heavyweight for some applications. That&amp;#8217;s why I&amp;#8217;m proposing a lightweight alternative which has been a steadfast design pattern for nearly two decades.&lt;/p&gt;
&lt;h3&gt;The Command Pattern: Pros and Cons&lt;/h3&gt;
&lt;p&gt;The Command pattern has long been the go-to pattern for encapsulating undoable/redoable actions in &lt;span class="caps"&gt;GUI&lt;/span&gt; applications. I used it in the development of my game, &lt;a href="http://elitecommand.net/"&gt;Elite Command&lt;/a&gt;, to great effect. My original intent was to add multiple undo to the game, but then it had the great side-benefit of removing a &lt;em&gt;lot&lt;/em&gt; of game logic from my models and separating possible player commands into their own easily-testable classes. The result: skinny controllers, skinny models, and relatively skinny Command classes each concerned with an individual feature of the game.&lt;/p&gt;
&lt;p&gt;Here are some of the advantages to the Command approach, many of which are the same as for &lt;span class="caps"&gt;DCI&lt;/span&gt;:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Skinny models.&lt;/strong&gt; Like &lt;span class="caps"&gt;DCI&lt;/span&gt;, the Command pattern encapsulates individual business goals into their own classes, leaving models concerned purely with access, validation, and persistence.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Clarity.&lt;/strong&gt; Like with &lt;span class="caps"&gt;DCI&lt;/span&gt;, there is no question as to where the logic for a given business role should go: it goes into its own Command class.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Testability.&lt;/strong&gt; Like with &lt;span class="caps"&gt;DCI&lt;/span&gt;, since each business goal lives in its own class, it is supremely easy to test each scenario in isolation.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Peformance.&lt;/strong&gt; Unlike &lt;span class="caps"&gt;DCI&lt;/span&gt;, the Command pattern requires no extension of objects at runtime. Commands are merely Plain Old Ruby Objects hiding a business goal behind a simple interface. Indeed, the Command pattern can in many ways be regarded as &lt;span class="caps"&gt;DCI&lt;/span&gt; without the Roles.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Fewer classes, less boilerplate.&lt;/strong&gt; Without Roles or runtime extension of objects, one only needs to look in one place for a complete step-by-step view of a given feature&amp;#8217;s functionality.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Undo and redo support.&lt;/strong&gt; The Command pattern was originally designed with undo support in mind, so it&amp;#8217;s a natural fit if you plan to add undo or redo to your Rails application. Of course, it&amp;#8217;s basically just &lt;span class="caps"&gt;DCI&lt;/span&gt; without Roles, so I don&amp;#8217;t see why &lt;span class="caps"&gt;DCI&lt;/span&gt; couldn&amp;#8217;t also do this fairly easily.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;A natural fit with the Composite pattern.&lt;/strong&gt; The Composite pattern allows a tree of objects to be treated as a single object. An advanced implementation of the Command pattern might include a CompositeCommand class which allows multiple Commands to be executed in sequence. This can be useful for things like minimizing Ajax requests by bundling multiple Commands into a single CompositeCommand, a technique I used to great effect in Elite Command. &lt;span class="caps"&gt;DCI&lt;/span&gt; may be capable of this as well, although I&amp;#8217;ve never seen an implementation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I like the Command pattern for its simplicity. Of course, there are always trade-offs. Here are some of the cons to the Command pattern versus &lt;span class="caps"&gt;DCI&lt;/span&gt;:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;No explicit Roles.&lt;/strong&gt; You don&amp;#8217;t get the one-to-one mapping of Agile user roles to Role modules that you do with &lt;span class="caps"&gt;DCI&lt;/span&gt;. This can be a nice thing to have, depending on the relative complexity of the application&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Not necessarily as &lt;span class="caps"&gt;DRY&lt;/span&gt;.&lt;/strong&gt; I can imagine some circumstances where Roles might be a good place for code which is reused between Commands.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Coupling between Commands and model interfaces.&lt;/strong&gt; Where &lt;span class="caps"&gt;DCI&lt;/span&gt; has coupling between Roles and models, the Command classes have coupling between Commands and models, with no intermediary. This might not be a big deal, but it&amp;#8217;s something to keep in mind.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The real disadvantage to the Command pattern versus &lt;span class="caps"&gt;DCI&lt;/span&gt; is that Roles are not present. This results in fewer classes and less boilerplate, but as a trade-off you may need to place some logic which would go into Roles into either a Command superclass or into one of the models themselves in order to keep the code &lt;span class="caps"&gt;DRY&lt;/span&gt;. In Elite Command, I opted to include shared logic as modules into the Command class, which has generally worked fine.&lt;/p&gt;
&lt;p&gt;The main advantages over &lt;span class="caps"&gt;DCI&lt;/span&gt; are the performance gains from not having to extend anything at runtime and the fewer classes and lines of code required to support the pattern.&lt;/p&gt;
&lt;h3&gt;An example of the Command pattern in action&lt;/h3&gt;
&lt;p&gt;Here is a simple implementation of adding an item to a shopping cart using the Command pattern. Elite Command actually uses a much more sophisticated, fully-featured implementation which I may cover in a future article, but for now here is a quick demonstration.&lt;/p&gt;
&lt;p&gt;First, our simple models:&lt;/p&gt;
&lt;script src="https://gist.github.com/1776508.js?file=user.rb"&gt;&lt;/script&gt;&lt;script src="https://gist.github.com/1776508.js?file=item.rb"&gt;&lt;/script&gt;&lt;script src="https://gist.github.com/1776508.js?file=cart_item.rb"&gt;&lt;/script&gt;&lt;p&gt;And now, the Command superclass:&lt;/p&gt;
&lt;script src="https://gist.github.com/1776508.js?file=command.rb"&gt;&lt;/script&gt;&lt;p&gt;And finally, a spec and implementation for adding an item to a cart:&lt;/p&gt;
&lt;script src="https://gist.github.com/1776508.js?file=add_to_cart_spec.rb"&gt;&lt;/script&gt;&lt;script src="https://gist.github.com/1776508.js?file=add_to_cart.rb"&gt;&lt;/script&gt;&lt;p&gt;Simple, no? Of course, because it&amp;#8217;s an exceedingly simple example. However, Commands really shine when they encapsulate more complex algorithms involving interactions between multiple models. And with a dash of persistence and the addition of &lt;code&gt;#unexecute!&lt;/code&gt; methods, we have really easy undo support ready to go!&lt;/p&gt;
&lt;p&gt;As mentioned above, there are more sophisticated features which can be attained with the Command pattern and which proved to be a great boon for Elite Command. If there&amp;#8217;s enough interest, I may write on this further in the future.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;As always, design decisions come with trade-offs. I am not advocating the use of the Command pattern &lt;em&gt;instead&lt;/em&gt; of &lt;span class="caps"&gt;DCI&lt;/span&gt;. Rather, I am suggesting an alternative which shares many of DCI&amp;#8217;s benefits but with a slightly different set of drawbacks. Before going with one or the other, ask yourself whether the explicitly defined Roles are worth it to your application, or whether the lighter conceptual overhead and smaller performance footprint of the Command pattern are of greater concern.&lt;/p&gt;</content>
    <author>
      <name>Chris Vincent</name>
    </author>
  </entry>
  <entry>
    <id>tag:code.isdangero.us,2005:Post/25</id>
    <published>2011-06-13T23:19:08+00:00</published>
    <updated>2011-06-13T23:21:25+00:00</updated>
    <link type="text/html" rel="alternate" href="http://code.isdangero.us/posts/Only-tools-use-too-many-tools"/>
    <title>Only tools use too many tools</title>
    <content type="html">&lt;p&gt;One thing I&amp;#8217;ve found that most engineers dislike is the overuse of tools. I&amp;#8217;m not talking about build tools or other command line tools, which automate repetitive tasks and make our lives easier. I&amp;#8217;m talking about the tools that management wants everyone to use, whether it be for bug tracking, feature reviews, project management, or any other work that is peripheral to the actual task of writing software.&lt;/p&gt;
&lt;p&gt;These tools aren&amp;#8217;t inherently bad. They can be of great assistance to the process of deploying quality, production-ready code. But I&amp;#8217;ve encountered the situation more than a few times where these tools have done more to get in the way than they have to actually help. Usually it&amp;#8217;s either due to not picking a tool and sticking with it, or to using tools where they aren&amp;#8217;t necessary.&lt;/p&gt;
&lt;h3&gt;Exhibit A: Too many tools&lt;/h3&gt;
&lt;p&gt;Here&amp;#8217;s one scenario from real life. One company I worked at used &lt;em&gt;five&lt;/em&gt; different tools for tracking progress. &lt;em&gt;Five.&lt;/em&gt; &lt;em&gt;Two&lt;/em&gt; is one too many, and they had &lt;em&gt;five.&lt;/em&gt; Trac, Pivotal Tracker, Basecamp, and a couple others whose names I don&amp;#8217;t even remember, all played into some sort of chaotic dance to which nobody in the company knew the steps. Every project had its own tool for tracking bugs and progress. Nobody knew which tool to go to for updates. It was a mess.&lt;/p&gt;
&lt;p&gt;They eventually moved to a convoluted, over-engineered &lt;span class="caps"&gt;JIRA&lt;/span&gt; setup, but I won&amp;#8217;t get into that.&lt;/p&gt;
&lt;h3&gt;Exhibit B: Redundant, low-quality tools&lt;/h3&gt;
&lt;p&gt;Here&amp;#8217;s another scenario. A company is using GitHub to manage its code repositories. Great! GitHub has a lot built-in, much of which can be put to good use by companies of many sizes. But this same company is also using a completely separate tool, Review Board, to do code reviews. Using this tool involves the complicated process of running a special script for rebasing and diffing your feature branch, which can break for many reasons and leave your local repo in a weird state. Even if you do succeed in generating the correct diff, you have to then manually upload it to the Review Board software.&lt;/p&gt;
&lt;p&gt;Why go through that trouble? GitHub has Pull Requests built-in and has for a long time. They provide a diff of your branch as well as a discussion thread for that diff. You can track changes as you go, and when it&amp;#8217;s ready, just click a button to ship it. What more do you need?&lt;/p&gt;
&lt;h3&gt;Exhibit C: The right approach&lt;/h3&gt;
&lt;p&gt;One last thing. Many of these tools are more to help managers do their jobs than engineers themselves. To that end, I think it&amp;#8217;s a good policy to limit engineers&amp;#8217; exposure to such tools as much as possible. Let them spend their time writing software.&lt;/p&gt;
&lt;p&gt;Another company I worked with had a great approach; engineers were not expected to update Trac at all. Each team would have a sprint meeting with the relevant managers at the beginning of each week, where each ticket would be addressed via projector and the manager running the meeting would take care of interfacing with Trac. It was a marvelous approach. We engineers could focus on writing code and the managers could focus on tracking progress. The way it&amp;#8217;s supposed to be.&lt;/p&gt;
&lt;p&gt;Conclusion? Choose your tools wisely. Don&amp;#8217;t use tools redundantly.&lt;/p&gt;</content>
    <author>
      <name>Chris Vincent</name>
    </author>
  </entry>
  <entry>
    <id>tag:code.isdangero.us,2005:Post/23</id>
    <published>2011-02-13T00:27:05+00:00</published>
    <updated>2011-02-13T00:43:02+00:00</updated>
    <link type="text/html" rel="alternate" href="http://code.isdangero.us/posts/Basic-funnel-tracking-in-Rails"/>
    <title>Basic funnel tracking in Rails</title>
    <content type="html">&lt;p&gt;This is the first in a series of articles I intend to publish about the technology, philosophy, and process behind my latest Rails project, &lt;a href="http://elitecommand.net/?src=cid_0_2"&gt;Elite Command&lt;/a&gt;. Elite Command is a turn-based, multiplayer strategy game, and a lot of interesting approaches were taken in developing for its unique requirements.&lt;/p&gt;
&lt;p&gt;Before I get too into the grittier aspects of the game, I&amp;#8217;m going to cover something which applies to any web application which strives for commercial success: &lt;em&gt;analytics&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Having designed and maintained various analytics platforms over the last three years, I&amp;#8217;ve learned a thing or two about best practices and capable architectures for supporting the requirements of a robust analytics infrastructure. I&amp;#8217;ve also learned a lot about the types of metrics which are most useful in a business sense. With this knowledge, adding analytics to Elite Command was a matter of choosing the 20% effort which would yield 80% of the useful results. That&amp;#8217;s why the first analytics tool I baked in was funnel tracking.&lt;/p&gt;
&lt;p&gt;Note that my code is using MongoDB with Mongoid for the &lt;span class="caps"&gt;ORM&lt;/span&gt;, but that this is all just as applicable to whatever data store you may be using.&lt;/p&gt;
&lt;h3&gt;What is this funnel of which you speak?&lt;/h3&gt;
&lt;p&gt;Funnels are incredibly useful for exactly one thing: tracking conversion rates of users through a flow. That&amp;#8217;s why it&amp;#8217;s called a funnel. In any given user flow, there is a chance for users to drop off, leaving fewer and fewer remaining users who actually reach the final step. A funnel allows you to pinpoint exactly where you&amp;#8217;re losing users, and thus gives you some evidence on which to base targeted improvements with the goal of converting more users each step of the way.&lt;/p&gt;
&lt;p&gt;This is extremely valuable when trying to build a user base. The first funnel you would want to measure is naturally the experience for brand-new users. From the moment they arrive at your landing page from a given source (such as an ad) to reaching the sign up page, to signing up, to engaging with your application, you want to know where users are giving up and leaving, and you need hard data to support your theories and measure improvement. This is especially important when users are coming from ads, as you want to make sure that you are maximizing the cost-effectiveness of paying for clicks or impressions.&lt;/p&gt;
&lt;h3&gt;The source and the cookie&lt;/h3&gt;
&lt;p&gt;The first thing you want is some kind of trigger for slapping the user with a unique identifier when they come from a trackable source. For this purpose, Elite Command looks for a query string such as &lt;code&gt;?src=cid_0_2&lt;/code&gt; (which is indeed included in the link in this article) and saves that, along with a unique tracking ID, to the user&amp;#8217;s cookies. The &lt;code&gt;src&lt;/code&gt; string can be anything, but I recommend coming up with a standard format which makes sense for your needs. Mine is &amp;#8220;[source name] _ [creative number] _ [release number]&amp;#8221;, allowing me to measure the effectiveness of ad channels, individual ads, and the actual release of Elite Command. Here&amp;#8217;s the code for creating these cookies:&lt;/p&gt;
&lt;script src="https://gist.github.com/824246.js?file=ec_funnels_1.rb"&gt;&lt;/script&gt;&lt;p&gt;The &lt;code&gt;tid&lt;/code&gt; is the unique tracking ID, which comes from a class method on &lt;code&gt;User&lt;/code&gt;. Here&amp;#8217;s the code for that:&lt;/p&gt;
&lt;script src="https://gist.github.com/824253.js?file=ec_funnels_2.rb"&gt;&lt;/script&gt;&lt;p&gt;The &lt;span class="caps"&gt;UUID&lt;/span&gt; class comes from the &lt;span class="caps"&gt;UUID&lt;/span&gt; gem and generates a &lt;a href="http://en.wikipedia.org/wiki/Universally_unique_identifier"&gt;Universally-Unique Identifier&lt;/a&gt;, simply a string which is by all practical means completely unique within the scope of the application.&lt;/p&gt;
&lt;p&gt;Now we have a cookie which uniquely identifies the user and tells us the source from which they came.&lt;/p&gt;
&lt;h3&gt;The User model&lt;/h3&gt;
&lt;p&gt;Cookies are great, but if a user signs up, we may want to know throughout the application&amp;#8217;s lifetime which source they came from. We can use this to make funnels which stretch across multiple uses of the application. For example, we may want to create funnels which track whether users respond to emails sent by the app. To do this, it just makes sense to save our &lt;code&gt;tid&lt;/code&gt; and &lt;code&gt;src&lt;/code&gt; to the user record itself. This is pretty simple. First, just add the fields to your model (here using Mongoid):&lt;/p&gt;
&lt;script src="https://gist.github.com/824261.js?file=ec_funnels_3.rb"&gt;&lt;/script&gt;&lt;p&gt;Notice that we have the &lt;code&gt;ensure_tid&lt;/code&gt; callback. This attaches a unique identifier to every user, even if they did not get tagged through one of our sources. This simply means we can track them within the same system.&lt;/p&gt;
&lt;script src="https://gist.github.com/824263.js?file=ec_funnels_4.rb"&gt;&lt;/script&gt;&lt;p&gt;Now every new &lt;code&gt;User&lt;/code&gt; has a &lt;code&gt;tid&lt;/code&gt;, and they also have a &lt;code&gt;src&lt;/code&gt; if they came from one of our predefined sources. Now it&amp;#8217;s time to put this all to use and start recording some data.&lt;/p&gt;
&lt;h3&gt;The UserAction model&lt;/h3&gt;
&lt;p&gt;Now we need a way to record when an action is taken, along with the &lt;code&gt;tid&lt;/code&gt; and &lt;code&gt;src&lt;/code&gt;, if available, of that user. Behold, the &lt;code&gt;UserAction&lt;/code&gt; model:&lt;/p&gt;
&lt;script src="https://gist.github.com/824265.js?file=ec_funnels_5.rb"&gt;&lt;/script&gt;&lt;p&gt;That&amp;#8217;s all there is to it! Now we can call &lt;code&gt;UserAction#record&lt;/code&gt; whenever we want. You can pass in both a &lt;code&gt;User&lt;/code&gt; instance (which can be &lt;code&gt;nil&lt;/code&gt;) and a &lt;code&gt;cookies&lt;/code&gt; object, and &lt;code&gt;#record&lt;/code&gt; will do the right thing with it.&lt;/p&gt;
&lt;h3&gt;Funnels!&lt;/h3&gt;
&lt;p&gt;Now we can create a &lt;code&gt;Funnel&lt;/code&gt; model. This model consists of a series of ordered steps (or &lt;code&gt;UserAction#name&lt;/code&gt; strings) and a name. We also need a way to calculate the numbers of unique &lt;code&gt;tids&lt;/code&gt; recorded at each step. Without further ado, here it is:&lt;/p&gt;
&lt;script src="https://gist.github.com/824266.js?file=ec_funnels_6.rb"&gt;&lt;/script&gt;&lt;p&gt;There you have it! I won&amp;#8217;t go into details on creating the admin UI for creating and viewing these funnels, but it should be pretty straightforward. &lt;code&gt;Funnel#step_results(src)&lt;/code&gt; returns an array of pairs, each pair consisting of the name of the step and the number of unique &lt;code&gt;tids&lt;/code&gt; remaining at that step. There are many ways to display this data. I settled for a simple column of numbers and percentages with &lt;span class="caps"&gt;CSS&lt;/span&gt;-generated bars representing the portion of users remaining at each step. Whatever lets you see the data.&lt;/p&gt;
&lt;h3&gt;What next?&lt;/h3&gt;
&lt;p&gt;Using this data, I&amp;#8217;ve made several ad runs using Facebook Ads and tracked the effectiveness of the new user experience. The goal is to get users not only to sign up but to become active users of the game. With each ad run, I can see exactly where the flow could use the most improvement. This is where I get creative, imagining what might entice the users to keep going forward. I implement and launch the improvements, do another ad run, and then look at the funnel numbers for that source. From this, I can determine whether the improvements worked or not and continue iterating toward an optimal new user experience.&lt;/p&gt;
&lt;p&gt;There is certainly room for improvement. For one thing, it would be nice to track source by &lt;span class="caps"&gt;HTTP&lt;/span&gt; referrer for untracked users coming from an unknown source. It would also be nice to calculate the funnel in a more strict manner, ensuring not only unique &lt;code&gt;tids&lt;/code&gt; at each step, but also enforcing the order of the steps. And, as I&amp;#8217;m sure goes without saying, there is plenty of room to improve on performance; the funnel numbers should be calculated using map-reduce, and there are some missing indices as well. But this works for the immediate need, and I&amp;#8217;ve been able to use this system to improve retention of new users considerably.&lt;/p&gt;
&lt;p&gt;Let me know what you think and if you have any ideas for improving the system. Also, be sure to give &lt;a href="http://elitecommand.net/?src=cid_0_2"&gt;Elite Command&lt;/a&gt; a whirl and tell me what you think, and don&amp;#8217;t forget to invite your friends! I hope this article proves useful to someone else&amp;#8217;s project.&lt;/p&gt;</content>
    <author>
      <name>Chris Vincent</name>
    </author>
  </entry>
  <entry>
    <id>tag:code.isdangero.us,2005:Post/22</id>
    <published>2011-01-27T14:04:27+00:00</published>
    <updated>2011-01-27T14:52:57+00:00</updated>
    <link type="text/html" rel="alternate" href="http://code.isdangero.us/posts/The-virtues-of-flying-solo"/>
    <title>The virtues of flying solo</title>
    <content type="html">&lt;p&gt;In the last month, I&amp;#8217;ve had ample time for the first time in a long time to really dive into a solo programming project. It was something I had actually been working on for longer than that, but not until this last month have I had the rare chance to work completely uninterrupted on my own. The result is a product launch&#8212;that&amp;#8217;s right, this thing is shipping, next week! When that happens, I will write a more detailed post about some of the approaches, fairly unique to the Rails world, which I took to a few different problems.&lt;/p&gt;
&lt;p&gt;But first, I wanted to write a post reflecting on the merits of working alone as a programmer. There are many articles which talk about the different challenges and advantages of working in teams, but rarely on programming solo. This makes sense, to an extent, as most of us have Actual Paying Jobs&#8482; and work with teams more than we work alone, and there is also all the ongoing buzz about the benefits of pair programming over the last several years. At the same time, though, it&amp;#8217;s surprising, since most of the best programmers I&amp;#8217;ve met on various teams got their start doing it on their own, as a hobby, as an amateur, a lover of the craft, and only joined companies when they realized they had bills stacking up.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re one of those programmers, think back. Remember that? Remember the first time you got your compiler working? Remember fixing your first bug? Remember the first time you programmed something, not because you were trying to learn a skill or complete a job requirement, but because you were curious to see if it could be done? Let&amp;#8217;s take a step back to that time for a moment.&lt;/p&gt;
&lt;h3&gt;It&amp;#8217;s not (that) dangerous!&lt;/h3&gt;
&lt;p&gt;When you&amp;#8217;ve spent years working on teams where practices such as regular code reviews and pair programming are enforced as part of the development process, it can be easy to get the general impression that working on something by yourself, in a vacuum, as they say, is a Bad Idea&#174;. I want to dispel that right now. It&amp;#8217;s actually a Really, Really &lt;em&gt;Good&lt;/em&gt; Idea&#174;!&lt;/p&gt;
&lt;p&gt;Don&amp;#8217;t get me wrong. Code reviews and pair programming are great ideas for teams, if they&amp;#8217;re done in the right way. The wrong way is to have the attitude that it&amp;#8217;s done to prevent incompetent code or designs from getting into the ever-growing repository. Well, okay, that is true to a small extent. But the real reason code reviews and pair programming are a good idea is not because we don&amp;#8217;t trust our peers; rather, it&amp;#8217;s because working on a team introduces a &lt;em&gt;new challenge&lt;/em&gt; which solo programmers don&amp;#8217;t face: knowledge sharing. It prevents someone from becoming the only one who knows about parts of the system, which makes them a liability if they get hit by a bus, decide to move on, or otherwise leave the project.&lt;/p&gt;
&lt;p&gt;Solo programmers don&amp;#8217;t have this problem! This makes irrelevant the bulk of what code reviews and pairing are meant to address. Sure, if something plays out and the solo programmer goes writing code that ends up becoming popular as open source, or ends up building a business and having to hire more programmers, then someone else will need to learn the code. However, at this point, assuming there are good tests in place, it should be fairly simple. Indeed, I&amp;#8217;ve found that working on the guts of open source tools which originated from a single programmer is consistently &lt;em&gt;easier&lt;/em&gt; than with code written by an organization. Perhaps the code lacks some optimizations that the individual did not know about, but at least there&amp;#8217;s a greater likelihood of consistency in things like naming and stylistic conventions, as well as a more cohesive design altogether. (Naturally, this assumes that the individual is a programmer of reasonable talent.)&lt;/p&gt;
&lt;p&gt;The point is, individuals can and do build great, reliable software. In fact, free of the risks and pitfalls inherent in working on a &lt;em&gt;team&lt;/em&gt;, magical things can happen.&lt;/p&gt;
&lt;h3&gt;No interruptions, no compromises&lt;/h3&gt;
&lt;p&gt;Another one of the challenges brought in by working with a team is the constant need to stay in sync. This brings in things like status stand-up meetings, sprint meetings, design/planning meetings, and the like. Throw in code reviews, pair programming, the usual interruptions from support, QA, company meetings, and lunch (because we &lt;em&gt;gotta&lt;/em&gt; eat), and one might rarely get the chance to just sit and do some quality, solo programming. While many of these things have their place, I know I&amp;#8217;m not alone as a programmer when I say that one of my favorite things about programming is being able to put some tunes on in the earbuds, shut out the world, get into the flow, and slam out some fine, fine functionality. Such is a &lt;em&gt;luxury&lt;/em&gt;, and often one nobody can afford, when working on a team, especially larger teams.&lt;/p&gt;
&lt;p&gt;But for a team to work, everyone needs to be on the same page. The solo programmer is &lt;em&gt;already&lt;/em&gt; on the same page, assuming the lack of conditions such as schizophrenia. The solo programmer doesn&amp;#8217;t need planning meetings or design meetings. The solo programmer devises a solution and then makes it happen. The solo programmer doesn&amp;#8217;t need complicated development processes checking and double-checking his every move, nor similarly-complicated bug tracking software. The solo programmer has his vision on scraps of paper or a simple to-do list app, and when the solo programmer wants to check his progress, he simply looks at what he&amp;#8217;s accomplished.&lt;/p&gt;
&lt;p&gt;Maybe the solo programmer doesn&amp;#8217;t come up with the most optimal possible solution. But given what I&amp;#8217;ve seen and the kinds of egos harbored by the most talented programmers, neither does a planning meeting or analysis by paralysis (reversal intended). Even at its best, a planning meeting certainly doesn&amp;#8217;t get any actual work done. At least the solo programmer, proceeding audaciously with no more advice than could be gleaned from a Google search, a reference manual, and past experience, gets things done.&lt;/p&gt;
&lt;h3&gt;The glorious return of the individual hacker&lt;/h3&gt;
&lt;p&gt;We as programmers can sometimes forget the power that we wield in today&amp;#8217;s age. People of all stripes in the industrialized world are reliant upon the technology which we know how to shape and form and apply at a whim. Most people interact with software every single day, often without even being aware of it. The internet itself is ever expanding its reach into the homes of more and more people, all over the world. For those of us with the knowhow, computing technology is in a unique position to spread innovation and to disrupt industries. And of those among us with the knowhow, a single visionary, working independently and with determination, can accomplish a lot, including much that a team cannot.&lt;/p&gt;
&lt;p&gt;There is no reason that any programmer of reasonable talent, anywhere, should feel as though they require the stability of someone else&amp;#8217;s vision and guiding hand. If we so choose, we individuals can be the sole visionaries and guiding hands of our own labors. I can cite many cases of this happening, but I should not need to; if you&amp;#8217;re working in the tech industry, you are likely mere degrees away from someone who made exactly that choice, and, indeed, probably working &lt;em&gt;for them&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;I can&amp;#8217;t speak for everyone, but I can say conclusively for myself that the number of times I have felt the fleeting moment of utter joy at what I&amp;#8217;d done while working for someone else absolutely pales in comparison the the number of times I&amp;#8217;ve experienced that feeling working on my own projects, even those projects which never panned out into anything greater than &amp;#8220;for my eyes only&amp;#8221;. I can say this with confidence, even while I have had the opportunity to build some pretty wicked shit, if I do say so myself, while working for the man. Programming solo on a project I wanted to do just to do it &lt;em&gt;always&lt;/em&gt; feels &lt;em&gt;infinitely&lt;/em&gt; better than working on someone else&amp;#8217;s project for a paycheck, even if they have a pretty cool project. Why? Because your own project is your own project. You can only fake that level of enthusiasm for so long.&lt;/p&gt;
&lt;h3&gt;Make it happen&lt;/h3&gt;
&lt;p&gt;I will end this post with a call to action, one which echos what I heard Hampton Caitlin preach at a Ruby conference, reminiscing about when he built Haml.&lt;/p&gt;
&lt;p&gt;That side-project you&amp;#8217;ve been mulling over in your head? The one you know you could build? The one you could build so well, so elegantly, you can almost see it unfold in your mind&amp;#8217;s eye? The one that you would love to at least start on, but you feel so tired after a long day at work, and those days at work just don&amp;#8217;t seem to be getting any shorter, even as the rate of pay remains the same?&lt;/p&gt;
&lt;p&gt;Build it. Work late. Spend the energy, even if it takes a toll on you. Just do it. Buy yourself a sixer of your favorite beer, if that&amp;#8217;s what gets you motivated, and just code until you can&amp;#8217;t anymore. Shut the world out for a while and do what it is you want to do. Be selfish for a little bit. Allow yourself that pleasure, that old, worn, first joy of programming, the one that has been left dusty in your sepia-toned nostalgia in exchange for that regular paycheck.&lt;/p&gt;
&lt;p&gt;You&amp;#8217;ll be glad that you did. And maybe what you work on blossoms into a thing of its own. Maybe you can quit your job and instead make a living as both visionary and implementor, rather than merely some visionary&amp;#8217;s implementor.&lt;/p&gt;
&lt;p&gt;Or maybe not. Maybe there wasn&amp;#8217;t a market for your idea, or the timing was bad, or it just didn&amp;#8217;t gain traction. But you&amp;#8217;ll feel better having taken the risk and stuck it out there instead of taking the &amp;#8220;easier&amp;#8221; mundane route. Who needs security? Fuck security. Security is an illusion, and all the accolades and perks from your bosses can&amp;#8217;t give you true freedom. Go get dirty, get bruised, and then get back up and do it again. Throw your creativity to the wind and watch it fly or watch it die, because who cares? Life is short. Make these bets while you can, or die regretting that you didn&amp;#8217;t.&lt;/p&gt;</content>
    <author>
      <name>Chris Vincent</name>
    </author>
  </entry>
  <entry>
    <id>tag:code.isdangero.us,2005:Post/21</id>
    <published>2010-04-02T01:57:38+00:00</published>
    <updated>2010-04-02T01:59:58+00:00</updated>
    <link type="text/html" rel="alternate" href="http://code.isdangero.us/posts/SimpleFacebook-A-stupid-simple-wrapper-for-the-Facebook-API"/>
    <title>SimpleFacebook: A stupid-simple wrapper for the Facebook API</title>
    <content type="html">&lt;p&gt;I recently encountered a need for a minimal wrapper for Facebook&amp;#8217;s &lt;span class="caps"&gt;API&lt;/span&gt;, so I wrote &lt;a href="http://github.com/cvincent/simple_facebook"&gt;SimpleFacebook&lt;/a&gt;. Clocking in at just 56 lines, it&amp;#8217;s perfect for interfacing with Facebook via Ruby, and nothing more. This is not intended as a replacement for &lt;a href="http://facebooker.rubyforge.org/"&gt;Facebooker&lt;/a&gt; or &lt;a href="http://rfacebook.rubyforge.org/"&gt;RFacebook&lt;/a&gt;. It doesn&amp;#8217;t provide any explicit Rails integration, such as controller filters for gating users. It only does the dirty work of putting together a valid &lt;span class="caps"&gt;API&lt;/span&gt; request and returning the results, deserialized from &lt;span class="caps"&gt;JSON&lt;/span&gt;. Example usage:&lt;/p&gt;
&lt;script src="http://gist.github.com/352640.js?file=gistfile1.rb"&gt;&lt;/script&gt;&lt;p&gt;What is it useful for? My use case was an asynchronous worker which needed to grab some data from Facebook to be stored in a database somewhere. A Rails process was not necessary to do this, so loading up Facebooker or RFacebook seemed like overkill.&lt;/p&gt;
&lt;p&gt;Someone else might find it useful, so I&amp;#8217;ve released it under the &lt;span class="caps"&gt;MIT&lt;/span&gt; license. Everything is up on GitHub, which you can download and install as a gem (using &lt;code&gt;rake install&lt;/code&gt;). The code is fairly simple, and fleshed out with specs.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://github.com/cvincent/simple_facebook"&gt;SimpleFacebook on GitHub&lt;/a&gt;&lt;/p&gt;</content>
    <author>
      <name>Chris Vincent</name>
    </author>
  </entry>
  <entry>
    <id>tag:code.isdangero.us,2005:Post/19</id>
    <published>2009-11-06T01:06:08+00:00</published>
    <updated>2009-11-06T01:06:08+00:00</updated>
    <link type="text/html" rel="alternate" href="http://code.isdangero.us/posts/Bluepill-Low-impact-process-monitoring"/>
    <title>Bluepill: Low-impact process monitoring</title>
    <content type="html">&lt;p&gt;At &lt;a href="http://seriousbusiness.com/"&gt;Serious Business&lt;/a&gt;, we&amp;#8217;ve been using &lt;a href="http://god.rubyforge.org/"&gt;God&lt;/a&gt; to monitor long-running background tasks and other daemonized processes. While God provides a nice &lt;span class="caps"&gt;DSL&lt;/span&gt; for configuration, it has issues with memory leaks which forced us to keep a close eye on it (meta-monitoring?) and reboot it periodically via cron.&lt;/p&gt;
&lt;p&gt;To remedy the problem, a few of the guys got together over a weekend and wrote &lt;a href="http://github.com/arya/bluepill"&gt;Bluepill&lt;/a&gt;, a replacement monitoring tool with a &lt;span class="caps"&gt;DSL&lt;/span&gt; inspired by God, but written for low memory consumption. Check out &lt;a href="http://asemanfar.com/"&gt;Arya&amp;#8217;s blog&lt;/a&gt; for a &lt;a href="http://asemanfar.com/Why-We-Wrote-Bluepill"&gt;detailed explanation and breakdown of Bluepill&amp;#8217;s features&lt;/a&gt;. See the graph comparing Bluepill and God memory consumption over time. You&amp;#8217;re sold.&lt;/p&gt;</content>
    <author>
      <name>Chris Vincent</name>
    </author>
  </entry>
  <entry>
    <id>tag:code.isdangero.us,2005:Post/9</id>
    <published>2009-05-19T23:17:24+00:00</published>
    <updated>2009-09-21T22:06:01+00:00</updated>
    <link type="text/html" rel="alternate" href="http://code.isdangero.us/posts/Test-failure-scenarios-first"/>
    <title>Test failure scenarios first</title>
    <content type="html">&lt;p&gt;Lately in test-driven development, I&amp;#8217;ve noticed that I tend to write tests against invalid input before I get to tests against valid input. This is a subtle technique which I think merits some discussion.&lt;/p&gt;
&lt;p&gt;One of the big wins with &lt;span class="caps"&gt;TDD&lt;/span&gt; is the way that it forces you to think about the problem in terms of the &lt;span class="caps"&gt;API&lt;/span&gt;; this pushes the engineer to &lt;a href="http://mmwaikar.wordpress.com/guru-gyaan/favorite-books/programming-books/interface-oriented-design/chapter-2-interface-contracts/"&gt;design to an interface, not an implementation&lt;/a&gt;, which is one of the major takeaways from the original Gang of Four book on design patterns. And I think the higher-level concern that designing to an interface facilitates is the process of knowing the problem domain, which leads organically into the process of dividing up responsibilities between discrete classes and modules.&lt;/p&gt;
&lt;p&gt;In many ways, a problem domain can be defined not only by what it&amp;#8217;s supposed to do, but also by its &lt;em&gt;constraints&lt;/em&gt;, the cases in which it should fail. Thinking about these cases upfront, testing against invalid or nonsensical inputs, leads to software which is more resilient to misuse and unexpected scenarios.&lt;/p&gt;
&lt;p&gt;I find that defining these constraints up front is a great way not only to get the ball rolling. It also ensures that you&amp;#8217;re intentionally thinking about constraints as you write your tests. For example, it&amp;#8217;s very easy to write simple tests with &lt;code&gt;assert_raise&lt;/code&gt; blocks and then have the implementation raise the appropriate exceptions for those scenarios.  Just like that, you&amp;#8217;ve got passing tests around some basic constraints, such as parameter requirements. Once you have a good set of constraints defined and tests for them are passing, you can start writing tests against the cases which are &lt;em&gt;supposed&lt;/em&gt; to work.&lt;/p&gt;
&lt;p&gt;If you read my Shoulda tests, you will often see a &lt;code&gt;context&lt;/code&gt; start with a bunch of tests that look like &lt;code&gt;should 'fail if X' do ... end&lt;/code&gt;. After that, you start to see the tests which test the real meat of the feature.&lt;/p&gt;
&lt;p&gt;Besides that it lubricates the initial friction of writing tests, I think this approach leads to solid, secure, and fault-tolerant code. The client code can catch the exceptions as appropriate and react accordingly. Whatever happens, you can rest easy that the &lt;span class="caps"&gt;API&lt;/span&gt; won&amp;#8217;t let the caller do things it shouldn&amp;#8217;t because you thought of these things up front and wrote tests against those cases first thing. Of course, human nature is that we can always miss cases that we hadn&amp;#8217;t considered, but thinking about them from the get-go is much better than trying to rig it in after you already have an otherwise complete implementation.&lt;/p&gt;
&lt;p&gt;This is just something which I&amp;#8217;ve noticed emerging in my own testing style, which is of course in a continuous state of evolution. Does anybody else have thoughts on testing around constraints? Do you tend to write them first or save them for later? Do you notice any patterns in your testing style which you&amp;#8217;d like to share?&lt;/p&gt;</content>
    <author>
      <name>Chris Vincent</name>
    </author>
  </entry>
</feed>
