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

<channel>
	<title>Floorplanner Tech Blog &#187; Willem van Bergen</title>
	<atom:link href="http://techblog.floorplanner.com/author/willem/feed/" rel="self" type="application/rss+xml" />
	<link>http://techblog.floorplanner.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Thu, 19 Nov 2009 04:00:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Request-log-analyzer 1.5.0</title>
		<link>http://techblog.floorplanner.com/2009/11/18/request-log-analyzer-1-5-0/</link>
		<comments>http://techblog.floorplanner.com/2009/11/18/request-log-analyzer-1-5-0/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 17:51:42 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[request-log-analyzer]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[slow query log]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=801</guid>
		<description><![CDATA[Bart and I just released request-log-analyzer version 1.5.0. New features include:

MySQL slow query log format support to analyze what queries are slowing down your database.
Format autodetection: with all those supported file formats, remembering the right --format parameter gets tricky. With format autodetection, this usually is not needed anymore!

As always, run the following command to install [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F11%2F18%2Frequest-log-analyzer-1-5-0%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F11%2F18%2Frequest-log-analyzer-1-5-0%2F" height="61" width="51" /></a></div><p>Bart and I just released <a href="http://github.com/wvanbergen/request-log-analyzer">request-log-analyzer</a> version 1.5.0. New features include:</p>
<ul>
<li><a href="http://wiki.github.com/wvanbergen/request-log-analyzer/mysql-slow-query-log">MySQL slow query log</a> format support to analyze what queries are slowing down your database.</li>
<li><strong>Format autodetection:</strong> with all those supported file formats, remembering the right <code style="white-space: nowrap">--format</code> parameter gets tricky. With format autodetection, this usually is not needed anymore!</li>
</ul>
<p>As always, run the following command to install or upgrade to the latest version:</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family: Monaco,monospace;">$ gem install request-log-analyzer</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/11/18/request-log-analyzer-1-5-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Case-insensitive validates_uniqueness_of slowness</title>
		<link>http://techblog.floorplanner.com/2009/11/17/case-insensitive-validates_uniqueness_of-slowness/</link>
		<comments>http://techblog.floorplanner.com/2009/11/17/case-insensitive-validates_uniqueness_of-slowness/#comments</comments>
		<pubDate>Tue, 17 Nov 2009 14:01:02 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[case insensitive]]></category>
		<category><![CDATA[index]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[validates_uniqueness_of]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=787</guid>
		<description><![CDATA[Watch out when using validates_uniqueness_of :field, :case_sensitive => false. Rails transforms this in a query that cannot be supported by an index, which will really slow validation down if the underlying table grows larger.
For example, we use validates_uniqueness_of to check for duplicate e-mail addresses. Because email addresses are case-insensitive, adding :case_sensitive => false seems like [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F11%2F17%2Fcase-insensitive-validates_uniqueness_of-slowness%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F11%2F17%2Fcase-insensitive-validates_uniqueness_of-slowness%2F" height="61" width="51" /></a></div><p>Watch out when using <code>validates_uniqueness_of :field, :case_sensitive => false</code>. Rails transforms this in a query that cannot be supported by an index, which will really slow validation down if the underlying table grows larger.</p>
<p>For example, we use <code>validates_uniqueness_of</code> to check for duplicate e-mail addresses. Because email addresses are case-insensitive, adding <code>:case_sensitive => false</code> seems like a natural choice. However, this results in the following queries:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family: Monaco,monospace;"><span style="color: #808080; font-style: italic;"># For a new User instance:</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> users 
 <span style="color: #993333; font-weight: bold;">WHERE</span> LOWER<span style="color: #66cc66;">&#40;</span>users<span style="color: #66cc66;">.</span>email<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">BINARY</span> <span style="color: #ff0000;">'user@example.com'</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># For an existing User instance:</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> users 
 <span style="color: #993333; font-weight: bold;">WHERE</span> LOWER<span style="color: #66cc66;">&#40;</span>users<span style="color: #66cc66;">.</span>email<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">BINARY</span> <span style="color: #ff0000;">'user@example.com'</span> 
   <span style="color: #993333; font-weight: bold;">AND</span> users<span style="color: #66cc66;">.</span>id <span style="color: #66cc66;">&lt;&gt;</span> <span style="color: #cc66cc;">42</span></pre></div></div>

<p>This query cannot be optimized by a (unique) index on the email field and thus has to scan the full table. As our users table grew larger, these queries started to show up in our slow query log. </p>
<p>However, MySQL uses case-insensitive comparison by default. (To be exact, case-sensitiveness depends on the current collation, which can vary. Rails generates the weird query to make sure the check works, regardless of the current collation.) The conversion to lowercase therefore is not necessary for a uniqueness check (as long as the field has a case-insensitive collation like <code>utf8_general_ci</code>). I decided to write my own validation method that issues a query that can be optimized by a query.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;">  <span style="color:#008000; font-style:italic;"># Alternative for validates_uniqueness_of :email, :case_sensitive =&gt; false</span>
  validate <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>user<span style="color:#006600; font-weight:bold;">|</span>
    conditions = <span style="color:#996600;">&quot;users.email = :email&quot;</span>
    conditions <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot; AND users.id != :id&quot;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> user.<span style="color:#9900CC;">new_record</span>?
    conditions = <span style="color:#006600; font-weight:bold;">&#91;</span>conditions, <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:email</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> user.<span style="color:#9900CC;">email</span>, <span style="color:#ff3333; font-weight:bold;">:id</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> user.<span style="color:#9900CC;">id</span> <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> User.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:first</span>, <span style="color:#ff3333; font-weight:bold;">:select</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:id</span>, <span style="color:#ff3333; font-weight:bold;">:conditions</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> conditions<span style="color:#006600; font-weight:bold;">&#41;</span>
      user.<span style="color:#9900CC;">errors</span>.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:email</span>, <span style="color:#996600;">'Already in use'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>There is <a href="https://rails.lighthouseapp.com/projects/8994/tickets/2503-validates_uniqueness_of-is-horribly-inefficient-in-mysql">a ticket for this issue in Rails&#8217;s Lighthouse</a>, but as of yet this issue is unresolved. For now, this solution works to keep our slow query log nice and quiet!</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/11/17/case-insensitive-validates_uniqueness_of-slowness/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Evaluating static ParseTree subtrees</title>
		<link>http://techblog.floorplanner.com/2009/10/03/evaluating-static-parsetree-subtrees/</link>
		<comments>http://techblog.floorplanner.com/2009/10/03/evaluating-static-parsetree-subtrees/#comments</comments>
		<pubDate>Sat, 03 Oct 2009 12:34:21 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[evaluate]]></category>
		<category><![CDATA[ParseTree]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[syntax tree]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=734</guid>
		<description><![CDATA[ParseTree is a very useful to gem that can translate Ruby code into a syntax tree. I recently needed to evaluate a static part of this tree to return the original hash it represented. I wrote a simple method called ParseTree.eval_static_tree for this purpose. 
The method can only evaluate trees that have a static value [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F10%2F03%2Fevaluating-static-parsetree-subtrees%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F10%2F03%2Fevaluating-static-parsetree-subtrees%2F" height="61" width="51" /></a></div><p><a href="http://parsetree.rubyforge.org/">ParseTree</a> is a very useful to gem that can translate Ruby code into a syntax tree. I recently needed to evaluate a static part of this tree to return the original hash it represented. I wrote a simple method called <code>ParseTree.eval_static_tree</code> for this purpose. </p>
<p>The method can only evaluate trees that have a static value composed of hashes, arrays, strings, symbols and numerics. You can however pass a block to the function that will be called for every dynamic part the method encounters (function calls, etc.) </p>
<p><script src="http://gist.github.com/200607.js"></script></p>
<p>A quick sample on how to use it:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;">code = <span style="color:#996600;">'{ :static_array =&gt; [&quot;str&quot;, 123, 4.5], :dynamic =&gt; method_call }'</span>
tree = ParseTree.<span style="color:#9900CC;">translate</span><span style="color:#006600; font-weight:bold;">&#40;</span>code<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#008000; font-style:italic;"># =&gt; [:hash, [:lit, :static_array], [:array, [:str, &quot;str&quot;], </span>
<span style="color:#008000; font-style:italic;">#       [:lit, 123], [:lit, 4.5]], [:lit, :dynamic], [:vcall, :method_call]]</span>
&nbsp;
ParseTree.<span style="color:#9900CC;">eval_static_tree</span><span style="color:#006600; font-weight:bold;">&#40;</span>tree<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#008000; font-style:italic;"># =&gt; RuntimeError: tree is not static: :vcall ...</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># Pass a block to simply return nil for every dynamic item in the tree.</span>
ParseTree.<span style="color:#9900CC;">eval_static_tree</span><span style="color:#006600; font-weight:bold;">&#40;</span>tree<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>dynamic_subtree<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#0000FF; font-weight:bold;">nil</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#008000; font-style:italic;"># =&gt; {:dynamic=&gt;nil, :static_array=&gt;[&quot;str&quot;, 123, 4.5]}</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/10/03/evaluating-static-parsetree-subtrees/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Request-log-analyzer 1.4.0</title>
		<link>http://techblog.floorplanner.com/2009/09/30/request-log-analyzer-1-4-0/</link>
		<comments>http://techblog.floorplanner.com/2009/09/30/request-log-analyzer-1-4-0/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 09:40:04 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Amazon S3]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[log analysis]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[profiling]]></category>
		<category><![CDATA[Rack CommonLogger]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[request-log-analyzer]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=729</guid>
		<description><![CDATA[Bart and I have been working a lot on request-log-analyzer lately, our tool to produce performance reports for web applications based on their log files. Today, we released version 1.4.0, which boasts many new features since I last blogged about a release. The changelog contains all changes we have implemented recently with some additional information, [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F09%2F30%2Frequest-log-analyzer-1-4-0%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F09%2F30%2Frequest-log-analyzer-1-4-0%2F" height="61" width="51" /></a></div><p>Bart and I have been working a lot on <a href="http://github.com/wvanbergen/request-log-analyzer">request-log-analyzer</a> lately, our tool to produce performance reports for web applications based on their log files. Today, we released version 1.4.0, which boasts many new features since I last blogged about a release. The <a href="http://wiki.github.com/wvanbergen/request-log-analyzer/changelog">changelog</a> contains all changes we have implemented recently with some additional information, but these are the highlights:</p>
<ul>
<li><strong>New and improved log formats:</strong> r-l-a can now handle <a href="http://wiki.github.com/wvanbergen/request-log-analyzer/apache-access-log">Apache access logs</a>, <a href="http://wiki.github.com/wvanbergen/request-log-analyzer/apache-access-log#rack">Rack CommonLogger logs</a> and <a href="http://wiki.github.com/wvanbergen/request-log-analyzer/amazon-s3-access-log">Amazon S3 access logs</a>. Moreover, the Rails format has been restructured to offer <a href="http://wiki.github.com/wvanbergen/request-log-analyzer/rails-request-log">more flexibility</a>.</li>
<li><strong>Improved database support: </strong>the database supports other databases than SQLite3 as well, and r-l-a can append information to an existing database instead of overwriting it. Moreover, a console tool similar to Rails&#8217;s script/console is bundled to inspect the database and run queries on it easily.</li>
<li><strong>Added standard deviation to reports: </strong>the standard deviation measure has been added to duration and traffic reports to get some feel of the variation in values besides the mean.</li>
<li><strong>E-mailing reports:</strong> r-l-a can email the performance report to a given e-mail address. This can be useful when running r-l-a in a cron job.</li>
<li><strong>Compressed log support:</strong> r-l-a will decompress compressed logs automatically.</li>
<li><strong>Speed improvements:</strong> we have profiled <a href="http://techblog.floorplanner.com/2009/09/27/performance-tweaking-of-ruby-algorithms/">request-log-analyzer itself</a> and significantly improved its performance.</li>
<li><strong>API:</strong> we created a basic API so it is possible to use the r-l-a engine as a library as well.</li>
<li><strong>Monitoring integration:</strong> integrate performance information into your <a href="http://github.com/barttenbrinke/munin-plugins-rails/">Munin dashboard</a> or your <a href="http://wiki.github.com/wvanbergen/request-log-analyzer/scout">Scout account</a>.</li>
</ul>
<p>As always, use <code>sudo gem install request-log-analyzer</code> to install or upgrade.</p>
<h3>Ruby en Rails 2009 conference</h3>
<p>Bart and I will be presenting request-log-analyzer and performance tuning of Rails applications in general at the <a href="http://2009.rubyenrails.nl">Ruby en Rails</a> conference in Amsterdam, October 30-31 2009. We hope to see you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/09/30/request-log-analyzer-1-4-0/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Adyen payment services for Rails</title>
		<link>http://techblog.floorplanner.com/2009/09/27/adyen-payment-services-for-rails/</link>
		<comments>http://techblog.floorplanner.com/2009/09/27/adyen-payment-services-for-rails/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 18:27:23 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[adyen]]></category>
		<category><![CDATA[forms]]></category>
		<category><![CDATA[payments]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[signature calculation]]></category>
		<category><![CDATA[soap]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=726</guid>
		<description><![CDATA[Michel and I have been playing around with integrating Adyen payment services in Rails applications. We have assembled some of the pieces of code we have written, combined them, written specs for them and released the result as a gem. The package is also included on the Adyen support site.
Currently, the gem provides the following:

Simple [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F09%2F27%2Fadyen-payment-services-for-rails%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F09%2F27%2Fadyen-payment-services-for-rails%2F" height="61" width="51" /></a></div><p>Michel and I have been playing around with integrating <a href="http://www.adyen.com/">Adyen payment services</a> in Rails applications. We have assembled some of the pieces of code we have written, combined them, written specs for them and <a href="http://github.com/wvanbergen/adyen">released the result as a gem</a>. The package is also included on the <a href="https://support.adyen.com/index.php?_m=downloads&amp;_a=viewdownload&amp;downloaditemid=43">Adyen support site</a>.</p>
<p>Currently, the gem provides the following:</p>
<ul>
<li>Simple configuration and setup.</li>
<li>Uses Adyen&#8217;s test or production environment based on your Rails environment.</li>
<li>Generating hidden form fields for redirecting to Adyen for a payment.</li>
<li>Calculating the signature to sign these redirects.</li>
<li>Checking Adyen&#8217;s signature when the user gets redirected back.</li>
<li>Matchers to easily test your payment forms using RSpec.</li>
<li>Receiving and storing notifications from Adyen.</li>
<li>Calling the Adyen SOAP services (requires the <a href="http://github.com/troelskn/handsoap">Handsoap gem</a>).</li>
</ul>
<p>Currently, not all SOAP services are implemented (because we didn&#8217;t need them all). It should be quite easy to implement them as well based on the other services that are implemented already. Don&#8217;t hesitate to submit patches!</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/09/27/adyen-payment-services-for-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Performance tweaking of Ruby algorithms</title>
		<link>http://techblog.floorplanner.com/2009/09/27/performance-tweaking-of-ruby-algorithms/</link>
		<comments>http://techblog.floorplanner.com/2009/09/27/performance-tweaking-of-ruby-algorithms/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 06:02:42 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[analysis]]></category>
		<category><![CDATA[blocks]]></category>
		<category><![CDATA[parallelization]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[profiling]]></category>
		<category><![CDATA[regular expressions]]></category>
		<category><![CDATA[request-log-analyzer]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby-prof]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=716</guid>
		<description><![CDATA[I have been working on request-log-analyzer quite a lot recently. One of the things I focused on was improving the parsing performance: because it parses log files that often are very big, processing times tend to be long. So all savings are very welcome.
Improving the performance of a command line application that does a lot [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F09%2F27%2Fperformance-tweaking-of-ruby-algorithms%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F09%2F27%2Fperformance-tweaking-of-ruby-algorithms%2F" height="61" width="51" /></a></div><p>I have been working on <a href="http://github.com/wvanbergen/request-log-analyzer">request-log-analyzer</a> quite a lot recently. One of the things I focused on was improving the parsing performance: because it parses log files that often are very big, processing times tend to be long. So all savings are very welcome.</p>
<p>Improving the performance of a command line application that does a lot of processing is very different from optimizing the performance of a web application. Request-log-analyzer basically reads a file line by line and processes it, so small performance improvements in the line processing algorithm can really add up when the file has a lot of lines. I used <a href="http://ruby-prof.rubyforge.org/">ruby-prof</a> to get information about the performance of our algorithms split out by method to focus my tweaking efforts. I have written down some of my findings below; hopefully they can be helpful.</p>
<h3>Parallelization</h3>
<p>My first thought for improving performance was parallelization: parse multiple lines at the same time. Unfortunately, this did not yield the results I was hoping for: it instead become slower. Probably, this is because Ruby implements its own in-process threading and thus only uses one core of my processor.</p>
<h3>Block overhead</h3>
<p>The overhead of using a block should not be underestimated. Consider the following simple change, which improved the performance of request-log-analyzer by 1.5-2% on large log files:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#008000; font-style:italic;"># with block</span>
io.<span style="color:#9900CC;">each_line</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>line<span style="color:#006600; font-weight:bold;">|</span> process_line<span style="color:#006600; font-weight:bold;">&#40;</span>line<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># without block</span>
process_line<span style="color:#006600; font-weight:bold;">&#40;</span>line<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">while</span> line = io.<span style="color:#CC0066; font-weight:bold;">gets</span></pre></div></div>

<h3>Regular expressions</h3>
<p>If you&#8217;re using complex regular expressions, and you do not expect that every string will match it successfully, it can be beneficial to test the string with a simpler regexp first. For example, request-log-analyzer uses a complex regexp to see if a line in a log file is a &#8220;Completed in&#8230;&#8221; line with the request duration in it:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#008000; font-style:italic;"># Check every line to see if it is a &quot;completed&quot; line and capture the values</span>
<span style="color:#9966CC; font-weight:bold;">if</span> line =~ <span style="color:#006600; font-weight:bold;">/</span>Completed <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#40;</span>\d<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>ms \<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>?:View: <span style="color:#006600; font-weight:bold;">&#40;</span>\d<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#006600; font-weight:bold;">&#41;</span>?DB: <span style="color:#006600; font-weight:bold;">&#40;</span>\d<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>\<span style="color:#006600; font-weight:bold;">&#41;</span> \<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">&#40;</span>\d\d\d<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#006600; font-weight:bold;">+</span>\<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#40;</span>http.<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>\<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">/</span>
  <span style="color:#008000; font-style:italic;"># do something with the captured values</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>I improved this by first checking for a superficial regexp that tells me with 99% certainty that the complex regexp will match the line successfully as well:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#9966CC; font-weight:bold;">if</span> line =~ <span style="color:#006600; font-weight:bold;">/</span>Completed <span style="color:#9966CC; font-weight:bold;">in</span><span style="color:#006600; font-weight:bold;">/</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> line =~ <span style="color:#006600; font-weight:bold;">/</span>Completed <span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#006600; font-weight:bold;">&#40;</span>\d<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>ms \<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>?:View: <span style="color:#006600; font-weight:bold;">&#40;</span>\d<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#006600; font-weight:bold;">&#41;</span>?DB: <span style="color:#006600; font-weight:bold;">&#40;</span>\d<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>\<span style="color:#006600; font-weight:bold;">&#41;</span> \<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">&#40;</span>\d\d\d<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#006600; font-weight:bold;">+</span>\<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#40;</span>http.<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006600; font-weight:bold;">&#41;</span>\<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">/</span>
    <span style="color:#008000; font-style:italic;"># do something with the captured values</span>
  <span style="color:#9966CC; font-weight:bold;">else</span>
    <span style="color:#ff6633; font-weight:bold;">$stderr</span>.<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{line.inspect} expected to match 'Completed' regexp!&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Depending on the log file, this can increase performance by ~3%. Another benefit of this approach is that it will give feedback on lines that matched the simple regexp, but not the complex one. This information can be used to correct the regular expressions.</p>
<h3>Calculate things that do not change only once</h3>
<p>Calculate things that do not change only once is easier said than done. For instance, request-log analyzer can aggregate durations in a category. A category can be based on a request field that is parsed from the log, or a <code>Proc</code> that calculates it:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#008000; font-style:italic;"># during parsing:</span>
<span style="color:#9966CC; font-weight:bold;">if</span> categorizer.<span style="color:#9900CC;">respond_to</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:call</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  category = categorizer.<span style="color:#9900CC;">call</span><span style="color:#006600; font-weight:bold;">&#40;</span>request<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">else</span>
  category = request<span style="color:#006600; font-weight:bold;">&#91;</span>categorizer<span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
categories<span style="color:#006600; font-weight:bold;">&#91;</span>category<span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">aggregate_request</span><span style="color:#006600; font-weight:bold;">&#40;</span>request<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>With this implementation, <code>categorizer</code> will be checked to be a <code>Proc</code> for every request, but as the value of <code>categorizer</code> will not change, the result of the check will be constant as well. I solved this my making sure that it is always a <code>Proc</code> beforehand, so the check is no longer necessary during parsing:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#008000; font-style:italic;"># before parsing:</span>
<span style="color:#9966CC; font-weight:bold;">if</span> categorizer.<span style="color:#9900CC;">respond_to</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:call</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  categorizer_proc = categorizer
<span style="color:#9966CC; font-weight:bold;">else</span>
  categorizer_proc = <span style="color:#CC0066; font-weight:bold;">lambda</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>request<span style="color:#006600; font-weight:bold;">|</span> request<span style="color:#006600; font-weight:bold;">&#91;</span>categorizer<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># during parsing:</span>
category = categorizer_proc.<span style="color:#9900CC;">call</span><span style="color:#006600; font-weight:bold;">&#40;</span>request<span style="color:#006600; font-weight:bold;">&#41;</span>
categories<span style="color:#006600; font-weight:bold;">&#91;</span>category<span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">aggregate_request</span><span style="color:#006600; font-weight:bold;">&#40;</span>request<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Performance gain: ~1%! And because on several instances a similar technique could be applied, the performance got improved by about 4% in total.</p>
<h3>Check the most common case first</h3>
<p>Consider the following example, which converts a number in any traffic unit (kilobytes, MB, etc) to bytes:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> convert_traffic<span style="color:#006600; font-weight:bold;">&#40;</span>value, unit<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">case</span> unit
  <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#ff3333; font-weight:bold;">:GB</span>, <span style="color:#ff3333; font-weight:bold;">:G</span>, <span style="color:#ff3333; font-weight:bold;">:gigabyte</span>      <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#006600; font-weight:bold;">&#40;</span>value.<span style="color:#9900CC;">to_f</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006666;">1000</span>_000_000<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">round</span>
  <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#ff3333; font-weight:bold;">:MB</span>, <span style="color:#ff3333; font-weight:bold;">:M</span>, <span style="color:#ff3333; font-weight:bold;">:megabyte</span>      <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#006600; font-weight:bold;">&#40;</span>value.<span style="color:#9900CC;">to_f</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006666;">1000</span>_000<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">round</span>
  <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#ff3333; font-weight:bold;">:KB</span>, <span style="color:#ff3333; font-weight:bold;">:K</span>, <span style="color:#ff3333; font-weight:bold;">:kilobyte</span>, <span style="color:#ff3333; font-weight:bold;">:kB</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#006600; font-weight:bold;">&#40;</span>value.<span style="color:#9900CC;">to_f</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006666;">1000</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">round</span>
  <span style="color:#008000; font-style:italic;"># ... even more units here</span>
  <span style="color:#9966CC; font-weight:bold;">else</span> value.<span style="color:#9900CC;">to_i</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>In most cases, the value will simply given in bytes, which will be returned by the final <code>else</code> after all possibilities have been checked. This can be improved by checking for this possibility first:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#008000; font-style:italic;"># Converts traffic in any unit to bytes.</span>
<span style="color:#9966CC; font-weight:bold;">def</span> convert_traffic<span style="color:#006600; font-weight:bold;">&#40;</span>value, unit<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">case</span> unit
  <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#0000FF; font-weight:bold;">nil</span>, <span style="color:#ff3333; font-weight:bold;">:B</span>, <span style="color:#ff3333; font-weight:bold;">:byte</span>          <span style="color:#9966CC; font-weight:bold;">then</span> value.<span style="color:#9900CC;">to_i</span>
  <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#ff3333; font-weight:bold;">:GB</span>, <span style="color:#ff3333; font-weight:bold;">:G</span>, <span style="color:#ff3333; font-weight:bold;">:gigabyte</span>      <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#006600; font-weight:bold;">&#40;</span>value.<span style="color:#9900CC;">to_f</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006666;">1000</span>_000_000<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">round</span>
  <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#ff3333; font-weight:bold;">:MB</span>, <span style="color:#ff3333; font-weight:bold;">:M</span>, <span style="color:#ff3333; font-weight:bold;">:megabyte</span>      <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#006600; font-weight:bold;">&#40;</span>value.<span style="color:#9900CC;">to_f</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006666;">1000</span>_000<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">round</span>
  <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#ff3333; font-weight:bold;">:KB</span>, <span style="color:#ff3333; font-weight:bold;">:K</span>, <span style="color:#ff3333; font-weight:bold;">:kilobyte</span>, <span style="color:#ff3333; font-weight:bold;">:kB</span> <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#006600; font-weight:bold;">&#40;</span>value.<span style="color:#9900CC;">to_f</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006666;">1000</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">round</span>
  <span style="color:#008000; font-style:italic;"># ... even more units here</span>
  <span style="color:#9966CC; font-weight:bold;">else</span> <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#996600;">&quot;Unknown unit: #{unit.inspect}!&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Again this change adds up to a ~1% performance increase if this method is called very often.</p>
<p>These kinds of changes really improved the performance of request-log-analyzer by quite a bit, so upgrade to the latest version to get some of your valuable time back! <img src='http://techblog.floorplanner.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/09/27/performance-tweaking-of-ruby-algorithms/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>New version of Scoped search</title>
		<link>http://techblog.floorplanner.com/2009/08/31/new-version-of-scoped-search/</link>
		<comments>http://techblog.floorplanner.com/2009/08/31/new-version-of-scoped-search/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 09:37:22 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[LIKE]]></category>
		<category><![CDATA[query language]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[scoped_search]]></category>
		<category><![CDATA[search]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=698</guid>
		<description><![CDATA[After an almost complete rewrite, I am proud to present version 2.0 of scoped_search, the ActiveRecord plugin that makes it easy to find records using a simple query language. This new version support a new query language that supports more complex constructs, and can therefore be used to conduct more fine-grained queries on your models.
New [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F08%2F31%2Fnew-version-of-scoped-search%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F08%2F31%2Fnew-version-of-scoped-search%2F" height="61" width="51" /></a></div><p>After an almost complete rewrite, I am proud to present version 2.0 of <a href="http://github.com/wvanbergen/scoped_search">scoped_search</a>, the ActiveRecord plugin that <a href="http://techblog.floorplanner.com/2008/07/26/easy-search-with-activerecord/">makes it easy to find records using a simple query language</a>. This new version support a new query language that supports more complex constructs, and can therefore be used to conduct more fine-grained queries on your models.</p>
<h3>New query language</h3>
<ul>
<li>Logical operators: AND (&amp;, &amp;&amp;), OR (|, ||) and NOT (!, -) operators, and parentheses to structure the boolean logic: <code>police AND (car || uniform), -"village people"</code>. By default, the AND operator is used to combine different segments of your query.</li>
<li>Comparison operators: the most common comparison operators are supported, and to what you expect on integer and date field.</li>
<li>Explicit field support: only search in the specified field instead of all fields: <code>age &gt;= 21</code>, <code>created &lt; 2009-01-01</code>, <code>username != "root"</code>.</li>
<li>Check for NULL fields: <code>null? parent</code>, <code>set? error_message</code></li>
<li>Commas are supported to separate the different parts of the query.</li>
</ul>
<p>More information about <a href="http://wiki.github.com/wvanbergen/scoped_search/query-language">the query language</a> can be found in the project wiki on GitHub.</p>
<h3>New definition syntax</h3>
<p>The new version supports a new syntax to define what fields of your model can be searched and in what cases. An example:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> User <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>   
  belongs_to <span style="color:#ff3333; font-weight:bold;">:account_type</span>
&nbsp;
  scoped_search <span style="color:#ff3333; font-weight:bold;">:on</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:first_name</span>, <span style="color:#ff3333; font-weight:bold;">:last_name</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  scoped_search <span style="color:#ff3333; font-weight:bold;">:on</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:created_at</span>, <span style="color:#ff3333; font-weight:bold;">:alias</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:created</span>, <span style="color:#ff3333; font-weight:bold;">:only_explicit</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
  scoped_search <span style="color:#ff3333; font-weight:bold;">:in</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:account_type</span>, <span style="color:#ff3333; font-weight:bold;">:on</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#ff3333; font-weight:bold;">:description</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>After the fields have been defined, the <code>search_for</code> method can be used to search your models using a named scope, just like it was before. The <a href="http://wiki.github.com/wvanbergen/scoped_search/search-definition">project wiki</a> has more information about this new syntax. The search syntax itself hasn&#8217;t changed:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#0066ff; font-weight:bold;">@users</span> = User.<span style="color:#9900CC;">search_for</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:q</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">paginate</span><span style="color:#006600; font-weight:bold;">&#40;</span>page <span style="color:#006600; font-weight:bold;">=&gt;</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:page</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<h3>Installation or upgrade</h3>
<p>Include the gem in your <code>environment.rb</code> configuration and run <code>rake gems:install</code> to install it:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;">config.<span style="color:#9900CC;">gem</span> <span style="color:#996600;">'scoped_search'</span>, <span style="color:#ff3333; font-weight:bold;">:source</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'http://gemcutter.org'</span></pre></div></div>

<h3>Backwards compatibility</h3>
<p>The new version has a new syntax to define the fields that can be searched with a query. This new syntax gives you more fine-grained control over the queries that will be generated, so I urge you to adopt this new syntax. However, the old <code>searchable_on</code> syntax is still available for backwards compatibility.</p>
<p>Please contact me if you have any issues with the new version.</p>
<p><small>(Updated with new gemcutter installation instructions.)</small></p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/08/31/new-version-of-scoped-search/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Counter feedback</title>
		<link>http://techblog.floorplanner.com/2009/03/28/counter-feedback/</link>
		<comments>http://techblog.floorplanner.com/2009/03/28/counter-feedback/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 16:32:14 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Collaboration]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[counter]]></category>
		<category><![CDATA[flickr]]></category>
		<category><![CDATA[Floorplanner]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[quality improvement]]></category>
		<category><![CDATA[request-log-analyzer]]></category>
		<category><![CDATA[web 2.0]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=561</guid>
		<description><![CDATA[
This week, request-log-analyzer obtained its 100th watcher on GitHub!
Bart and I have worked hard to make r-l-a a useful product for many people in various situations. The fact that more than 100 people are following the project&#8217;s progress and that at this moment, the gem has been download almost 200 times, shows that we are [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F03%2F28%2Fcounter-feedback%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F03%2F28%2Fcounter-feedback%2F" height="61" width="51" /></a></div><p><a style="float: right" href="http://github.com/wvanbergen/request-log-analyzer/watchers"><img class="size-full wp-image-568 alignright" style="border: 1px solid black;" title="102 request-log-analyzer watchers on Github and counting!" src="http://techblog.floorplanner.com/wp-content/uploads/2009/03/picture-2.png" alt="Request-log-analyzer watchers on Github" width="161" height="26" /></a></p>
<p>This week, <a href="http://github.com/wvanbergen/requets-log-analyzer">request-log-analyzer</a> obtained <a href="http://github.com/wvanbergen/request-log-analyzer/watchers">its 100th watcher on GitHub</a>!</p>
<p>Bart and I have worked hard to make r-l-a a useful product for many people in various situations. The fact that more than 100 people are following the project&#8217;s progress and that at this moment, <a href="http://gems.rubyforge.org/stats.html">the gem has been download almost 200 times</a>, shows that we are somewhat successful in this regard. Numbers like these, in combination with the e-mail messages we have received, motivate us to keep spending time on the project and keep improving it, even if these improvements are not directly useful for our own projects. It has grown beyond <em>scratching our own itch</em>. </p>
<p>On a related note, <a href="http://www.flickr.com/photos/willemvanbergen">my Flickr photostream</a> recently welcomed its 10,000th visitor.</p>
<p style="text-align: center; "><a href="http://www.flickr.com/photos/willemvanbergen"><img class="size-full wp-image-562 aligncenter" style="border: 1px solid black;" title="10,000 visitors on my Flickr photostream!" src="http://techblog.floorplanner.com/wp-content/uploads/2009/03/picture-1.png" alt="10,000 visitors on my Flickr photostream!" width="502" height="84" /></a></p>
<p>What started as a convenient utility to backup and share <a href="http://www.flickr.com/photos/willemvanbergen/collections/72157600336728559/">my holiday photos</a> with my family and friends, now has become somewhat of a showcase of <a href="http://www.flickr.com/photos/willemvanbergen/sets/72157601618255001/">what I</a> <a href="http://www.flickr.com/photos/willemvanbergen/sets/72157594253547759/">am about</a> and <a href="http://www.flickr.com/photos/willemvanbergen/collections/72157607936471141/">what I</a> <a href="http://www.flickr.com/photos/willemvanbergen/sets/72157613466104360/">am up to</a>. I would not consider myself a &#8220;professional&#8221; photographer and I am not an active member of the Flickr community, but still I get feedback on my photographs by visitors, because their visits increase the view counters of my photos.</p>
<p>These counters have really motivated me to make more of an effort when I put photos on Flickr. I started by adding titles, descriptions and tags, so that my photos are easier to find. I also became much more critical of the pictures I upload to Flickr: new uploads have to add something significant to my collection. Analyzing why some pictures got more attention than others made me a better photographer, although there still is a lot of room for improvement. <img src='http://techblog.floorplanner.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  </p>
<h3>Ignite the lazyweb, kick-start a quality improvement loop</h3>
<p>What interests me in these examples is that simple counters like watchers on GitHub or views on Flickr can be valuable feedback and can motivate people to put in effort. The end result is quality improvement: write better software, make better pictures, etc.. Even an inherently lazy person like me can get motivated to keep putting in effort and to keep improving myself, because of such a simple feedback loop! <img src='http://techblog.floorplanner.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Additionally, it creates a dependence on the website in question. I look at my Flickr stats page every day, and I am subscribed to my activity feed on GitHub to get notified when new people start watching my projects. I now<em> </em>simply have to publish tools I write on GitHub to boost its quality, immediately and in the long run. And I have to upload pictures to Flickr as it is vital for my photography learning curve.</p>
<p>I guess I finally figured out what Web 2.0 is all about! <img src='http://techblog.floorplanner.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Can we use a similar technique on Floorplanner to boost the quality of the designs our visitors make?</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/03/28/counter-feedback/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a REST API for a Flash application</title>
		<link>http://techblog.floorplanner.com/2009/02/25/creating-a-rest-api-for-a-flash-application/</link>
		<comments>http://techblog.floorplanner.com/2009/02/25/creating-a-rest-api-for-a-flash-application/#comments</comments>
		<pubDate>Wed, 25 Feb 2009 16:49:47 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Flash+ActionScript]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[caveats]]></category>
		<category><![CDATA[DELETE]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[PUT]]></category>
		<category><![CDATA[request]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=486</guid>
		<description><![CDATA[We have been working hard to implement an XML-based REST-style API for Floorplanner and some of our partners are using it already to access their users and plans. We now have started to use this API ourselves.
The Floorplanner Flash application communicates with our servers to load and save projects and designs. The backend for this [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F02%2F25%2Fcreating-a-rest-api-for-a-flash-application%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F02%2F25%2Fcreating-a-rest-api-for-a-flash-application%2F" height="61" width="51" /></a></div><p>We have been working hard to implement an XML-based REST-style API for Floorplanner and some of our partners are using it already to access their users and plans. We now have started to use this API ourselves.</p>
<p>The Floorplanner Flash application communicates with our servers to load and save projects and designs. The backend for this functionality used to be written in PHP. Eliminating this PHP application simplifies our server setup, eases development and reduces our maintenance burden. To rewrite this functionality in Rails, we decided to eat our own dogfood and use the REST API to load and save designs. Why reinvent the wheel?</p>
<p>However, while implementing the changes it the Flash application, we found that it did not work out of the box, because of some limitations in ActionScript. Note that we still use ActionScript 2, so some of these issues may not be relevant for ActionScript 3. In this post, we will detail what these issues are and how we overcame them.</p>
<h3> Using a separate format </h3>
<p>Our REST API uses the XML format supplied by Rails. Because we had to make some changes to make it work from ActionScript, we decided to add a distinct format that we could implement differently without altering the behavior of the default XML API. Adding a new format, called &#8220;flash&#8221; can be done in Rails by adding a MIME alias to your environment:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;"><span style="color:#6666ff; font-weight:bold;">Mime::Type</span>.<span style="color:#9900CC;">register_alias</span> <span style="color:#996600;">&quot;application/xml&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:flash</span></pre></div></div>

<p>Now we can send different responses based on this format:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;">respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>   <span style="color:#006600; font-weight:bold;">&#123;</span> ... <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#008000; font-style:italic;"># default API behavior</span>
  <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">flash</span> <span style="color:#006600; font-weight:bold;">&#123;</span> ... <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#008000; font-style:italic;"># do something different</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<h3> HTTP status codes </h3>
<p>REST APIs use HTTP status codes to return whether a call succeeded, and if not, why. Flash however uses the browser to perform HTTP requests. The browser only returns something to Flash if the request was successful. So, if an error code is used if a request failed together with some error messages, these error messages will not be delivered to Flash and cannot be displayed to the user. We resolved this by always sending the HTTP OK status.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;">respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>   <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@project</span>.<span style="color:#9900CC;">errors</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">422</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">flash</span> <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> XML.<span style="color:#9900CC;">failure</span><span style="color:#006600; font-weight:bold;">&#40;</span>@project.<span style="color:#9900CC;">errors</span>, <span style="color:#006666;">422</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Our <code>XML.failure</code> method will return something like:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family: Monaco,monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;failure</span> <span style="color: #000066;">status</span>=<span style="color: #ff0000;">&quot;422&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;error</span> <span style="color: #000066;">on</span>=<span style="color: #ff0000;">&quot;name&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>A project should have a name!<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/error<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/failure<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Note that other HTTP success statuses than 200 work in Safari and Firefox, but not in Internet Explorer. So, never return a 201 (<code>:created</code>), because Internet Explorer will not send the result to Flash!</p>
<h3> PUT and DELETE requests </h3>
<p>REST-style APIs use HTTP PUT requests to alter objects and DELETE requests to destroy objects. Most browsers do not support these request type. It is not supported by ActionScript either, because Flash uses the browser to send the request. </p>
<p>To overcome this problem, these types of requests can be simulated in Rails by sending a <code>_method</code> parameter along with a POST request. Unfortunately, this does not work when calling the REST API. The POST request body cannot be used to send additional variables, because it is used for the XML payload.</p>
<p>We solved this issue by creating additional routes for POST requests to the <code>update</code> and <code>destroy</code> actions of our resource controllers. Our <code>routes.rb</code> file now looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family: Monaco,monospace;">  map.<span style="color:#9900CC;">resources</span> <span style="color:#ff3333; font-weight:bold;">:projects</span>, <span style="color:#ff3333; font-weight:bold;">:member</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:update</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:post</span>, <span style="color:#ff3333; font-weight:bold;">:destroy</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:post</span> <span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>These routes route to exactly the same methods as the default REST actions (<code>ProjectsController#update</code> and <code>ProjectsController#destroy</code>), so no additional code is needed. The following calls are now equivalent:</p>
<pre>
PUT    /projects/123.xml
POST   /projects/123/update.xml
POST   /projects/123/update.flash

DELETE /projects/123.xml
POST   /projects/123/destroy.xml
POST   /projects/123/destroy.flash
</pre>
<h3>The result </h3>
<p>It requires some stretching of the pure REST principles, but doing so is worth it: we can now reuse the code we use for our API to handle Flash application calls and we can eliminate the PHP backend.</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/02/25/creating-a-rest-api-for-a-flash-application/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Request-log-analyzer 1.0</title>
		<link>http://techblog.floorplanner.com/2009/01/12/request-log-analyzer-10/</link>
		<comments>http://techblog.floorplanner.com/2009/01/12/request-log-analyzer-10/#comments</comments>
		<pubDate>Mon, 12 Jan 2009 13:17:38 +0000</pubDate>
		<dc:creator>Willem van Bergen</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA["rails-log-analyzer"]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[production.log]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[reporting]]></category>
		<category><![CDATA[request-log-analyzer]]></category>
		<category><![CDATA[requests]]></category>
		<category><![CDATA[statistics]]></category>

		<guid isPermaLink="false">http://techblog.floorplanner.com/?p=409</guid>
		<description><![CDATA[After a complete rewrite, Bart and I are proud to present request-log-analyzer version 1.0! Request-log-analyzer is an open-source command-line tool to analyze production log files from your Rails application to produce a performance report.
What&#8217;s new?

More robust log parser. It parses more lines and it now combines all lines that belong to the same request, which greatly [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F01%2F12%2Frequest-log-analyzer-10%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Ftechblog.floorplanner.com%2F2009%2F01%2F12%2Frequest-log-analyzer-10%2F" height="61" width="51" /></a></div><p>After a complete rewrite, <a title="Bart's Moves on Rails website" href="http://www.movesonrails.com">Bart</a> and I are proud to present <strong>request-log-analyzer</strong> version <strong>1.0!</strong> Request-log-analyzer is an open-source command-line tool to analyze production log files from your Rails application to produce a performance report.</p>
<h3>What&#8217;s new?</h3>
<ul>
<li>More robust log parser. It parses more lines and it now combines all lines that belong to the same request, which greatly improves the amount of information available. </li>
<li>It produces more detailed and more beautiful <a title="Sample report" href="http://wiki.github.com/wvanbergen/request-log-analyzer/sample-output">reports</a>. </li>
<li>A <a href="http://wiki.github.com/wvanbergen/request-log-analyzer/creating-a-request-database">database builder</a> is included, which will create an SQLite 3 database with all parsed request information, so you can roll your own queries.</li>
<li>Request filtering options, so you can exclude irrelevant data. <a title="In-depth analysis example" href="http://wiki.github.com/wvanbergen/request-log-analyzer/in-depth-analysis">An example</a> on how this can be applied in practice can be found in the wiki. </li>
<li>Better, more modularized design under the hood. The parser is now fully log file format-agnostic. Developing extensions and modifications, or adding support for other log file formats should be much easier now. See the <a title="Request-log-analyzer development" href="http://wiki.github.com/wvanbergen/request-log-analyzer/development">development</a>-page for some pointers.</li>
<li>Documentation in the <a href="http://wiki.github.com/wvanbergen/request-log-analyzer">project&#8217;s wiki</a>. Hopefully, this helps people get up to speed with the new version and answers most questions about using the tool. If you still have questions, please contact us so we can keep improving it!</li>
</ul>
<h3>Installation</h3>
<p>Install or upgrade to the new version with the following command:</p>
<pre>$ sudo gem install wvanbergen-request-log-analyzer 
                --source http://gems.github.com</pre>
<p>To get the best results out of request-log-analyzer, it is important to configure logging correctly for your application. Some pointers on how to set things up correctly <a title="Configuring logging correctly" href="http://wiki.github.com/wvanbergen/request-log-analyzer/configure-logging">can be found in the wiki</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://techblog.floorplanner.com/2009/01/12/request-log-analyzer-10/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
