Skip to content

Instantly share code, notes, and snippets.

@valpackett
Last active December 19, 2015 09:09
Show Gist options
  • Save valpackett/5930513 to your computer and use it in GitHub Desktop.
Save valpackett/5930513 to your computer and use it in GitHub Desktop.
Ruby: async & thread pool under one EventMachine server

Imagine if you could run a synchronous Rack app (maybe Rails) on a thread pool and an asynchronous one under one server? Celluloid to the rescue!

In this example, both sync and async versions have (almost) equal concurrency under siege -b (running on Rubinius).

require 'celluloid/autostart'
SIMULATED_TIME = 0.2
PAYLOAD = [200, {'Content-Type' => 'text/plain'}, ['Hello']]
class SyncApp
def call(env)
sleep SIMULATED_TIME
PAYLOAD
end
end
class AsyncApp
def call(env)
EM.add_timer(SIMULATED_TIME) do
env['async.callback'].call PAYLOAD
end
throw :async
end
end
class SyncAppCell < SyncApp
include Celluloid
def call(env)
env['async.callback'].call super(env)
end
end
sac_pool = SyncAppCell.pool size: 16
map '/sync' do
run lambda { |env|
sac_pool.async.call env
throw :async
}
end
map '/async' do
run AsyncApp.new
end
source 'http://rubygems.org'
gem 'thin'
gem 'celluloid'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment