You have an issue right now. By running EventMachine, you are blocking Ruby's ability to do concurrent IO using Thread, which means that you've reduced the entire ruby infrastructure (except the EM async code style that nobody programs for anymore) to a single blocking IO thread, dependent on 10-15k+ lines of awful C code that haven't been under active development in over four years, which breaks the premise of ruby's synchronous development methodology, is extremely difficult to debug, and which everyone agrees (including the maintainers) needs to be obsoleted.
Indeed, there are a few maintainers on EM, for the sole purpose of preventing it from breaking every single time the ruby team releases an update, because if it broke, it would cause a problem with legacy code in the ruby space. If the EM maintainers walked away, Coinbase would be stuck on an old version of ruby until they themselves patched EM to solve it. EventMachine is not something people should be basing new projects on, especially projects that involve money.
Tony Arcieri wrote nio4r (https://github.com/celluloid/nio4r), which solves this problem in a far better way, and then used it to implement cellluloid-io (https://github.com/celluloid/celluloid-io), which doesn't choke ruby's ability to do concurrent IO using it's internal threading mechanism. Combined with JRuby, you get even more than concurrent IO here like with MRI, you can also get real threading, which is important in a space where CPUs aren't getting faster, they're getting more parallel. Node.js has the same problem, but unlike Ruby/EM, JavaScript is actually designed to be async, so at least everything is designed to expect it.
Because Sinatra (like all non-EM ruby code) uses the threading style for concurrency, as soon as you start running EventMachine, everything will block for a single request, even if it's slow IO bound. You can demonstrate this very easily by putting this into the code:
get '/blocking' do
sleep(10)
end
get '/notblocking' do
'ok'
end
Hit /blocking with curl, and then hit /nonblocking with a second curl command. The second request is blocked until the first one completes. Now try the same thing without eventmachine, and it serves the second request concurrently without a problem. That's what you lose in this exchange, and it's a big thing to lose. I'm using sleep here, but the same blocking will occur for database queries, remote cache hits, HTTPS requests (to get things like, say, the exchange rate), everything involving IO.
The only way to get around this problem and still use ruby synchronously is to resort to crazy hacks, including a fairly popular project I created a while ago called sinatra-synchrony (https://github.com/kyledrake/sinatra-synchrony), which wraps async code using fibers. But in order for that to work, every library you're using has to support it, so this path would require a massive refactor of the entire ruby ecosystem, and that's simply not going to happen. It's also incredibly difficult to debug, and there's a lot of bugs with EM - sometimes things would just lock up or segfault, or ruby would spit out an error stack that had nothing to do with the actual exception that occurred.
I tried very politely to explain this problem to Coinbase about two years ago during an interview, and their reaction was to ask about my college degree, give me a bunch of weird whiteboard problems that had nothing to do with actual programming, and then show me the door, one day after I helped fix all of their client libraries when they switched SSL CA providers and didn't even realize it, and then provided a pull request to coinbase-ruby providing concurrency support using this very same threading mechanism, on the two-hour flight there (proof: https://github.com/coinbase/coinbase-ruby/pull/6)