2012-09-21 63 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',對它有一些不好的經驗。 –