<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>The Napkin ~ A Blog By Highgroove Studios</title>
    <link>http://cleanair.highgroove.com/</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>The Napkin ~ A Blog By Highgroove Studios</description>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/cleanair" type="application/rss+xml" /><item>
      <title>MerbCamp Registration Open</title>
      <description>&lt;p&gt;MerbCamp is the first official gathering for the &lt;a href="http://merbivore.com/"&gt;Merb&lt;/a&gt; community.&lt;/p&gt;


	&lt;p&gt;Our own Matt Todd is speaking on &amp;#8220;Going Beyond Web Sites with Merb&amp;#8221;&amp;#8212;where he&amp;#8217;ll talk about using Merb to do things other than just your run-of-the-mill web-sites&amp;#8212;things like APIs, Web Services, lightweight protocols, and making your grass greener.  Well, maybe not that last one.&lt;/p&gt;


	&lt;p&gt;You can Register at:&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://merbcamp.com/"&gt;http://merbcamp.com/&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/cleanair?a=n5upL"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=n5upL" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/cleanair?a=qtPlL"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=qtPlL" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/cleanair/~4/387940468" height="1" width="1"/&gt;</description>
      <pubDate>Tue,  9 Sep 2008 14:15:00 EST</pubDate>
      <guid isPermaLink="false">http://cleanair.highgroove.com/articles/2008/09/09/merbcamp-registration-open</guid>
      <link>http://feeds.feedburner.com/~r/cleanair/~3/387940468/merbcamp-registration-open</link>
      <trackback:ping>http://cleanair.highgroove.com/articles/trackback/107</trackback:ping>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=cleanair&amp;itemurl=http%3A%2F%2Fcleanair.highgroove.com%2Farticles%2F2008%2F09%2F09%2Fmerbcamp-registration-open</feedburner:awareness><feedburner:origLink>http://cleanair.highgroove.com/articles/2008/09/09/merbcamp-registration-open</feedburner:origLink></item>
    <item>
      <title>Looking for insight? Skip the coffee</title>
      <description>&lt;style&gt;
blockquote { 
   padding : 3px; 
   margin-left: 3em; 
   margin-bottom:0.2em;
   background: #f9f9f9 none; 
   color: #000; 
   font-family:Georgia;
   line-height: 150%;
}
.credit { 
  text-align : right; 
  page-break-before: avoid;
  margin-bottom: 10px;
}
.credit small { font-size: 80%; } 
blockquote p { margin: 0; text-indent:1.5em; }

&lt;/style&gt;

	&lt;p&gt;It hurts &amp;#8211; it feels like giving up. You&amp;#8217;re stuck on a problem and do the last thing that makes sense &amp;#8211; stop thinking about it. And the minute you forgot about the problem the solution comes into focus. Sometimes it&amp;#8217;s a shower, for others it&amp;#8217;s a long walk or playing a video game.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;&lt;a href="http://www.newyorker.com/reporting/2008/07/28/080728fa_fact_lehrer"&gt;The Eureka Hunt &amp;#8211; Why do good ideas come to us when they do?&lt;/a&gt;&lt;/em&gt;, an article by Jonah Lehrer published in the the July 28th issue of the &lt;a href="http://www.newyorker.com"&gt;New Yorker&lt;/a&gt;, covered scientific research on moments of insight. There were a couple nuggets on provoking insights:&lt;/p&gt;


	&lt;h2&gt;Simmer down the focus.
Avoid things that help you focus (like caffeine).&lt;/h2&gt;


&lt;blockquote&gt;If you&amp;#8217;re in an environment that forces you to produce and produce, and you feel very stressed, then you&amp;#8217;re not going to have any insights&amp;#8230;Concentration, it seems, comes with the hidden cost of diminished creativity.&lt;/blockquote&gt;
&lt;div class="credit"&gt;
&lt;small&gt;John Kounious, Cognitive Neuroscientist, Drexel University&lt;/small&gt;
&lt;/div&gt;

	&lt;h2&gt;Set the alarm clock a few minutes early&lt;/h2&gt;


&lt;blockquote&gt;The drowsy brain is unwound and disorganized, open to all sorts of unconvential ideas. The right hemisphere is unusally active.&lt;/blockquote&gt; 

	&lt;h2&gt;Get in a good mood&lt;/h2&gt;


