I have a Sinatra Application enclosed in Sinatra::Base
and I\'d like to run some code once the server has started, how should I go about doing this?
Her
If you're using Rack (which you probably are) I just found out there's a function you can call in config.ru
(it's technically an instance method of Rack::Builder
) that lets you run a block of code after the server has been started. It's called warmup, and here's the documented usage example:
warmup do |app|
client = Rack::MockRequest.new(app)
client.get('/')
end
use SomeMiddleware
run MyApp
This is how I do it; basically running either sinatra or the other code in a separate thread:
require 'sinatra/base'
Thread.new {
sleep(1) until MyApp.settings.running?
p "this code executes after Sinatra server is started"
}
class MyApp < Sinatra::Application
# ... app code here ...
# start the server if ruby file executed directly
run! if app_file == $0
end
Using the configure block is not the correct way to do this. Whenever you load the file the commands will be run.
Try extending run!
require 'sinatra'
require 'launchy'
class MyServer < Sinatra::Base
def self.run!
Launchy.open("http://#{settings.host}:#{settings.port}/")
super
end
get '/' do
"My server"
end
end
The only valid answer in stackoverflow to this question (which is asked 3-4 times) is given by levinalex on Start and call Ruby HTTP server in the same script, and I quote:
run! in current Sinatra versions takes a block that is called when the app is started.
Using that callback you can do this:
require 'thread' def sinatra_run_wait(app, opts) queue = Queue.new thread = Thread.new do Thread.abort_on_exception = true app.run!(opts) do |server| queue.push("started") end end queue.pop # blocks until the run! callback runs end sinatra_run_wait(TestApp, :port => 3000, :server => 'webrick')
This seems to be reliable for WEBrick, but when using Thin the callback is still sometimes called a little bit before the server accepts connections.