<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/2.3.1" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>
<channel>
	<title>Comments on: Taming the autotest Beast with FSEvents</title>
	<link>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/</link>
	<description>Ruby and Ruby on Rails Development</description>
	<pubDate>Sat, 11 Oct 2008 22:37:29 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.1</generator>
		<item>
		<title>By: Luke Kanies</title>
		<link>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-851</link>
		<dc:creator>Luke Kanies</dc:creator>
		<pubDate>Sun, 25 May 2008 22:29:18 +0000</pubDate>
		<guid>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-851</guid>
		<description>Just thought I'd throw a belated non-rails perspective in here.

I'm the core developer for Puppet, and I've currently got 172 spec files, with a total of about 23k lines of code (I've still got a lot of legacy test/unit code).

According to two important but qualitative tests, autotest was taking a lot of my machine's energy.  First, when it was running, the fan *never* stopped, and second, the MenuMeters graph in my menubar was always at around 25% cpu.

I'd recently taken to hitting ^z when not actively programming, since it was making my computer so much hotter, louder, and generally more annoying.

I've switched in this code and now my machine once again is behaving like I'm not playing a video all the time.

So, Ryan: I'd say autotest in its current form works fine for smaller projects or maybe if you're interested in waiting longer for tests to trigger, but it's pretty clear that events are a better way to handle this than polling, in the general case but especially for larger projects.  Most platforms support some kind of polling interface -- Linux has had FAM-like daemons for years, and now OS X has a good one too.  I think this bit of autotest should be abstracted out so it can be made to support whatever events system exists locally, with a fall-back to using polling when necessary.</description>
		<content:encoded><![CDATA[<p>Just thought I&#8217;d throw a belated non-rails perspective in here.</p>
<p>I&#8217;m the core developer for Puppet, and I&#8217;ve currently got 172 spec files, with a total of about 23k lines of code (I&#8217;ve still got a lot of legacy test/unit code).</p>
<p>According to two important but qualitative tests, autotest was taking a lot of my machine&#8217;s energy.  First, when it was running, the fan *never* stopped, and second, the MenuMeters graph in my menubar was always at around 25% cpu.</p>
<p>I&#8217;d recently taken to hitting ^z when not actively programming, since it was making my computer so much hotter, louder, and generally more annoying.</p>
<p>I&#8217;ve switched in this code and now my machine once again is behaving like I&#8217;m not playing a video all the time.</p>
<p>So, Ryan: I&#8217;d say autotest in its current form works fine for smaller projects or maybe if you&#8217;re interested in waiting longer for tests to trigger, but it&#8217;s pretty clear that events are a better way to handle this than polling, in the general case but especially for larger projects.  Most platforms support some kind of polling interface &#8212; Linux has had FAM-like daemons for years, and now OS X has a good one too.  I think this bit of autotest should be abstracted out so it can be made to support whatever events system exists locally, with a fall-back to using polling when necessary.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Woody Peterson</title>
		<link>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-745</link>
		<dc:creator>Woody Peterson</dc:creator>
		<pubDate>Thu, 10 Apr 2008 23:36:12 +0000</pubDate>
		<guid>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-745</guid>
		<description>With the newer versions of rspec/zentest (i'm using 1.1.3/3.9.2, respectively) it looks like you need to change hook :run to hook :initialize on line 3.</description>
		<content:encoded><![CDATA[<p>With the newer versions of rspec/zentest (i&#8217;m using 1.1.3/3.9.2, respectively) it looks like you need to change hook :run to hook :initialize on line 3.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matt Schick</title>
		<link>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-498</link>
		<dc:creator>Matt Schick</dc:creator>
		<pubDate>Tue, 08 Jan 2008 16:58:01 +0000</pubDate>
		<guid>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-498</guid>
		<description>Bah!  Ignore what I wrote, autotest loads either the project .autotest or your home directory .autotest.</description>
		<content:encoded><![CDATA[<p>Bah!  Ignore what I wrote, autotest loads either the project .autotest or your home directory .autotest.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Scott Nedderman</title>
		<link>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-491</link>
		<dc:creator>Scott Nedderman</dc:creator>
		<pubDate>Sun, 06 Jan 2008 01:38:03 +0000</pubDate>
		<guid>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-491</guid>
		<description>Ryan is correct that this issue is directly related to having a stuffed vendor directory (mine has 3500 files, not rails).  Autotest was using 25-30% of my cpu when running.  However, the issue was complicated by also using the rspec_on_rails plugin which prevents excluding other directories because of the way it overrides AutoTest:initialize (see my example).

Here’s the solution: http://blog.netphase.com/2008/01/05/autotest-cpu-fix/</description>
		<content:encoded><![CDATA[<p>Ryan is correct that this issue is directly related to having a stuffed vendor directory (mine has 3500 files, not rails).  Autotest was using 25-30% of my cpu when running.  However, the issue was complicated by also using the rspec_on_rails plugin which prevents excluding other directories because of the way it overrides AutoTest:initialize (see my example).</p>
<p>Here’s the solution: <a href="http://blog.netphase.com/2008/01/05/autotest-cpu-fix/" rel="nofollow">http://blog.netphase.com/2008/01/05/autotest-cpu-fix/</a></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matt Schick</title>
		<link>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-489</link>
		<dc:creator>Matt Schick</dc:creator>
		<pubDate>Sat, 05 Jan 2008 03:50:00 +0000</pubDate>
		<guid>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-489</guid>
		<description>Tammer and Yossef, I've been having the same problem of failed tests re-running over and over again.  After digging around in the code for awhile I figured out what was causing the problem for me:

When a test fails it's file and failure message are placed in @files_to_test.  I believe this is how autotest remembers what tests failed before so it can just rerun that failed test if any changes occurred that are nonspecific to any tests. Now a few of my tests create files while running and then delete the files when the test is over.  The deletion of these files triggers an FSEvent.  run_tests_in_paths is called from the callback and no files are found.  So ideally it should stop right here.  But remember that our friend @files_to_test still has the last failed test in it so run_tests_in_paths keeps running and reruns our test again, and again, and again....

To fix this problem I made a few changes that allow FSEvent to ignore certain files based on a project by project specification.  First I hooked into initialize and added a class level variable to stash our ignore pattern into (~/.autotest):

Autotest.add_hook :initialize do &#124;i&#124;
  @@fsevent_ignore_pattern = nil
end

I modified the call back like so (~/.autotest):

callback = proc do &#124;stream, ctx, numEvents, paths, marks, eventIDs&#124;
    paths.regard_as('*')
    rpaths = []

    numEvents.times { &#124;i&#124; rpaths &#60; 0 
  end

What this does is converts the file paths taken from the FSEvent, converts them to relative paths (i.e.  ./spec/models/blog_spec.rb) and then filters them through @@fsevent_ignore_pattern.  I setup the setting of @@fsevent_ignore_pattern as a hook so it can be specified on a project by project basis.  So in my project directory autotest file (rails_app/.autotest):

Autotest.add_hook :set_fsevent_ignore_pattern do &#124;i&#124;
  @@fsevent_ignore_pattern = /^\.\/(?:spec\/test_data&#124;log\/)/
end

I should also mention one last thing that I did:  Since the paths from FSEvents are now converted to relative @exceptions now works as it should (before the paths were coming in absolute and the regexp was failing all the time).  In find_files_in_paths I swapped out the line:

filename = f[current_dir..-1]

for:

filename = f.sub(/^\.\//, '')
 
So I realize that this is a huge amount of reading, but I hope someone finds it helpful.  It's a basically a hack on top of a hack.  I'm going to try and write a plugin for autotest that handles this much cleaner in the future.

and thanks to Ryan for the tip on running autotest in verbose to get the file changes (apologies to Ryan: I said I had my .autotest disabled, but I guess I was wrong, however I also said it was most likely my fault ;-)</description>
		<content:encoded><![CDATA[<p>Tammer and Yossef, I&#8217;ve been having the same problem of failed tests re-running over and over again.  After digging around in the code for awhile I figured out what was causing the problem for me:</p>
<p>When a test fails it&#8217;s file and failure message are placed in @files_to_test.  I believe this is how autotest remembers what tests failed before so it can just rerun that failed test if any changes occurred that are nonspecific to any tests. Now a few of my tests create files while running and then delete the files when the test is over.  The deletion of these files triggers an FSEvent.  run_tests_in_paths is called from the callback and no files are found.  So ideally it should stop right here.  But remember that our friend @files_to_test still has the last failed test in it so run_tests_in_paths keeps running and reruns our test again, and again, and again&#8230;.</p>
<p>To fix this problem I made a few changes that allow FSEvent to ignore certain files based on a project by project specification.  First I hooked into initialize and added a class level variable to stash our ignore pattern into (~/.autotest):</p>
<p>Autotest.add_hook :initialize do |i|<br />
  @@fsevent_ignore_pattern = nil<br />
end</p>
<p>I modified the call back like so (~/.autotest):</p>
<p>callback = proc do |stream, ctx, numEvents, paths, marks, eventIDs|<br />
    paths.regard_as(&#8217;*')<br />
    rpaths = []</p>
<p>    numEvents.times { |i| rpaths &lt; 0<br />
  end</p>
<p>What this does is converts the file paths taken from the FSEvent, converts them to relative paths (i.e.  ./spec/models/blog_spec.rb) and then filters them through @@fsevent_ignore_pattern.  I setup the setting of @@fsevent_ignore_pattern as a hook so it can be specified on a project by project basis.  So in my project directory autotest file (rails_app/.autotest):</p>
<p>Autotest.add_hook :set_fsevent_ignore_pattern do |i|<br />
  @@fsevent_ignore_pattern = /^\.\/(?:spec\/test_data|log\/)/<br />
end</p>
<p>I should also mention one last thing that I did:  Since the paths from FSEvents are now converted to relative @exceptions now works as it should (before the paths were coming in absolute and the regexp was failing all the time).  In find_files_in_paths I swapped out the line:</p>
<p>filename = f[current_dir..-1]</p>
<p>for:</p>
<p>filename = f.sub(/^\.\//, &#8221;)</p>
<p>So I realize that this is a huge amount of reading, but I hope someone finds it helpful.  It&#8217;s a basically a hack on top of a hack.  I&#8217;m going to try and write a plugin for autotest that handles this much cleaner in the future.</p>
<p>and thanks to Ryan for the tip on running autotest in verbose to get the file changes (apologies to Ryan: I said I had my .autotest disabled, but I guess I was wrong, however I also said it was most likely my fault <img src='http://rails.aizatto.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Yossef</title>
		<link>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-466</link>
		<dc:creator>Yossef</dc:creator>
		<pubDate>Mon, 17 Dec 2007 20:24:19 +0000</pubDate>
		<guid>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-466</guid>
		<description>To possibly assuage any problems with this not being cross-platform, I personally put this in my .autotest wrapped in a begin block with
  
rescue LoadError =&#62; e
  puts "Failed to use FSEvents instead of polling files"
end

Only recently and only on one project have I noticed the problem Tammer's talking about. I'm not sure what it is and haven't bothered to investigate yet.</description>
		<content:encoded><![CDATA[<p>To possibly assuage any problems with this not being cross-platform, I personally put this in my .autotest wrapped in a begin block with</p>
<p>rescue LoadError =&gt; e<br />
  puts &#8220;Failed to use FSEvents instead of polling files&#8221;<br />
end</p>
<p>Only recently and only on one project have I noticed the problem Tammer&#8217;s talking about. I&#8217;m not sure what it is and haven&#8217;t bothered to investigate yet.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ryan Davis</title>
		<link>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-450</link>
		<dc:creator>Ryan Davis</dc:creator>
		<pubDate>Sun, 16 Dec 2007 04:49:49 +0000</pubDate>
		<guid>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-450</guid>
		<description>I just had a thought... 

You're all doing rails development with a stuffed-to-the-gills vendor/ aren't you? Ever think of excluding the vendor directory?

Next version of autotest will make doing that a lot cleaner... coming soon.</description>
		<content:encoded><![CDATA[<p>I just had a thought&#8230; </p>
<p>You&#8217;re all doing rails development with a stuffed-to-the-gills vendor/ aren&#8217;t you? Ever think of excluding the vendor directory?</p>
<p>Next version of autotest will make doing that a lot cleaner&#8230; coming soon.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Brandon Keepers</title>
		<link>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-399</link>
		<dc:creator>Brandon Keepers</dc:creator>
		<pubDate>Thu, 06 Dec 2007 01:21:20 +0000</pubDate>
		<guid>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-399</guid>
		<description>Sorry Ryanâ€¦but I have to call BS too.  I use autotest all the time and notice a significant decrease (25%-50%) in battery life when it's running. It's a great tool and I don't think I could code without it, but it does use a fair amount of resources.

aizatto, thanks for sharing the code.  Now I can use autotest on flights.</description>
		<content:encoded><![CDATA[<p>Sorry Ryanâ€¦but I have to call BS too.  I use autotest all the time and notice a significant decrease (25%-50%) in battery life when it&#8217;s running. It&#8217;s a great tool and I don&#8217;t think I could code without it, but it does use a fair amount of resources.</p>
<p>aizatto, thanks for sharing the code.  Now I can use autotest on flights.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: aizatto</title>
		<link>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-389</link>
		<dc:creator>aizatto</dc:creator>
		<pubDate>Sat, 01 Dec 2007 13:47:17 +0000</pubDate>
		<guid>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-389</guid>
		<description>@Ryan actually I opted to re implement find_files_in_paths and run_tests_in_paths just to specifically look in the directories that have been updated, rather than scan the whole current directory again.  Even so, most of the code from the two functions is relatively the same, with a one or two line change. I previously used the original code but thought I would optimize it a bit.

Is there anything wrong with targeting a certain platform?  If you are working on OS X, then one should be happy that because you are on this platform you can use this feature, whilst working on the other ones, you don't really have much choice.  Just pros and cons of the platforms one uses. Does it take away from the functionality of autotest?  No.

Yes, you can put it to sleep for a while, but I still find it unnecessary to traverse the directory tree again if you don't really need to.</description>
		<content:encoded><![CDATA[<p>@Ryan actually I opted to re implement find_files_in_paths and run_tests_in_paths just to specifically look in the directories that have been updated, rather than scan the whole current directory again.  Even so, most of the code from the two functions is relatively the same, with a one or two line change. I previously used the original code but thought I would optimize it a bit.</p>
<p>Is there anything wrong with targeting a certain platform?  If you are working on OS X, then one should be happy that because you are on this platform you can use this feature, whilst working on the other ones, you don&#8217;t really have much choice.  Just pros and cons of the platforms one uses. Does it take away from the functionality of autotest?  No.</p>
<p>Yes, you can put it to sleep for a while, but I still find it unnecessary to traverse the directory tree again if you don&#8217;t really need to.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ryan Davis</title>
		<link>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-388</link>
		<dc:creator>Ryan Davis</dc:creator>
		<pubDate>Sat, 01 Dec 2007 10:59:46 +0000</pubDate>
		<guid>http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/#comment-388</guid>
		<description>I should also add... the sleep time IS parameterized... a 1 line addition to your .autotest vs 97 lines of not-cross-platfrom ruby? You decide.

P.S. alias the method and you won't get that warning.</description>
		<content:encoded><![CDATA[<p>I should also add&#8230; the sleep time IS parameterized&#8230; a 1 line addition to your .autotest vs 97 lines of not-cross-platfrom ruby? You decide.</p>
<p>P.S. alias the method and you won&#8217;t get that warning.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
