2013-11-11 9 views
2

Я хотел бы знать, чтобы приостановить корневое волокно в рубине (если возможно).Sinatra + Fibers + EventMachine

У меня есть это приложение Sinatra, и я делаю асинхронные вызовы внешнему API с EventMachine. Я не хочу отвечать клиенту, пока апи не ответит мне.

Например, спящее корневое волокно в Синатре до тех пор, пока обратный вызов EventMachine не разбудит его.

Спасибо.

ответ

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 

EDIT

В вашем случае вы должны порождать Волокно для каждого запроса. Так. Во-первых, создать 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 Синатра приложение:

# 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

+0

Это точно что я говорю о @ fl00r. Вы не можете уступить корневое волокно. Получение этой ошибки «не может быть получено из корневого волокна». – Ron

+0

Рон, понял. Смотрите мое обновление – fl00r

+0

Спасибо @ fl00r, вы дали хороший старт. Но я читал, и я не совсем понимаю кое-что. Прежде всего, это не лучший подход, не так ли? потому что, если вы получите 1000 запросов, он создаст 1000 волокон. Во всяком случае, самый важный вопрос: когда бросаете: асинхронно, волокно ждет? или вы можете получить новый запрос? потому что второе - ожидаемое поведение, но этого не происходит. Благодарю. – Ron