Pregunta

I would like to know to to pause a Root Fiber in ruby (if possible).

I have this Sinatra app, and I am making async calls to an external API with EventMachine. I don't want to respond to the client until the api responds me.

For example, sleeping the Root Fiber in Sinatra until the EventMachine callback wake it up.

Thanks.

¿Fue útil?

Solución

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

EDIT

In your case you should spawn a Fiber for each request. So. Firstly create Rack config file and add some magick:

# 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

Then your http Sinatra application:

# 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

Now you could run it under thin for example:

> thin start -R config.ru

Then if you will visit locakhost:3000 you'll see your Hello World message

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top