Skip to content

Silent failure after re-evaluating Guardfile #166

Closed
dgutov opened this Issue Oct 16, 2011 · 18 comments

5 participants

@dgutov
dgutov commented Oct 16, 2011

I'm running virtualized Ubuntu on Win7 host, the working directory is mounted with vboxsf driver.

If I edit Guardfile while guard is running, it prints

Ignoring paths: public
Guardfile has been re-evaluated.

and then stops running the current guards.
Commands p, r and q work as expected, but hitting return doesn't do anything anymore, neither does editing any of the watched files.

If I quit it like that, guard-spork leaves the spork process running. The problem could be on its side, but the related issue is supposedly fixed.

Gemfile:

group :test do
  gem 'spork', '~> 0.9.0.rc'
  gem 'spork-testunit'
  gem 'mocha'
  gem 'guard-spork'
  gem 'guard-test'
end

Guardfile:

ignore_paths 'public'

guard 'spork', :wait => 30, :notification => true do
  watch('config/application.rb')
  watch('config/environment.rb')
  watch('config/routes.rb')
  watch(%r{^config/environments/.*\.rb$})
  watch(%r{^config/initializers/.*\.rb$})
  watch('Gemfile')
  watch('Gemfile.lock')
  watch('test/test_helper.rb')
end

