<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" version="2.0">
  <channel>
    <title>overstimulate the feed</title>
    <description>Jesse Hacks Here</description>
    <link>http://overstimulate.com</link>
    <language>en-us</language>
    <ttl>60</ttl>

    <geo:lat>37.443688</geo:lat><geo:long>-122.150714</geo:long><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/overstimulate" type="application/rss+xml" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">overstimulate</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
      <title>New Relic Firefox Status Bar</title>
      <description>&lt;p&gt;Monitoring the performance of your rails application is easy with New Relic.  When I shared my &lt;a href="http://overstimulate.com/articles/new-relic-munin"&gt;munin charting for New Relic&lt;/a&gt; I mentioned I was building a status bar.  At the time it was ugly and didn't work with multiple accounts.  After using New Relic to fix an issue on &lt;a href="http://www.clikball.com"&gt;cliKball&lt;/a&gt; this evening I decided to improve the extension.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://s3.overstimulate.com/blog/relic-uso.png" alt="new relic status bar" style="margin: 0 auto; border: 1px solid #888" /&gt;&lt;/p&gt;

&lt;p&gt;After entering your license key (found in the Accounts tab of your dashboard), your application's health is checked every minute, showing the &lt;em&gt;traffic lights&lt;/em&gt; for your selected app.  To change between your applications you can click on the new relic dropdown menu.  Hovering on the traffic light gives you more information, clicking on the lights takes you to the overview for your application.&lt;/p&gt;

&lt;h2&gt;Installation and source&lt;/h2&gt;

&lt;p&gt;From Firefox click &lt;a href="http://s3.amazonaws.com/overstimulate/relic.xpi"&gt;http://s3.amazonaws.com/overstimulate/relic.xpi&lt;/a&gt; to install (you might need to click "allow" in the upper right corner of your browser after the first click).&lt;/p&gt;

&lt;p&gt;The source is on github at &lt;a href="https://github.com/anotherjesse/foxy-relic"&gt;anotherjesse/foxy-relic&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=rxMplQJwRbU:3lLKhaA-IxI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=rxMplQJwRbU:3lLKhaA-IxI:COZEx2SDH_w"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=rxMplQJwRbU:3lLKhaA-IxI:COZEx2SDH_w" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=rxMplQJwRbU:3lLKhaA-IxI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=rxMplQJwRbU:3lLKhaA-IxI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sun, 15 Mar 2009 18:45:24 GMT</pubDate>
      <link>http://overstimulate.com/articles/firefox-new-relic</link>
      <guid>http://overstimulate.com/articles/firefox-new-relic</guid>
    </item>
    <item>
      <title>Tweetworthy Firefox Extensions</title>
      <description>&lt;p&gt;&lt;a href="http://www.backtype.com"&gt;BackType&lt;/a&gt; recently released a cool &lt;a href="http://backtweets.com/"&gt;Twitter link search-engine&lt;/a&gt;, BackTweet.  Since every tweet use a different short-url service BackTweet lets you search based on the final URLs instead of only short-urls.  Now I can see when people tweet about &lt;a href="http://backtweets.com/search?q=overstimulate.com"&gt;my site&lt;/a&gt;, which wasn't easy to search for before.&lt;/p&gt;

&lt;h2&gt;Get your scrapers ready!&lt;/h2&gt;

&lt;p&gt;Since BackTweet doesn't seem to have a JSON api, and I really wanted to see what Firefox extensions are most tweeted, I wrote screen scrapping code that creates a report for tweets over the last 3 days (max of 500 results for &lt;a href="http://backtweets.com/search?q=addons.mozilla.org"&gt;addons.mozilla.org&lt;/a&gt; search).  No surprise that Twitter extensions are popular.  (&lt;a href="http://gist.github.com/75300"&gt;ruby code to generate report&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;Extensions with 3+ tweets&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/9591'&gt;Power Twitter&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F9591'&gt;104&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/5081'&gt;TwitterFox&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F5081'&gt;43&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/4664'&gt;TwitterBar&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F4664'&gt;40&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/126'&gt;TinyUrl Creator&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F126'&gt;10&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/10722'&gt;KallOut - Accelerators for Firefox&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F10722'&gt;9&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/5457'&gt;Shareaholic&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F5457'&gt;9&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/1419'&gt;IE Tab&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F1419'&gt;8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/10536'&gt;Duck Duck Go Toolbar&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F10536'&gt;7&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/2695'&gt;EditPrefs&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F2695'&gt;6&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/748'&gt;Greasemonkey&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F748'&gt;6&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/1122'&gt;Tab Mix Plus&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F1122'&gt;6&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/4476'&gt;LeechBlock&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F4476'&gt;5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/7631'&gt;Twitbin&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F7631'&gt;5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/1865'&gt;Adblock Plus&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F1865'&gt;4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/8442'&gt;FacePAD: Facebook Photo Album Downloader&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F8442'&gt;4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/1843'&gt;Firebug&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F1843'&gt;4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/2410'&gt;Foxmarks Bookmark Synchronizer&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F2410'&gt;4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/3481'&gt;Glue&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F3481'&gt;4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/8636'&gt;LongURL Mobile Expander&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F8636'&gt;4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/10977'&gt;MySocial 24x7 Bar&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F10977'&gt;4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/115'&gt;ReloadEvery&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F115'&gt;4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/10279'&gt;Twitter Search&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F10279'&gt;4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/10869'&gt;JSONView&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F10869'&gt;3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/539'&gt;MeasureIt&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F539'&gt;3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/8758'&gt;UrlbarExt&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F8758'&gt;3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/3006'&gt;Video DownloadHelper&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F3006'&gt;3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/60'&gt;Web Developer&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F60'&gt;3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href='https://addons.mozilla.org/firefox/addon/7369'&gt;is.gd Creator&lt;/a&gt; &lt;a href='http://backtweets.com/search?q=addon%2F7369'&gt;3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=flwOUHZelBI:hO3oDOQ3Lwc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=flwOUHZelBI:hO3oDOQ3Lwc:COZEx2SDH_w"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=flwOUHZelBI:hO3oDOQ3Lwc:COZEx2SDH_w" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=flwOUHZelBI:hO3oDOQ3Lwc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=flwOUHZelBI:hO3oDOQ3Lwc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sat, 07 Mar 2009 10:41:48 GMT</pubDate>
      <link>http://overstimulate.com/articles/most-tweeted-extensions</link>
      <guid>http://overstimulate.com/articles/most-tweeted-extensions</guid>
    </item>
    <item>
      <title>Firefox New Tab + Addons</title>
      <description>&lt;p&gt;Aza has been leading a discussion about &lt;a href="http://labs.mozilla.com/2009/03/new-tab-page-proposed-design-principles-and-prototype/"&gt;what the blank tab should have&lt;/a&gt;.  Chrome did a good job of taking some real-estate that was blank and providing something to the user that has value.  Chrome hasn't had to deal with a serious usability problem we have in Firefox-land yet - that of addons trying to communicate with the user.&lt;/p&gt;

