Execute code once Sinatra server is running

时光怂恿深爱的人放手 提交于 2019-12-19 17:44:42

问题


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("http://#{settings.host}:#{settings.port}/")
  end
end

Any ideas?


回答1:


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



回答2:


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



回答3:


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



回答4:


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.



来源:https://stackoverflow.com/questions/2589356/execute-code-once-sinatra-server-is-running

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!