guard :test, :drb => true do
  watch(%r{^lib/(.+)/([^/]+)\.rb$}) { |m| "test/#{m[1]}/#{m[2]}_test.rb" }
  { "models" => "unit", "controllers" => "functional" }.each do |cs, ts|
    watch(%r{^app/#{cs}/([^/]+)\.rb$}) { |m| "test/#{ts}/#{m[1]}_test.rb" }
  end
  watch(%r{^test/(.+)/.*test_case\.rb}) { |m| "test/#{m[1]}" }
  watch(%r{^test/.*test\.rb})
end
@thibaudgg
Guard member

Please can you try to launch guard with the debug option bundle exec guard -d and give the complete output. Thanks

@dgutov
dgutov commented Oct 16, 2011

Sure.

$ bundle exec guard -d
Please install rb-inotify gem for Linux inotify support
Using polling (Please help us to support your system better than that).
Please install libnotify gem for Linux notification support and add it to your Gemfile
Ignoring paths: public
Guard is now watching at '(...)'
DEBUG (22:57:06): Hook :start_begin executed for Guard::Spork
DEBUG (22:57:06): Killing Spork servers with PID: 
Starting Spork for Test::Unit 
DEBUG (22:57:06): Spawned Spork server 10251 ('bundle exec spork testunit -p 8988')
Using TestUnit
Preloading Rails environment
Loading Spork.prefork block...
Spork is ready and listening on 8988!
Spork server for Test::Unit successfully started
DEBUG (22:57:19): Hook :start_end executed for Guard::Spork
DEBUG (22:57:19): Hook :start_begin executed for Guard::Test
Guard::Test 0.4.0 is running, with Test::Unit 2.4.0!
Running all tests
Using testdrb to run the tests
DEBUG (22:57:19): Command execution: testdrb -Itest (...)
Running tests with args ["-Itest", (...)]...
Specify ruby-prof as application's dependency in Gemfile to run benchmarks.
Loaded suite [(...)]
Started
PP

Finished in 5.831700728 seconds.

52 tests, 242 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
0% passed

8.92 tests/s, 41.50 assertions/s

Pending Cases:
(...)
Done.

DEBUG (22:57:28): Hook :start_end executed for Guard::Test
Ignoring paths: public
Guardfile has been re-evaluated.

After that, nothing.
I censored the output a bit, since I don't think the repo location and the test file paths can be of any help.

@thibaudgg
Guard member

Can you add rb-inotify & libnotify in your development group in your Gemfile and move guard-spork & guard-test in that one too. Maybe it's an issue with the polling listener, but that's weird.

@dgutov
dgutov commented Oct 17, 2011

rb-inotify doesn't make much of a difference, except looks like it's ignoring the ignore_paths instruction:

/home/gutov/.rvm/gems/ruby-1.9.2-p180/gems/rb-inotify-0.8.8/lib/rb-inotify/watcher.rb:80:in `initialize': No space left on device - Failed to watch "/home/gutov/docs/Ruby/estate/public/system/images/000/003/561": The user limit on the total number of inotify watches was reached or the kernel failed to allocate a needed resource. (Errno::ENOSPC)

As soon as I moved the public/system directory out of the way and rebooted(!) the machine, it worked just like before, with the same problem.
libnotify works as expected, it's just more or less useless to me, since guard-test doesn't support it in Drb mode.

@thibaudgg
Guard member

And if you try without guard-spork or guard-rspec you got the same issue?
And it's only happens when you edit the Guardfile right? Otherwise it works fine?

@dgutov
dgutov commented Oct 17, 2011

Commented them out, tried guard-shell with ctags example -- same issue.

It works fine otherwise, yes.

@netzpirat

You can change the maximum number of allowed inotify watches:

echo 16384 > /proc/sys/fs/inotify/max_user_watches

The above for example doubles the allowed watches.

@dgutov
dgutov commented Oct 17, 2011

Thanks, but that's not the issue here.

@dyfrgi
dyfrgi commented Oct 18, 2011

I am having this same problem on the current 0.8.6 release. I wonder if there is anyone for whom this is a regression - if so, git-bisect could find the bug.

@netzpirat

Why not just start the debugger and tell us what's happening? It's hard to debug something that cannot be clearly reproduced.

@dyfrgi
dyfrgi commented Oct 18, 2011

I get roughly the same output as dgutov.

Guard is now watching at '/home/dyfrgi/work/tendril/energize'
DEBUG (14:50:16): Hook :start_begin executed for Guard::Spork
DEBUG (14:50:16): Command execution: ps aux | awk '/spork/&&!/awk/{print $2;}'
DEBUG (14:50:16): Killing Spork servers with PID: 
DEBUG (14:50:16): Command execution: ps aux | awk '/spork/&&!/awk/{print $2;}'
Starting Spork for RSpec & Cucumber 
DEBUG (14:50:16): Spawned Spork server 13778 ('bundle exec spork -p 8989')
DEBUG (14:50:16): Command execution: ps aux | awk '/spork/&&!/awk/{print $2;}'
DEBUG (14:50:16): Spawned Spork server 13786 ('bundle exec spork cu -p 8990')
Using RSpec
Preloading Rails environment
Using Cucumber
Preloading Rails environment
/home/dyfrgi/.rvm/gems/ruby-1.9.2-p290@energize/gems/rack-1.3.4/lib/rack/backports/uri/common_192.rb:53: warning: already initialized constant WFKV_
/home/dyfrgi/.rvm/gems/ruby-1.9.2-p290@energize/gems/rack-1.3.4/lib/rack/backports/uri/common_192.rb:53: warning: already initialized constant WFKV_
Loading Spork.prefork block...
Loading Spork.prefork block...
Spork is ready and listening on 8989!
Spork is ready and listening on 8990!
Spork server for RSpec & Cucumber successfully started
DEBUG (14:51:13): Hook :start_end executed for Guard::Spork
DEBUG (14:51:13): Hook :start_begin executed for Guard::RSpec
Guard::RSpec is running, with RSpec 2!
DEBUG (14:51:13): Hook :start_end executed for Guard::RSpec
DEBUG (14:51:13): Hook :start_begin executed for Guard::Cucumber
DEBUG (14:51:13): Hook :start_end executed for Guard::Cucumber
Guardfile has been re-evaluated.

And then nothing, regardless of input.

@netzpirat

Good news! @dyfrgi was kind enough to create a reproducible test case, available as Git repository: https://github.com/dyfrgi/Guard-Broken

Wow. Thanks a lot. Making it reproducible fixes half of the bug. I will take care of it tomorrow.

@rymai
Guard member
rymai commented Oct 18, 2011

Hey guys, I've just found the issue. It's fixed, thanks for the report and the "broken-guard" script @dyfrgi! ;)

I'll push and release a new version once all is green.

@rymai rymai pushed a commit that closed this issue Oct 18, 2011
Rémy Coutable Fix #166: Silent failure after re-evaluating Guardfile. caaada6
@rymai rymai closed this in caaada6 Oct 18, 2011
@dgutov
dgutov commented Oct 18, 2011

Great. Thanks for fixing!

@rymai
Guard member
rymai commented Oct 18, 2011

A quick explanation:

When the Guardfile is evaluated, each guard is given the group in which it is defined, or :default if the guard is not in a group block. Note that you couldn't see the issue happening if all your guards were declared in named groups (that was my case for instance).

On Guard.setup, the @groups variable is set to [Group.new(:default)] so when Guard run the reload method for instance (with no specific group given to run the task) it is taking all the groups in @groups (including the :default group) and run the task for all the guards in each group.

But when the Guardfile was re-evaluated, in Guard::Dsl.reevaluate_guardfile we were clearing the @groups variable so the next time Guard was running reload (with no specific group given to run the task), @groups was missing the :default group so it was running the task only for the named groups (the one declared explicitly in the Guardfile).

Hope I was clear enough. :)

@rymai
Guard member
rymai commented Oct 18, 2011

You're welcome, you can now grab the 0.8.7.

@netzpirat

Great explanation and fix! Thanks all.

@thibaudgg
Guard member

Nice catch and fix. Thanks all!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.