&lt;h2&gt;No place like new tab?&lt;/h2&gt;

&lt;p&gt;A couple of months ago, at the Mozilla Open House, &lt;a href="http://www.reybango.com/"&gt;Rey Bango&lt;/a&gt; talked with extension developers about issues we have and firefox users have.  Some of it was pretty, but Mozilla (in particular Ray) did a good job of trying to move forward and find solutions.  One issue he shared was highlighted by the user experience of &lt;a href="https://addons.mozilla.org/en-US/firefox/fashionyourfirefox"&gt;Fashion Your Firefox&lt;/a&gt;.  These extension packs could be quite painful as each extension runs first-run/setup in a different manner.  Installing a  pack could result in multiple dialogs, notification banners, and a frustrating user experience.&lt;/p&gt;

&lt;p&gt;Aza's discussion of new tab is a great time to consider how users could benefit from using it as a place to interact with extensions.  Ray and the AMO team probably have better ideas about how this could work, but here are some of my thoughts.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;When new extensions are added they can provide a box of info with how to use/configure it.&lt;/li&gt;
  &lt;li&gt;Installed extensions are listed, providing quick access to settings/status.&lt;/li&gt;
  &lt;li&gt;Non-crucial notifications (eg, something that doesn't warrant a window) could be added to an "inbox"/notices section on the tab.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Jono posted about &lt;a href="http://jonoscript.wordpress.com/2009/03/05/ubiquity-user-testing-reveals-desperate-need-for-better-first-run-experience/"&gt;Ubiquity's first run woes&lt;/a&gt;.  It is clear that the Mozilla team is thinking how to make the user experience better.  It would be interesting to see what Jono thinks can be generalized from the Ubiquity first-run/install experience and added directly to the extension platform.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=OpuBRws2FLo:qNP7NOX6_dQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=OpuBRws2FLo:qNP7NOX6_dQ:COZEx2SDH_w"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=OpuBRws2FLo:qNP7NOX6_dQ:COZEx2SDH_w" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=OpuBRws2FLo:qNP7NOX6_dQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=OpuBRws2FLo:qNP7NOX6_dQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Fri, 06 Mar 2009 08:11:15 GMT</pubDate>
      <link>http://overstimulate.com/articles/firefox-new-tab-addons</link>
      <guid>http://overstimulate.com/articles/firefox-new-tab-addons</guid>
    </item>
    <item>
      <title>Viral Grid Computing</title>
      <description>&lt;p&gt;Ilya Grigorik's post on &lt;a href="http://www.igvita.com/2009/03/03/collaborative-map-reduce-in-the-browser/"&gt;Collaborative Map-Reduce in the Browser&lt;/a&gt; explores how to leverage visitors to do computation.  While I think he is looking in the right direction, I don't think he is thinking large enough.  Moving your worker code into widgets lets you "leverage viral growth" to do computation.&lt;/p&gt;

&lt;h2&gt;Why Google bought Youtube&lt;/h2&gt;

&lt;p&gt;
&lt;a href="http://www.youtube.com/watch?v=sV1a6UBdrPk"&gt;&lt;img src="http://s3.overstimulate.com/blog/ppp.png" alt="Computing with Youtube" align="left" style="margin: 0 10px 10px 0" /&gt;&lt;/a&gt;

Anytime you see a Youtube embed, your computer is doing computation in the background.  Ask a Mac user and they will tell you how hot their computer gets with a single Youtube video.  I suspect Google is testing their grid by having Macs compute pi to hundreds of digits.  If results are positive, G2C2 (Global Google Compute Cluster) will be activated for everyone.&lt;/p&gt;

&lt;h2&gt;Computation is serious business&lt;/h2&gt;

&lt;p&gt;Lowly clients can do some serious work.  Bit-torrent uses a variant of &lt;a href="http://en.wikipedia.org/wiki/Tit_for_tat"&gt;Tit for Tat&lt;/a&gt; to punish leechers who download without contributing bandwidth to others.  &lt;a href="http://www.youtube.com/watch?v=cQ25-glGRzI"&gt;Avril Lavigne - Girlfriend&lt;/a&gt;'s 116 million views could have contributed 838 years of compute time.&lt;/p&gt;

&lt;p&gt;Bloggers and social networkers could leverage their reach to help cure cancer.  &lt;a href="http://laughingsquid.com/"&gt;Laughing Squid&lt;/a&gt; could embed a &lt;a href="http://code.google.com/apis/youtube/overview.html"&gt;wrapped youtube player&lt;/a&gt; that &lt;a href="http://folding.stanford.edu/"&gt;folds protein&lt;/a&gt; in the background.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=jqG3srjBQII:4EjIDiT7aVM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=jqG3srjBQII:4EjIDiT7aVM:COZEx2SDH_w"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=jqG3srjBQII:4EjIDiT7aVM:COZEx2SDH_w" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=jqG3srjBQII:4EjIDiT7aVM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=jqG3srjBQII:4EjIDiT7aVM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Wed, 04 Mar 2009 21:09:49 GMT</pubDate>
      <link>http://overstimulate.com/articles/tit-for-tat-grid-widgets</link>
      <guid>http://overstimulate.com/articles/tit-for-tat-grid-widgets</guid>
    </item>
    <item>
      <title>My Computer Setup</title>
      <description>&lt;p&gt;Long ago I would spend days designing and building a new computer every year, only to tinker unendingly until it was time to start over.  My hardware lust has moved on to phone lust, leaving behind my minimal approach to my setup.  What I consider the most important parts now were previously afterthoughts.  As technology caught up with me, older laptops satisfied my power requirements and years of improper use highlighted the importance of the chair and keyboard.&lt;/p&gt;

&lt;h2&gt;The important stuff&lt;/h2&gt;

&lt;p&gt;
  &lt;a href="http://www.flickr.com/photos/anotherjesse/3313605830/" title="Desk, kinesis, chair, monitor by anotherjesse, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3539/3313605830_c6b5420fe1_m.jpg" style="margin-right: 20px" width="180" height="240" alt="Desk, kinesis, chair, monitor" align="left"/&gt;&lt;/a&gt;
  A &lt;b&gt;good chair&lt;/b&gt; is my top priority.  The cheap office store chair never feels right and starts to hurt you within a few months.  I had an &lt;a href="http://en.wikipedia.org/wiki/Aeron_chair"&gt;Aeron&lt;/a&gt; at a previous job and it was nice.  I knew I'd found my true love after using a &lt;a href="http://store.steelcase.com/go/products/detail/E/"&gt;Steelcase Leap&lt;/a&gt; for a month at work.  Ordering the Leap for $849 shipped might have been painful for my bank account, but it has done wonders for my back.&lt;/p&gt;
&lt;p&gt;A &lt;b&gt;good keyboard&lt;/b&gt; is my second priority.  During summer break from college I blew out my wrists coding &lt;a href="http://tuxtype.sourceforge.net/screens/"&gt;Tux Typing&lt;/a&gt; on a dell laptop keyboard.  While the Latitude keyboard was horrible almost a decade ago, I am mostly to blame for working in unhealthy positions.  I seem to remember spending most of that time laying on my stomach looking forwards to see the screen.  I am very picky about laptops in the sense that they must have a good keyboard.  The &lt;a href="http://www.thinkwiki.org/wiki/Category:X60#ThinkPad_X60"&gt;ThinkPad X60&lt;/a&gt; has good laptop  keyboard, but cannot compare to the &lt;a href="http://www.kinesis-ergo.com/advantage.htm"&gt;Kinesis Advantage&lt;/a&gt; when at sitting at a desk.  The Kinesis takes some time to get used to, but if you struggle through it, instead of switching back your normal keyboard whenever you get frustrated, you can master it in a few days.&lt;/p&gt;
&lt;p&gt;A nice &lt;b&gt;LCD&lt;/b&gt; is important.  While Monitors are commodity, choose one that can be correctly positioned.  You don't want to strain your neck looking at your laptop or monitor.&lt;/p&gt;

&lt;h2&gt;My mobile setup&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/anotherjesse/3313605826/" title="My &amp;quot;real&amp;quot; setup by anotherjesse, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3621/3313605826_eb806554db_m.jpg" width="240" height="180" alt="My &amp;quot;real&amp;quot; setup" align="right" style="margin-left: 20px"/&gt;&lt;/a&gt;

&lt;ul&gt;
  &lt;li&gt;An awesome tiny bag that fits everything on this list.  My mom was giving it away and luckily my laptop barely fits into it (not a 1/4" to spare).&lt;/li&gt;
  &lt;li&gt;Google Dev Phone (android) - more functional, yet less complete, than the iPhone&lt;/li&gt;
  &lt;li&gt;A Moleskine journal - I would go digital if there was a fast notes app on android&lt;/li&gt;
  &lt;li&gt;Sony eReader - I've had this since 2006 and find reading e-ink pleasant. The selection of books is a fraction of what the Kindle offers, so I'll probably upgrade someday&lt;/li&gt;
  &lt;li&gt;iPod nano - the android uses USB-WTF for headphones :(  Perhaps the Palm Pre will work with normal headphones.  Unsurprisingly, the iPhone is a great music device.&lt;/li&gt;
  &lt;li&gt;ThinkPad X60 - I like this laptop so much I replaced my &lt;a href="http://www.flickr.com/photos/anotherjesse/3032358669/"&gt;crushed X60&lt;/a&gt; with another used one.  I've tried many netbooks, but the keyboards aren't big enough for my fingers.  You can find these used for about the same cost as a netbook - I paid $300 for mine.&lt;/p&gt;
  &lt;li&gt;A small X60 power cord and the laptop has the largest battery made for the X60&lt;/li&gt;
  &lt;li&gt;Golden Gate Transit schedule - indispensable yet frustrating.  90% of the data is irrelevant to me and none of the knowledge.  Someone should create a custom guide you can print with schedules of buses that come near where you need to travel (ala &lt;a href="http://www.offbeatguides.com/"&gt;offbeat guides&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;p&gt;All told, my chair cost more than all the items on this list.  The important parts are the ones that will destroy your back and wrists if you do them wrong.  I could replace/remove anything on this list and still have an effective setup.  I could not replace my chair or keyboard with an office store special and survive a week.  My back and wrists are too far gone.&lt;/p&gt;

&lt;h2&gt;What do you use?&lt;/h2&gt;

&lt;p&gt;And just as important, &lt;b&gt;what do you not use&lt;/b&gt;?&lt;/p&gt;

&lt;p&gt;Currently I have two rarely old laptops I use for testing with XP and OSX.  I should replace the XP laptop with a VM.  I think it isn't possible to OSX inside a VM, so I would need to keep the mac.  Other reductions seem to require replacement of multiple items at once (such as replacing my phone and iPod for a phone).&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=EIODkAcZBpE:6FBzBUK_jwQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=EIODkAcZBpE:6FBzBUK_jwQ:COZEx2SDH_w"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=EIODkAcZBpE:6FBzBUK_jwQ:COZEx2SDH_w" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=EIODkAcZBpE:6FBzBUK_jwQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=EIODkAcZBpE:6FBzBUK_jwQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Fri, 27 Feb 2009 08:26:17 GMT</pubDate>
      <link>http://overstimulate.com/articles/2009-laptop</link>
      <guid>http://overstimulate.com/articles/2009-laptop</guid>
    </item>
    <item>
      <title>Charting Health with New Relic and Munin</title>
      <description>&lt;p&gt;&lt;a href="http://newrelic.com"&gt;New Relic&lt;/a&gt; recently released the first version of an API.  They are even &lt;a href="http://blogs.newrelic.com/2009/01/new-relic-announces-data-api-contest.html"&gt;holding a contest&lt;/a&gt; for people to create cool apps/widgets/whatnot with their API.  What follows is not a cool app - just a simple &lt;a href="http://munin.projects.linpro.no/"&gt;munin&lt;/a&gt; plugin for generating static images of application health.&lt;/p&gt;

&lt;p&gt;By charting New Relic data in munin we have fast access to application health information right next to other system metrics.  The historical charting that munin is useful to show trends in how your system is behaving on the day, week, month, year scale.&lt;/p&gt;
&lt;p&gt;I added munin charts to my site's dashboard by embedding a munin chart.  Then I wrapped it with a link to the New Relic page with more information.&lt;/p&gt;

&lt;center&gt;&lt;a href="https://rpm.newrelic.com/browser/agent?account_id=902&amp;agent=15990"&gt;&lt;img src="http://munin.userscripts.org/localdomain/localhost.localdomain-relic_throughput-day.png" alt="calls per minute on userscripts.org" /&gt;&lt;/a&gt;&lt;/center&gt;

&lt;h2&gt;Installation&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Grab the code at &lt;a href="http://gist.github.com/70718"&gt;gist.github.com&lt;/a&gt; (click on raw) - save it as relic.rb&lt;/li&gt;
  &lt;li&gt;Add your New Relic license key&lt;/li&gt;
  &lt;li&gt;Put it on your server in /usr/share/munin/plugins&lt;/li&gt;
  &lt;li&gt;Make the script executable: &lt;em&gt;chmod +x relic.rb&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Sym-link for each metric you want to chart: &lt;em&gt;ln -s /usr/share/munin/plugins/relic.rb /etc/munin/plugins/relic_db&lt;/em&gt; (and/or relic_cpu relic_throughput relic_errors relic_response relic_memory)&lt;/li&gt;
  &lt;li&gt;Test running them manually: &lt;em&gt;/etc/munin/plugins/relic_db&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Restart munin node: &lt;em&gt;/etc/init.d/munin-node restart&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Wait 5 minutes for munin to run - hoping you didn't make any typos&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Issues/Ideas&lt;/h2&gt;

&lt;p&gt;I only have 1 application associated with my license key.  Modifications are needed to properly support multiple applications.&lt;/p&gt;

&lt;p&gt;Perhaps certain metrics should be grouped (CPU &amp;amp; DB, Errors &amp;amp; Throughput).&lt;/p&gt;

&lt;p&gt;I've also been working on a &lt;a href="http://getsatisfaction.com/newrelic/topics/new_relic_status_in_your_firefox_browser"&gt;New Relic status bar&lt;/a&gt; for firefox.  It needs work, so if you try it out let me know what you changes you would like!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=iqZzd7r2gBw:lvo50hIzG9Q:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=iqZzd7r2gBw:lvo50hIzG9Q:COZEx2SDH_w"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=iqZzd7r2gBw:lvo50hIzG9Q:COZEx2SDH_w" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=iqZzd7r2gBw:lvo50hIzG9Q:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=iqZzd7r2gBw:lvo50hIzG9Q:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Thu, 26 Feb 2009 07:37:17 GMT</pubDate>
      <link>http://overstimulate.com/articles/new-relic-munin</link>
      <guid>http://overstimulate.com/articles/new-relic-munin</guid>
    </item>
    <item>
      <title>Graceful Caching with Varnish</title>
      <description>&lt;p&gt;Your website is being hammered because &lt;a href="http://twitter.com/mchammer"&gt;Hammer&lt;/a&gt; told his 120,000 followers on twitter to check your site.  The content is highly cachable and no one would notice if you sent the same data for up to a minute.  To make matters worse the request takes 5 seconds to complete.  Hammer is threatening to send his posse after you.  What do you do?&lt;/p&gt;

&lt;p&gt;To simulate this theoretical event we will use a small &lt;a href="http://sinatrarb.com"&gt;sintra&lt;/a&gt; app and apache bench.&lt;/p&gt;

&lt;pre&gt;require 'rubygems'
require 'sinatra'

get '/work' do
  sleep 5
  body "result: #{rand}"
end&lt;/pre&gt;

&lt;p&gt;Requests take 5 seconds to process, in addition to any time spent waiting in the request queue.  Our single app server processes requests one at a time, so if requests are more often than every 5 seconds, requests will certainly be delayed.&lt;/p&gt;

&lt;p&gt;We could add more app servers to improve throughput, but each request would still take 5 seconds, and our concurrency is limited by the number of app servers.  Most requests are doing work that isn't needed since the results computed by the last request are good enough.&lt;/p&gt;

&lt;h2&gt;Getting Varnish&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="http://varnish.projects.linpro.no/"&gt;Varnish&lt;/a&gt; is a state-of-the-art, high-performance HTTP accelerator&lt;/em&gt;, meaning it is built for caching.  While your framework might have internal support for memcache or file system based caching, it is worth exploring how Varnish could integrate with your systems.  Varnish is a layer between your HTTP frontend server (nginx) and your app servers.  Besides caching it constantly checks the health of backend services, and only sends requests to those which are live.&lt;/p&gt;

&lt;p&gt;Varnish is currently 2.0.3 at the time of writing.  To install on linux:&lt;/p&gt;

&lt;pre&gt;wget http://downloads.sourceforge.net/varnish/varnish-2.0.3.tar.gz?use_mirror=internap
tar -zxvf varnish-2.0.3.tar.gz
cd varnish-2.0.3
./configure
make
sudo make install&lt;/pre&gt;

&lt;h2&gt;Connecting Varnish to Sinatra&lt;/h2&gt;

&lt;p&gt;Sinatra is listening on port 4567. We start our &lt;em&gt;sinatra.vcl&lt;/em&gt; by specifying where to find sinatra.&lt;/p&gt;

&lt;pre&gt;backend sinatra {
  .host = "127.0.0.1";
  .port = "4567";
}&lt;/pre&gt;

&lt;p&gt;We can now start varnishd and verify that &lt;a href="http://localhost:1234/work"&gt;http://localhost:1234/work&lt;/a&gt; works.&lt;/p&gt;

&lt;pre&gt;sudo varnishd -f /path/to/sinatra.vcl -a 0.0.0.0:1234&lt;/pre&gt;

&lt;p&gt;The cache time to live is set in &lt;em&gt;vcl_fetch&lt;/em&gt;.   We add a &lt;em&gt;ttl&lt;/em&gt; of 1 minute to our vcl and restart varnishd.&lt;/p&gt;

&lt;pre&gt;sub vcl_fetch {
  set obj.ttl = 1m;
}&lt;/pre&gt;

&lt;p&gt;At this point running &lt;em&gt;ab -c 100 -n 1000&lt;/em&gt; takes 5 seconds to complete.  Note that Varnish only sent the first request to the app server, and queued the others.  When the request finished the queued requests were served from cache.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Troubleshooting tip&lt;/b&gt;: Now comes the frustrating part.  Nothing seems to be cached when you test this in your browser.  Every request takes 5 seconds.  Luckily &lt;em&gt;varnishlog&lt;/em&gt; shows your browser is sending a cookie.  You remember cookies are per domain (not per domain:port), so cookies set when working on localhost earlier are still being sent.  By default Varnish doesn't serve cached results to sessions with cookies.  This is useful to serve cached pages to anonymous visitors while logged in users get custom versions of the page.  Varnish is quite customizable, but for now we will instruct varnish to ignore cookies in our &lt;em&gt;vcl_recv&lt;/em&gt;.&lt;/p&gt;

&lt;pre&gt;sub vcl_recv {
  unset req.http.cookie;
}&lt;/pre&gt;

&lt;p&gt;Now we have a painful first request, then all further requests for a minute are speed (my $300 laptop gets over 6,000 req/s with 1000 concurrent requests).  After the cache expires, we start over with requests being queued while a single request hits the backend.  So every minute all requests are blocked for 5 seconds while the backend works.&lt;/p&gt;

&lt;h2&gt;Being graceful: release the queue&lt;/h2&gt;

&lt;p&gt;Varnish optionally allows serving the dirty page during a grace period.  Varnish sends a single request is sent to the backend and serves all other requests from the dirty cache.&lt;/p&gt;

&lt;p&gt;To make sure we never send pages older than 1 minute, we will reduce the TTL to 45 seconds and add a 15 second grace by updating &lt;em&gt;vcl_fetch/vcl_recv&lt;/em&gt;.&lt;/p&gt;

&lt;pre&gt;backend sinatra {
  .host = "127.0.0.1";
  .port = "4567";
}

sub vcl_recv {
  unset req.http.cookie;
  set req.grace = 15s;
}

sub vcl_fetch {
  set obj.ttl = 45s;
  set obj.grace = 15s;
}&lt;/pre&gt;

&lt;p&gt;Now a single user will hit a 5 second request every minute but thousands of other requests will benefit from that user's generosity.

&lt;h2&gt;More caching&lt;/h2&gt;

&lt;p&gt;You should be caching the page on the client as well.  Adding even a small Cache-Control for the browser will improve visitors experiences.&lt;/p&gt;

&lt;p&gt;Wikia/Wikipedia, FunnyOrDie, and others have reported impressive results with Varnish.  Varnish is very extensible and supports ESI (server side include).  Varnish has great tools (varnishtop, varnishdist, varnishlog) to see how your systems are behaving.  Varnish takes headers very seriously, specially regarding cache-control, cookies.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=3pd6IM81TFc:VJKFnvdl7IY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=3pd6IM81TFc:VJKFnvdl7IY:COZEx2SDH_w"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=3pd6IM81TFc:VJKFnvdl7IY:COZEx2SDH_w" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=3pd6IM81TFc:VJKFnvdl7IY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=3pd6IM81TFc:VJKFnvdl7IY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Wed, 25 Feb 2009 09:30:26 GMT</pubDate>
      <link>http://overstimulate.com/articles/varnish-getting-started</link>
      <guid>http://overstimulate.com/articles/varnish-getting-started</guid>
    </item>
    <item>
      <title>FlashLiteBox - a tiny full screen flash lightbox</title>
      <description>&lt;p&gt;Flash was given a full screen capabilities a couple years ago, around the same time JavaScript based lightboxes were becoming popular.  While I prefer standards based solutions, I don't know of any other way to implement full screen.  My goal was to create a really small flash-based lightbox that uses all your pixels to show you images.  While not a finished project, I think this 647 byte swf shows potential.&lt;/p&gt;

&lt;h2&gt;Overview &amp;amp; demo&lt;/h2&gt;

&lt;p&gt;The basic idea to overlay thumbnails with a flash movie with arrows indicating you can make the image bigger.  If you click the arrows, you switch to full screen and the large version of the image is shown.&lt;/p&gt;

&lt;p&gt;You can see a demo at the &lt;a href="http://overstimulate.com/projects/flashlitebox"&gt;project page&lt;/a&gt;.  Sorry about that but flash embeds don't survive rss/email so I'm not even going to attempt it.&lt;/p&gt;

&lt;h2&gt;Code Walkthrough&lt;/h2&gt;

&lt;p&gt;FlashLiteBox is built using two open source projects.  &lt;a href="http://swfmill.org/"&gt;swfmill&lt;/a&gt; takes an xml file of resources and compiles the final swf.  &lt;a href="http://www.mtasc.org/"&gt;MTASC&lt;/a&gt; compiles the ActionScript 2 code into a swf for swfmill.&lt;/p&gt;

&lt;h3&gt;Arrows.as&lt;/h3&gt;

&lt;pre&gt;class Arrows extends MovieClip {
  function onLoad() {
    Stage.align = "TL";
    Stage.scaleMode = "noScale";
    Stage.addListener({
      onFullScreen: function(full) {
        if (!full) _root.image.removeMovieClip();
      }
    });
  }

  function onRelease() {
    if (Stage['displayState'] != "fullScreen") {
      Stage['displayState'] = "fullScreen";
      _root.createEmptyMovieClip("image", getNextHighestDepth());
      _root.image.loadMovie(_root.img_src);
    }
  }
}&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;onLoad&lt;/b&gt; runs when the movie starts.  We setup flash not to scale our image and to align the images to the top left.  A listener is added which checks for a change to full screen mode.  This listener allows removal of the image when escape is hit, leaving the flash movie in its original state.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;onRelease&lt;/b&gt; runs when the mouse button is released.  If the movie isn't already full screen we: enter fullscreen mode, then add a new "movie clip" into we load the image.  The URL of the image is provided as a flashvar and accessible via &lt;em&gt;_root.img_src&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This ActionScript is complied into &lt;em&gt;classes.swf&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;flashlitebox.xml&lt;/h3&gt;

&lt;pre&gt;&amp;lt;movie&amp;gt;
  &amp;lt;clip import="classes.swf"/&amp;gt;
  &amp;lt;background color="Black"/&amp;gt;
  &amp;lt;frame&amp;gt;
    &amp;lt;library&amp;gt;
      &amp;lt;clip class="Arrows" id="arrows" import="src/maximize.png"/&amp;gt;
    &amp;lt;/library&amp;gt;
    &amp;lt;place id="arrows"/&amp;gt;
  &amp;lt;/frame&amp;gt;
&amp;lt;/movie&amp;gt;&lt;/pre&gt;

&lt;p&gt;In the final flash movie we load several clips.  First we import &lt;em&gt;classes.swf&lt;/em&gt;, which is a compiled version of the code above.  Then &lt;em&gt;src/maximize.png&lt;/em&gt; is added as an image clip (16x16 png).  It is given an id, which we use place the movie clip into the main movie frame.  The class attribute attaches the actionscript classes we imported from classes.swf.&lt;/p&gt;

&lt;h2&gt;Further ideas &amp;amp; improvements&lt;/h2&gt;

&lt;p&gt;The code is open source (BSD) and on &lt;a href="http://github.com/anotherjesse/flashlitebox"&gt;github&lt;/a&gt;.  This is a crude prototype and I am not flash developer, so don't flame me!&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The demo html is crude and should probably add/position the flash via JavaScript, preferably gracefully degrading to a JavaScript lightbox if you don't have flash.&lt;/li&gt;
  &lt;li&gt;Instead of a 16x16 png to click, allow clicking anywhere on the thumbnail to open up the full screen view.  I think this requires the flash movie cover the image and capture the click for security reasons.&lt;/li&gt;
  &lt;li&gt;Show the progress of the large image while it downloads instead of a black screen&lt;/li&gt;
  &lt;li&gt;The image in full screen mode should be centered and scaled to fit&lt;/li&gt;
  &lt;li&gt;It would be nice to be able to go to the previous/next image without leaving full screen mode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'd love to see someone take this and create a movie usable by people creating galleries.  Or perhaps someone should create a &lt;a href="http://userscripts.org"&gt;greasemonkey script&lt;/a&gt; to add it to existing galleries.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=pRyGxTQeuq8:bDo3XsSze3s:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=pRyGxTQeuq8:bDo3XsSze3s:COZEx2SDH_w"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=pRyGxTQeuq8:bDo3XsSze3s:COZEx2SDH_w" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=pRyGxTQeuq8:bDo3XsSze3s:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=pRyGxTQeuq8:bDo3XsSze3s:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Tue, 24 Feb 2009 09:01:32 GMT</pubDate>
      <link>http://overstimulate.com/articles/fullscreen-flash-lightbox</link>
      <guid>http://overstimulate.com/articles/fullscreen-flash-lightbox</guid>
    </item>
    <item>
      <title>BlogBiking: Making RSS Healthy</title>
      <description>&lt;p&gt;
&lt;a href="http://www.flickr.com/photos/anotherjesse/3301913092/" title="How I Roll"&gt;&lt;img src="http://farm4.static.flickr.com/3369/3301913092_bce193dc3b_m.jpg" width="240" height="179" alt="How I Roll" align="right" style="margin-left: 20px" /&gt;&lt;/a&gt;
Exercise is boring.  You know you should, but you don't make time.  Motivated by &lt;a href="http://theweightlifter.blogspot.com/2006/10/low-cal-6011-min-warbiking-3-months-41.html"&gt;warbiking&lt;/a&gt; (playing warcraft while exercise biking), but not having time for it, I applied the concept to my existing time sinks.  Once passive tasks (blogs, &lt;a href="http://www.ted.com/"&gt;TED talks&lt;/a&gt;, pdfs) become active tasks while biking.&lt;/p&gt;

&lt;p&gt;Previously I would attempt to multi-task.  Sitting at my desk I would attempt stupid things like watching a video while skimming articles.  While effective at pruning unnecessary emails/posts, I rarely remembered the video afterwards.  Now I read articles &lt;em&gt;or&lt;/em&gt; watch videos while biking.  Because I'm biking I'm less fidgety and can concentrate on one thing since I know at the very least I'm staying healthy.&lt;/p&gt;

&lt;p&gt;A new Schwinn recumbent bike is $400, but you can find them used on craigslist.  I bought mine for $150 into which my X60 fits perfectly.&lt;/p&gt;

&lt;h2&gt;Don't break the chain&lt;/h2&gt;

&lt;p&gt;
&lt;a href="http://www.flickr.com/photos/anotherjesse/3302010130/" title="Seinfeld Calendar"&gt;&lt;img src="http://farm4.static.flickr.com/3068/3302010130_8daf2fb43a_m.jpg" width="147" height="240" alt="Seinfeld Calendar" align="left" style="margin-right: 20px" /&gt;&lt;/a&gt;
It is easy to lose motivation and stop.  After a few weeks of blogbiking in 2007 I stopped for a month.  Until this year I've only biked intermittently as I have to consciously remember to move to the bike.&lt;/p&gt;

&lt;p&gt;Jerry Seinfeld knew the &lt;a href="http://lifehacker.com/software/motivation/jerry-seinfelds-productivity-secret-281626.php"&gt;importance of showing up every day&lt;/a&gt;.  By working on your craft every day, you keep moving forward, even if the step is a small one.  By recording daily progress, you will be motivated to not skip a day (breaking the chain).  Knowing I've biked at least 5 miles for 32 continuous days pushes me to not skip a day.&lt;/p&gt;

&lt;p&gt;At first I overcomplicated the process.  I tried &lt;a href="http://www.calendaraboutnothing.com/"&gt;calendar about nothing&lt;/a&gt; and other online progress trackers.   My Christmas calendar and a sharpie was all I needed.  Each day I write my current streak length on today's date.&lt;/p&gt;

&lt;h2&gt;I know more about COBOL&lt;/h2&gt;

&lt;p&gt;Somedays I have to bike at midnight when I get home.  I need to find an alternative exercise I can do while traveling or during a break at work.&lt;/p&gt;

&lt;p&gt;As an exercise n00b, I'm unsure how to optimize for tone/health. Currently I bike at slow pace (10mph) with a high resistance, but perhaps programs that vary resistance (strength interval, ride in park, pyramids, ...) would be better?&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=HW0YGcik3Kc:62ooo1fx5-s:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=HW0YGcik3Kc:62ooo1fx5-s:COZEx2SDH_w"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=HW0YGcik3Kc:62ooo1fx5-s:COZEx2SDH_w" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=HW0YGcik3Kc:62ooo1fx5-s:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=HW0YGcik3Kc:62ooo1fx5-s:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Mon, 23 Feb 2009 02:11:41 GMT</pubDate>
      <link>http://overstimulate.com/articles/geek-exercise</link>
      <guid>http://overstimulate.com/articles/geek-exercise</guid>
    </item>
    <item>
      <title>Sending Email Alerts with BackgroundJob</title>
      <description>&lt;p&gt;Web requests should be lazy, putting off any work they can.  When a user updates a script on &lt;a href="http://userscripts.org"&gt;userscripts.org&lt;/a&gt; I send an email alert sent to its fans.  But the uploader shouldn't have to wait while hundreds of people are emailed.  There are many systems that allow for asynchronous tasks in rails.   Here is what worked best for me.&lt;/p&gt;

&lt;h2&gt;No spam please&lt;/h2&gt;

&lt;p&gt;Since I don't want to be a spammer, I need to allow a method for users to opt-in to receiving updates of their favorite scripts.  I've added a column to our user table to store whether a user wants emailed.&lt;/p&gt;

&lt;pre&gt;add_column :users, :email_favorite_activity, :boolean&lt;/pre&gt;

&lt;p&gt;UI changes are made to the settings page allowing them to subscribe to alerts.  Next I make sure emails include messaging about why they were sent and how to stop getting them.&lt;/p&gt;

&lt;h2&gt;A small job&lt;/h2&gt;

&lt;p&gt;Next I create a directory called jobs in the userscripts project directory.  I add a trival ruby script emails all the fans that opted into email of the passed in script.  This code runs within the rails environment allowing the use of ActiveRecord, ActionMailer and all their friends.&lt;/p&gt;

&lt;pre&gt;script_id = ARGV[0]
script = Script.find(script_id)
users = script.fans.select { |u| u.email_favorite_activity }
puts "Emailing #{users.count} fans"
users.each do |fan|
  Notification.deliver_new_script_version(script, fan)
end&lt;/pre&gt;

&lt;p&gt;The job can be ran manually using rails' built-in &lt;em&gt;script/runner&lt;/em&gt;.&lt;/p&gt;

&lt;pre&gt;script/runner ./jobs/email_script_fans.rb 42&lt;/pre&gt;

&lt;p&gt;In development mode the emails won't be sent, but I can see I'm ready to integrate the task.&lt;/p&gt;

&lt;h2&gt;Why &lt;strike&gt;starling&lt;/strike&gt; &lt;strike&gt;backgroundrb&lt;/strike&gt; bj?&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Starling_%28software%29"&gt;Starling&lt;/a&gt; is a queue system which speaks the memcache protocol.  It was designed by &lt;a href="http://romeda.org/"&gt;Blaine Cook&lt;/a&gt; to allow Twitter to route with a massive of tweet.  Starling requires a server daemon, and workers that are constantly asking for queued items.  My email load is a fraction of a fraction of twitter's load, so the increased complexity isn't worth it.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://backgroundrb.rubyforge.org/"&gt;BackgroundRB&lt;/a&gt; was created by &lt;a href="http://brainspl.at/"&gt;Ezra Zygmuntowicz&lt;/a&gt; (of EngineYard).  BackgroundRB requires a daemon as well, and if that daemon isn't running adding a task fails.  After spending a few hours I could see the potential but the complexity was overkill for sending a few emails.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://codeforpeople.rubyforge.org/svn/bj/trunk/README"&gt;BackgroundJob&lt;/a&gt; (BJ) was a perfect fit.  Jobs are stored in your database, so you don't have to worry about deploying and monitoring another daemon.  I was initially concerned that tasks are not rails specific.  Task are ran as regular processes, with the stdout/stderr being stored in columns after completion.  To run rails code you use script/runner.  Each job requires a new script/runner, so the overhead of loading rails for each task can become painful at volume.&lt;/p&gt;

&lt;p&gt;BJ was received support from EngineYard/Ezra and the community has taken over BackgroundRB.  There are other projects as well, but none of them seemed to:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;put the jobs in the database&lt;/li&gt;
  &lt;li&gt;not require a daemon to be running&lt;/li&gt;
  &lt;li&gt;not make the workers more complicated than the tasks&lt;/li&gt;
  &lt;li&gt;really easy deploy&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Installation&lt;/h2&gt;

&lt;p&gt;Start by install BackgroundJob as a plugin.&lt;/p&gt;

&lt;pre&gt;script/plugin install http://codeforpeople.rubyforge.org/svn/rails/plugins/bj
script/bj setup&lt;/pre&gt;

&lt;p&gt;Unfortunately BackgroundJob has a couple issues with the timezone improvements in rails 2.1. The fix is to change all instances of &lt;em&gt;Time.now&lt;/em&gt; to &lt;em&gt;Time.now.utc&lt;/em&gt; in two of the files.&lt;/p&gt;

&lt;pre&gt;vendor/plugins/bj/lib/bj/runner.rb
vendor/plugins/bj/lib/bj/table.rb&lt;/pre&gt;

&lt;p&gt;Then I trigger a job to be added when a new version of a script is uploaded.&lt;/p&gt;

&lt;pre&gt;class Version &lt; ActiveRecord::Base
  after_create :email_fans

  def email_fans
    Bj.submit "./script/runner ./jobs/email_script_fans.rb #{self.script_id}"
  end
end&lt;/pre&gt;

&lt;h2&gt;Server Setup&lt;/h2&gt;

&lt;p&gt;BackgroundJob upon receiving a new job will launch a worker if there isn't one running already, so after a cap deploy, emails will be sent.&lt;/p&gt;

&lt;h2&gt;Harder, Better, Faster, Stronger&lt;/h2&gt;

&lt;p&gt;&lt;b&gt;Harder&lt;/b&gt;: You need to setup bounce detection.  Sending an emails out without checking for bounces is a recipe for being blocked as your volume increases.  If an email bounces twice in a month disable updates and ask them to update their email the next time they visit.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Better&lt;/b&gt;: Add the ability for users to select HTML or text based emails.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Faster&lt;/b&gt;: You can speed up the process by making the email body and subject is the same for all fans, then you should use BCC to send a single email to all recipients at once.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Stronger&lt;/b&gt;: Generate a daily email to yourself that tells you how many emails were sent.  Have a cron entry generates this daily job.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=yDyFH6xn_zM:hlhs4WCkeLA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=yDyFH6xn_zM:hlhs4WCkeLA:COZEx2SDH_w"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=yDyFH6xn_zM:hlhs4WCkeLA:COZEx2SDH_w" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/overstimulate?a=yDyFH6xn_zM:hlhs4WCkeLA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/overstimulate?i=yDyFH6xn_zM:hlhs4WCkeLA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Sun, 22 Feb 2009 08:53:29 GMT</pubDate>
      <link>http://overstimulate.com/articles/rails-bj-email</link>
      <guid>http://overstimulate.com/articles/rails-bj-email</guid>
    </item>
  </channel>
</rss>
