# 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:

1. the script must wait until the server is started, then open the browser within a short time
2. 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 &'

Dir.chdir( PROJECT_DIR )

IO.popen( 'script/rails server 2>&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 }


• Do you mean what anybody will edit you post, with better script, or make an answer below? – Малъ Скрылевъ Nov 5 '13 at 15:03
• @majioa It's best to use the answer feature, so that others have the chance to see the original question and provide answers of their own. – CMW Nov 5 '13 at 20:13

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 &'
PORT            = ENV['PORT'].to_i       || 3000

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

Rack::Handler::WEBrick.run Rails.application, Port: PORT
end

#{ BROWSER_COMMAND }

Rack::Handler::WEBrick.shutdown



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.

• The logic is appropriate, but there is a bug! The completion of the application start is asynchronous, so that the browser starts before actually something is listening on the port. In addition to that, the webrick shutdown raises an error if the app is not fully started! – Marcus Nov 16 '13 at 15:17
• I've actually found a workaround - the WEBrick.run {|server|} variable can be stored in the thread local storage. immediately afterwards, it can be polled at intervals, until it's not nil. at that point, the server is ready. – Marcus Nov 16 '13 at 15:25
• Yeah, I mentioned that one in my answer. It was not necessary for me since my browser took a while to start and the server was ready by then. Glad you managed to figure it out. – CMW Nov 16 '13 at 20:27