Goliath ... a tiny GIANT

Traditional web servers

The IO issue
- L1-cache3 cycles
- L2-cache14 cycles
- RAM250 cycles
- Disk41 000 000 cycles
- Network240 000 000 cycles
Enters the Reactor
Single threaded while loop.
Your code reacts to incoming events
Watch out
: do not block the reactor !!
while reactor_running?
expired_timers.each {|timer| timer.process }
new_network_io.each {|io| io.process }
end
... and EventMachine

Spaghetti code !
db.find_url { |url|
http.get(url) { |response|
email.send(response) {
puts 'email sent'
}
}
}
Ruby's Fibers
- Available on MRI 1.9.x
- ~ Continuations
- Light-weigth concurrency: cheaper, easier than threads
fiber = Fiber.new do
Fiber.yield 1
2
end
puts fiber.resume # => 1
puts fiber.resume # => 2
puts fiber.resume # => FiberError: dead fiber called
EventMachine + Fibers ➪ EM::Synchrony
EventMachine.run {
page = EventMachine::HttpRequest.new('http://google.com/').get
page.errback { p "Google is down! terminate?" }
page.callback {
about = EventMachine::HttpRequest.new('http://google.com/search?q=eventmachine').get
about.callback { # callback nesting, ad infinitum }
about.errback { # error-handling code }
}
}
▼
EventMachine.synchrony do
page = EventMachine::HttpRequest.new("http://www.google.com").get
about = EventMachine::HttpRequest.new('http://google.com/search?q=eventmachine').get
EventMachine.stop
end
Goliath
- Mix EventMachine and EM::Synchrony
- Let PostRank iterates on this ...
require 'goliath'
class Hello < Goliath::API
# default to JSON output, allow Yaml as secondary
use Goliath::Rack::Render, ['json', 'yaml']
def response(env)
[200, {}, "Hello World"]
end
end
# > ruby hello.rb -sv
# > [97570:INFO] 2011-02-15 00:33:51 :: Starting server on 0.0.0.0:9000 in development mode. Watch out for stones.
Goliath
- App server
- Fully-asynchronous
- Streaming support
- Middleware support
- Simple configuration
- High performance: around 3000 req/s
- Readable and maitainable code
Bonus
- Middlewares
- Async Upload
- Streaming API
- Routing
- Websockets
- Integration testing
Use cases
- Interface with dbs (present dbs as REST resources)
- Proxying remote web-services
- Streaming API
- Websockets server