ruby - 在同一脚本中启动和调用 Ruby HTTP 服务器

标签 ruby multithreading events sinatra rack

我想知道如何启动 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/

相关文章:

c# - 锁定成本

javascript - Jquery:有没有办法在 anchor 标记的常规单击事件之前/之后附加单击事件

javascript - 如何监听双击jstree?

ruby-on-rails - 未检测到 Procfile,使用默认 Web 服务器 (webrick)

ruby - 无法让 google-appengine 让 Jruby 工作

ruby 代码 : why put colon in front of variable name (inside initialize method)

ruby-on-rails - 在 ubuntu 上安装 sqlite3 效果不好

linux - 一个进程的线程可以在多个物理 CPU 上运行?

c# - ASP.NET Core 中的 new Task 是如何利用依赖注入(inject)的?

wpf - WPF MVVM-在TreeViewItem中触发事件的最正确方法是什么