Script for starting a rails app, with some peculiarities I wanted to write a script, which starts a rails app, and opens it in the browser.
I'm trying to implement this in a peculiar way though - I expect two things:


the script must wait until the server is started, then open the browser within a short time
when I stop the script (Ctrl+C), the server process must stop.


The script I've written actually works, but I was wondering if there is a simplerr/more standard/more correct way of writing it.

The script is written for linux, but it's not meant to be platform specific - or more precisely, anything except Windows.

PROJECT_DIR          = '/path/to/app'
POLLING_TIME         = 0.1
SERVER_STARTED_REGEX = /WEBrick::HTTPServer#start/
BROWSER_COMMAND      = 'browser http://localhost:3000 &amp;'

Dir.chdir( PROJECT_DIR )

thread = Thread.new do
  IO.popen( 'script/rails server 2&gt;&amp;1' ) do | io |
    Thread.current[ :last_server_line ] = io.gets while true
  end
end

sleep POLLING_TIME while thread[ :last_server_line ] !~ SERVER_STARTED_REGEX

`#{ BROWSER_COMMAND }`

thread.join
This was an interesting one. Thank you :)

I dug around in the rails code and poked at webrick and rack for a while and this is what I came up with:

PROJECT_DIR     = ENV['PROJECT_DIR']     || '/path/to/app'
BROWSER_COMMAND = ENV['BROWSER_COMMAND'] || 'browser http://localhost:3000 &amp;'
PORT            = ENV['PORT'].to_i       || 3000

require "#{PROJECT_DIR}/config/environment.rb"

thread = Thread.new do
  Rack::Handler::WEBrick.run Rails.application, Port: PORT
end

`#{ BROWSER_COMMAND }`

Rack::Handler::WEBrick.shutdown

thread.join


This approach is actually borrowed from rack's webrick handler.

I load the environment prior to actually starting the webrick server making any waits unnecessary for me. If that should be necessary for you, I'm sure you could add it.

Then I pretty much stuck to what you did, putting the actual server into a thread. The Handler already provides that neat shutdown method.

Oh, I also took the liberty of adding some ENV variables so you can put this script into a file and run it from where ever you want.

EDIT: In the comments Marcus pointed out, that in order to resolve the timing issue, one can set the closure (block variable) from WEBrick.run {|server|} to a thread-local variable that can be polled afterwards.

There might also be ways to exploit Celluloid for messaging between the different threads.