2

我想知道在红宝石中暂停根纤维(如果可能的话)。

我有这个 Sinatra 应用程序,我正在使用 EventMachine 对外部 API 进行异步调用。在 api 响应我之前,我不想响应客户端。

例如,在 Sinatra 中休眠 Root Fiber,直到 EventMachine 回调将其唤醒。

谢谢。

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

编辑

在您的情况下,您应该为每个请求生成一个 Fiber。所以。首先创建 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 回答