2011-07-02 60 views
1

我想知道如何启动一个Ruby Rack应用程序(如Sinatra)并在同一脚本中使用Net :: HTTP或类似名称调用它。我可以做类似的东西...启动并在同一脚本中调用Ruby 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!' 

...但它不觉得最佳睡眠两秒钟,等待瘦开始。我需要的是当服务器启动或有人提出任何其他建议时的某种回调?

+0

[Execute code once Sinatra server running]可能重复(http://stackoverflow.com/questions/2589356/execute-code-once-sinatra-server-is-running) –

回答

2

我会用旗语(参见Ruby Semaphores?)与此任务的能力1:

主线程:

  1. 采集信号
  2. 产生新的线程
  3. 获取信号(将阻塞直到被产生的线程释放)

产生web服务器线程:

  1. App.run!
  2. 释放信号
+0

这并不能解决任何问题,因为'跑!'块。信号量永远不会在派生的服务器线程上释放。 –

4

如果您在base.rb看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是真的,你可以安全地做你的东西。


编辑:改进版本,有一点猴子修补善良。
添加一个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 
4

run! in current Sinatra versions需要时,应用程序启动时调用块。

使用回调,你可以这样做:

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') 

这似乎是可靠的WEBrick,但使用薄时,回调仍然是有时被称为一点点服务器接受连接之前。

+0

互联网上唯一有效的答案。 –

+0

如果'跑!'抛出,不是这个僵局? 'queue.pop'将永远等待。如何实现超时,如下所示:https://spin.atomicobject.com/2014/07/07/ruby-queue-pop-timeout/ –

相关问题