2012-09-21 60 views
1

我想了解如何使用各种非阻塞IO库在Ruby和使用西纳特拉做了一个简单的应用程序,用于测试没有性能比较收益,使用EM-HTTP请求

# proxy.rb 
require 'bundler/setup' 
require 'sinatra/base' 
require 'sinatra/synchrony' 
require 'faraday' 

class ProxyApp < Sinatra::Base 
    register Sinatra::Synchrony 

    get "/proxy" do 
    conn = Faraday.new("http://mirror.yandex.ru") do |faraday| 
     faraday.use Faraday::Adapter::EMSynchrony 
    end 
    conn.get "/ubuntu-releases/precise/ubuntu-12.04.1-alternate-i386.iso" 
    "Hello, world" 
    end 

    get "/" do 
    "Hello, world" 
    end 
end 

至于我知道,使用非阻塞IO下载文件应该允许执行其他请求,但它不会 - 如果我使用ab打开/proxy路径(我正在使用Thin作为应用服务器),请求/需要很长一段时间。难道我做错了什么?

回答

2

Sinatra :: Synchrony?为什么?

config.ru:

require File.join Dir.pwd, 'proxy.rb' 
run Proxy 

的Gemfile:

source 'https://rubygems.org' 

gem 'sinatra' 
gem 'thin' 
gem 'faraday' 
gem 'em-synchrony' 
gem 'em-http-request' 
gem 'rack-fiber_pool' 

proxy.rb:

require 'bundler' 
Bundler.require 

class Proxy < Sinatra::Base 
    use Rack::FiberPool 

    get "/proxy" do 
    conn = Faraday.new("http://mirror.yandex.ru") do |faraday| 
     faraday.use Faraday::Adapter::EMSynchrony 
    end 
    conn.get "/ubuntu-releases/precise/ubuntu-12.04.1-alternate-i386.iso" 
    "Hello, world" 
    end 

    get "/" do 
    "Hello, world" 
    end 
end 

开始:

thin start -d 
wget localhost:3000/proxy 

在另一端:

wget localhost:3000/ 

回答是直接为/,不管有多少请求/代理你parrallel做。

+0

我看到了ilya的帖子,关于解开代码。但是,你能解释一下,为什么它在这种特殊情况下起作用?它会在'con.get'内通过调用yield来暂停当前的EM光纤吗?为什么我不必把它放到'EM.snynchrony do'块中呢? –

+1

@ dre-hh正确。它产生[EMSynchrony]深处的某处(https://github.com/igrigorik/em-synchrony/blob/master/lib/em-synchrony/em-http.rb)。你只执行一个请求,所以'do'块是可选的。我怀疑它也可以使用'Faraday :: Adapter :: EMHttp'。并且放弃'Rack :: FiberPool',对它有一些不好的经验。 –