Question

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.

Était-ce utile?

La solution

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top