Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

webkit_server hangs periodically when run from Capybara in Ruby

I am having a problem where an instance of webkit_server with Capybara and capybara-webkit running headless connected to a local Xvfb screen hangs when visiting a URL. It seems to happen after several minutes of repeatedly visiting different URLs and executing finders. (I'm using capybara for a screen scraping application in vanilla Ruby, not for testing.)

I've confirmed that when it hangs the site is still accessible (for example, through curl or wget on the command line). I've also tried wrapping the Ruby code that invokes the visit and subsequent finders in a Timeout block so that after 60 seconds of waiting a new URL is visited, but any visit() attempt fails after the first time this occurs. The only way to fix the problem is to kill both the Ruby process invoking Capybara/capybara-webkit and the webkit_server process and restart.

When I strace the webkit_server process, I see output like this repeatedly:

clock_gettime(CLOCK_MONOTONIC, {5821, 680279627}) = 0
gettimeofday({1330890176, 712033}, {0, 33052112}) = 0
gettimeofday({1330890176, 712087}, {0, 140736435864256}) = 0
gettimeofday({1330890176, 712137}, {0, 33108640}) = 0
clock_gettime(CLOCK_MONOTONIC, {5821, 680486036}) = 0
clock_gettime(CLOCK_MONOTONIC, {5821, 680530091}) = 0
read(7, 0x1fac1b4, 4096)                = -1 EAGAIN (Resource temporarily unavailable)

And if I strace the Ruby process that invokes it, it is hung on a read():

Process 3331 attached - interrupt to quit
read(5, 
^C <unfinished ...>
Process 3331 detached

I know that the Ruby code hangs on the Capybara visit() method.

Any ideas on what I can do to troubleshoot or correct this is appreciated. I'm assuming the problem has something to do with some resource webkit_server needs to visit the URL but am not sure what to try next.

Thanks!

like image 267
Chris Hart Avatar asked Mar 04 '12 21:03

Chris Hart


3 Answers

The capybara-webkit 1.0 randomly hangs on entire suite for me as well.

Simply adding 'thin' was not enough. But explicit use of Thin handler worked. Added to env.rb:

Capybara.server do |app, port|
  require 'rack/handler/thin'
  Rack::Handler::Thin.run(app, :Port => port)
end

Note Thin usage warning: https://github.com/thoughtbot/capybara-webkit/issues/399#issuecomment-22328028

like image 165
Grimmo Avatar answered Nov 07 '22 09:11

Grimmo


I've found that calling Capybara.reset_sessions! after an error seems to correct this problem. I'm not sure why, but I haven't had the problem since.

like image 39
Chris Hart Avatar answered Nov 07 '22 10:11

Chris Hart


I've seen this problem when Capybara is using Webrick to run the server. Add "gem 'thin'" to your Gemfile & it will automatically use that instead. See if that helps?

like image 35
Jonathan del Strother Avatar answered Nov 07 '22 10:11

Jonathan del Strother