开发者

Execute code once Sinatra server is running

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?

Here's an example:

require 'sinatra'
require 'launchy'

class MyServer < Sinatra::Base
  get '/' do
    "My server"
  end

  # This is the bit I'm not sure how to do
  after_server_running do
    # Launches a browser with this webapp in it upon server start
    Launchy.open("ht开发者_如何转开发tp://#{settings.host}:#{settings.port}/")
  end
end

Any ideas?


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


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


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