&lt;blockquote&gt;Jung-Beeman&amp;#8217;s latest paper investigates why people who are in a good mood are so much better at solving insight puzzels (On average, they solve nearly twenty per cent more C.R.A. problems.)&lt;/blockquote&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/cleanair?a=tGX7aK"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=tGX7aK" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/cleanair?a=esgHCK"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=esgHCK" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/cleanair/~4/362600196" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 11 Aug 2008 23:35:00 EST</pubDate>
      <guid isPermaLink="false">http://cleanair.highgroove.com/articles/2008/08/11/looking-for-insight-skip-the-coffee</guid>
      <link>http://feeds.feedburner.com/~r/cleanair/~3/362600196/looking-for-insight-skip-the-coffee</link>
      <trackback:ping>http://cleanair.highgroove.com/articles/trackback/106</trackback:ping>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=cleanair&amp;itemurl=http%3A%2F%2Fcleanair.highgroove.com%2Farticles%2F2008%2F08%2F11%2Flooking-for-insight-skip-the-coffee</feedburner:awareness><feedburner:origLink>http://cleanair.highgroove.com/articles/2008/08/11/looking-for-insight-skip-the-coffee</feedburner:origLink></item>
    <item>
      <title>Matt Todd to speak at RubyFringe</title>
      <description>&lt;p&gt;We&amp;#8217;ve had the pleasure of working with &lt;a href="http://maraby.org"&gt;Matt Todd&lt;/a&gt; recently on several Highgroove projects.&lt;/p&gt;


	&lt;p&gt;Matt&amp;#8217;s going to be speaking at &lt;a href="http://rubyfringe.com"&gt;RubyFringe&lt;/a&gt;, &amp;#8220;an avant-garde conference for developers that are excited about emerging Ruby projects and technologies&amp;#8221; on July 18-20, 2008 in Toronto, Canada.&lt;/p&gt;


	&lt;p&gt;And while there is a very clever joke I could insinuate about Matt&amp;#8217;s talk entitled &lt;a href="http://rubyfringe.com/talks#matt_todd"&gt;Being Dumb And Using It To Your Advantage&lt;/a&gt;, on Matt being &amp;#8220;the expert on dumb,&amp;#8221; I can&amp;#8217;t quite come up with it&amp;#8212;and then there&amp;#8217;s the fact that he is actually really frickin&amp;#8217; smart.&lt;/p&gt;


	&lt;p&gt;If you&amp;#8217;ve ever thought of an idea, only to convince yourself &amp;#8220;eh, that&amp;#8217;ll never work, that&amp;#8217;s a dumb idea&amp;#8221;&amp;#8212;his talk will make you think otherwise.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/cleanair?a=CrEqAJ"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=CrEqAJ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/cleanair?a=v2f95J"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=v2f95J" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/cleanair/~4/332805275" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 11 Jul 2008 10:51:00 EST</pubDate>
      <guid isPermaLink="false">http://cleanair.highgroove.com/articles/2008/07/11/matt-todd-to-speak-at-rubyfringe</guid>
      <link>http://feeds.feedburner.com/~r/cleanair/~3/332805275/matt-todd-to-speak-at-rubyfringe</link>
      <category>Speaking</category>
      <trackback:ping>http://cleanair.highgroove.com/articles/trackback/105</trackback:ping>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=cleanair&amp;itemurl=http%3A%2F%2Fcleanair.highgroove.com%2Farticles%2F2008%2F07%2F11%2Fmatt-todd-to-speak-at-rubyfringe</feedburner:awareness><feedburner:origLink>http://cleanair.highgroove.com/articles/2008/07/11/matt-todd-to-speak-at-rubyfringe</feedburner:origLink></item>
    <item>
      <title>Say hello at RailsConf</title>
      <description>&lt;p&gt;Andre, Charles, and myself leave for RailsConf Thursday.&lt;/p&gt;


	&lt;p&gt;If you want to discuss Rails monitoring, Javascript, the business of Rails, biking, camping, or dogs, talk to us!&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m the tall, skinny scarecrow-like figure with the big head. Charles looks like he might belong to a hipster boy band. Andre&amp;#8230;well he looks completely normal. Just look for the scarecrow and the hipster &amp;#8211; Andre will be the other one in our group.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/cleanair?a=eRurCH"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=eRurCH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/cleanair?a=uNnuOH"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=uNnuOH" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/cleanair/~4/300255334" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 28 May 2008 21:32:00 EST</pubDate>
      <guid isPermaLink="false">http://cleanair.highgroove.com/articles/2008/05/28/say-hello-to-us-at-railsconf</guid>
      <link>http://feeds.feedburner.com/~r/cleanair/~3/300255334/say-hello-to-us-at-railsconf</link>
      <trackback:ping>http://cleanair.highgroove.com/articles/trackback/103</trackback:ping>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=cleanair&amp;itemurl=http%3A%2F%2Fcleanair.highgroove.com%2Farticles%2F2008%2F05%2F28%2Fsay-hello-to-us-at-railsconf</feedburner:awareness><feedburner:origLink>http://cleanair.highgroove.com/articles/2008/05/28/say-hello-to-us-at-railsconf</feedburner:origLink></item>
    <item>
      <title>Development with Rails + Passenger (AKA mod_rails) on Mac</title>
      <description>&lt;h2&gt;Passenger, AKA mod_rails&lt;/h2&gt;

