Skip to content

Instantly share code, notes, and snippets.

@sandro
Created September 8, 2011 08:52
Show Gist options
  • Save sandro/1202967 to your computer and use it in GitHub Desktop.
Save sandro/1202967 to your computer and use it in GitHub Desktop.
Imagining async rack-test
require 'rubygems'
require 'bundler'
Bundler.setup
require 'rack'
require 'rack/test'
require 'benchmark'
class Foo
def self.call(env)
sleep 1
[200, {'Content-Type' => 'text/plain'}, 'OK']
end
end
class AsyncApp
def initialize(app)
@app = app
@fds = {}
at_exit { run }
end
def call(env, &callback)
rd, wr = IO.pipe
fork do
rd.close
response = @app.call(env)
wr.write response
wr.close
exit!
end
wr.close
@fds[rd] = callback
end
def run
until @fds.empty?
reads = select(@fds.keys).first
reads.each do |io|
if io.eof?
@fds.delete(io)
else
@fds[io].call(io.read)
end
end
end
end
end
class AsyncTest
def app
@app ||= Rack::Builder.new do
run Foo
end
end
def async_app
@async_app ||= AsyncApp.new(app)
end
def async
env = Rack::MockRequest.env_for
async_app.call(env) { |resp|
p resp
}
end
end
test = AsyncTest.new
test.async
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment