<?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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>ELC Code Feed</title>
    <link>http://elctech.com/</link>
    <description>News, projects, and more.</description>
    <language>en-us</language>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/ElcCodeFeed" type="application/rss+xml" /><item>
      <title>Auto-solved simple_captcha while developing</title>
      <description>&lt;div class="preface"&gt;
&lt;p&gt;If you’re developing an app with the excellent &lt;a href="http://expressica.com/simple_captcha/" target="_blank"&gt;simple_captcha plugin&lt;/a&gt; do yourself a favor and monkey patch it in &lt;em&gt;config/environments/development.rb&lt;/em&gt;:&lt;/p&gt;
&lt;code language="ruby"&gt;&lt;pre class="sunburst"&gt;&lt;span class="Support"&gt;ActionView&lt;/span&gt;::&lt;span class="Entity"&gt;Base&lt;/span&gt;.&lt;span class="Entity"&gt;module_eval&lt;/span&gt; &lt;span class="Keyword"&gt;do&lt;/span&gt;
  &lt;span class="Keyword"&gt;def&lt;/span&gt; &lt;span class="Entity"&gt;simple_captcha_field&lt;/span&gt;(&lt;span class="Variable"&gt;options&lt;span class="Keyword"&gt;=&lt;/span&gt;&lt;span class="Variable"&gt;{&lt;/span&gt;&lt;span class="Variable"&gt;}&lt;/span&gt;&lt;/span&gt;)
    options[&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;object&lt;/span&gt;] &lt;span class="Keyword"&gt;?&lt;/span&gt;
      &lt;span class="Entity"&gt;text_field&lt;/span&gt;(options[&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;object&lt;/span&gt;], &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;captcha&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;value&lt;/span&gt; =&amp;gt; &lt;span class="Entity"&gt;simple_captcha_value&lt;/span&gt;(simple_captcha_key)) &lt;span class="Keyword"&gt;+&lt;/span&gt;
        &lt;span class="Entity"&gt;hidden_field&lt;/span&gt;(options[&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;object&lt;/span&gt;], &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;captcha_key&lt;/span&gt;, {&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;value&lt;/span&gt; =&amp;gt; options[&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;field_value&lt;/span&gt;]}) : 
      &lt;span class="Entity"&gt;text_field_tag&lt;/span&gt;(&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;captcha&lt;/span&gt;, &lt;span class="Entity"&gt;simple_captcha_value&lt;/span&gt;(simple_captcha_key))
  &lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElcCodeFeed/~4/504927623" height="1" width="1"/&gt;</description>
      <author>Dejan Simic</author>
      <pubDate>Wed, 07 Jan 2009 03:57:16 +0000</pubDate>
      <link>http://feeds.feedburner.com/~r/ElcCodeFeed/~3/504927623/auto-solved-simple_captcha-while-developing</link>
      <guid isPermaLink="false">http://elctech.com/snippets/auto-solved-simple_captcha-while-developing</guid>
    <feedburner:origLink>http://elctech.com/snippets/auto-solved-simple_captcha-while-developing</feedburner:origLink></item>
    <item>
      <title>Convert Filesize Bytes to Readable String in Javascript</title>
      <description>&lt;div class="preface"&gt;
&lt;code language="javascript"&gt;&lt;pre class="sunburst"&gt;&lt;span class="Storage"&gt;function&lt;/span&gt; &lt;span class="Entity"&gt;readablizeBytes&lt;/span&gt;(&lt;span class="Variable"&gt;bytes&lt;/span&gt;) {
    &lt;span class="Storage"&gt;var&lt;/span&gt; s &lt;span class="Keyword"&gt;=&lt;/span&gt; [&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;bytes&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;kb&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;MB&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;GB&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;TB&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;PB&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;];
    &lt;span class="Storage"&gt;var&lt;/span&gt; e &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Support"&gt;Math&lt;/span&gt;.&lt;span class="SupportFunction"&gt;floor&lt;/span&gt;(&lt;span class="Support"&gt;Math&lt;/span&gt;&lt;span class="SupportFunction"&gt;.log&lt;/span&gt;(bytes)/&lt;span class="Support"&gt;Math&lt;/span&gt;&lt;span class="SupportFunction"&gt;.log&lt;/span&gt;(&lt;span class="Constant"&gt;1024&lt;/span&gt;));
    &lt;span class="Keyword"&gt;return&lt;/span&gt; (bytes/&lt;span class="Support"&gt;Math&lt;/span&gt;.&lt;span class="SupportFunction"&gt;pow&lt;/span&gt;(&lt;span class="Constant"&gt;1024&lt;/span&gt;, &lt;span class="Support"&gt;Math&lt;/span&gt;.&lt;span class="SupportFunction"&gt;floor&lt;/span&gt;(e))).toFixed(&lt;span class="Constant"&gt;2&lt;/span&gt;)&lt;span class="Keyword"&gt;+&lt;/span&gt;&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt; &lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="Keyword"&gt;+&lt;/span&gt;s[e];
}
&lt;/pre&gt;&lt;/code&gt;
&lt;code language="javascript"&gt;&lt;pre class="sunburst"&gt;readablizeBytes(&lt;span class="Constant"&gt;5000&lt;/span&gt;); &lt;span class="Comment"&gt;&lt;span class="Comment"&gt;//&lt;/span&gt; 4.88 kb&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElcCodeFeed/~4/504620161" height="1" width="1"/&gt;</description>
      <author>Cary Dunn</author>
      <pubDate>Tue, 06 Jan 2009 20:34:44 +0000</pubDate>
      <link>http://feeds.feedburner.com/~r/ElcCodeFeed/~3/504620161/convert-filesize-bytes-to-readable-string-in-javascript</link>
      <guid isPermaLink="false">http://elctech.com/snippets/convert-filesize-bytes-to-readable-string-in-javascript</guid>
    <feedburner:origLink>http://elctech.com/snippets/convert-filesize-bytes-to-readable-string-in-javascript</feedburner:origLink></item>
    <item>
      <title>Converting Rails 'created_at' DateTime's to Flot Timestamps</title>
      <description>&lt;div class="preface"&gt;
&lt;p&gt;As far as graphing libraries go, &lt;a href="http://code.google.com/p/flot/" target="_blank"&gt;Flot&lt;/a&gt; is simple, powerful, and produces quality graphs.&lt;/p&gt;
&lt;p&gt;Graphing straight numerical data is very straightforward but there are times where you might want to graph numerical data over arbitrary periods of time.  Converting timestamps from ActiveRecord to the timestamps used in Flot is as simple as...&lt;/p&gt;
&lt;code language="ruby"&gt;&lt;pre class="sunburst"&gt;objekt.&lt;span class="Entity"&gt;created_at&lt;/span&gt;.&lt;span class="Entity"&gt;to_time&lt;/span&gt;.&lt;span class="Entity"&gt;to_i&lt;/span&gt;&lt;span class="Keyword"&gt;*&lt;/span&gt;&lt;span class="Constant"&gt;1000&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;You can now pair these UTC timestamps with your data-point and input your array of tuples directly into Flot for readable time based labels.&lt;/p&gt;
&lt;img src="http://elccore.s3.amazonaws.com/1/af1950835b7386a9b4ec26f8705c8938c697059a_1231272149_0.png" alt="Af1950835b7386a9b4ec26f8705c8938c697059a_1231272149_0" /&gt;
&lt;p&gt;Here is a simple example of a method I threw in a model to get a Flot compatible data string of some stat data for the object.&lt;/p&gt;
&lt;code language="ruby"&gt;&lt;pre class="sunburst"&gt;&lt;span class="Keyword"&gt;def&lt;/span&gt; &lt;span class="Entity"&gt;get_stats_since&lt;/span&gt;(&lt;span class="Variable"&gt;timeago&lt;span class="Keyword"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;1&lt;/span&gt;&lt;span class="Variable"&gt;&lt;span class="Variable"&gt;.&lt;/span&gt;&lt;span class="Entity"&gt;month&lt;/span&gt;&lt;/span&gt;&lt;span class="Variable"&gt;&lt;span class="Variable"&gt;.&lt;/span&gt;&lt;span class="Entity"&gt;ago&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;)
  ps &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="Support"&gt;Stat&lt;/span&gt;.&lt;span class="Entity"&gt;find&lt;/span&gt;(
    &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;all&lt;/span&gt;,
    &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;conditions&lt;/span&gt; =&amp;gt; [&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;post_id = ? AND created_at &amp;gt; ?&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="Variable"&gt;self&lt;/span&gt;.&lt;span class="Entity"&gt;id&lt;/span&gt;, timeago],
    &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;order&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;created_at asc&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  )
  stat_str &lt;span class="Keyword"&gt;=&lt;/span&gt; ps.&lt;span class="Entity"&gt;inject&lt;/span&gt;([]) &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;result&lt;/span&gt;, &lt;span class="Variable"&gt;p&lt;/span&gt;| result &lt;span class="Keyword"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;[&lt;span class="StringEmbeddedSource"&gt;&lt;span class="StringEmbeddedSource"&gt;#{&lt;/span&gt;p&lt;span class="StringEmbeddedSource"&gt;&lt;span class="StringEmbeddedSource"&gt;.&lt;/span&gt;&lt;span class="Entity"&gt;created_at&lt;/span&gt;&lt;/span&gt;&lt;span class="StringEmbeddedSource"&gt;&lt;span class="StringEmbeddedSource"&gt;.&lt;/span&gt;&lt;span class="Entity"&gt;to_time&lt;/span&gt;&lt;/span&gt;&lt;span class="StringEmbeddedSource"&gt;&lt;span class="StringEmbeddedSource"&gt;.&lt;/span&gt;&lt;span class="Entity"&gt;to_i&lt;/span&gt;&lt;/span&gt;&lt;span class="Keyword"&gt;*&lt;/span&gt;&lt;span class="StringConstant"&gt;1000&lt;/span&gt;&lt;span class="StringEmbeddedSource"&gt;}&lt;/span&gt;&lt;/span&gt;,&lt;span class="StringEmbeddedSource"&gt;&lt;span class="StringEmbeddedSource"&gt;#{&lt;/span&gt;&lt;span class="StringEmbeddedSource"&gt;(&lt;/span&gt;p&lt;span class="StringEmbeddedSource"&gt;&lt;span class="StringEmbeddedSource"&gt;.&lt;/span&gt;&lt;span class="Entity"&gt;hit_count&lt;/span&gt;&lt;/span&gt;&lt;span class="StringEmbeddedSource"&gt;&lt;span class="StringEmbeddedSource"&gt;.&lt;/span&gt;&lt;span class="Entity"&gt;blank?&lt;/span&gt;&lt;/span&gt; &lt;span class="Keyword"&gt;?&lt;/span&gt; &lt;span class="StringConstant"&gt;0&lt;/span&gt; &lt;span class="StringEmbeddedSource"&gt;:&lt;/span&gt; p&lt;span class="StringEmbeddedSource"&gt;&lt;span class="StringEmbeddedSource"&gt;.&lt;/span&gt;&lt;span class="Entity"&gt;hit_count&lt;/span&gt;&lt;/span&gt;&lt;span class="StringEmbeddedSource"&gt;)&lt;/span&gt;&lt;span class="StringEmbeddedSource"&gt;}&lt;/span&gt;&lt;/span&gt;]&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="Keyword"&gt;end&lt;/span&gt;
  &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;[&lt;span class="StringEmbeddedSource"&gt;&lt;span class="StringEmbeddedSource"&gt;#{&lt;/span&gt;stat_str&lt;span class="StringEmbeddedSource"&gt;&lt;span class="StringEmbeddedSource"&gt;.&lt;/span&gt;&lt;span class="Entity"&gt;join&lt;/span&gt;&lt;/span&gt;&lt;span class="StringEmbeddedSource"&gt;(&lt;/span&gt;&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;,&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class="StringEmbeddedSource"&gt;)&lt;/span&gt;&lt;span class="StringEmbeddedSource"&gt;}&lt;/span&gt;&lt;/span&gt;]&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class="Keyword"&gt;end&lt;/span&gt;
=&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;[[1231027849000,102204],[1231263741000,102374],[1231263746000,102454],[1231263753000,102194]]&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;

&lt;hr /&gt;&lt;blockquote&gt;Flot is a pure Javascript plotting library for jQuery. It produces graphical plots of arbitrary datasets on-the-fly client-side. &lt;/blockquote&gt;&lt;hr /&gt;
&lt;/div&gt;
&lt;img src="http://elccore.s3.amazonaws.com/1/32437b11ec7ddd2213a5a3c92bb1f1d49eb17779_1231271814_0.png" alt="32437b11ec7ddd2213a5a3c92bb1f1d49eb17779_1231271814_0" /&gt;&lt;img src="http://feeds.feedburner.com/~r/ElcCodeFeed/~4/504620162" height="1" width="1"/&gt;</description>
      <author>Cary Dunn</author>
      <pubDate>Tue, 06 Jan 2009 20:10:42 +0000</pubDate>
      <link>http://feeds.feedburner.com/~r/ElcCodeFeed/~3/504620162/converting-rails-created_at-datetime-s-to-flot-timestamps</link>
      <guid isPermaLink="false">http://elctech.com/snippets/converting-rails-created_at-datetime-s-to-flot-timestamps</guid>
    <feedburner:origLink>http://elctech.com/snippets/converting-rails-created_at-datetime-s-to-flot-timestamps</feedburner:origLink></item>
    <item>
      <title>Running MySQL on your Amazon EBS volume with RightScale</title>
      <description>&lt;div class="preface"&gt;
&lt;p&gt;&lt;a href="http://aws.amazon.com/ebs/" target="_blank"&gt;EBS&lt;/a&gt; (elastic block storage) is one of Amazon's newer innovations. It essentially offers the user a virtual hard drive of 1GB up to 1TB that can be mounted to any &lt;a href="http://aws.amazon.com/ec2/" target="_blank"&gt;EC2 instance&lt;/a&gt;. There are several benefits to such a service, including replication of data (handled by Amazon) as well as the ability to snapshot a volume at any point in time and shoot it up to &lt;a href="http://aws.amazon.com/s3/" target="_blank"&gt;S3&lt;/a&gt; (handled by the user). It is the latter benefit that interested me the most, and the reason it makes a lot of sense to store your db on this mounted volume.&lt;/p&gt;
&lt;/div&gt;

&lt;h2&gt;Getting Setup&lt;/h2&gt;

&lt;p&gt;
Here at ELC we are big supporters of &lt;a href="http://rightscale.com/" target="_blank"&gt;RightScale&lt;/a&gt;™ so this tutorial will be driven with that in mind. To start off I simply created a new EC2 instance equipped with Nginx and Mongrel, and setup a very simple Rails app with one table (blobs) just to show the db was working properly.
&lt;/p&gt;
&lt;img src="http://elccore.s3.amazonaws.com/3/f8b365b9fc07c2288e2b5fc9d0d1842e5a70f20e_1231264220_0.png" alt="F8b365b9fc07c2288e2b5fc9d0d1842e5a70f20e_1231264220_0" /&gt;
&lt;p&gt;Ok great, now we have our working Rails app and MySQL database running on EC2&lt;/p&gt;

&lt;h2&gt;Configuring the EBS Volume&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://rightscale.com/" target="_blank"&gt;RightScale&lt;/a&gt;™ makes it quite easy to create and attach an EBS volume to your instance. Simply click on the Volumes tab, 
&lt;img src="http://elccore.s3.amazonaws.com/3/e5d2f1af3cdba0b35e990e1c13b1a8e400874926_1231264220_1.png" alt="E5d2f1af3cdba0b35e990e1c13b1a8e400874926_1231264220_1" /&gt;
then Create and Attach Volume. 
&lt;img src="http://elccore.s3.amazonaws.com/3/2ec822c058af1bfe60ea388df06fc97acb0eb64c_1231264221_2.png" alt="2ec822c058af1bfe60ea388df06fc97acb0eb64c_1231264221_2" /&gt;
Choose a name and a size for it and click create, and in just a few minutes, we can see that the volume has been created at /dev/sdj:

&lt;/p&gt;&lt;code language="ruby"&gt;&lt;pre class="sunburst"&gt;[dlabare&lt;span class="Variable"&gt;&lt;span class="Variable"&gt;@&lt;/span&gt;domU&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;12&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;31&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;38&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;00&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;2D&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;82&lt;/span&gt;&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;/&lt;/span&gt;dev] ls &lt;span class="Keyword"&gt;-&lt;/span&gt;la
...
brw&lt;span class="Keyword"&gt;-&lt;/span&gt;r&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;  &lt;span class="Constant"&gt;1&lt;/span&gt; root    disk   &lt;span class="Constant"&gt;8&lt;/span&gt;,   &lt;span class="Constant"&gt;3&lt;/span&gt; &lt;span class="Variable"&gt;Jan&lt;/span&gt;  &lt;span class="Constant"&gt;5&lt;/span&gt; &lt;span class="Constant"&gt;12&lt;/span&gt;:&lt;span class="Constant"&gt;50&lt;/span&gt; sda3
brw&lt;span class="Keyword"&gt;-&lt;/span&gt;r&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;  &lt;span class="Constant"&gt;1&lt;/span&gt; root    disk   &lt;span class="Constant"&gt;8&lt;/span&gt;, &lt;span class="Constant"&gt;144&lt;/span&gt; &lt;span class="Variable"&gt;Jan&lt;/span&gt;  &lt;span class="Constant"&gt;5&lt;/span&gt; &lt;span class="Constant"&gt;15&lt;/span&gt;:&lt;span class="Constant"&gt;01&lt;/span&gt; sdj
drwxr&lt;span class="Keyword"&gt;-&lt;/span&gt;xr&lt;span class="Keyword"&gt;-&lt;/span&gt;x  &lt;span class="Constant"&gt;2&lt;/span&gt; root    root       &lt;span class="Constant"&gt;40&lt;/span&gt; &lt;span class="Variable"&gt;Jan&lt;/span&gt;  &lt;span class="Constant"&gt;5&lt;/span&gt; &lt;span class="Constant"&gt;12&lt;/span&gt;:&lt;span class="Constant"&gt;50&lt;/span&gt; shm
...
&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;

Now let's format it.
&lt;/p&gt;&lt;code language="java"&gt;&lt;pre class="sunburst"&gt;[dlabare@domU&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;12&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;31&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;38&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;00&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;2D&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;82&lt;/span&gt;:&lt;span class="Keyword"&gt;/&lt;/span&gt;dev] sudo &lt;span class="Keyword"&gt;/&lt;/span&gt;sbin&lt;span class="Keyword"&gt;/&lt;/span&gt;mkfs.ext3 &lt;span class="Keyword"&gt;/&lt;/span&gt;dev&lt;span class="Keyword"&gt;/&lt;/span&gt;sdj 
mke2fs &lt;span class="Constant"&gt;1.39&lt;/span&gt; (&lt;span class="Constant"&gt;29&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Storage"&gt;May&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;2006&lt;/span&gt;)
&lt;span class="Keyword"&gt;/&lt;/span&gt;dev&lt;span class="Keyword"&gt;/&lt;/span&gt;sdj is entire device, not just one partition&lt;span class="Keyword"&gt;!&lt;/span&gt;
&lt;span class="Storage"&gt;Proceed&lt;/span&gt; anyway? (y,n) y
&lt;span class="Storage"&gt;Filesystem&lt;/span&gt; label=
&lt;span class="Constant"&gt;OS&lt;/span&gt; type: &lt;span class="Storage"&gt;Linux&lt;/span&gt;
&lt;span class="Storage"&gt;Block&lt;/span&gt; size=&lt;span class="Constant"&gt;4096&lt;/span&gt; (log=&lt;span class="Constant"&gt;2&lt;/span&gt;)
&lt;span class="Storage"&gt;Fragment&lt;/span&gt; size=&lt;span class="Constant"&gt;4096&lt;/span&gt; (log=&lt;span class="Constant"&gt;2&lt;/span&gt;)
&lt;span class="Constant"&gt;6553600&lt;/span&gt; inodes, &lt;span class="Constant"&gt;13107200&lt;/span&gt; blocks
&lt;span class="Constant"&gt;655360&lt;/span&gt; blocks (&lt;span class="Constant"&gt;5.00&lt;/span&gt;&lt;span class="Keyword"&gt;%&lt;/span&gt;) reserved &lt;span class="Keyword"&gt;for&lt;/span&gt; the &lt;span class="Variable"&gt;super&lt;/span&gt; user
&lt;span class="Storage"&gt;First&lt;/span&gt; data block=&lt;span class="Constant"&gt;0&lt;/span&gt;
&lt;span class="Storage"&gt;Maximum&lt;/span&gt; filesystem blocks=&lt;span class="Constant"&gt;0&lt;/span&gt;
&lt;span class="Constant"&gt;400&lt;/span&gt; block groups
&lt;span class="Constant"&gt;32768&lt;/span&gt; blocks per group, &lt;span class="Constant"&gt;32768&lt;/span&gt; fragments per group
&lt;span class="Constant"&gt;16384&lt;/span&gt; inodes per group
&lt;span class="Storage"&gt;Superblock&lt;/span&gt; backups stored on blocks: 
	&lt;span class="Constant"&gt;32768&lt;/span&gt;, &lt;span class="Constant"&gt;98304&lt;/span&gt;, &lt;span class="Constant"&gt;163840&lt;/span&gt;, &lt;span class="Constant"&gt;229376&lt;/span&gt;, &lt;span class="Constant"&gt;294912&lt;/span&gt;, &lt;span class="Constant"&gt;819200&lt;/span&gt;, &lt;span class="Constant"&gt;884736&lt;/span&gt;, &lt;span class="Constant"&gt;1605632&lt;/span&gt;, &lt;span class="Constant"&gt;2654208&lt;/span&gt;, 
	&lt;span class="Constant"&gt;4096000&lt;/span&gt;, &lt;span class="Constant"&gt;7962624&lt;/span&gt;, &lt;span class="Constant"&gt;11239424&lt;/span&gt;

&lt;span class="Storage"&gt;Writing&lt;/span&gt; inode tables: done                            
&lt;span class="Storage"&gt;Creating&lt;/span&gt; &lt;span class="Entity"&gt;journal&lt;/span&gt; (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 34 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;

Great, now we've got our drive, let's mount it.
&lt;/p&gt;&lt;code language="java"&gt;&lt;pre class="sunburst"&gt;[dlabare@domU&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;12&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;31&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;38&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;00&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;2D&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;82&lt;/span&gt;:&lt;span class="Keyword"&gt;/&lt;/span&gt;dev] sudo mkdir &lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs
[dlabare@domU&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;12&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;31&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;38&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;00&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;2D&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;82&lt;/span&gt;:&lt;span class="Keyword"&gt;/&lt;/span&gt;dev] sudo mount &lt;span class="Keyword"&gt;/&lt;/span&gt;dev&lt;span class="Keyword"&gt;/&lt;/span&gt;sdj &lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs
[dlabare@domU&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;12&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;31&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;38&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;00&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;2D&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;82&lt;/span&gt;:&lt;span class="Keyword"&gt;/&lt;/span&gt;dev] df
&lt;span class="Storage"&gt;Filesystem&lt;/span&gt;           1K&lt;span class="Keyword"&gt;-&lt;/span&gt;blocks      &lt;span class="Storage"&gt;Used&lt;/span&gt; &lt;span class="Storage"&gt;Available&lt;/span&gt; &lt;span class="Storage"&gt;Use&lt;/span&gt;&lt;span class="Keyword"&gt;%&lt;/span&gt; &lt;span class="Storage"&gt;Mounted&lt;/span&gt; on
&lt;span class="Keyword"&gt;/&lt;/span&gt;dev&lt;span class="Keyword"&gt;/&lt;/span&gt;sda1             &lt;span class="Constant"&gt;10320888&lt;/span&gt;   &lt;span class="Constant"&gt;2080172&lt;/span&gt;   &lt;span class="Constant"&gt;7716380&lt;/span&gt;  &lt;span class="Constant"&gt;22&lt;/span&gt;&lt;span class="Keyword"&gt;%&lt;/span&gt; &lt;span class="Keyword"&gt;/&lt;/span&gt;
&lt;span class="Keyword"&gt;/&lt;/span&gt;dev&lt;span class="Keyword"&gt;/&lt;/span&gt;sda2            &lt;span class="Constant"&gt;153899044&lt;/span&gt;    &lt;span class="Constant"&gt;252388&lt;/span&gt; &lt;span class="Constant"&gt;145829032&lt;/span&gt;   &lt;span class="Constant"&gt;1&lt;/span&gt;&lt;span class="Keyword"&gt;%&lt;/span&gt; &lt;span class="Keyword"&gt;/&lt;/span&gt;mnt
&lt;span class="Keyword"&gt;/&lt;/span&gt;dev&lt;span class="Keyword"&gt;/&lt;/span&gt;sdj              &lt;span class="Constant"&gt;51606140&lt;/span&gt;    &lt;span class="Constant"&gt;184272&lt;/span&gt;  &lt;span class="Constant"&gt;48800428&lt;/span&gt;   &lt;span class="Constant"&gt;1&lt;/span&gt;&lt;span class="Keyword"&gt;%&lt;/span&gt; &lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs
&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;

Cool, now we've got our EBS volume located at /mnt/ebs (it's only 50 gigs for demo purposes, you'd probably choose a larger size for anything serious)

&lt;h2&gt;MySQL Config&lt;/h2&gt;

&lt;p&gt;First thing to do is stop mysql for now
&lt;/p&gt;&lt;code language="java"&gt;&lt;pre class="sunburst"&gt;[dlabare@domU&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;12&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;31&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;38&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;00&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;2D&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;82&lt;/span&gt;:&lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs] sudo &lt;span class="Keyword"&gt;/&lt;/span&gt;etc&lt;span class="Keyword"&gt;/&lt;/span&gt;init.d&lt;span class="Keyword"&gt;/&lt;/span&gt;mysqld stop
&lt;span class="Storage"&gt;Stopping&lt;/span&gt; &lt;span class="Storage"&gt;MySQL&lt;/span&gt;:                                            [  &lt;span class="Constant"&gt;OK&lt;/span&gt;  ]
&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;
&lt;/p&gt;

&lt;p&gt;Now let's move over the database files onto the EBS volume
&lt;/p&gt;&lt;code language="java"&gt;&lt;pre class="sunburst"&gt;sudo mkdir &lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs&lt;span class="Keyword"&gt;/&lt;/span&gt;lib &lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs&lt;span class="Keyword"&gt;/&lt;/span&gt;log
sudo mv &lt;span class="Keyword"&gt;/&lt;/span&gt;var&lt;span class="Keyword"&gt;/&lt;/span&gt;lib&lt;span class="Keyword"&gt;/&lt;/span&gt;mysql &lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs&lt;span class="Keyword"&gt;/&lt;/span&gt;lib&lt;span class="Keyword"&gt;/&lt;/span&gt;
sudo mv &lt;span class="Keyword"&gt;/&lt;/span&gt;var&lt;span class="Keyword"&gt;/&lt;/span&gt;log&lt;span class="Keyword"&gt;/&lt;/span&gt;mysql&lt;span class="Keyword"&gt;*&lt;/span&gt; &lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs&lt;span class="Keyword"&gt;/&lt;/span&gt;log&lt;span class="Keyword"&gt;/&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;

Then we need to tell MySQL about where to find these files. Edit your /etc/my.cnf file to point to the correct locations.

&lt;/p&gt;&lt;code language="java"&gt;&lt;pre class="sunburst"&gt;[client]
#password       = your_password
#port           = &lt;span class="Constant"&gt;3306&lt;/span&gt;
socket          = &lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs&lt;span class="Keyword"&gt;/&lt;/span&gt;lib&lt;span class="Keyword"&gt;/&lt;/span&gt;mysql&lt;span class="Keyword"&gt;/&lt;/span&gt;mysql.sock

[mysqld]
datadir=&lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs&lt;span class="Keyword"&gt;/&lt;/span&gt;lib&lt;span class="Keyword"&gt;/&lt;/span&gt;mysql
socket=&lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs&lt;span class="Keyword"&gt;/&lt;/span&gt;lib&lt;span class="Keyword"&gt;/&lt;/span&gt;mysql&lt;span class="Keyword"&gt;/&lt;/span&gt;mysql.sock
...

##&lt;span class="Storage"&gt;Inno&lt;/span&gt; &lt;span class="Constant"&gt;DB&lt;/span&gt;
innodb_data_home_dir = &lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs&lt;span class="Keyword"&gt;/&lt;/span&gt;lib&lt;span class="Keyword"&gt;/&lt;/span&gt;mysql&lt;span class="Keyword"&gt;/&lt;/span&gt;
innodb_log_group_home_dir = &lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs&lt;span class="Keyword"&gt;/&lt;/span&gt;lib&lt;span class="Keyword"&gt;/&lt;/span&gt;mysql
innodb_log_arch_dir = &lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs&lt;span class="Keyword"&gt;/&lt;/span&gt;lib&lt;span class="Keyword"&gt;/&lt;/span&gt;mysql
...

[mysql.server]
user=mysql
basedir=&lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs&lt;span class="Keyword"&gt;/&lt;/span&gt;lib

[mysqld_safe]
log&lt;span class="Keyword"&gt;-&lt;/span&gt;error=&lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs&lt;span class="Keyword"&gt;/&lt;/span&gt;log&lt;span class="Keyword"&gt;/&lt;/span&gt;mysqld.log
pid&lt;span class="Keyword"&gt;-&lt;/span&gt;file=&lt;span class="Keyword"&gt;/&lt;/span&gt;var&lt;span class="Keyword"&gt;/&lt;/span&gt;run&lt;span class="Keyword"&gt;/&lt;/span&gt;mysqld&lt;span class="Keyword"&gt;/&lt;/span&gt;mysqld.pid

...
&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;

Now go ahead and restart mysql:
&lt;/p&gt;&lt;code language="java"&gt;&lt;pre class="sunburst"&gt;[dlabare@domU&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;12&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;31&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;38&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;00&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;2D&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;82&lt;/span&gt;:&lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs] sudo &lt;span class="Keyword"&gt;/&lt;/span&gt;etc&lt;span class="Keyword"&gt;/&lt;/span&gt;init.d&lt;span class="Keyword"&gt;/&lt;/span&gt;mysqld start
&lt;span class="Storage"&gt;Starting&lt;/span&gt; mysqld daemon with databases from &lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs&lt;span class="Keyword"&gt;/&lt;/span&gt;lib&lt;span class="Keyword"&gt;/&lt;/span&gt;mysql
&lt;span class="Storage"&gt;Starting&lt;/span&gt; &lt;span class="Storage"&gt;MySQL&lt;/span&gt;:                                            [  &lt;span class="Constant"&gt;OK&lt;/span&gt;  ]
&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;

Great, it worked*. Now save this config file to your EBS volume so it doesn't get lost if your instance crashes.

&lt;div style="font-size:8px;font-weight:italic;text-align:right"&gt;
*crap, it didn't work? Check your mysql logs for more info (/mnt/ebs/logs/mysqld.log)
&lt;/div&gt;

&lt;/p&gt;&lt;code language="java"&gt;&lt;pre class="sunburst"&gt;sudo cp &lt;span class="Keyword"&gt;/&lt;/span&gt;etc&lt;span class="Keyword"&gt;/&lt;/span&gt;my.cnf &lt;span class="Keyword"&gt;/&lt;/span&gt;mnt&lt;span class="Keyword"&gt;/&lt;/span&gt;ebs&lt;span class="Keyword"&gt;/&lt;/span&gt;my.cnf&lt;span class="Keyword"&gt;-&lt;/span&gt;bak
&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;
&lt;/p&gt;

&lt;h2&gt;Volume Snapshots&lt;/h2&gt;
&lt;p&gt;You can manually take snapshots of your volume through the &lt;a href="http://rightscale.com/" target="_blank"&gt;RightScale&lt;/a&gt;™ interface when needed, as well as have a cron job run back ups periodically. Eric Hammond has written a nice little backup script that that uses &lt;a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=351&amp;categoryID=88" target="_blank"&gt;EC2 API tools&lt;/a&gt;, the script can be found &lt;a href="http://ec2-snapshot-xfs-mysql.notlong.com" target="_blank"&gt;here&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
You can also read his detailed &lt;a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1663" target="_blank"&gt;post&lt;/a&gt; on how to do this whole setup using the command line tools, which was a great help for me when getting setup.
&lt;/p&gt;

&lt;h2&gt;Why this is a good thing&lt;/h2&gt;
&lt;p&gt;
There are many good reasons to try this method of deployment:
&lt;ul&gt;
&lt;li&gt;Easily bump up (or down) your instance size without having to copy your database each time. Simply mount the volume to your new instance, copy over your mysql config, and you're good to go.&lt;/li&gt;
&lt;li&gt;Rest assured knowing your snapshot data is backed up in multiple geographic locations&lt;/li&gt;
&lt;li&gt;Know that your database storage is unaffected by your instance failing&lt;/li&gt;
&lt;li&gt;Grow your volume size easily when space gets low&lt;/li&gt;
&lt;/ul&gt;&lt;/p&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ElcCodeFeed/~4/504548702" height="1" width="1"/&gt;</description>
      <author>Danny LaBare</author>
      <pubDate>Mon, 05 Jan 2009 18:27:08 +0000</pubDate>
      <link>http://feeds.feedburner.com/~r/ElcCodeFeed/~3/504548702/running-mysql-on-your-amazon-ebs-volume-with-rightscale</link>
      <guid isPermaLink="false">http://elctech.com/articles/running-mysql-on-your-amazon-ebs-volume-with-rightscale</guid>
    <feedburner:origLink>http://elctech.com/articles/running-mysql-on-your-amazon-ebs-volume-with-rightscale</feedburner:origLink></item>
    <item>
      <title>Xapian Vs Sphinx in Rails</title>
      <description>&lt;div class="preface"&gt;
&lt;p&gt;&lt;a href="http://xapian.org"&gt;Xapian&lt;/a&gt; and &lt;a href="http://www.sphinxsearch.com/"&gt;Sphinx&lt;/a&gt; are both great open source full text searching solutions, but I'm wonder whose performance is better, Xapian has an official comparison to solr, but no sphinx, so I do it myself.&lt;/p&gt;

&lt;h2&gt;Dataset&lt;/h2&gt;
&lt;p&gt;My dataset is about 12,000 blog records like below:&lt;/p&gt;

&lt;code language="ruby"&gt;&lt;pre class="sunburst"&gt;&lt;span class="Keyword"&gt;class&lt;/span&gt; &lt;span class="JEntityNameType"&gt;Blog&lt;span class="EntityInheritedClass"&gt; &lt;span class="EntityInheritedClass"&gt;&amp;lt;&lt;/span&gt; ActiveRecord::Base&lt;/span&gt;&lt;/span&gt;
&lt;span class="Comment"&gt;  &lt;span class="Comment"&gt;#&lt;/span&gt; Thinking sphinx indexes&lt;/span&gt;
  define_index &lt;span class="Keyword"&gt;do&lt;/span&gt;
    indexes &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;title&lt;/span&gt;
    indexes &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;description&lt;/span&gt;
  &lt;span class="Keyword"&gt;end&lt;/span&gt;
  
&lt;span class="Comment"&gt;  &lt;span class="Comment"&gt;#&lt;/span&gt; Acts_as_xapian indexes&lt;/span&gt;
  acts_as_xapian &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;texts&lt;/span&gt; =&amp;gt; [ &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;title&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;description&lt;/span&gt; ]

  ...
&lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;
&lt;/div&gt;

&lt;h2&gt;Environment&lt;/h2&gt;
&lt;p&gt;And here's the environment I used to do the testing:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Sphinx: 0.9.8&lt;/li&gt;
  &lt;li&gt;Xapian: 1.0.1&lt;/li&gt;
  &lt;li&gt;Sphinx plugin: &lt;a href="http://ts.freelancing-gods.com/"&gt;thinking_sphinx&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Xapian plugin: &lt;a href="http://github.com/frabcus/acts_as_xapian/tree/master"&gt;acts_as_xapian&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Ruby: 1.8.6 p114&lt;/li&gt;
  &lt;li&gt;Rails: 2.1.0&lt;/li&gt;
  &lt;li&gt;Mysql: 5.0.51&lt;/li&gt;
  &lt;li&gt;OS: OS X 10.5.6&lt;/li&gt;
  &lt;li&gt;CPU: Intel Core 2 Duo 2.0G&lt;/li&gt;
  &lt;li&gt;Ram: 4G&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Indexing&lt;/h2&gt;
&lt;p&gt;Let's start from indexing at first:&lt;/p&gt;
&lt;code language="ruby"&gt;&lt;pre class="sunburst"&gt;$ time rake xapian&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;rebuild_index&lt;/span&gt; models&lt;span class="Keyword"&gt;=&lt;/span&gt;&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Blog&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
real    2m12.942s
user    0m24.569s
sys    0m12.798s
$ time rake thinking_sphinx&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;index&lt;/span&gt;
real    1m53.543s
user    0m4.725s
sys    0m0.887s
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Sphinx is win in this section, and because sphinx has a progress report, I feel it's shorted than it occupied indeed.&lt;/p&gt;

&lt;h2&gt;Querying&lt;/h2&gt;
&lt;p&gt;Then is querying, below is my testing code:&lt;/p&gt;
&lt;code language="ruby"&gt;&lt;pre class="sunburst"&gt;keywords &lt;span class="Keyword"&gt;=&lt;/span&gt; [&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;key1&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;key2&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;, ..., &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;key30&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;] 

&lt;span class="Support"&gt;Benchmark&lt;/span&gt;.&lt;span class="Entity"&gt;bm&lt;/span&gt; &lt;span class="Keyword"&gt;do &lt;/span&gt;|&lt;span class="Variable"&gt;x&lt;/span&gt;|
  x.&lt;span class="Entity"&gt;report&lt;/span&gt;(&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Xapian&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) { &lt;span class="Constant"&gt;30&lt;/span&gt;.&lt;span class="Entity"&gt;times&lt;/span&gt; {|&lt;span class="Variable"&gt;i&lt;/span&gt;| &lt;span class="Support"&gt;ActsAsXapian&lt;/span&gt;::&lt;span class="Entity"&gt;Search&lt;/span&gt;.&lt;span class="Entity"&gt;new&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Blog&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, keywords[i], &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;limit&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;10&lt;/span&gt; } }
  x.&lt;span class="Entity"&gt;report&lt;/span&gt;(&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;Sphinx&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) { &lt;span class="Constant"&gt;30&lt;/span&gt;.&lt;span class="Entity"&gt;times&lt;/span&gt; {|&lt;span class="Variable"&gt;i&lt;/span&gt;| &lt;span class="Support"&gt;Blog&lt;/span&gt;.&lt;span class="Entity"&gt;search&lt;/span&gt; keywords[i], &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;per_page&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;10&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;page&lt;/span&gt; =&amp;gt; &lt;span class="Constant"&gt;1&lt;/span&gt; }}
&lt;span class="Keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;And here's the results, the winner goes ....... &lt;/p&gt;
&lt;code language="ruby"&gt;&lt;pre class="sunburst"&gt;      user     system      total        real
&lt;span class="Variable"&gt;Xapian&lt;/span&gt;  &lt;span class="Constant"&gt;0.020000&lt;/span&gt;   &lt;span class="Constant"&gt;0.020000&lt;/span&gt;   &lt;span class="Constant"&gt;0.040000&lt;/span&gt; (  &lt;span class="Constant"&gt;0.042381&lt;/span&gt;)
&lt;span class="Variable"&gt;Sphinx&lt;/span&gt;  &lt;span class="Constant"&gt;0.150000&lt;/span&gt;   &lt;span class="Constant"&gt;0.030000&lt;/span&gt;   &lt;span class="Constant"&gt;0.180000&lt;/span&gt; (  &lt;span class="Constant"&gt;0.285173&lt;/span&gt;)
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Yes, Xapian wins, but I'm afraid most of people will still choose sphinx, because acts_as_xapian is really hard to use than thinking sphinx.&lt;/p&gt;
&lt;p&gt;At last, my testing is only based on a very small dataset, so it may be not correct in other situations.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ElcCodeFeed/~4/504465801" height="1" width="1"/&gt;</description>
      <author>Yuanyi Zhang</author>
      <pubDate>Tue, 06 Jan 2009 07:11:26 +0000</pubDate>
      <link>http://feeds.feedburner.com/~r/ElcCodeFeed/~3/504465801/xapian-vs-sphinx-in-rails</link>
      <guid isPermaLink="false">http://elctech.com/articles/xapian-vs-sphinx-in-rails</guid>
    <feedburner:origLink>http://elctech.com/articles/xapian-vs-sphinx-in-rails</feedburner:origLink></item>
    <item>
      <title>Benchmarking with AutoBench</title>
      <description>&lt;div class="preface"&gt;
&lt;p&gt;You've got a rails app, an environment to deploy to, but how do you figure out if that environment can sustain the demand that your users create?&lt;/p&gt;
&lt;/div&gt;

&lt;h2&gt;Enter httperf, autobench and gnuplot&lt;/h2&gt;

&lt;p&gt;To performance/load test rails applications, I've become a big fan of httperf. It has a multitude of configuration options and other various bells and whistles that really make it a jack-of-all-trades when it comes to application performance testing and load testing(both hardware and software)&lt;/p&gt;

&lt;p&gt;The httperf package can be one of those intimidating command line tools, with more switches and arguments than one person can easily remember without using the software daily. AutoBench is a great wrapper for this that does some amazing extras. Let's dive in and see what we can do, starting with the config file:&lt;/p&gt;

&lt;pre&gt;# Autobench Configuration File

# host1, host2 
# The hostnames of the servers under test
# Eg. host1 = iis.test.com 
#     host2 = apache.test.com

host1 = test1.example.com 
host2 = test2.example.com

# uri1, uri2
# The URI to test (relative to the document root).  For a fair comparison
# the files should be identical (although the paths to them may differ on the 
# different hosts)

uri1  = /foo/bar/1
uri2  = /foo/bar/1.xml

# port1, port2
# The port number on which the servers are listening

port1 = 80
port2 = 80
# low_rate, high_rate, rate_step
# The 'rate' is the number of number of connections to open per second.
# A series of tests will be conducted, starting at low rate,
# increasing by rate step, and finishing at high_rate.
# The default settings test at rates of 20,30,40,50...180,190,200

low_rate  = 10
high_rate = 200
rate_step = 10

# num_conn, num_call
# num_conn is the total number of connections to make during a test
# num_call is the number of requests per connection
# The product of num_call and rate is the the approximate number of
# requests per second that will be attempted.

num_conn  = 500
num_call  = 10

# timeout sets the maximimum time (in seconds) that httperf will wait
# for replies from the web server.  If the timeout is exceeded, the
# reply concerned is counted as an error.

timeout   = 5

# output_fmt
# SET TO tsv to use with included bench2graph 
# sets the output type - may be either "csv", or "tsv";

output_fmt = tsv

## Config for distributed autobench (autobench_admin)
# clients  
# comma separated list of the hostnames and portnumbers for the
# autobench clients.  No whitespace can appear before or after the commas.
# clients = bench1.foo.com:4600,bench2.foo.com:4600,bench3.foo.com:4600

clients = localhost:4600&lt;/pre&gt;&lt;br /&gt;

&lt;p&gt;The above mentioned config file is created upon the first invocation of the autobench utility, which by default places it in ~/.autobench.conf. Once you have modified that file it's as easy as running:
&lt;pre&gt; autobench --file output.tsv &lt;/pre&gt;&lt;br /&gt;
My preference is to run a test suite stepping up from 500 connections making 1 request per second in 1 request intervals. This provides me what could be considered overkill on data samples but gives a very fine resolution of exactly where app/server starts to fall apart(requests fail, 500s thrown, etc.). This makes it very easy to find that performance sweet spot within the application, and gives a perfect baseline with which to test different server stacks against (mongrel vs. thin vs. passenger seems to be the debate of the day. Also, if you are able to access your data objects in multiple formats, be sure to test each of them, you'd surprised at what kind of overhead templating engines actually have.&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;h3&gt;&lt;strong&gt;Q:&lt;/strong&gt;Now what do I do with all these *ghasp* Tab-Delimited-Files?&lt;/h3&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;p&gt;&lt;strong&gt;A:&amp;nbsp;Generate Graphs!&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;
  The sparkling gem within autotest is the included bonus utility...... bench2graph!
  &lt;pre&gt;  Usage          : bench2graph PARAM_1 PARAM_2 [ PARAM_3 ... PARAM_N ]
  Parameter 1    : autobench results file
  Parameter 2    : name of the postscript output file
  Parameter 3..N : [optional] columns to display in the graphic
  &lt;/pre&gt;
   This utility takes your data from the autotest suite(only if you save tsv and not csv) runs it through gnuplot and outputs a pretty little graph as a postscript file that looks like the one below:
  &lt;img src="http://elccore.s3.amazonaws.com/12/87dab8b53ae130343cb9c936ec5e70cc538efb45_1231234249_0.jpg" height="321px" alt="87dab8b53ae130343cb9c936ec5e70cc538efb45_1231234249_0" width="463px" /&gt;&lt;br /&gt;
  Have fun with finding just how much can be thrown at your app :)
  &lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ElcCodeFeed/~4/504170778" height="1" width="1"/&gt;</description>
      <author>Max Murphy</author>
      <pubDate>Mon, 05 Jan 2009 23:50:19 +0000</pubDate>
      <link>http://feeds.feedburner.com/~r/ElcCodeFeed/~3/504170778/benchmarking-with-autobench</link>
      <guid isPermaLink="false">http://elctech.com/articles/benchmarking-with-autobench</guid>
    <feedburner:origLink>http://elctech.com/articles/benchmarking-with-autobench</feedburner:origLink></item>
    <item>
      <title>Weekly Bookmark Recap (01/04)</title>
      <description>&lt;div class="preface"&gt;
&lt;p&gt;Thank you to everyone out there who maintains a personal or team blog to share their knowledge and findings!  Here are a few of our teams favorite bookmarks from last week.&lt;/p&gt;
&lt;ul&gt;
  
  &lt;li&gt;&lt;a href="/feeds/1187"&gt;ImageMagick + MySQL on Fedora - Red91.com&lt;/a&gt;&lt;/li&gt;
  
  &lt;li&gt;&lt;a href="/feeds/922"&gt;dehash »  AS3 Papervision3D GreatWhite Flashdevelop example code  « Layers Demo&lt;/a&gt;&lt;/li&gt;
  
  &lt;li&gt;&lt;a href="/feeds/203"&gt;Ruby On Rails Security Guide&lt;/a&gt;&lt;/li&gt;
  
  &lt;li&gt;&lt;a href="/feeds/1188"&gt;Bamboo Blog - Upload progress with Nginx&lt;/a&gt;&lt;/li&gt;
  
  &lt;li&gt;&lt;a href="/feeds/1190"&gt;java:j2me-on-mac-osx [EscayDocuments]&lt;/a&gt;&lt;/li&gt;
  
  &lt;li&gt;&lt;a href="/feeds/154"&gt;23 Most Incredible Photoshop Tutorials :: Elite By Design&lt;/a&gt;&lt;/li&gt;
  
  &lt;li&gt;&lt;a href="/feeds/153"&gt;Into the Cloud: Our 5 Favorite Online Storage Services - ReadWriteWeb&lt;/a&gt;&lt;/li&gt;
  
  &lt;li&gt;&lt;a href="/feeds/502"&gt;Lightweight Webservices with Sinatra and RestClient - SlideShare&lt;/a&gt;&lt;/li&gt;
  
  &lt;li&gt;&lt;a href="/feeds/1189"&gt;Increase heap size in Java to prevent java.lang.OutOfMemoryError&lt;/a&gt;&lt;/li&gt;
  
  &lt;li&gt;&lt;a href="/feeds/969"&gt;$ cheat git&lt;/a&gt;&lt;/li&gt;
  
  &lt;li&gt;&lt;a href="/feeds/155"&gt;20 Websites to Help You Master User Interface Design - Six Revisions&lt;/a&gt;&lt;/li&gt;
  
  &lt;li&gt;&lt;a href="/feeds/474"&gt;Stumped by multiple ssh key pair on github or unfuddle? - Rex Chung - Web Strategy, Startups and Ruby on Rails&lt;/a&gt;&lt;/li&gt;
  
  &lt;li&gt;&lt;a href="/feeds/368"&gt;kaourantin.net: Pixel Bender .pbj files&lt;/a&gt;&lt;/li&gt;
  
  &lt;li&gt;&lt;a href="/feeds/512"&gt;SuperCal™ by bergdesign&lt;/a&gt;&lt;/li&gt;
  
  &lt;li&gt;&lt;a href="/feeds/492"&gt;RESTful Service - Ajax Patterns&lt;/a&gt;&lt;/li&gt;
  
&lt;/ul&gt;
&lt;br /&gt;
&lt;p&gt;You can search our favorite links, bookmarks, as well as our own ELC Core content by using our new &lt;a href="/explore" target="_blank"&gt;Explore&lt;/a&gt; feature. Check it out!&lt;/p&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElcCodeFeed/~4/502289549" height="1" width="1"/&gt;</description>
      <author>ELC Team</author>
      <pubDate>Sun, 04 Jan 2009 05:00:38 +0000</pubDate>
      <link>http://feeds.feedburner.com/~r/ElcCodeFeed/~3/502289549/weekly-bookmark-recap-01-04</link>
      <guid isPermaLink="false">http://elctech.com/articles/weekly-bookmark-recap-01-04</guid>
    <feedburner:origLink>http://elctech.com/articles/weekly-bookmark-recap-01-04</feedburner:origLink></item>
    <item>
      <title>Tips and Tricks From a Self Proclaimed Cybernomad</title>
      <description>&lt;div class="preface"&gt;
&lt;p&gt;Last time I wrote about why I think &lt;a href="http://www.elctech.com/projects/-1-team-jetpack"&gt;distributed development is a viable way to work&lt;/a&gt;. Now I'm going to write about why it's an amazing way to work. Leading static lives can lead to static thinking. Dynamic lives lead to dynamic thinking. Remote development can free you from the dregs of traffic and 'the office', but can enslave you to your home (office). If you have worked from home before, you will know exactly what I am talking about. Some days you won't even leave your house. Office work will blend with house work and the next thing you know you're whole day feels like work. Ok, so you have the good fortune of being on a high functioning distributed team (like team jetpack) and you want to take it to the next level, here is some advice for how to travel, live and work without skipping a beat or missing a meeting.
&lt;/p&gt;
&lt;/div&gt;

&lt;h2&gt;The Setup&lt;/h2&gt;

&lt;p&gt;Obviously not everybody can just take off for long periods of time. It helps to be in a low/no rent situation at home base and not have any dependents (kids, pets or bf(s)/gf(s)). Subletting your room or apartment will help cover the bills while you are away. Direct deposit and internet bill pay are a must.&lt;/p&gt;

&lt;h2&gt;The Gear&lt;/h2&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;First rule: Pack light (major bonus points if you can fly carry on)&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;h3&gt;Backpacking Pack&lt;/h3&gt;&lt;p&gt;
I think the backpack is a step up from the roller bags.
&lt;br /&gt;(supressed_rant) They are expandable, because you WILL collect more stuff as you travel around. The thing I really like about them, other than not having to roll them around, is that they are long and (can be) skinny. Which is prefect for fitting into the over-head bins and the compression straps make them easy to change their shape.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;h3&gt;Pelican Case&lt;/h3&gt;
&lt;img src="http://elccore.s3.amazonaws.com/15/3f0b107bc72478d6fb55c584c9d111e084234c44_1229558972_0.jpg" alt="3f0b107bc72478d6fb55c584c9d111e084234c44_1229558972_0" /&gt;
&lt;p&gt;The &lt;a href="http://www.pelican.com/cases_detail.php?Case=1470" target="_blank"&gt;pelican case&lt;/a&gt; is a must for me. It's bigger, heavier and more expensive than a normal computer case, but still worth it. You must protect your computer. The Pelican case will keep your life line safe and sound. It locks, has this rad break-away foam so you can customize the interior shape. The bottom is a great place to store important documents like passport or extra cash. Toting around my Pelican adds mystique to my travel persona. Put stickers on it to gain some travel-cred.&lt;/p&gt;

&lt;img src="http://elccore.s3.amazonaws.com/15/ed190570579240fce1270a42fb4f744a1a3e3dd4_1229645938_0.jpg" alt="Ed190570579240fce1270a42fb4f744a1a3e3dd4_1229645938_0" /&gt;

&lt;h3&gt;Sound/Noise Isolating headphones&lt;/h3&gt;&lt;p&gt;
They are good for two reasons: you can tune out the world and the person next to you doesn't have to listen to the newest Diplo mix tape (which is absolutely awesome btw).&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;h3&gt;Microfiber towel&lt;/h3&gt;
&lt;p&gt;BOYTowel. Its small, super absorbent, quick drying and anti-microbial. I have this one made by &lt;a href="http://waboba.com/InfoBuy.aspx?ID=20&amp;Page=1&amp;Cat=3" target="_blank"&gt;Waboba&lt;/a&gt; (the waboba ball is also a big hit).&lt;/p&gt;

&lt;h3&gt;Chargers&lt;/h3&gt;&lt;p&gt;
My cell phone charger also works for my camera, so that cuts down on the clutter. But don't neglect the power adapters if you are leaving the country.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;h3&gt;Geek Phone&lt;/h3&gt;&lt;p&gt;
Get a good geek phone. AT&amp;T offers a Blackberry unlimitedinternational data plan for $80/month. I know, I know, what about the Iphone. Try and get unlimited international data for the Iphone. Then get a good jabber client and Google Maps. I can't stress how valuable Google Maps and its positioning feature are. Even the transit directions are super useful in the bigger cities, where it's supported.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;h2&gt;The Travel&lt;/h2&gt;&lt;p&gt;
Second Rule: Don't let traveling interfere with your team involvement. &lt;/p&gt;

&lt;p&gt;Okay, so now you are all geared up and ready to see the world. But don't forget you still have to work. In my first post on distributed teams, one of the team agreements was temporal. So you have to plan your travel times around your team. This goes beyond when you fly or ride the train. It also influences where you go, because working with a 12 hour time difference will start to affect your ability to work and communicate. I would not recommend more than +/- 8 time zones away from your teams agreed upon time zone.&lt;/p&gt;

&lt;p&gt;Take the train; it's a great way to see the country side and get some quality hacking done. Save some money, byob.&lt;/p&gt;

&lt;p&gt;Buy one-way tickets, because you never know when you might want to stay longer or leave earlier. Also one-way plane tickets can be really cheap, if you troll the right internet sites.&lt;/p&gt;

&lt;p&gt;Keep offline documentation and e-books. You'll  find yourself without internet and want to look something up.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;h3&gt;Where to Work&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;It's obviously ideal to have internet where you are staying. But that's not always the case and what fun is it if you just stay holed up somewhere? Besides the obvious coffee shops and internet cafes, I also enjoy working from libraries, universities, and outside of random apartment buildings. Keep in mind noise levels, your own and others, when choosing a place for the day.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;h3&gt;Where to Stay&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;I can't afford to stay in hotels every night; that's just not feasible. So be creative and opportunistic with where you travel and stay. Go and visit all the friends you haven't seen in a while. Make sure to be an awesome guest: tell rad stories, bring wine, do dishes, clean up. One of the best ways to fit in is to not require constant entertainment, get out and do things on your own.&lt;/p&gt;

&lt;p&gt;Hostels are great, cheap ways to stay places where you don't know anybody. They usually have free internet and you are guaranteed to meet other cool travelers.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;p&gt;There are also international traveling communities online like &lt;a href="http://couchsurfing.com" target="_blank"&gt;Couch Surfing&lt;/a&gt; which is full of generous travelers offering and looking for places to stay for free. The high level of member verification makes it a safe and reliable way to travel, if you are willing to participate by sharing your home also. &lt;/p&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Subletting is a great way to make a long term stay comfortable and cost effective. Craigslist has a lot of good opportunities to rent furnished apartments or rooms in houses, though not heavily used in Europe. Usually private and internet ready, they provide a stable and independent environment.&lt;/p&gt;

&lt;p&gt;It doesn't matter if you are a globe trekker or just a local explorer, the point is to approach life like your software development. Become cybernomadic, be agile, have fun, live and learn. You'll be a better person and better developer for it.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/ElcCodeFeed/~4/501497236" height="1" width="1"/&gt;</description>
      <author>Nicholaus</author>
      <pubDate>Sat, 03 Jan 2009 03:25:29 +0000</pubDate>
      <link>http://feeds.feedburner.com/~r/ElcCodeFeed/~3/501497236/tips-and-tricks-from-a-self-proclaimed-cybernomad</link>
      <guid isPermaLink="false">http://elctech.com/articles/tips-and-tricks-from-a-self-proclaimed-cybernomad</guid>
    <feedburner:origLink>http://elctech.com/articles/tips-and-tricks-from-a-self-proclaimed-cybernomad</feedburner:origLink></item>
    <item>
      <title>[Solved] rake gems:refresh_specs to fix this</title>
      <description>&lt;div class="preface"&gt;
&lt;code language="ruby"&gt;&lt;pre class="sunburst"&gt;$ rake gems&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;refresh_specs&lt;/span&gt;
(&lt;span class="Keyword"&gt;in&lt;/span&gt; .&lt;span class="Keyword"&gt;/&lt;/span&gt;project)
config.&lt;span class="Entity"&gt;gem&lt;/span&gt;: &lt;span class="Variable"&gt;Unpacked&lt;/span&gt; gem encrypted_strings&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;0.3&lt;/span&gt;.&lt;span class="Constant"&gt;1&lt;/span&gt; &lt;span class="Keyword"&gt;in&lt;/span&gt; vendor&lt;span class="Keyword"&gt;/&lt;/span&gt;gems has no specification file. &lt;span class="Variable"&gt;Run&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;rake gems:refresh_specs&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt; to fix this.
rake aborted!
uninitialized constant &lt;span class="Support"&gt;Rails&lt;/span&gt;::&lt;span class="Entity"&gt;Initializer&lt;/span&gt;::&lt;span class="Entity"&gt;EncryptedStrings&lt;/span&gt;

(&lt;span class="Variable"&gt;See&lt;/span&gt; full trace by running task with &lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Keyword"&gt;-&lt;/span&gt;trace)
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;My vote for most circuitously unhelpful error recovery hint. Here's how to fix:&lt;/p&gt;
&lt;/div&gt;

&lt;h2&gt;Hand-unpacked gem&lt;/h2&gt;
&lt;p&gt;The gem at issue here was copied by me like:&lt;/p&gt;
&lt;code language="ruby"&gt;&lt;pre class="sunburst"&gt;cp &lt;span class="Keyword"&gt;-&lt;/span&gt;r &lt;span class="Keyword"&gt;/&lt;/span&gt;&lt;span class="Variable"&gt;Library&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;&lt;span class="Variable"&gt;Ruby&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;&lt;span class="Variable"&gt;Gems&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;&lt;span class="Constant"&gt;1.8&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;gems&lt;span class="Keyword"&gt;/&lt;/span&gt;encrypted_strings&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;0.3&lt;/span&gt;.&lt;span class="Constant"&gt;1&lt;/span&gt; &lt;span class="Variable"&gt;Projects&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;project&lt;span class="Keyword"&gt;/&lt;/span&gt;vendor&lt;span class="Keyword"&gt;/&lt;/span&gt;gems&lt;span class="Keyword"&gt;/&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;Usually this "just works" but for encrypted strings I needed the .specification file that is in the gem source. This .specification file was not installed in my /Library... copy. The solution was to add the gem to my config/environment.rb gem list (as I should have for clear dependency recording) and then let rake do the work.&lt;/p&gt;
&lt;code language="ruby"&gt;&lt;pre class="sunburst"&gt;&lt;span class="Comment"&gt;  &lt;span class="Comment"&gt;#&lt;/span&gt; In config/environment.rb:&lt;/span&gt;
  config.&lt;span class="Entity"&gt;gem&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;encrypted_strings&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;source&lt;/span&gt; =&amp;gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;git://github.com/pluginaweek/encrypted_strings.git&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;And the unpack itself:&lt;/p&gt;
&lt;code language="ruby"&gt;&lt;pre class="sunburst"&gt;$ rake gems&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;unpack&lt;/span&gt;
(&lt;span class="Keyword"&gt;in&lt;/span&gt; .&lt;span class="Keyword"&gt;/&lt;/span&gt;project)
&lt;span class="Variable"&gt;WARNING&lt;/span&gt;:  &lt;span class="Variable"&gt;Installing&lt;/span&gt; to &lt;span class="Keyword"&gt;~&lt;/span&gt;&lt;span class="StringRegexp"&gt;&lt;span class="StringRegexp"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class="StringRegexp"&gt;.gem since &lt;/span&gt;&lt;span class="StringRegexp"&gt;&lt;span class="StringRegexp"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class="Variable"&gt;Library&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;&lt;span class="Variable"&gt;Ruby&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;&lt;span class="Variable"&gt;Gems&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;&lt;span class="Constant"&gt;1.8&lt;/span&gt; &lt;span class="Keyword"&gt;and&lt;/span&gt;
	  &lt;span class="StringRegexp"&gt;&lt;span class="StringRegexp"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class="StringRegexp"&gt;usr&lt;/span&gt;&lt;span class="StringRegexp"&gt;&lt;span class="StringRegexp"&gt;/&lt;/span&gt;&lt;/span&gt;bin aren&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;t both writable.&lt;/span&gt;
&lt;span class="String"&gt;Unpacked gem: &lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;span class="Variable"&gt;Projects&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;project&lt;span class="Keyword"&gt;/&lt;/span&gt;vendor&lt;span class="Keyword"&gt;/&lt;/span&gt;gems&lt;span class="Keyword"&gt;/&lt;/span&gt;encrypted_strings&lt;span class="Keyword"&gt;-&lt;/span&gt;&lt;span class="Constant"&gt;0.3&lt;/span&gt;.&lt;span class="Constant"&gt;1&lt;/span&gt;&lt;span class="String"&gt;&lt;span class="String"&gt;'&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;Now rake runs fine and the only file-level difference is the appearance of the .specifications file in vendor/gems:&lt;/p&gt;
&lt;code language="ruby"&gt;&lt;pre class="sunburst"&gt;$ git status
&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; On branch master&lt;/span&gt;
&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt; Changes to be committed:&lt;/span&gt;
&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;   (use &amp;quot;git reset HEAD &amp;lt;file&amp;gt;...&amp;quot; to unstage)&lt;/span&gt;
&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span class="Comment"&gt;&lt;span class="Comment"&gt;#&lt;/span&gt;	new file:   vendor/gems/encrypted_strings-0.3.1/.specification&lt;/span&gt;
&lt;span class="Keyword"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Keyword"&gt;/&lt;/span&gt;file&lt;span class="Keyword"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;&lt;img src="http://feeds.feedburner.com/~r/ElcCodeFeed/~4/500568008" height="1" width="1"/&gt;</description>
      <author>Jonathan Siegel</author>
      <pubDate>Sun, 28 Dec 2008 22:31:48 +0000</pubDate>
      <link>http://feeds.feedburner.com/~r/ElcCodeFeed/~3/500568008/-solved-rake-gems-refresh_specs-to-fix-this</link>
      <guid isPermaLink="false">http://elctech.com/snippets/-solved-rake-gems-refresh_specs-to-fix-this</guid>
    <feedburner:origLink>http://elctech.com/snippets/-solved-rake-gems-refresh_specs-to-fix-this</feedburner:origLink></item>
    <item>
      <title>Preview RDoc with Vim</title>
      <description>&lt;div class="preface"&gt;
&lt;p&gt;Many times I want to view RDoc HTMLized quickly without having to switch to terminal, to see if it looks good. I wrote a small method to do it from Vim.&lt;/p&gt;

&lt;p&gt;Add the following snippet to ~/.vimrc or add it to ~/.vim/plugin/&lt;a href="http://gist.github.com/41910" target="_blank"&gt;rdoc.vim&lt;/a&gt;&lt;/p&gt;

&lt;code language="javascript"&gt;&lt;pre class="sunburst"&gt;command&lt;span class="Keyword"&gt;!&lt;/span&gt; &lt;span class="Keyword"&gt;-&lt;/span&gt;nargs&lt;span class="Keyword"&gt;=&lt;/span&gt;&lt;span class="Constant"&gt;0&lt;/span&gt; RDocPreview call RDocRenderBufferToPreview()

&lt;span class="Storage"&gt;function&lt;/span&gt;&lt;span class="Keyword"&gt;!&lt;/span&gt; RDocRenderBufferToPreview()
  let rdocoutput &lt;span class="Keyword"&gt;=&lt;/span&gt; &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;/tmp/vimrdoc/&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  call system(&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;rdoc &lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; . bufname(&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;%&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) . &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt; --op &lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; . rdocoutput)
  call system(&lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;open -a Safari &lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;. rdocoutput . &lt;span class="String"&gt;&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;index.html&lt;span class="String"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)
endfunction
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Restart Vim, open a ruby file and type:&lt;/p&gt;

&lt;code language="ruby"&gt;&lt;pre class="sunburst"&gt;&lt;span class="Constant"&gt;&lt;span class="Constant"&gt;:&lt;/span&gt;RDocPreview&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;

And voilà!

&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ElcCodeFeed/~4/499255515" height="1" width="1"/&gt;</description>
      <author>Husein Choroomi</author>
      <pubDate>Wed, 31 Dec 2008 07:11:24 +0000</pubDate>
      <link>http://feeds.feedburner.com/~r/ElcCodeFeed/~3/499255515/preview-rdoc-with-vim</link>
      <guid isPermaLink="false">http://elctech.com/snippets/preview-rdoc-with-vim</guid>
    <feedburner:origLink>http://elctech.com/snippets/preview-rdoc-with-vim</feedburner:origLink></item>
  </channel>
</rss>