&lt;p&gt;There are a number of posts (&lt;a href="http://www.fngtps.com/2008/04/using-passenger-on-osx-for-rails-development"&gt;one&lt;/a&gt;,  &lt;a href="http://benr75.com/articles/2008/04/12/setup-mod_rails-phusion-mac-os-x-leopard"&gt;two&lt;/a&gt;) out there on getting Phusion's &lt;a href="http://www.modrails.com/"&gt;Passenger&lt;/a&gt; up and running on OSX (Leopard). I decided to give it a go, and was pleased to discover several things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Despite reports to the contrary, Passenger installed just fine with Leopard's built-in Apache (I'm running Apache 2.2.8).&lt;/li&gt;
&lt;li&gt;Setup is very easy, as advertised.&lt;/li&gt;
&lt;li&gt;My default doc root(~/Sites) is works exactly as it did before. I do some HTML and PHP work there, so it was key that it continue to work properly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Since the install process itself is quite easy, I wanted to offer a few tips for utilizing Passenger in a typical dev environment -- i.e., what you need after you get your first Passenger-powered Rails app up and running.&lt;/p&gt;

&lt;h2&gt;Your Brain on Passenger&lt;/h2&gt;

&lt;p&gt;As you know, &lt;code&gt;script/server&lt;/code&gt; starts your Rails app on a specific port. If you bounce around between a number of applications at any one time, you're probably used to either starting them on different ports, or control-c'ing your current mongrel, cd'ing to another app's directory, and script/server'ing again. This familiar pattern changes when you're running passenger. All your apps are available at any one time, as long as you have your vhosts configured.&lt;/p&gt;

&lt;p&gt;If you're like me, you usually hit your currently running Rails app on http://localhost:3000. That also changes when you're running Passenger. Instead, you'll hit a unique URL for each app, which you've configured in /etc/hosts to just go to 127.0.0.1&lt;/p&gt;

&lt;h2&gt;Setting up a new app&lt;/h2&gt;

&lt;p&gt;I set up a lot of Rails apps in my dev environment. With Passenger, in exchange for the on-demand convenience of accessing any of your apps any time, there are a few additional setup steps to take whenever you introduce a new app into your dev environment.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;create your rails project as usual&lt;/li&gt;
&lt;li&gt;add a new vhost. I configure mine in &lt;code&gt;/private/etc/apache2/extra/http-vhosts.conf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;add the host in /etc/hosts&lt;/li&gt;
&lt;li&gt;restart apache: sudo apachectl restart&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's a &lt;strong&gt;vhosts&lt;/strong&gt; example with two apps I'm running locally. You can set up as many apps as you want this way:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  &amp;lt;VirtualHost *:80&amp;gt;
    DocumentRoot "/Users/andre/projects/rails/hotspotr/public"
    ServerName dev.hotspotr.com
    ErrorLog "/Users/andre/projects/rails/hotspotr/log/error.log"
  &amp;lt;/VirtualHost&amp;gt;

  &amp;lt;VirtualHost *:80&amp;gt;
    DocumentRoot "/Users/andre/projects/rails/shapewiki/public"
    ServerName dev.shapewiki.com
    ErrorLog "/Users/andre/projects/rails/shapewiki/log/error.log"
  &amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Two things to note here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The ErrorLog line is optional. If you don't include it, the error output for this app will go to &lt;code&gt;/private/var/log/apache2/error.log&lt;/code&gt;. Not that that's bad, but you're probably not used to looking for Rails logs there.&lt;/li&gt;
&lt;li&gt;I decided to go with the convention of dev.[PRODUCTION_URL].com. You can use anything here, as long as it matches up with an entry in /etc/hosts (see below)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And here's an example &lt;code&gt;/etc/hosts&lt;/code&gt; addition to match the two virtual hosts above:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  127.0.0.1       dev.hotspotr.com
  127.0.0.1       dev.shapewiki.com
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That's it! Go to (for example) http://dev.hotspotr.com, and you're hitting you local development app. There is nothing to start and stop. The first request for any app you hit will take a moment. Subsequent requests will feel quite snappy.&lt;/p&gt;

&lt;h2&gt;Let's Set up some Aliases to Make it all Flow&lt;/h2&gt;

&lt;p&gt;Here are the aliases I added to my &lt;code&gt;.bashrc&lt;/code&gt; file to give me quick access to everything I needed for a new, Passenger-centric workflow in my development environment:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Use this in any RAILS_ROOT dir. That restart.txt file tells mod_rails to restart this app.
# You'll want to do this when (for example) you install a new plugin.
alias restart_rails='touch tmp/restart.txt'

# By default, your app's error log now goes here. Unless you configure your apps otherwise, 
# it's helpful to have an alias to take you to your error log quickly.
alias apache_logs='cd /private/var/log/apache2/'

# You'll be adding to your vhosts configuration everytime you introduce a new Rails app. 
# Might as well make it a shortcut
alias vhosts='sudo vi /private/etc/apache2/extra/httpd-vhosts.conf'

# Dito with hosts
alias hosts='sudo vi /etc/hosts'

# You'll need to restart apache whenever you make a change to vhosts. 
# You can also click System Preference-&amp;gt;Sharing-&amp;gt;Web Sharing, but this is quicker.
alias apache_restart='sudo apachectl restart'
&lt;/code&gt;&lt;/pre&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/cleanair?a=DBHTAH"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=DBHTAH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/cleanair?a=P0Y7vH"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=P0Y7vH" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/cleanair/~4/298803971" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 27 May 2008 08:18:00 EST</pubDate>
      <guid isPermaLink="false">http://cleanair.highgroove.com/articles/2008/05/27/development-with-rails-passenger-aka-mod_rails-on-mac</guid>
      <link>http://feeds.feedburner.com/~r/cleanair/~3/298803971/development-with-rails-passenger-aka-mod_rails-on-mac</link>
      <trackback:ping>http://cleanair.highgroove.com/articles/trackback/102</trackback:ping>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=cleanair&amp;itemurl=http%3A%2F%2Fcleanair.highgroove.com%2Farticles%2F2008%2F05%2F27%2Fdevelopment-with-rails-passenger-aka-mod_rails-on-mac</feedburner:awareness><feedburner:origLink>http://cleanair.highgroove.com/articles/2008/05/27/development-with-rails-passenger-aka-mod_rails-on-mac</feedburner:origLink></item>
    <item>
      <title>Running Background Jobs in Ruby on Rails Revisited</title>
      <description>&lt;p&gt;A while back, we wrote an article on &lt;a href="http://cleanair.highgroove.com/articles/2006/06/23/running-background-jobs"&gt;Running Background Jobs in Ruby on Rails&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;The Ruby on Rails framework has a number of tools for running your code outside of the web-request, including the venerable &lt;code&gt;script/runner&lt;/code&gt; for one-off tasks, but using them can be a little heavy on your server.  If you want to run a task on the minute, or on demand, &lt;code&gt;script/runner&lt;/code&gt; will load your entire Rails environment, which can be from 20-50 MB, depending on how many libraries and how much code you&amp;#8217;re pulling in.&lt;/p&gt;


	&lt;p&gt;There are also a few other good guides, recipes, and libraries that we&amp;#8217;ve mentioned before, including:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;A chapter I helped write in Obie Fernandez&amp;#8217;s &lt;a href="http://www.amazon.com/Rails-Way-Addison-Wesley-Professional-Ruby/dp/0321445619"&gt;The Rails Way&lt;/a&gt; on Background Processing&lt;/li&gt;
		&lt;li&gt;A Rails Recipe in the &lt;a href="http://www.pragprog.com/titles/fr_arr/advanced-rails-recipes"&gt;Advanced Rails Recipes&lt;/a&gt; Book on background processing with Rails by &lt;a href="http://slantwisedesign.com/"&gt;Jon Dahl&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://backgroundrb.rubyforge.org"&gt;BackgrounDRb&lt;/a&gt; a library used to divorce long-running tasks from the web-cycle of a Rails application&lt;/li&gt;
		&lt;li&gt;A great article by &lt;a href="http://justlooking.recursion.org/"&gt;Luke Francl&lt;/a&gt; explaining &lt;a href="http://railspikes.com/2007/6/1/rails-email-processing"&gt;Stress-free Incoming E-Mail Processing with Rails&lt;/a&gt; which helped inspire this solution&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;We&amp;#8217;ve found that it&amp;#8217;s not terribly hard to build your own job server that runs continuously in the background and can handle all kinds of jobs, including those that should run on a specified interval.  Here&amp;#8217;s how we did it.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;re going to make use of the Daemons gem, so install it first:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
sudo gem install daemons
&lt;/code&gt;
&lt;/pre&gt;

Let&amp;#8217;s go ahead and build in two types of jobs: 
	&lt;ul&gt;
	&lt;li&gt;those that Run Once (immediately) and&lt;/li&gt;
		&lt;li&gt;those that Run on an interval (every x seconds or minutes or days)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;We&amp;#8217;ll use ActiveRecord&amp;#8217;s Single Table Inheritance (STI) to handle both types of jobs and dictate their differing behaviors.&lt;/p&gt;


	&lt;p&gt;Create a PeriodicJob model:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
script/generate model PeriodicJob type:string \
 job:text interval:integer last_run_at:datetime
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;And migrate up.  Now, fill in the PeriodicJob#run! method:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
# app/models/periodic_job.rb
class PeriodicJob &amp;lt; ActiveRecord::Base

  # Runs a job and updates the +last_run_at+ field.
  def run!
    begin
      eval(self.job)
    rescue Exception
      logger.error "'#{self.job}' could not run: #{$!.message}\n#{$!.backtrace}" 
    end
    self.last_run_at = Time.now.utc
    self.save  
  end

end
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Note that we&amp;#8217;re using Time.now.utc so as not to cause confusion&amp;#8212;our AR is configured to use &lt;span class="caps"&gt;UTC&lt;/span&gt; by default.&lt;/p&gt;


	&lt;p&gt;Now, let&amp;#8217;s create the subclass for Run Once jobs and let it inherit from our PeriodicJob model.  We&amp;#8217;ll  add two more class methods to it, including a finder and a cleanup method:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
# app/models/run_once_periodic_job.rb
class RunOncePeriodicJob &amp;lt; PeriodicJob

  # RunOncePeriodicJobs run if they have no PeriodicJob#last_run_at time.
  def self.find_all_need_to_run
    self.find(:all, :conditions =&amp;gt; ["last_run_at IS NULL"])
  end

  # Cleans up all jobs older than a day.
  def self.cleanup
    self.destroy_all ['last_run_at &amp;lt; ?', 1.day.ago]
  end

end
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Now let&amp;#8217;s define the Run on an Interval Job and add the interval specific finder:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
# app/models/run_interval_periodic_job.rb
class RunIntervalPeriodicJob &amp;lt; PeriodicJob

# RunIntervalPeriodicJobs run if PeriodicJob#last_run_at time plus 
# PeriodicJob#interval (in seconds) is past the current time (Time.now).
  def self.find_all_need_to_run
    self.find(:all).select {|job| job.last_run_at.nil? || 
      (job.last_run_at + job.interval &amp;lt;= Time.now.utc)}
  end

end
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Now, let&amp;#8217;s write some tests, to make it clear how it should work:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
# test/unit/periodic_job_test.rb
require File.dirname(__FILE__) + '/../test_helper'

class PeriodicJobTest &amp;lt; Test::Unit::TestCase
  fixtures :periodic_jobs

  def test_should_run_job
    assert_nothing_thrown { periodic_jobs(:run_once_job).run! }
  end

  def test_should_find_run_once_job
    assert RunOncePeriodicJob.find_all_need_to_run.include?(periodic_jobs(:run_once_job))
  end

  def test_should_not_find_run_job_already_run
    assert !RunOncePeriodicJob.find_all_need_to_run.include?(periodic_jobs(:run_once_job_to_be_deleted))
  end

  def test_should_find_run_interval_job
    assert RunIntervalPeriodicJob.find_all_need_to_run.include?(periodic_jobs(:run_interval_job_needs_run))        
  end

  def test_should_not_find_run_interval_job_not_within_interval
    assert !RunIntervalPeriodicJob.find_all_need_to_run.include?(periodic_jobs(:run_interval_job_does_not_need_run))
  end

  def test_should_cleanup_old_jobs
    jobs_count = RunOncePeriodicJob.count

    assert periodic_jobs(:run_once_job_to_be_deleted).last_run_at
    RunOncePeriodicJob.cleanup

    assert jobs_count - 1, RunOncePeriodicJob.count
  end

end
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Here are our fixtures that setup the scenarios:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
# test/fixtures/periodic_jobs.yml
run_once_job:
  id: 1
  type: RunOncePeriodicJob
  job: 'what = "w00t once!"'
run_interval_job_needs_run:
  id: 2
  type: RunIntervalPeriodicJob
  interval: 60
  job: 'what = "w00t on the minute dood!"'
  last_run_at: &amp;lt;%= (Time.now.utc - 5.minutes).to_s(:db) %&amp;gt;
run_interval_job_does_not_need_run:
  id: 3
  type: RunIntervalPeriodicJob
  interval: 60
  job: 'what = "w00t on the minute dood!"'
  last_run_at: &amp;lt;%= (Time.now.utc - 5).to_s(:db) %&amp;gt;
run_once_job_to_be_deleted:
  id: 4
  type: RunOncePeriodicJob
  job: 'what = "w00t once!"'
  last_run_at: &amp;lt;%= (Time.now.utc - 8.days).to_s(:db) %&amp;gt;
run_interval_job_needs_run_never_run_before:
  id: 5
  type: RunIntervalPeriodicJob
  interval: 60
  job: 'what = "w00t on the minute dood!"'
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Now, we have a built in system for running Periodic Jobs.  Note that all we have to do is create a new Periodic Job with the actual code we would normally toss to script/runner in the PeriodicJob#code field, and when we call the PeriodicJob#run! method, it will evaluate it.&lt;/p&gt;


	&lt;p&gt;We now need a way to always run a background task server to check these PeriodicJobs and run them.&lt;/p&gt;


	&lt;p&gt;Create a file called task_server.rb in your script directory.&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
# script/task_server.rb
#!/usr/bin/env ruby
#
# Background Task Server
#
# Relies on ActiveRecord PeriodicJob and STI table (periodic_jobs):
#
# type:         string    ("RunOncePeriodicJob", or "RunIntervalPeriodicJob")
# interval:     integer   (in seconds)
# job:          text      (actual ruby code to eval)
# last_run_at:  datetime  (stored time of last run)
#
# Main algorithm is daemon process runs every XX seconds, wakes up and
# looks for jobs. Jobs placed in the RunOncePeriodicJob queue are run 
# immediately (if no last_run_at time) and stored until they are cleaned up 
# (deleted). Jobs placed in the RunIntervalPeriodicJob queue are run if: 
# their last_run_at time + their interval (in seconds) is past the current 
# time (Time.now).
#

options = {}
ARGV.options do |opts|

  opts.on( "-e", "--environment ENVIRONMENT", String,
           "The Rails Environment to run under." ) do |environment|
    options[:environment] = environment
  end

  opts.parse!
end

RAILS_ENV = options[:environment] || 'development'  

require File.dirname(__FILE__) + '/../config/environment.rb'

if RAILS_ENV  "development" or RAILS_ENV  &amp;#8220;test&amp;#8221; 
  &lt;span class="caps"&gt;SLEEP&lt;/span&gt;_TIME = 10
else
  &lt;span class="caps"&gt;SLEEP&lt;/span&gt;_TIME = 60
end

	&lt;p&gt;&lt;/code&gt;
&lt;/pre&gt;&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
loop do
  # Find all Run Once jobs, and run them
  RunOncePeriodicJob.find_all_need_to_run.each do |job|
    job.run!
  end

  # Find all Run on Interval jobs, and run them  
  RunIntervalPeriodicJob.find_all_need_to_run.each do |job|
    job.run!
  end

  # Cleans up periodic jobs, removes all RunOncePeriodicJobs over one
  # day old.
  RunOncePeriodicJob.cleanup

  sleep(SLEEP_TIME)
end
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;That&amp;#8217;s it.  Now, we create a control script using the daemons gem.&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
# script/task_server_control.rb
#!/usr/bin/env ruby
#
# Background Task Server Control - A daemon for running jobs
#

require 'rubygems'
require 'daemons'

options = {}

default_pid_dir = "/var/run/task_server" 

if File.exists?(default_pid_dir)
  options[:dir_mode] = :normal
  options[:dir] = default_pid_dir
end

Daemons.run(File.dirname(__FILE__) + '/../script/task_server.rb', options)
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Create an optional /var/run/task_server dir if you&amp;#8217;re running on a server (in production mode):&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
mkdir -p /var/run/task_server
chown deploy:deploy /var/run/task_server
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;We can start it up in the normal server mode, as a daemon (using the start/stop commands, or we can start it up in interactive mode (so we can see the results) using the run command:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
ruby script/task_server_control.rb run
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;In another window, add some jobs:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
ruby script/console
&amp;gt;&amp;gt; RunOncePeriodicJob.create(:job =&amp;gt; 'puts "This job will only run once."')
=&amp;gt; #...
RunIntervalPeriodicJob.create(:job =&amp;gt; 'puts "This job runs every 30 seconds, and it ran: #{Time.now.utc}"', :interval =&amp;gt; 30)
=&amp;gt; #...
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;You should see the task_server_control.rb file running these jobs as the task server wakes up.&lt;/p&gt;


	&lt;p&gt;And now, it wouldn&amp;#8217;t be complete without some Capistrano support to enable restarting after we make code changes to the model, and to allow start/stop/restart:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
# config/deploy.rb

# In case you're running on multiple app servers,
# we define the task_server to make sure that 
# jobs only run on one server.
role :task_server, "app_server1.example.com" 

namespace :background_task_server do

  task :setup, :roles =&amp;gt; :task_server do
    run "mkdir -p /var/run/task_server" 
    run "chown #{user}:#{group} /var/run/task_server" 
  end

  # start background task server
  task :start, :roles =&amp;gt; :task_server do
    run "#{current_path}/script/task_server_control.rb start -- -e production" 
  end

  # stop background task server
  task :stop, :roles =&amp;gt; :task_server do
    run "#{current_path}/script/task_server_control.rb stop -- -e production" 
  end

  # start background task server
  task :restart, :roles =&amp;gt; :task_server do
    # TODO: since restart won't cold_start, we could read call to status, if 
    # it returns:
    #    task_server.rb: no instances running
    # we could simply issue the start command
    run "#{current_path}/script/task_server_control.rb restart -- -e production" 
  end

end

# optional:
# after "deploy", "background_task_server:restart" 

&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Note the use of the task_server, so you can simply allow one app server to be your task server (if you&amp;#8217;re running on multiple servers).&lt;/p&gt;


	&lt;p&gt;And now, because I&amp;#8217;m feeling generous, let&amp;#8217;s set monit up to monitor your task server, so that if it ever goes down for some strange reason, monit should boot it back up (this also ensures that restarts will boot your task server back up):&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
# /etc/monit.d/task_server.conf

check process task-server with pidfile /var/run/task_server/task_server.rb.pid
  group task-server
  start program = "/usr/bin/ruby /var/www/apps/example/current/script/task_server_control.rb start -- --environment=production" 
  stop program  = "/usr/bin/ruby /var/www/apps/example/current/script/task_server_control.rb stop -- --environment=production" 
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;That&amp;#8217;s it!  If there&amp;#8217;s any interest in forming a plugin around this with generators to create the migration and models, I&amp;#8217;ll give it a go and stick it on github.&lt;/p&gt;


	&lt;p&gt;Feedback appreciated!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/cleanair?a=j404oH"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=j404oH" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/cleanair?a=oNl51H"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=oNl51H" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/cleanair/~4/295508316" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 21 May 2008 20:42:00 EST</pubDate>
      <guid isPermaLink="false">http://cleanair.highgroove.com/articles/2008/05/21/running-background-jobs-in-ruby-on-rails-revisited</guid>
      <link>http://feeds.feedburner.com/~r/cleanair/~3/295508316/running-background-jobs-in-ruby-on-rails-revisited</link>
      <trackback:ping>http://cleanair.highgroove.com/articles/trackback/101</trackback:ping>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=cleanair&amp;itemurl=http%3A%2F%2Fcleanair.highgroove.com%2Farticles%2F2008%2F05%2F21%2Frunning-background-jobs-in-ruby-on-rails-revisited</feedburner:awareness><feedburner:origLink>http://cleanair.highgroove.com/articles/2008/05/21/running-background-jobs-in-ruby-on-rails-revisited</feedburner:origLink></item>
    <item>
      <title>We're Presenting at StartupRiot</title>
      <description>&lt;p&gt;&lt;img src="http://farm4.static.flickr.com/3196/2432151661_4acd7c6b63_o.png" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;Come see us talk about &lt;a href="http://scoutapp.com"&gt;Scout Server Monitoring and Reporting&lt;/a&gt; at &lt;a href="http://www.startupriot.com/"&gt;StartupRiot&lt;/a&gt; on May 19, 2008, and watch all the other startups present their wares.  This looks to be a really great event.&lt;/p&gt;


	&lt;p&gt;See ya there!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/cleanair?a=HTxD4H"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=HTxD4H" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/cleanair?a=znIuIH"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=znIuIH" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/cleanair/~4/290252921" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 14 May 2008 10:30:00 EST</pubDate>
      <guid isPermaLink="false">http://cleanair.highgroove.com/articles/2008/05/14/were-presenting-at-startupriot</guid>
      <link>http://feeds.feedburner.com/~r/cleanair/~3/290252921/were-presenting-at-startupriot</link>
      <trackback:ping>http://cleanair.highgroove.com/articles/trackback/100</trackback:ping>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=cleanair&amp;itemurl=http%3A%2F%2Fcleanair.highgroove.com%2Farticles%2F2008%2F05%2F14%2Fwere-presenting-at-startupriot</feedburner:awareness><feedburner:origLink>http://cleanair.highgroove.com/articles/2008/05/14/were-presenting-at-startupriot</feedburner:origLink></item>
    <item>
      <title>Doing it your way</title>
      <description>&lt;p&gt;&lt;a href="http://www.paulgraham.com/startuphubs.html"&gt;You need to be in the Bay Area&lt;/a&gt;. &lt;a href="http://www.37signals.com/svn/posts/987-are-you-sure-you-want-to-be-in-san-francisco"&gt;You shouldn&amp;#8217;t be in the Bay Area&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://www.calacanis.com/2008/03/07/how-to-save-money-running-a-startup-17-really-good-tips/"&gt;You need to work crazy hours&lt;/a&gt;. &lt;a href="http://www.alistapart.com/articles/fourdayweek"&gt;You shouldn&amp;#8217;t work more than 4 days a week&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://blog.pmarca.com/2007/07/the-pmarca-guid.html"&gt;You need to raise as much money as you can&lt;/a&gt;. &lt;a href="http://www.texasstartupblog.com/2006/09/14/be-narrow-be-tiny-dont-raise-money/"&gt;You shouldn&amp;#8217;t raise money&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;The topics above never seem to get old and I think it&amp;#8217;s unfortunate.&lt;/p&gt;


	&lt;p&gt;Just run your business the way that feels right. The majority of your time during the week is spent working. Whether you&amp;#8217;re working for yourself or for someone else, if you&amp;#8217;re not working the way you want to, it won&amp;#8217;t last.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/cleanair?a=IigScjG"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=IigScjG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/cleanair?a=zxjKr8G"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=zxjKr8G" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/cleanair/~4/276299577" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 23 Apr 2008 11:53:00 EST</pubDate>
      <guid isPermaLink="false">http://cleanair.highgroove.com/articles/2008/04/23/doing-it-your-way</guid>
      <link>http://feeds.feedburner.com/~r/cleanair/~3/276299577/doing-it-your-way</link>
      <trackback:ping>http://cleanair.highgroove.com/articles/trackback/99</trackback:ping>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=cleanair&amp;itemurl=http%3A%2F%2Fcleanair.highgroove.com%2Farticles%2F2008%2F04%2F23%2Fdoing-it-your-way</feedburner:awareness><feedburner:origLink>http://cleanair.highgroove.com/articles/2008/04/23/doing-it-your-way</feedburner:origLink></item>
    <item>
      <title>Scout's Grand Opening</title>
      <description>&lt;p&gt;&lt;a href="http://scoutapp.com"&gt;Scout, our server monitoring and application&lt;/a&gt;, is now available for public consumption. 
&lt;div style="float:right"&gt;&lt;img src="http://scoutapp.com/images/logo.jpg" alt="" /&gt;&lt;/div&gt;
Scout is for the 95% of us that either gave up on installing &amp;#38; maintaining monitoring applications or used the old fashion monitoring method &amp;#8211; an email from a customer when your web application is down. I&amp;#8217;m not calling you out, it&amp;#8217;s simply that monitoring used to be more painful than &lt;em&gt;not&lt;/em&gt; monitoring. We think Scout changes that in a beautiful way.&lt;/p&gt;


	&lt;p&gt;Scout makes it easy to bring all of your data together &amp;#8211; from the monitoring standbys (url monitoring, server load, memory usage, etc) to modern day analytics (the number of user accounts on your web application, unique visitors, inbound links, etc). It&amp;#8217;s all done through an easy plugin system that you configure through our web interface &amp;#8211; you never have to login to each of your servers and install or edit monitoring scripts. You&amp;#8217;re not limited to the plugins we built &amp;#8211; &lt;a href="http://scoutapp.com/plugin_urls/static/creating_a_plugin"&gt;you can roll your own with a couple of elegant lines of Ruby code&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/cleanair?a=6AnyETG"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=6AnyETG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/cleanair?a=6tpVjQG"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=6tpVjQG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/cleanair/~4/270801629" height="1" width="1"/&gt;</description>
      <pubDate>Tue, 15 Apr 2008 09:08:00 EST</pubDate>
      <guid isPermaLink="false">http://cleanair.highgroove.com/articles/2008/04/15/scouts-grand-opening</guid>
      <link>http://feeds.feedburner.com/~r/cleanair/~3/270801629/scouts-grand-opening</link>
      <category>Scout</category>
      <trackback:ping>http://cleanair.highgroove.com/articles/trackback/98</trackback:ping>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=cleanair&amp;itemurl=http%3A%2F%2Fcleanair.highgroove.com%2Farticles%2F2008%2F04%2F15%2Fscouts-grand-opening</feedburner:awareness><feedburner:origLink>http://cleanair.highgroove.com/articles/2008/04/15/scouts-grand-opening</feedburner:origLink></item>
    <item>
      <title>What's different in this picture?</title>
      <description>&lt;p&gt;We&amp;#8217;ve used &lt;a href="http://scoutapp.com"&gt;Scout&lt;/a&gt; for several months internally. Along with Colloquy, Google Docs, Basecamp, and Skitch, it&amp;#8217;s one of the few apps I use every day.&lt;/p&gt;


	&lt;p&gt;We think this makes Scout a better service &amp;#8211; we&amp;#8217;re not watching Scout from a third-person perspective. However, sometimes things sneak through &amp;#8211; the type of things that don&amp;#8217;t bother you after using an application for months but can be hurdle to others when getting started.&lt;/p&gt;


	&lt;p&gt;There were 2 nagging issues that stood out in the Scout user experience. I&amp;#8217;ll cover how I addressed the first one here.&lt;/p&gt;
&lt;p&gt;With Scout, you have a client that is installed on a server. The client has many plugins, which do things like monitor a &lt;span class="caps"&gt;URL&lt;/span&gt; or the load on the server.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Here&amp;#8217;s the top of the client detail page:&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://img.skitch.com/20080402-dnmpwjgq7qchuh1ps6a9n8twk9.jpg" alt="client_detail"/&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;...and the top of the plugin detail page:&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://img.skitch.com/20080402-cbi1aasyjbx9nw6j4k9kxxwuwu.jpg" alt="plugin_detail"/&gt;&lt;/p&gt;


	&lt;p&gt;The pages are so similar, it&amp;#8217;s difficult to tell you changed views. &lt;strong&gt;Compare the previous image with the new plugin detail view:&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://img.skitch.com/20080402-1r8qbnik4hp9si7ig33wrwbiie.jpg" alt="[NEW ALERT] Scout ~ PlaceShout"/&gt;&lt;/p&gt;


	&lt;p&gt;It&amp;#8217;s easy to blindly follow a site design blueprint and try to make every page fit the same style guidelines. I did a little too much of that in our initial release, but I think this makes the distinction between the two views much clearer without sacrificing a clean look-and-feel.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/cleanair?a=r9cBUUG"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=r9cBUUG" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~f/cleanair?a=jrDFpIG"&gt;&lt;img src="http://feeds.feedburner.com/~f/cleanair?i=jrDFpIG" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/cleanair/~4/262674742" height="1" width="1"/&gt;</description>
      <pubDate>Wed,  2 Apr 2008 08:00:00 EST</pubDate>
      <guid isPermaLink="false">http://cleanair.highgroove.com/articles/2008/04/02/whats-different-in-this-picture</guid>
      <link>http://feeds.feedburner.com/~r/cleanair/~3/262674742/whats-different-in-this-picture</link>
      <trackback:ping>http://cleanair.highgroove.com/articles/trackback/97</trackback:ping>
    <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=cleanair&amp;itemurl=http%3A%2F%2Fcleanair.highgroove.com%2Farticles%2F2008%2F04%2F02%2Fwhats-different-in-this-picture</feedburner:awareness><feedburner:origLink>http://cleanair.highgroove.com/articles/2008/04/02/whats-different-in-this-picture</feedburner:origLink></item>
  <feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetFeedData?uri=cleanair</feedburner:awareness></channel>
</rss>
