2

async 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 秒あたりの要求数が非常に多くなります。涼しい!

4

1 に答える 1

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 アクション内で実行できます。

また、特にEMアダプターを使用したFaradayもご覧ください。

于 2012-08-12T01:51:10.737 に答える