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.
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