e.g. to get credentials to each OpenStack computing region • Concurrent HTTP requests from the app, e.g. to combine information from different microservices Challenges
is based on unicorn, but designed to handle applications that expect long request/response times and/or slow clients. For network concurrency, models we currently support are: • EventMachine • FiberPool • ThreadPool • etc. rainbows http://rainbows.bogomips.org/
for reducing HTTP overhead by combining requests. sequential – option to execute all operations sequentially, rather than in parallel. This parameter is currently REQUIRED and must be set to true. (In the future the Batch API will offer parallel processing for thread-safe apps, and hence this parameter must be supplied in order to explicitly preserve expected behavior.) batch_api https://github.com/arsduo/batch_api
provides event-driven I/O using the Reactor pattern, much like Node.js. Pros: • Good performance for networked apps (web server, proxy) • No memory overhead per connection • No threaded programming eventmachine https://github.com/eventmachine/eventmachine
+ 10k(C++) vs 6k LOC in Celluloid • Hard to debug complex systems: errors, callbacks • Work done per tick should be small • Lack of good and supported libraries around EM eventmachine
the Rack::FiberPool middleware • Adds em-http-request to do concurrent HTTP calls • Patches TCPSocket via EM-Synchrony • Patches Rack::Test to run tests within an EventMachine • Patches Resolv via em-resolv-replace sinatra-synchrony https://github.com/kyledrake/sinatra-synchrony
the Rack::FiberPool middleware • Adds em-http-request to do concurrent HTTP calls • Patches TCPSocket via EM-Synchrony • Patches Rack::Test to run tests within an EventMachine • Patches Resolv via em-resolv-replace sinatra-synchrony https://github.com/kyledrake/sinatra-synchrony
Since then, I’ve changed my mind. Ruby developers need to stop using EventMachine. It’s the wrong direction. sinatra-synchrony http://www.slideshare.net/KyleDrake/hybrid-concurrency-patterns
Angelo, which is similar to Sinatra but uses Celluloid, Celluloid::IO, Reel, and doesn't compromise real threads or require stupid EM monkey patches. This is a way, way, way better solution than sinatra-synchrony, rack, or EM will ever be. I will not be maintaining this gem anymore. If anyone is interested in maintaining it, feel free to inquire, but I recommend not using EventMachine or sinatra- synchrony anymore. sinatra-synchrony https://github.com/kyledrake/sinatra-synchrony
use • Processes Cons: • No master process and forks • No dashboards • No plugins • Uses Timeout delayed_job https://github.com/collectiveidea/delayed_job
on literally any line. That's not even possible. So Thread.raise is basically like a sneak attack on your code that could result in almost anything. It would probably be okay if it were pure-functional code that did not modify any state. But this is Ruby, so that's unlikely :) Why Ruby’s Timeout is dangerous http://jvns.ca/blog/2015/11/27/why-rubys-timeout-is-dangerous-and-thread-dot-raise-is-terrifying/
other EMish dependencies • Use Puma to survive under high load • Use Curb / Typhoeus to make concurrent HTTP requests • Contribute to open source ;) Solutions
application thread waits on I/O. If, for example, your application is waiting for an HTTP response from a payments provider, Puma can still accept requests in the Reactor thread or even complete other requests in different application threads. Puma has a "clustered" mode, where it combines its multi- threaded model with Unicorn's multi-process model. In clustered mode, then, Puma can deal with slow requests (thanks to a separate master process whose responsibility it is to download requests and pass them on) and slow application responses (thanks to spawning multiple workers). puma https://www.nateberkopec.com/2015/07/29/scaling-ruby-apps-to-1000-rpm.html