diff --git a/lib/spring/application_manager.rb b/lib/spring/application_manager.rb index ca4671fb..ae9795ac 100644 --- a/lib/spring/application_manager.rb +++ b/lib/spring/application_manager.rb @@ -32,7 +32,11 @@ def restart end def alive? - @pid + return false if @pid.nil? + Process.getpgid(@pid) + true + rescue Errno::ESRCH + false end def with_child @@ -109,10 +113,24 @@ def start_child(preload = false) ) end - start_wait_thread(pid, child) if child.gets + wait_for_child_to_boot + start_wait_thread(pid, child) + rescue => e + log "error while starting child: #{e.message}" + abort("error while starting child: #{e.message}") + ensure child_socket.close end + def wait_for_child_to_boot + timeout = 1 + loop do + break if IO.select([child], nil, nil, timeout) + raise "child has exited unexpectedly" unless alive? + end + child.gets + end + def start_wait_thread(pid, child) Process.detach(pid) diff --git a/lib/spring/test/acceptance_test.rb b/lib/spring/test/acceptance_test.rb index c3da1ce7..a6def602 100644 --- a/lib/spring/test/acceptance_test.rb +++ b/lib/spring/test/acceptance_test.rb @@ -194,6 +194,23 @@ def self.omg assert_success app.spring_test_command end + test "deleting the app root should kill the server" do + app.run app.spring_test_command + assert spring_env.server_running?, "The server should be running but it isn't" + FileUtils.rm_rf(app.root) + sleep 2 # wait for the watcher to notice and react + assert !spring_env.server_running?, "The server should not be running but it is" + end + + test "server restarts when the app root is deleted and recreated" do + assert_success app.spring_test_command + FileUtils.rm_rf(app.root) + sleep 1 # wait for the watcher to notice and react + + generator.copy_to(app.root) + assert_success app.spring_test_command + end + test "stop command kills server" do app.run app.spring_test_command assert spring_env.server_running?, "The server should be running but it isn't"