Autotest CPU Fix

Update 1/15/2008
Autotest and rspec both posted updates today. Now, the way to fix this issue is slightly different:

Autotest.add_hook :run do |autotest|
  autotest.add_exception(/^\.\/vendor/)
  autotest.add_exception(/\.svn/)
end

Thanks Ryan and David for the updates!

I’ve been noticing in my current project that running autotest was constantly consuming about 25-30% of my cpu and causing my macbook pro to run really hot. I did a little googling and found this discussion on the topic.

For me, my problem was definitely the vendor directory (~3500 files in 4 plugins: rspec, rspec_on_rails, restful_open_id_authentication and active_merchant). I tried excluding the entire directory by adding this to my ~/.autotest file:

Autotest.add_hook :initialize do |autotest|
  autotest.exceptions <<
   %r%^\./(?:db|doc|log|public|script|vendor|previous_failures.txt)%
end

However, that didn’t work. After some investigation, I found out that the rspec_on_rails plugin in my vendor directory was subclassing Autotest::Rspec and setting it’s own exceptions string like this:

def initialize
  super
  @exceptions = 
   %r%^\./(?:db|doc|log|public|script|vendor\/rails|previous_failures.txt)%
...

See the problem? It dutifully calls super so AutoTest:initialize can do it’s stuff (including calling my hook) and then wipes out the exception string with it’s own.

So, I browsed the lib/autotest.rb code and found another hook. Adding this to my ~/.autotest now lowers the cpu usage to about 5%. Huzzah!

Autotest.add_hook :run do |autotest|
  autotest.exceptions = Regexp.union(/^\.\/vendor/, autotest.exceptions)
end

8 Comments to “Autotest CPU Fix”

  1. Ryan Davis 7 January 2008 at 4:29 am #

    I should have communicated more and synchronized with Dave about the changes I made to @exceptions. sorry. We’ll both release something soon to get them back in sync and happier with each other.

  2. BrianC 11 January 2008 at 11:03 pm #

    Thanks for posting this. I noticed the same thing but vendor wasn’t my issue. I ran ‘find’ looking for a big chunk of files and found them in .git This is a project where I’m using git-svn. After adding .git to the exception CPU usage is down below 5%.

  3. th 16 January 2008 at 7:14 pm #

    Thanks! This helped me stop acts_as_solr from making autotest run in a continuous loop when the plugin log files were updated!

  4. austinfromboston 17 January 2008 at 4:39 pm #

    This was really helpful, thank you.

  5. KevinB 18 January 2008 at 7:27 pm #

    I have also noticed absurd CPU usage spikes with autotest. So I was happy to see this post. I upgraded ZenTest to 3.8.0 and put the updated code in my ~/.autotest and now get the following bustage:

    loading autotest/rails_rspec
    /usr/local/lib/ruby/gems/1.8/gems/ZenTest-3.8.0/lib/autotest.rb:515:in `add_exception’: exceptions already compiled (RuntimeError)

    Any ideas?

  6. KevinB 18 January 2008 at 8:03 pm #

    Needed to update rspec too – works like a charm.

    Thanks!

  7. scott 19 January 2008 at 4:12 pm #

    If you’re getting the “exceptions already compiled” error, you could try changing the hook to “Autotest.add_hook :initialize”. I didn’t need to do that, but both work.

  8. Zubin 26 February 2008 at 11:48 pm #

    After editing my ~/.autotest file as described, got this message when starting autotest:

    hook run has been deprecated, use initialize

    After making the change suggested by Scott (thanks!), the message disappeared.

    But it still ran slow, so I added more directories. Responds about 10 times faster now!

    Here’s what I did (some are probably already excluded by default):

    Autotest.add_hook :initialize do |autotest|
    autotest.add_exception(/^\.\/vendor/)
    autotest.add_exception(/^\.\/artwork/)
    autotest.add_exception(/^\.\/public/)
    autotest.add_exception(/^\.\/db/)
    autotest.add_exception(/^\.\/lib/)
    autotest.add_exception(/^\.\/tmp/)
    autotest.add_exception(/\.svn/)
    end


Leave a Reply