0

I use an api, that is written on top of EM. This means that to make a call, I need to write something like the following:

EventMachine.run do
  api.query do |result|
    # Do stuff with result
  end
  EventMachine.stop
end

Works fine.

But now I want to use this same API within a Sinatra controller. I tried this:

get "/foo" do
  output = ""
  EventMachine.run do
    api.query do |result|
      output = "Result: #{result}"
    end
    EventMachine.stop
  end
  output
end

But this doesn't work. The run block is bypassed, so an empty response is returned and once stop is called, Sinatra shuts down.

Not sure if it's relevant, but my Sinatra app runs on Thin.

What am I doing wrong?

troelskn
  • 115,121
  • 27
  • 131
  • 155
  • [This post](http://stackoverflow.com/a/3007083/1177119) might be of some help to you. – Josh Voigts Dec 19 '12 at 17:03
  • see this post: http://stackoverflow.com/questions/2999430/any-success-with-sinatra-working-together-with-eventmachine-websockets – Poul May 01 '13 at 12:36

1 Answers1

0

I've found a workaround by busy waiting until data becomes available. Possibly not the best solution, but it works at least:

helpers do

  def wait_for(&block)
    while (return_val = block.call).nil?
      sleep(0.1)
    end
    return_val
  end

end

get "/foo" do
  output = nil
  EventMachine.run do
    api.query do |result|
      output = "Result: #{result}"
    end
  end
  wait_for { output }
end
troelskn
  • 115,121
  • 27
  • 131
  • 155
  • there are libraries for asynchronous request processing in Sinatra. for example https://github.com/raggi/async_sinatra. here is my post on a related subject: http://stackoverflow.com/questions/14993386/async-requests-using-sinatra-streaming-api – akonsu May 25 '13 at 05:05