使用Sinatra和EventMachine在相同的长时间运行操作上发出多个http请求

时间:2012-07-30 15:58:25

标签: asynchronous concurrency sinatra httprequest eventmachine

我正在尝试了解如何使用异步sinatra和EventMachine的组合来使用公平的Web服务器。

在下面的代码中,'/'上的每个请求都会为google生成一个新的异步http请求。是否有一个优雅的解决方案来检测请求是否已在进行并等待其执行?

如果我在'/'上有100个并发请求,则会向Google后端生成100个请求。最好有一种方法来检测已经存在正在进行的后端请求并等待其执行。

感谢您的回答。

require 'sinatra'
require 'json'
require 'eventmachine'
require 'em-http-request'
require 'sinatra/async'


Sinatra.register Sinatra::Async

def get_data
  puts "Start request"
  http = EventMachine::HttpRequest.new("http://www.google.com").get
  http.callback { 
    puts "Request completed"
    yield http.response
  }
end

aget '/' do
  get_data {|data| body data}
end

更新

我实际上发现你可以在同一个http请求中添加几个回调。因此,它很容易实现:

class Request
  def get_data
    if !@http || @http.response_header.status != 0
      #puts "Creating new request"
      @http = EventMachine::HttpRequest.new("http://www.bbc.com").get
    end
    #puts "Adding callback"
    @http.callback do 
      #puts "Request completed"
      yield @http.response
    end
  end
end

$req = Request.new

aget '/' do
  $req.get_data {|data| body data}
end

这每秒提供非常多的请求。酷!

1 个答案:

答案 0 :(得分:1)

你根本不需要使用sinatra / async来实现它,只需使用一个事务服务器(Thin,Rainbows!,Goliath)运行它。

查看em-synchrony以获取多个并行请求的示例,而不引入意大利面条回调代码:

require "em-synchrony"
require "em-synchrony/em-http"

EventMachine.synchrony do
  multi = EventMachine::Synchrony::Multi.new
  multi.add :a, EventMachine::HttpRequest.new("http://www.postrank.com").aget
  multi.add :b, EventMachine::HttpRequest.new("http://www.postrank.com").apost
  res = multi.perform

  p "Look ma, no callbacks, and parallel HTTP requests!"
  p res

  EventMachine.stop
end

是的,你可以在你的Sinatra行动中运行它。

另请查看Faraday,特别是使用EM适配器。