<?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>Code Iteratively &#187; tech</title>
	<atom:link href="http://iterat.ive.ly/index.php/category/tech/feed/" rel="self" type="application/rss+xml" />
	<link>http://iterat.ive.ly</link>
	<description>Hi there. I&#039;m Christopher Gooley. I build technology. I like to share technology musings and products on this blog. I also like to ramble about non-technology topics. Besides coding, this is my main outlet for sharing and creativity.</description>
	<lastBuildDate>Mon, 19 Dec 2011 23:23:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Four Steps to Turbocharge Rails + AJAX Development with Nginx and&#160;Foreman</title>
		<link>http://iterat.ive.ly/index.php/2011/06/30/four-steps-to-turbocharge-local-ajax-rails-development-with-nginx-and-foreman/</link>
		<comments>http://iterat.ive.ly/index.php/2011/06/30/four-steps-to-turbocharge-local-ajax-rails-development-with-nginx-and-foreman/#comments</comments>
		<pubDate>Fri, 01 Jul 2011 05:54:30 +0000</pubDate>
		<dc:creator>Christopher Gooley</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[earbits]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[rails3]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby-on-rails]]></category>
		<category><![CDATA[source]]></category>

		<guid isPermaLink="false">http://iterat.ive.ly/?p=579</guid>
		<description><![CDATA[If you&#8217;re developing a chatty AJAX app on Rails and using a single mongrel to run it on your workstation, you probably are a bit annoyed with delays waiting for requests to be fulfilled one-at-a-time. So, here I&#8217;ll walk through the steps to run your own &#8220;cluster&#8221; on your OS X workstation using Foreman and [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re developing a chatty AJAX app on Rails and using a single mongrel to run it on your workstation, you probably are a bit annoyed with delays waiting for requests to be fulfilled one-at-a-time.  So, here I&#8217;ll walk through the steps to run your own &#8220;cluster&#8221; on your OS X workstation using Foreman and Nginx.</p>
<p>In the course of building the frontend application for <a href="http://www.earbits.com/play">Earbits</a>, I&#8217;ve been constantly annoyed with the responsiveness of my local development server.  As a pretty complex AJAX application, there are lots of little (and some bigger) calls to the Rails backend APIs to do <a href="#slow-things">lots of potentially slow things</a>. This means that there are lots of calls that are originating in the browser and being served by one mongrel, so the server ends up handling requests too slowly. Which leads to me being frustrated.  Which leads to me finding a nice solution to the problem.</p>
<p><span id="more-579"></span><br />
<h4>Warning: This May Not Apply To You</h4>
<p>If you have slow running requests that have to run in series, or if you&#8217;re not doing AJAX-y things, this isn&#8217;t going to help you much.  This setup is only useful if your app sends a bunch of parallel requests to the backend. For instance, if after your main page loads, you need to do AJAX requests to a) load the user&#8217;s friends, b) get their comment history, c) calculate some suggestions, and d) check to see if you should show a popup promo to the user, then this might help you out.  But if you need the results of request (a) to get (b) and the results of (b) to get (c), then you&#8217;re out of luck and this will be a waste of your time.</p>
<p>Ok, ready to do this?</p>
<h2>Step 1 &#8211; Install Nginx</h2>
<p>This is much simpler if you have <a href="http://www.macports.org/">macports</a> installed.  So go do that first if you haven&#8217;t already. If the first step below doesn&#8217;t do anything, you don&#8217;t have macports. Once you have macports, it&#8217;s a simple two-command process to install nginx.</p>
<p><code>$ sudo port -d selfupdate<br />
$ sudo port install nginx +ssl +debug</code></p>
<p>Now, while nginx is installing you can open a new terminal window and keep going. The install will take a few minutes.</p>
<h2>Step 2 &#8211; Configure Foreman</h2>
<p><a href="http://blog.daviddollar.org/2011/05/06/introducing-foreman.html">Foreman</a> is a great tool released by David Dollar to make running web processes and workers crazy easy.  It uses a Procfile to define the different things it controls and you should refer to his blog or a Google search to learn about the finer points of Foreman.  We use a pretty simplistic file here as an example.</p>
<p>To get started just run:<br />
<code>$ gem install foreman</code></p>
<p>Then create a file called Procfile in the root of your project using the text editor of your choice.  My Procfile has just one line that define a web process using the standard Rails server:</p>
<pre class="brush:html;">
web:    bundle exec rails server -p $PORT
</pre>
<h2>Step 3 &#8211; Configure Nginx</h2>
<p>Now that nginx is probably finished installing, we can get it configured to act as a local Load Balancer for our Rails server. I&#8217;m going to set it up using port 80 locally. If you are running an HTTP server locally already on port 80, then you should adjust your configuration accordingly.  But if you&#8217;re not using port 80, Rails redirects might cause you some headaches.  So I suggest you stick with the standard port.</p>
<p>First, you&#8217;ll need to find your nginx.conf configuration file.  If you used macports to install it, it&#8217;s probably in <code>/opt/local/etc/nginx/nginx.conf</code> but if you can&#8217;t find it, run <code>nginx -V</code> to see where it&#8217;s hiding.</p>
<p>If you&#8217;re not familiar with nginx at all, there are two main directives that you&#8217;ll be using, <code>server</code> and <code>upstream</code>. The server directive defines the front-end part of nginx (i.e. where it listens for incoming requests).  The upstream directive defines the back-end (i.e. where to send requests so that Rails can handle them).  Both of these snippets should exist within the <code>http</code> section of your config file. <em>I&#8217;ll provide a complete nginx.conf at the end of this section so that you can just replace the default file and then tweak it if necessary.</em></p>
<h4>Upstream section</h4>
<p>This is the configuration that I&#8217;m using, I will explain it in a second:</p>
<pre class="brush:plain;">
upstream foreman4000 {
  server localhost:4000;
  server localhost:4001;
  server localhost:4002;
  server localhost:4003;
  server localhost:4004;
}
</pre>
<p>Here on line 1 we&#8217;re defining the upstream which we will reference later. Note that &#8220;foreman4000&#8243; is just an arbitrary name used to reference it within the config. Then since we plan on running 5 web processes starting at port 4000, we list out each of the ports where our Foreman will be listening for requests.</p>
<h4>Server section</h4>
<p>This will define a server so that nginx will listen to requests on port 80 and direct them to the <code>upstream</code> we created above (line 6).  We also pass the real IP of the request and the hostname along to the server (lines 7-9, in case you need either of these bits of data.</p>
<pre class="brush:plain;">
 server {
    listen       80;
    server_name  localhost;
    access_log  /opt/local/var/log/nginx/foreman4000.access.log  main;
    location / {
      proxy_pass http://foreman4000;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $remote_addr;
    }
 }
</pre>
<h4>Test the config</h4>
<p>After you&#8217;re done making the changes above (or if you <a href="http://ive.ly/cPj" target="_blank">download my nginx.conf example file</a>), you should run <code>$ sudo nginx -t</code> to test the config and make sure it&#8217;s all good. If it fails, double check everything. If it&#8217;s good, you&#8217;re ready to start it up.</p>
<h2>Step 4 &#8211; Start your Engines</h2>
<p>Now all we have to do is start everything up. In your Rails project directory:<br />
<code>$ sudo nginx<br />
$ foreman start -p 4000 -c web=5</code></p>
<p>Note: I use the non-standard port 4000 as the starting point so that other random servers can run on 3000 (rails default) and 5000 (foreman default) without conflicting with this setup.</p>
<p>If it&#8217;s working you should be able to open up http://localhost in your browser and your Rails site should load. In the terminal running Foreman, you should see it handing requests to each of the 5 web processes (web.1 &#8211; web.5) like this:</p>
<p><a href="http://iterat.ive.ly/wp-content/uploads/2011/06/Screen-shot-2011-06-30-at-9.34.04-PM.png"><img src="http://iterat.ive.ly/wp-content/uploads/2011/06/Screen-shot-2011-06-30-at-9.34.04-PM.png" alt="" title="Screen shot 2011-06-30 at 9.34.04 PM" width="336" height="226" class="aligncenter size-full wp-image-597" /></a></p>
<p>Now, enjoy your new, super-responsive AJAX server! I know I do.</p>
<h2 id="slow-things">Notes and Extras</h2>
<p>There are a few reasons my local development environment is slow.  Firstly, I&#8217;m using a <a href="https://mongohq.com/home" target="_blank">hosted mongodb</a> that is shared among a few of our developers so that we can more easily collaborate on work. It makes it possible for me to add a new feature and seed the database with some good example data, then hand it off to our UI guy to style it up with zero configuration on his end other than a <code>git pull</code>. Secondly, we make heavy use of the Facebook Graph APIs which can at times be sluggish over my mere-mortal internet connection.  Getting someone&#8217;s friends might take a full second, posting something to a wall might take a couple seconds.  You can imagine how with just one process running, it would get a bit slow.</p>
<p>The third reason our site is slow in development is the simple fact that it&#8217;s designed to be chatty.  Instead of large monolithic views getting rendered for the user, we do a lot of client-side template rendering using <a href="http://documentcloud.github.com/underscore/" target="_blank">underscore.js</a> based on json data requested by the client app (which leverages <a href="http://documentcloud.github.com/backbone/" target="_blank">backbone.js</a> for much of the interaction logic).  In production, this works great because we can fire up a bunch of web processes and everything scales on out.  But in development, between the slow database access and the numerous calls, things can take seemingly forever to fully load.  But not anymore!</p>
<p>BTW &#8211; if you haven&#8217;t tried <a href="http://www.earbits.com/play" title="free online radio">Earbits</a> out for your online radio needs, you absolutely should. Great way to discover new music, share with your friends and really just have a great time. And you should stop listening to so much Genesis anyway. It&#8217;s time for something fresher.</p>
]]></content:encoded>
			<wfw:commentRss>http://iterat.ive.ly/index.php/2011/06/30/four-steps-to-turbocharge-local-ajax-rails-development-with-nginx-and-foreman/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>UPS: Web-Mobile Integration Done&#160;Right</title>
		<link>http://iterat.ive.ly/index.php/2010/05/25/ups-web-mobile-integration-done-right/</link>
		<comments>http://iterat.ive.ly/index.php/2010/05/25/ups-web-mobile-integration-done-right/#comments</comments>
		<pubDate>Tue, 25 May 2010 18:22:47 +0000</pubDate>
		<dc:creator>Christopher Gooley</dc:creator>
				<category><![CDATA[cool stuff]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://iterat.ive.ly/?p=193</guid>
		<description><![CDATA[With just a few clicks, I can go from UPS shipment notification to tracking it on my iPhone through the UPS app. It&#8217;s really pretty slick. 1) From shipment notification, hit the tracking number link. 2) Click the save button on the UPS site (you&#8217;ll need to be logged in, but they have a nice [...]]]></description>
			<content:encoded><![CDATA[<p>With just a few clicks, I can go from UPS shipment notification to tracking it on my iPhone through the UPS app. It&#8217;s really pretty slick.</p>
<p><span id="more-193"></span></p>
<p>1) From shipment notification, hit the tracking number link.</p>
<p><img class="alignnone size-full wp-image-194" title="ups-rei-a" src="http://iterat.ive.ly/wp-content/uploads/2010/05/ups-rei-a.jpg" alt="" width="400" height="217" /></p>
<p>2) Click the save button on the UPS site (you&#8217;ll need to be logged in, but they have a nice persistent login)</p>
<p><img class="alignnone size-full wp-image-195" title="ups-save" src="http://iterat.ive.ly/wp-content/uploads/2010/05/ups-save.jpg" alt="" width="400" height="237" /></p>
<p>3) Open the iPhone app, see your tracking number</p>
<p><img class="alignnone size-full wp-image-200" title="ups-iphone1" src="http://iterat.ive.ly/wp-content/uploads/2010/05/ups-iphone1.jpg" alt="" width="231" height="348" /></p>
<p>4) Nickname it for easy reference!</p>
<p><img class="alignnone size-full wp-image-201" title="ups-iphone2" src="http://iterat.ive.ly/wp-content/uploads/2010/05/ups-iphone2.jpg" alt="" width="233" height="350" /></p>
<p>5) Refresh constantly.</p>
<p>Kudos to UPS for making it so simple and so right.</p>
]]></content:encoded>
			<wfw:commentRss>http://iterat.ive.ly/index.php/2010/05/25/ups-web-mobile-integration-done-right/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Maker&#8217;s Schedule&#160;Explained</title>
		<link>http://iterat.ive.ly/index.php/2009/07/27/149/</link>
		<comments>http://iterat.ive.ly/index.php/2009/07/27/149/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 18:13:35 +0000</pubDate>
		<dc:creator>Christopher Gooley</dc:creator>
				<category><![CDATA[software]]></category>
		<category><![CDATA[tech]]></category>

		<guid isPermaLink="false">http://iterat.ive.ly/?p=149</guid>
		<description><![CDATA[Another great essay from Paul Graham of Y Combinator about the differences between &#8220;managers&#8221; and &#8220;makers&#8221; and how they schedule their day. I&#8217;ve personally found that most non-makers are completely oblivious to how much having even short meetings during the day can disrupt our work process.  I can&#8217;t remember where I read it (maybe Joel [...]]]></description>
			<content:encoded><![CDATA[<p>Another great <a title="Maker's Schedule, Manager's Schedule" href="http://www.paulgraham.com/makersschedule.html" target="_blank">essay</a> from Paul Graham of Y Combinator about the differences between &#8220;managers&#8221; and &#8220;makers&#8221; and how they schedule their day.</p>
<p>I&#8217;ve personally found that most non-makers are completely oblivious to how much having even short meetings during the day can disrupt our work process.  I can&#8217;t remember where I read it (maybe Joel Spolsky) but I recall a discussion about how if it takes 15 or 30 minutes for a developer to &#8220;get in the zone&#8221;, a couple 15 second distractions can ruin a whole day of productivity.</p>
<blockquote><p>When you&#8217;re operating on the maker&#8217;s schedule, meetings are a disaster. A single meeting can blow a whole afternoon, by breaking it into two pieces each too small to do anything hard in. [...]</p>
<p>I find one meeting can sometimes affect a whole day. A meeting commonly blows at least half a day, by breaking up a morning or afternoon. But in addition there&#8217;s sometimes a cascading effect. If I know the afternoon is going to be broken up, I&#8217;m slightly less likely to start something ambitious in the morning. I know this may sound oversensitive, but if you&#8217;re a maker, think of your own case. Don&#8217;t your spirits rise at the thought of having an entire day free to work, with no appointments at all? Well, that means your spirits are correspondingly depressed when you don&#8217;t. And ambitious projects are by definition close to the limits of your capacity. A small decrease in morale is enough to kill them off.</p>
<p><a href="http://www.paulgraham.com/makersschedule.html" target="_blank">[full essay here]</a></p></blockquote>
<p>On a related note, why in the world does Paul Graham not have an RSS feed for his essays??  <a title="the father of RSS" href="http://scripting.com/" target="_blank">Dave Winer</a> needs to make that happen.</p>
]]></content:encoded>
			<wfw:commentRss>http://iterat.ive.ly/index.php/2009/07/27/149/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HOWTO: Export IIS7 Configuration to Another&#160;Webserver</title>
		<link>http://iterat.ive.ly/index.php/2009/06/10/howto-export-iis7-configuration-to-another-webserver/</link>
		<comments>http://iterat.ive.ly/index.php/2009/06/10/howto-export-iis7-configuration-to-another-webserver/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 21:15:15 +0000</pubDate>
		<dc:creator>Christopher Gooley</dc:creator>
				<category><![CDATA[dot.net]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[iis7]]></category>
		<category><![CDATA[infrastructure]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://iterat.ive.ly/?p=140</guid>
		<description><![CDATA[IIS7 has this great new feature called Shared Configuration.  Except that it has a tendency to do horrible things which usually result in all the websites and application pools being removed from your server and your production website starting to serve 503 Service Unavailable errors. For an innexplicable reason, Microsoft decided to kill the Export [...]]]></description>
			<content:encoded><![CDATA[<p>IIS7 has this great new feature called Shared Configuration.  Except that it has a tendency to do horrible things which usually result in all the websites and application pools being removed from your server and your production website starting to serve 503 Service Unavailable errors.</p>
<p>For an innexplicable reason, Microsoft decided to kill the Export function from IIS7 in favor of this new feature.  But for those of us who don&#8217;t trust technology, we like to do things manually and to get a repeatable result that doesn&#8217;t update automatically when we least expect it.  Yes, I am the sort of person who wonders why the default Windows Update on servers is to Install and Reboot Automatically at 2am&#8230;</p>
<p>In any case, in a simple 3 step process you too can export and import your Internet Information Server 7 websites and app pools.<span id="more-140"></span></p>
<p>I will call the target server TWEB (this is the server where you want a duplicate configuration) and the source server SWEB (this is where the current configuration exists).</p>
<p>First, on TWEB make a backup copy of the files in C:\Windows\System32\inetsrv\config.  I just created a subfolder called &#8220;bak&#8221; and copied them.  <strong>This is very important.  If you forget or skip this step because backups are for sissies, you will be re-installing IIS7 in step 4.</strong></p>
<p>Second, copy the AppliationHost.config from SWEB into the C:\Windows\System32\inetsrv\config folder on TWEB.  Also copy any application files like your c:\websites folder or whatever over to TWEB in the appropriate location if you haven&#8217;t already.</p>
<p><img class="alignright" src="http://f.ive.ly/Aen.jpg" alt="" width="198" height="110" />Third, on TWEB open both the new ApplicationHost.config and the backup ApplicationHost.config from step 1 and locate the &lt;configProtectedData&gt; node in the backup.  Copy that node and replace it into the new config file.</p>
<p>Fourth, if you didn&#8217;t backup the existing config file, remove the IIS role and add it back, then start at step 1.</p>
<p><strong>Note:</strong> if you have custom accounts under which you&#8217;re running app pools (cuz you&#8217;re not using LocalSystem, right?) then you just need to go into the IIS Management Console and re-configure the passwords for those accounts.  They were encrypted with the other server&#8217;s AES keys so they won&#8217;t be valid on this server and the pools won&#8217;t start.</p>
<p>That&#8217;s it.  Hope that helps.  It should work the same for C# .NET applications (which is what I&#8217;m using) or just static websites or whatever.  But of course, you shouldn&#8217;t trust me.  Test it yourself first.</p>
<p>My new good-karma policy is that if I spend more than an hour tracking down a general bug or wacky configuration thing, I promise to blog the solution.</p>
]]></content:encoded>
			<wfw:commentRss>http://iterat.ive.ly/index.php/2009/06/10/howto-export-iis7-configuration-to-another-webserver/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>critical axiom</title>
		<link>http://iterat.ive.ly/index.php/2007/02/22/critical-axiom/</link>
		<comments>http://iterat.ive.ly/index.php/2007/02/22/critical-axiom/#comments</comments>
		<pubDate>Fri, 23 Feb 2007 04:47:24 +0000</pubDate>
		<dc:creator>Christopher Gooley</dc:creator>
				<category><![CDATA[asides]]></category>
		<category><![CDATA[photocore]]></category>
		<category><![CDATA[tech]]></category>
		<category><![CDATA[criticalaxiom]]></category>

		<guid isPermaLink="false">http://iterat.ive.ly/index.php/2007/02/22/critical-axiom/</guid>
		<description><![CDATA[Starting to ramp up for licensing photocore and I decided it was time for (another) company to handle all that business stuff. And thus critical axiom was born&#8230; And yes, my primary reason for saying something here is to get some links going on to get the site indexed :-)]]></description>
			<content:encoded><![CDATA[<p>Starting to ramp up for licensing <a href="http://photocore.us">photocore</a> and I decided it was time for (another) company to handle all that business stuff.  And thus <a href="http://criticalaxiom.com">critical axiom</a> was born&#8230;  And yes, my primary reason for saying something here is to get some links going on to get the site indexed :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://iterat.ive.ly/index.php/2007/02/22/critical-axiom/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Logitech Revolution-ary</title>
		<link>http://iterat.ive.ly/index.php/2007/02/05/logitech-revolution-ary/</link>
		<comments>http://iterat.ive.ly/index.php/2007/02/05/logitech-revolution-ary/#comments</comments>
		<pubDate>Tue, 06 Feb 2007 02:29:21 +0000</pubDate>
		<dc:creator>Christopher Gooley</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[mouse]]></category>
		<category><![CDATA[review]]></category>

		<guid isPermaLink="false">http://iterat.ive.ly/index.php/2007/02/05/logitech-revolution-ary/</guid>
		<description><![CDATA[The Logitech Revolution MX mouse is worth every single one of the rather large number of pennies it costs. I&#8217;ve had it for a week now and I liked it initally, but today I upgraded to SetPoint 3.3 (the config software) and now i&#8217;m totally hooked. The mouse has two scroll wheels and three buttons. [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.logitech.com/index.cfm/products/details/US/EN,CRID=2135,CONTENTID=12134&#038;ad=lgp_MXRev">Logitech Revolution MX</a> mouse is worth every single one of the rather large number of pennies it costs.  I&#8217;ve had it for a week now and I liked it initally, but today I upgraded to SetPoint 3.3 (the config software) and now i&#8217;m totally hooked.  The mouse has two scroll wheels and three buttons.  The normal scroll wheel up top scrolls vertically, leans left and right and clicks.  Then it has a thumb wheel that scrolls horizontally and clicks.  It also has the usual Forward-Backward browser buttons.</p>
<p>The way I set it up, the top wheel scrolls documents like any normal mouse and the left-right clicks are set to do Prev-Next in my iTunes playlist.  The thumb wheel is set to do volume up-down and click to mute.  Then it still has the browser back button, a middle click for tabbed browsing and an interesting Search button where you can highlight text and press it, then it opens a google search on that phrase. Cool. Very cool.</p>
]]></content:encoded>
			<wfw:commentRss>http://iterat.ive.ly/index.php/2007/02/05/logitech-revolution-ary/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

