culerity icon indicating copy to clipboard operation
culerity copied to clipboard

IO.popen("script/server") makes the Rails app sad

Open SFEley opened this issue 15 years ago • 7 comments

So I've been using Culerity for my complex MongoDB-driven Rails app for a few days now. Love the concept. Love it -- I think it's the sanest Javascript Cucumber integration I've yet seen. (Granted, that's in a field of fairly insane competitors.) But I was having major problems keeping it up and running during my BDD cycle, especially when using autospec for automatic feature testing.

The behavior I saw was that it would run once just fine, and then on the second and subsequent runs I'd get a consistent error on every Celerity step:

NativeException: org.apache.commons.httpclient.NoHttpResponseException: The server localhost failed to respond (Culerity::CulerityException)

This happened on both Webrick and Thin. (I'm using Ruby 1.9 so Mongrel is out.) Thin was also throwing an interesting yet dramatic exception:

/opt/local/lib/ruby/gems/1.9.1/gems/thin-1.2.5/lib/thin/logging.rb:28:in `write': Broken pipe - <STDOUT> (Errno::EPIPE)

After a fair amount of experimentation and headbanging, I found the problem: both the Rake task and the Culerity steps' built-in $rails_server invocations are using IO.popen to start the Rails app. Which means that STDIN and STDOUT are both being captured and held by the Ruby process that invokes it. This makes sense for the Celerity server, which has to be communicated with; but the Rails server is just supposed to sit there. You never do anything with the IO object except retrieve its pid. This causes problems when the process that started it ends, leaving the Rails process orphaned with no input or output. (Hence the Broken pipe - <STDOUT> error I saw with Thin.)

The fix to this is really simple: use Kernel.spawn to start the Rails server. The spawn method returns immediately with the pid value, and doesn't interfere with the child's in/out in any way. For extra cleanness, use the -d option to script/server to detach its output and keep it from interfering with Cucumber output in that shell.

This seems to work fine in my own app, so I'll be forking Culerity right now and submitting this to you shortly as a pull request. While I'm at it, I'll set up Thin as a viable server option and address issue #16 about the pid file location. (Thin seems to solve some other problems I was having with Webrick in Culerity, possibly related to startup time or request speed.)

SFEley avatar Jan 10 '10 04:01 SFEley

awesome. i've had some occasional problems like you described but i never found the time to properly investigate. i will merge this immediately when you've pushed it.

langalex avatar Jan 11 '10 12:01 langalex

Is this issue still open? I'm having this problem and would like to confirm if still needs to be patched or I should investigate further...

raul avatar Feb 10 '10 19:02 raul

probably not, since mattmatt recently replaced popen with fork (Kernel.spawn seem to be ruby 1.9 only). have you tried the latest release? (0.2.8)

langalex avatar Feb 11 '10 09:02 langalex

I'm having what could be the same problem with ruby 1.9.2 using culerity 0.2.10 on a rails3 beta3 project. The celerity server throws a 500 error (different issue), but it bubbles up through culerity and then causes a Broken pipe - STDOUT.

sriedel avatar May 12 '10 06:05 sriedel

sounds like the process that runs the celerity server died.

langalex avatar May 12 '10 08:05 langalex

I forked and added a patch that fixes this issue for me (running jruby-1.5.0 and rails 2.3.5)

timfel avatar May 20 '10 12:05 timfel

that's great but why did you delete your repo before i could pull the patch?

langalex avatar May 20 '10 16:05 langalex