2

ルビーでルートファイバーを一時停止する方法を知りたいです(可能であれば)。

この Sinatra アプリがあり、EventMachine を使用して外部 API への非同期呼び出しを行っています。API が応答するまで、クライアントに応答したくありません。

たとえば、EventMachine コールバックが起動するまで Sinatra でルート ファイバーをスリープ状態にします。

ありがとう。

4

1 に答える 1

2
get '/some/route/' do
  fib = Fiber.current
  req = EM::SomeNonBlokingLib.request
  req.callback do |response|
    fib.resume(response)
  end
  req.errback do |err|
    fib.resume(err)
  end
  Fiber.yield
end

編集

あなたの場合、リクエストごとにファイバーを生成する必要があります。そう。最初に Rack 設定ファイルを作成し、マジックを追加します。

# config.ru
BOOT_PATH = File.expand_path('../http.rb',  __FILE__)
require BOOT_PATH

class FiberSpawn
  def initialize(app)
    @app = app
  end

  def call(env)
    fib = Fiber.new do
      res = @app.call(env)
      env['async.callback'].call(res)
    end
    EM.next_tick{ fib.resume }
    throw :async
  end
end

use FiberSpawn
run Http

次に、http Sinatra アプリケーション:

# http.rb
require 'sinatra'
require 'fiber'

class Http < Sinatra::Base
  get '/' do
    f = Fiber.current
    EM.add_timer(1) do
      f.resume("Hello World")
    end
    Fiber.yield
  end
end

thinたとえば、次のように実行できます。

> thin start -R config.ru

その後、あなたが訪問locakhost:3000する場合は、あなたのHello Worldメッセージが表示されます

于 2013-11-19T10:22:18.360 に答える