<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>James Badger&#039;s Personal Site &#187; Development</title>
	<atom:link href="http://jamesbadger.ca/category/development/feed/" rel="self" type="application/rss+xml" />
	<link>http://jamesbadger.ca</link>
	<description></description>
	<lastBuildDate>Wed, 21 Mar 2012 00:45:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Run Nginx and Pow on your Mac</title>
		<link>http://jamesbadger.ca/2012/03/20/run-nginx-and-pow-on-your-mac/</link>
		<comments>http://jamesbadger.ca/2012/03/20/run-nginx-and-pow-on-your-mac/#comments</comments>
		<pubDate>Wed, 21 Mar 2012 00:45:08 +0000</pubDate>
		<dc:creator>James Badger</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://jamesbadger.ca/?p=170</guid>
		<description><![CDATA[Pow is a dead-simple Rack server for OS X. Easy setup, easy restarting, easy development. Nginx is a lightweight HTTP proxy server. Easy on resources, and great at what it does. Suppose you want to run Nginx to serve some &#8230; <a href="http://jamesbadger.ca/2012/03/20/run-nginx-and-pow-on-your-mac/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://pow.cx">Pow</a> is a dead-simple Rack server for OS X. Easy setup, easy restarting, easy development.</p>
<p><a href="http://nginx.org/">Nginx</a> is a lightweight HTTP proxy server. Easy on resources, and great at what it does.</p>
<p>Suppose you want to run Nginx to serve some static assets off your development machine, for demonstration purposes. But you also want to use Pow for your Rails and Rack work. If you have already tried to run both, you may have noticed that Pow takes port 80 using a ipfw rule, and no requests make it to Nginx. There&#8217;s a fairly easy solution.</p>
<p>What we are looking to have is:</p>
<ul>
<li><code>http://localhost/</code> to Nginx</li>
<li><code>http://myapp.dev/</code> to Pow</li>
<li><code>http://dev.example.com/</code> to development machine to Nginx</li>
<li><code>http://myapp.dev.example.com/</code> to development machine to Pow</li>
</ul>
<p>Those last two are only if you want external access to these services. They will require you to have your DNS setup properly to redirect <code>dev.example.com</code> and <code>*.dev.example.com</code> to your development machine (substituting your own domain of course).</p>
<h2>From the Top</h2>
<p>I&#8217;m going to assume you&#8217;re running Snow Leopard (10.6) or newer &mdash; Pow doesn&#8217;t run on older OS X versions. You should also have Nginx and Pow installed. I&#8217;m using Pow 0.3.2 and Nginx 1.0.14 on Mac OS 10.7.3.</p>
<p>Pow uses a resolver and an ipfw rule to redirect requests from <code>*.dev</code> to your Rack app. Take a look:</p>
<pre><code>$ cat /etc/resolver/dev
# Lovingly generated by Pow
nameserver 127.0.0.1
port 20560

$ sudo ipfw list
00100 0 0 fwd 127.0.0.1,20559 tcp from any to me dst-port 80
65535 allow ip from any to any
</code></pre>
<p>That first rule, <code>00100</code>, redirects any requests to port 80 to Pow at <code>127.0.0.1:20559</code>. We can&#8217;t just remove the rule, as Pow will re-add it with a Launch Daemon on startup. And we can&#8217;t just remove the Launch Daemon, as pow needs it to run. (I tried). Instead, let&#8217;s let Pow take over a port we don&#8217;t care about.</p>
<pre><code>$ echo "export POW_DST_PORT=19999" &gt;&gt; ~/.powconfig
</code></pre>
<p>And reinstall pow to pick up the new configuration:</p>
<pre><code>$ curl get.pow.cx | sh
</code></pre>
<p>With that gone, if you try to load <code>http://localhost/</code> you should get Nginx&#8217;s welcome page (if it is running)! One caveat: we can&#8217;t access our Rack servers from the <code>http://*.dev/</code> domain anymore. This is where Nginx&#8217;s config comes into play.</p>
<h2>Step into Nginx</h2>
<p>Open Nginx&#8217;s config (<code>/usr/local/etc/nginx/nginx.conf</code> if you&#8217;re using Homebrew) in your favourite editor, and we will add some new server blocks.</p>
<p>Look for the existing server block, and adjust it&#8217;s <code>server_name</code> to include your external address.</p>
<pre><code>server {
  listen       80;
  server_name  localhost dev.example.com;

  #charset koi8-r;
  ...
</code></pre>
<p>If you save it and reload Nginx now (<code>sudo nginx -s reload</code>), you should see the Nginx welcome page at your domain. Nice!</p>
<p>Back to the conf file, add two new server blocks above the existing server directive.</p>
<pre><code>server {
  listen 80;
  server_name *.dev;
  location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_redirect off;
    proxy_pass http://localhost:20559;
  }
}

server {
  listen 80;
  server_name myapp.dev.example.com;
  location / {
    proxy_set_header Host "myapp.dev"; # Host for Pow
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_redirect off;
    proxy_pass http://localhost:20559;
  }
}

server {
    listen       80;
    server_name  localhost dev.example.com;
    ...
</code></pre>
<p>Save and reload Nginx. <a href="http://localhost/">localhost</a> now goes to Nginx. <a href="http://myapp.dev/">myapp.dev</a> now goes to Pow. And externally, <code>dev.example.com</code> goes to Nginx, and <code>myapp.dev.example.com</code> goes to Pow.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamesbadger.ca/2012/03/20/run-nginx-and-pow-on-your-mac/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails 3: Rack-Throttle your Rack API</title>
		<link>http://jamesbadger.ca/2012/01/14/rails-3-rack-throttle-your-rack-api/</link>
		<comments>http://jamesbadger.ca/2012/01/14/rails-3-rack-throttle-your-rack-api/#comments</comments>
		<pubDate>Sat, 14 Jan 2012 21:49:16 +0000</pubDate>
		<dc:creator>James Badger</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Cucumber]]></category>
		<category><![CDATA[Rack]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://jamesbadger.ca/?p=130</guid>
		<description><![CDATA[Sometimes, you will want to decouple your Rails app and place your API in its own special folder in lib. You could be using Sinatra, Grape, or even your own Rack app. The advantage is you can separate out your &#8230; <a href="http://jamesbadger.ca/2012/01/14/rails-3-rack-throttle-your-rack-api/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Sometimes, you will want to decouple your Rails app and place your API in its own special folder in lib. You could be using <a href="http://www.sinatrarb.com/">Sinatra</a>, <a href="https://github.com/intridea/grape">Grape</a>, or even your own Rack app. The advantage is you can separate out your API code, making it just that much easier to port over to another app. This guide is not intended to show you how to extract an API from your code, but how to throttle an API that has already been extracted. For some tips on how you can mount your API in your Rails app, take a look at <a href="http://inductor.induktiv.at/blog/2010/05/23/mount-rack-apps-in-rails-3/">the Inductor blog</a> for a quick intro.</p>
<p>Now that you&#8217;ve skimmed the basics of mounting your Rack app (e.g. API) in your Rails app <em>without touching your rackup file</em>, you&#8217;re all set for the next step: <del datetime="2012-01-12T20:13:45+00:00">throttling!</del> testing!</p>
<p>Let&#8217;s go over a quick example with <a href="http://cukes.info/">Cucumber</a>. Don&#8217;t worry, I&#8217;ll keep it simple.<br />
<span id="more-130"></span><br />
Go ahead and install <code>cucumber-rails</code> and <code>database_cleaner</code> into your Gemfile, if you aren&#8217;t using them already.</p>
<p>Note: You can use anything for your Rack app here, Sinatra, Grape, etc. as long as it returns a 200 status code for its base path. If you want to follow along, you can use this dumb rack app. There&#8217;s a link to a Github repo at the end of the post.</p>
<p>Here it is, a simple Rack app (a proc!) mounted in your Rails app at &#8220;/api&#8221;. It always responds &#8220;OK&#8221;, with status code 200.</p>
<div id="gist-1603022" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="c1"># routes.rb</span></div><div class='line' id='LC2'><span class="no">RailsApp</span><span class="o">::</span><span class="no">Application</span><span class="o">.</span><span class="n">routes</span><span class="o">.</span><span class="n">draw</span> <span class="k">do</span></div><div class='line' id='LC3'>&nbsp;&nbsp;<span class="n">mount</span> <span class="nb">proc</span> <span class="p">{</span> <span class="o">|</span><span class="n">env</span><span class="o">|</span></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">[</span><span class="mi">200</span><span class="p">,</span> <span class="p">{},</span> <span class="o">[</span><span class="s2">&quot;OK&quot;</span><span class="o">]]</span></div><div class='line' id='LC5'>&nbsp;&nbsp;<span class="p">}</span> <span class="o">=&gt;</span> <span class="s2">&quot;/api&quot;</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'>&nbsp;&nbsp;<span class="c1"># your other Rails routes</span></div><div class='line' id='LC8'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1603022/2bb719d653bd1ee1d1aca7fd50a9905ee592d28c/routes.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1603022#file_routes.rb" style="float:right;margin-right:10px;color:#666">routes.rb</a>
            <a href="https://gist.github.com/1603022">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>At this point, you can start up the Rails server and hit your &#8220;API&#8221; at <a href="http://localhost:3000/api">http://localhost:3000/api</a>. You should see the word &#8220;<code>OK</code>&#8221; — that means it&#8217;s running. You just created a Rack app in your Rails app. Wasn&#8217;t that easy?</p>
<p>Now for the cuking. A simple feature to start off:</p>
<div id="gist-1603022" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="c"># features/my_dumb_api.feature</span><span class="nf"></span></div><div class='line' id='LC2'><span class="k">Feature:</span><span class="nf"> My Dumb API</span></div><div class='line' id='LC3'><span class="nf">  In order to retrieve an API response</span></div><div class='line' id='LC4'><span class="nf">  As a web API developer</span></div><div class='line' id='LC5'><span class="nf">  I want an API to respond to my requests</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'><span class="nf">  </span><span class="k">Scenario:</span><span class="nf"> API is available</span></div><div class='line' id='LC8'><span class="k">    When </span><span class="nf">I send a GET request for &quot;</span><span class="s">http://example.com/api/</span><span class="nf">&quot;</span></div><div class='line' id='LC9'><span class="nf">    </span><span class="k">Then </span><span class="nf">the response code should be &quot;</span><span class="s">200</span><span class="nf">&quot;</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1603022/f2f8fcc7422814d25858ab9a4b6551c2690a2103/my_dumb_api.feature" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1603022#file_my_dumb_api.feature" style="float:right;margin-right:10px;color:#666">my_dumb_api.feature</a>
            <a href="https://gist.github.com/1603022">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>And some step definitions:</p>
<div id="gist-1603022" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="no">When</span> <span class="sr">/^I send a GET request for &quot;([^&quot;]*)&quot;$/</span> <span class="k">do</span> <span class="o">|</span><span class="n">path</span><span class="o">|</span></div><div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">get</span> <span class="n">path</span></div><div class='line' id='LC3'><span class="k">end</span></div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="no">Then</span> <span class="sr">/^the response code should be &quot;([^&quot;]*)&quot;$/</span> <span class="k">do</span> <span class="o">|</span><span class="n">code</span><span class="o">|</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">last_response</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="n">code</span><span class="o">.</span><span class="n">to_i</span></div><div class='line' id='LC7'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1603022/39bf593a0c4e9e008aacd47fef5aa9bc740583db/api_steps.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1603022#file_api_steps.rb" style="float:right;margin-right:10px;color:#666">api_steps.rb</a>
            <a href="https://gist.github.com/1603022">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>Now give cucumber a run.</p>
<pre>
$ cucumber features/my_dumb_api.feature

Using the default profile...
# features/my_dumb_api.feature
Feature: My Dumb API
  In order to retrieve an API response
  As a web API developer
  I want an API to respond to my requests

  Scenario: API is available                                # features/my_dumb_api.feature:7
    When I send a GET request for "http://example.com/api/" # features/step_definitions/api_steps.rb:1
    Then the response code should be "200"                  # features/step_definitions/api_steps.rb:5

1 scenario (1 passed)
2 steps (2 passed)
0m0.154s
</pre>
<p>Excellent! It picked it up right away. <em>Now</em> we can start thinking about throttling. Jump over to your Gemfile and add <a href="https://github.com/datagraph/rack-throttle">rack-throttle</a>:</p>
<pre>
gem 'rack-throttle', :require => 'rack/throttle'
</pre>
<p>Update your bundle. Now, let&#8217;s start with the Cucumber feature this time.</p>
<div id="gist-1603143" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">Feature:</span><span class="nf"> My Dumb API</span></div><div class='line' id='LC2'><span class="nf">  In order to retrieve an API response</span></div><div class='line' id='LC3'><span class="nf">  As a web API developer</span></div><div class='line' id='LC4'><span class="nf">  I want an API to respond to my requests</span></div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'><span class="nf">  </span><span class="k">Scenario:</span><span class="nf"> API is available</span></div><div class='line' id='LC7'><span class="k">    When </span><span class="nf">I send a GET request for &quot;</span><span class="s">http://example.com/api/</span><span class="nf">&quot;</span></div><div class='line' id='LC8'><span class="nf">    </span><span class="k">Then </span><span class="nf">the response code should be &quot;</span><span class="s">200</span><span class="nf">&quot;</span></div><div class='line' id='LC9'><br/></div><div class='line' id='LC10'><span class="nf">  </span><span class="k">Scenario:</span><span class="nf"> Exceeding API Query Rate</span></div><div class='line' id='LC11'><span class="k">    When </span><span class="nf">I send more than one GET request in a second to &quot;</span><span class="s">http://example.com/api</span><span class="nf">&quot;</span></div><div class='line' id='LC12'><span class="nf">    </span><span class="k">Then </span><span class="nf">the response code should be &quot;</span><span class="s">403</span><span class="nf">&quot;</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1603143/04e313002e3a134b0b0a0e15dee3493457449466/my_dumb_api.feature" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1603143#file_my_dumb_api.feature" style="float:right;margin-right:10px;color:#666">my_dumb_api.feature</a>
            <a href="https://gist.github.com/1603143">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>And it&#8217;s corresponding steps file:</p>
<div id="gist-1603143" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="no">When</span> <span class="sr">/^I send a GET request for &quot;([^&quot;]*)&quot;$/</span> <span class="k">do</span> <span class="o">|</span><span class="n">path</span><span class="o">|</span></div><div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">get</span> <span class="n">path</span></div><div class='line' id='LC3'><span class="k">end</span></div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="no">When</span> <span class="sr">/^I send more than one GET request in a second to &quot;([^&quot;]*)&quot;$/</span> <span class="k">do</span> <span class="o">|</span><span class="n">path</span><span class="o">|</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1"># We&#39;ll assume this happens in &lt; 1 second</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">get</span> <span class="n">path</span></div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">get</span> <span class="n">path</span></div><div class='line' id='LC9'><span class="k">end</span></div><div class='line' id='LC10'><br/></div><div class='line' id='LC11'><span class="no">Then</span> <span class="sr">/^the response code should be &quot;([^&quot;]*)&quot;$/</span> <span class="k">do</span> <span class="o">|</span><span class="n">code</span><span class="o">|</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">last_response</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="n">code</span><span class="o">.</span><span class="n">to_i</span></div><div class='line' id='LC13'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1603143/a84591976e051b5a57dd5878556f125c06e81404/api_steps.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1603143#file_api_steps.rb" style="float:right;margin-right:10px;color:#666">api_steps.rb</a>
            <a href="https://gist.github.com/1603143">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>If we run this through Cucumber, it fails, because we haven&#8217;t done throttling yet. Jump to your routes file, and switch it to:</p>
<div id="gist-1603143" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="no">RailsApp</span><span class="o">::</span><span class="no">Application</span><span class="o">.</span><span class="n">routes</span><span class="o">.</span><span class="n">draw</span> <span class="k">do</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="n">mount</span> <span class="no">Rack</span><span class="o">::</span><span class="no">Builder</span><span class="o">.</span><span class="n">new</span> <span class="p">{</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">use</span> <span class="no">Rack</span><span class="o">::</span><span class="no">Throttle</span><span class="o">::</span><span class="no">Interval</span><span class="p">,</span> <span class="ss">:min</span> <span class="o">=&gt;</span> <span class="mi">1</span><span class="o">.</span><span class="mi">0</span></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">run</span> <span class="nb">proc</span> <span class="p">{</span> <span class="o">|</span><span class="n">env</span><span class="o">|</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">[</span><span class="mi">200</span><span class="p">,</span> <span class="p">{},</span> <span class="o">[</span><span class="s2">&quot;OK&quot;</span><span class="o">]]</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC7'>&nbsp;&nbsp;<span class="p">}</span> <span class="o">=&gt;</span> <span class="s2">&quot;/api&quot;</span></div><div class='line' id='LC8'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1603143/e4bd6267148b82aa537b22363d2b9b761ed5e75e/routes.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1603143#file_routes.rb" style="float:right;margin-right:10px;color:#666">routes.rb</a>
            <a href="https://gist.github.com/1603143">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>There, we just built a Rack app with middleware (the <code>Rack::Throttle</code> line), which defers to our Rack app (the proc) when the middleware passes the request onwards. Now when you run Cucumber, everything passes! You may think you&#8217;re ready to Cuke out the rest of your API, but you&#8217;re about to hit a roadblock — throttling hits all your Cucumber features. I have considered two ways to deal with this: </p>
<ol>
<li>Stub out <code>Rack::Throttle</code> and tell it which features you specifically want to throttle using Cucumber tags.</li>
<li>Use a separate Rack app for Cucumber testing, and turn throttling on for certain features with Cucumber tags.</li>
</ol>
<p>I chose the second option. First, I added the @no-throttle tag to the scenarios where throttling was not relevant:</p>
<div id="gist-1603216" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="k">Feature:</span><span class="nf"> My Dumb API</span></div><div class='line' id='LC2'><span class="nf">  In order to retrieve an API response</span></div><div class='line' id='LC3'><span class="nf">  As a web API developer</span></div><div class='line' id='LC4'><span class="nf">  I want an API to respond to my requests</span></div><div class='line' id='LC5'><br/></div><div class='line' id='LC6'><span class="nf">  @no-throttle</span></div><div class='line' id='LC7'><span class="nf">  </span><span class="k">Scenario:</span><span class="nf"> API is available</span></div><div class='line' id='LC8'><span class="k">    When </span><span class="nf">I send a GET request for &quot;</span><span class="s">http://example.com/api/</span><span class="nf">&quot;</span></div><div class='line' id='LC9'><span class="nf">    </span><span class="k">Then </span><span class="nf">the response code should be &quot;</span><span class="s">200</span><span class="nf">&quot;</span></div><div class='line' id='LC10'><br/></div><div class='line' id='LC11'><span class="nf">  </span><span class="k">Scenario:</span><span class="nf"> Exceeding API Query Rate</span></div><div class='line' id='LC12'><span class="k">    When </span><span class="nf">I send more than one GET request in a second to &quot;</span><span class="s">http://example.com/api</span><span class="nf">&quot;</span></div><div class='line' id='LC13'><span class="nf">    </span><span class="k">Then </span><span class="nf">the response code should be &quot;</span><span class="s">403</span><span class="nf">&quot;</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1603216/107aa7591acb5050d997fc032af8bf4be8728212/my_dumb_api.feature" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1603216#file_my_dumb_api.feature" style="float:right;margin-right:10px;color:#666">my_dumb_api.feature</a>
            <a href="https://gist.github.com/1603216">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>And then a before filter in the steps file:</p>
<div id="gist-1603216" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="no">Before</span> <span class="s2">&quot;@no-throttle&quot;</span> <span class="k">do</span></div><div class='line' id='LC2'>&nbsp;&nbsp;<span class="vi">@app</span> <span class="o">=</span> <span class="no">Rack</span><span class="o">::</span><span class="no">Builder</span><span class="o">.</span><span class="n">new</span> <span class="p">{</span></div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">map</span> <span class="s2">&quot;/api&quot;</span> <span class="k">do</span></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">run</span> <span class="nb">proc</span> <span class="p">{</span> <span class="o">|</span><span class="n">env</span><span class="o">|</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="o">[</span><span class="mi">200</span><span class="p">,</span> <span class="p">{},</span> <span class="o">[</span><span class="s2">&quot;OK&quot;</span><span class="o">]]</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">end</span></div><div class='line' id='LC8'>&nbsp;&nbsp;<span class="p">}</span> </div><div class='line' id='LC9'><span class="k">end</span></div><div class='line' id='LC10'><br/></div><div class='line' id='LC11'><span class="no">When</span> <span class="sr">/^I send a GET request for &quot;([^&quot;]*)&quot;$/</span> <span class="k">do</span> <span class="o">|</span><span class="n">path</span><span class="o">|</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">get</span> <span class="n">path</span></div><div class='line' id='LC13'><span class="k">end</span></div><div class='line' id='LC14'><br/></div><div class='line' id='LC15'><span class="no">When</span> <span class="sr">/^I send more than one GET request in a second to &quot;([^&quot;]*)&quot;$/</span> <span class="k">do</span> <span class="o">|</span><span class="n">path</span><span class="o">|</span></div><div class='line' id='LC16'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="c1"># We&#39;ll assume this happens in &lt; 1 second</span></div><div class='line' id='LC17'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">get</span> <span class="n">path</span></div><div class='line' id='LC18'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">get</span> <span class="n">path</span></div><div class='line' id='LC19'><span class="k">end</span> </div><div class='line' id='LC20'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='line' id='LC21'><span class="no">Then</span> <span class="sr">/^the response code should be &quot;([^&quot;]*)&quot;$/</span> <span class="k">do</span> <span class="o">|</span><span class="n">code</span><span class="o">|</span></div><div class='line' id='LC22'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">last_response</span><span class="o">.</span><span class="n">status</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="n">code</span><span class="o">.</span><span class="n">to_i</span></div><div class='line' id='LC23'><span class="k">end</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/1603216/fa1d4556da2657d087a8df31aeee9f3fefee6322/api_steps.rb" style="float:right;">view raw</a>
            <a href="https://gist.github.com/1603216#file_api_steps.rb" style="float:right;margin-right:10px;color:#666">api_steps.rb</a>
            <a href="https://gist.github.com/1603216">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>Now when you run your Cucumber features, the unthrottled scenarios will use a separate rack app, mounted without throttling. The downside to this method is that your have to keep the Rack app in <code>api_steps.rb</code> up to date with the one in <code>routes.rb</code>. A small price to pay, but less work than stubbing out <code>Rack::Throttle</code>.</p>
<p>You can <a href="https://github.com/openfirmware/dumb_app">browse the source code for this example Rails app</a> on Github.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamesbadger.ca/2012/01/14/rails-3-rack-throttle-your-rack-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Play Sound (Universal)</title>
		<link>http://jamesbadger.ca/2011/04/04/play-sound-universal/</link>
		<comments>http://jamesbadger.ca/2011/04/04/play-sound-universal/#comments</comments>
		<pubDate>Tue, 05 Apr 2011 01:40:37 +0000</pubDate>
		<dc:creator>James Badger</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Local Talk]]></category>

		<guid isPermaLink="false">http://jamesbadger.ca/?p=106</guid>
		<description><![CDATA[I received some requests to update the Play Sound Automator action to work with newer Macs, so I went and posted the source to Github. Upon restoring the source code from a backup, it was quite a surprise finding out &#8230; <a href="http://jamesbadger.ca/2011/04/04/play-sound-universal/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I received some requests to update the <a href="http://jamesbadger.ca/2005/11/16/20/">Play Sound</a> Automator action to work with newer Macs, so I went and posted the <a href="https://github.com/openfirmware/Play-Sound">source to Github.</a> Upon restoring the source code from a backup, it was quite a surprise finding out that it was already a git repo… five years ago!</p>
<p>I also rebuilt a binary version of the action, which is incredibly simple to install: just double-click. It is also compatible with both PPC and Intel Macs, I had success running it with 10.4 on a G4 Mac Mini. You can <a href="https://github.com/downloads/openfirmware/Play-Sound/PlaySound_Universal.zip">download from Github</a> or <a href="http://jamesbadger.ca/wp-downloads/PlaySound_Universal.zip">download from my site</a>.</p>
<p>Additionally, it is now open source so if you see any changes (the code has been changed in over five years), fork it on Github and let me know!</p>
<p>Special Thanks:<br />
<a href="http://stackoverflow.com/questions/5303507/create-universal-automator-action/5343462#5343462">StackOverflow — Create Universal Automator Action</a><br />
<a href="http://googlefodder.tumblr.com/post/287723746/64-bit-automator-and-snow-leopard">Google Fodder — 64-bit Automator and Snow Leopard</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jamesbadger.ca/2011/04/04/play-sound-universal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

