我想知道如何启动 Ruby Rack 应用程序(例如 Sinatra)并在同一脚本中使用 Net::HTTP 或类似的方式调用它。当然我可以做类似...
require 'sinatra/base'
require 'net/http'
t = Thread.new do
class App < Sinatra::Base
get '/' do
'Hi!'
end
end
App.run! :host => 'localhost', :port => 1234
end
sleep 2
puts Net::HTTP.start('localhost', 1234) { |http| http.get('/') }.body
t.join
puts 'Bye!'
...但是睡两秒钟,等待 Thin 开始,感觉不是最佳选择。我需要的是服务器启动时的某种回调,或者有人有任何其他建议吗?
最佳答案
如果您查看 base.rb 中 sinatra 源代码中的 run!
方法,您将看到:
def run!(options={})
...
handler.run self, :Host => bind, :Port => port do |server|
[:INT, :TERM].each { |sig| trap(sig) { quit!(server, handler_name) } }
set :running, true
end
...
end
这里无法附加回调。但!如您所见,一旦服务器启动,:running
设置就会更改。
因此,简单的解决方案似乎是在一个小的轮询循环中(每隔 500 毫秒或类似的时间)让一个线程监视 App.settings.running
。一旦 running
为真,您就可以安全地做您的事情了。
编辑:改进的版本,带有一点猴子修补的优点。
向 Sinatra 添加 after_running 回调:
class Sinatra::Base
# Redefine the 'running' setting to support a threaded callback
def self.running=(isup)
metadef(:running, &Proc.new{isup})
return if !defined?(after_running)
return if !isup
Thread.new do
Thread.pass
after_running
end
end
end
class App < Sinatra::Base
set :after_running, lambda {
puts "We're up!"
puts Net::HTTP.start('localhost', 1234) { |http| http.get('/') }.body
puts "Done"
}
get '/' do
'Hi!'
end
end
App.run! :host => "localhost", :port => 1234
关于ruby - 在同一脚本中启动和调用 Ruby HTTP 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6557079/