Rack Presentation Oct 07
Transcript of Rack Presentation Oct 07
-
8/14/2019 Rack Presentation Oct 07
1/36
rackrolling your own, tiny like, web thingoespresentation by ryan allen - yeahnah.org (and etc)
-
8/14/2019 Rack Presentation Oct 07
2/36
the problem?
each framework has to write its ownhandlers to mongrel, webrick, fast-cgi
duplication among frameworks, lachie killskittens
new frameworks are required to writeeven more duplicate code, boring!
-
8/14/2019 Rack Presentation Oct 07
3/36
a solution - rack
super simple API for writing web apps
single API to connect to mongrel, fast-cgi,webrick
based on pythons WSGI, which was a goodthing for python
-
8/14/2019 Rack Presentation Oct 07
4/36
the api
can be satisfied with a lambda
really, no, im serious
-
8/14/2019 Rack Presentation Oct 07
5/36
lambda { |env| [200, {}, Hello World! }
-
8/14/2019 Rack Presentation Oct 07
6/36
the api, cont. an object that responds to call and
accepts one argument:env, and returns:
a status, i.e.200 the headers, i.e.{Content-Type =>text/html}
an object that responds to
each, i.e.
some random string
-
8/14/2019 Rack Presentation Oct 07
7/36
this env thing
a hash of environment variables, things likePATH_INFO,QUERY_STRING,REMOTE_ADDR,REQUEST_URI, all that
junk
-
8/14/2019 Rack Presentation Oct 07
8/36
things do to with env
use Rack::Request to construct arequest object, pull out GET and POSTdata
Rack borrows code from Camping, Railsand IOWA in this department
-
8/14/2019 Rack Presentation Oct 07
9/36
request = Rack::Request.new(env)
request.GETrequest.POST
-
8/14/2019 Rack Presentation Oct 07
10/36
talking back, eloquently
use Rack::Response to talk to clientsabout cookies
additionally, you can use this instead of the[200, {}, ] return value, see:
-
8/14/2019 Rack Presentation Oct 07
11/36
response = Rack::Response.new('Hello World!')
response.set_cookie('sess-id', 'abcde')response.finish
-
8/14/2019 Rack Presentation Oct 07
12/36
lots of love to mongrel
we love mongrel to bits
despite the fact we can plug into webrickand fast-cgi we really just love mongrel
poor webrick and fast-cgi :(
-
8/14/2019 Rack Presentation Oct 07
13/36
%w(rubygems rack).each { |dep| require dep }
app = lambda { |env| [200, {}, 'Hello World!'] }Rack::Handler::Mongrel.run(app, :Port => 3000)
-
8/14/2019 Rack Presentation Oct 07
14/36
oh, and that was acom lete rack a
-
8/14/2019 Rack Presentation Oct 07
15/36
run it, it works, really!
-
8/14/2019 Rack Presentation Oct 07
16/36
%w(rubygems rack).each { |dep| require dep }
app = lambda { |env| [200, {}, 'Hello World!'] }Rack::Handler::Mongrel.run(app, :Port => 3000)
-
8/14/2019 Rack Presentation Oct 07
17/36
concurrency galore
using the mongrel handler we can get crazyconcurrency
lets have a look at this, using ab
-
8/14/2019 Rack Presentation Oct 07
18/36
%w(rubygems rack).each { |dep| require dep }
app = lambda { |env| sleep(5); [200, {}, 'Oi!'] }Rack::Handler::Mongrel.run(app, :Port => 3000)
-
8/14/2019 Rack Presentation Oct 07
19/36
ab -c 100 -n 300 http://0.0.0.0:3000/
-
8/14/2019 Rack Presentation Oct 07
20/36
Benchmarking 0.0.0.0 (be patient)Completed 100 requestsCompleted 200 requestsFinished 300 requestsConcurrency Level: 100Time taken for tests: 15.232 secondsComplete requests: 300Failed requests: 0
-
8/14/2019 Rack Presentation Oct 07
21/36
so?
good like camping - very minimal, single fileapplications
but better because camping isnt multi-threaded, requests are wrapped in a mutex
like rails, boo!
-
8/14/2019 Rack Presentation Oct 07
22/36
so??
good like merb - multithreaded, non-blocking requests
but better (in some scenarios) beacusemerb is a big framework mirroring a lot of
what rails does
-
8/14/2019 Rack Presentation Oct 07
23/36
so???
people use merb to write non-blockinguploader applications to compliment rails
applications
but, why arent they using rack instead?
rack is smaller, more lightweight and supereasy to write and deploy!
-
8/14/2019 Rack Presentation Oct 07
24/36
time to break stuff
question - ok, so how doesActiveRecord operate underconcurrency?
answer - creates a connection-per-threadwhen allow_concurrency is true
exhaust max-connections, anyone?
lets try!
-
8/14/2019 Rack Presentation Oct 07
25/36
%w(rubygems rack active_record).each { |dep| require dep }AR = ActiveRecord::BaseAR.allow_concurrency = trueAR.establish_connection(:adapter => 'mysql',:username => 'root',
:database => 'flashden')def user_count AR.connection.select_all('select * from users limit 1000')endapp = lambda { |env| [200, {}, user_count.inspect] }Rack::Handler::Mongrel.run(app, :Port => 3000)
-
8/14/2019 Rack Presentation Oct 07
26/36
ab -c 100 -n 100 http://0.0.0.0:3000/
-
8/14/2019 Rack Presentation Oct 07
27/36
Thu Oct 25 17:01:09 +1000 2007: ERROR: Too many connectionsThu Oct 25 17:01:09 +1000 2007: ERROR: Too many connectionsThu Oct 25 17:01:09 +1000 2007: ERROR: Too many connectionsThu Oct 25 17:01:10 +1000 2007: ERROR: Too many connectionsThu Oct 25 17:01:10 +1000 2007: ERROR: Too many connectionsThu Oct 25 17:01:10 +1000 2007: ERROR: Too many connectionsThu Oct 25 17:01:10 +1000 2007: ERROR: Too many connectionsThu Oct 25 17:01:10 +1000 2007: ERROR: Too many connections
Thu Oct 25 17:01:10 +1000 2007: ERROR: Too many connectionsThu Oct 25 17:01:10 +1000 2007: ERROR: Too many connectionsThu Oct 25 17:01:10 +1000 2007: ERROR: Too many connectionsThu Oct 25 17:01:10 +1000 2007: ERROR: Too many connectionsThu Oct 25 17:01:10 +1000 2007: ERROR: Too many connectionsThu Oct 25 17:01:11 +1000 2007: ERROR: Too many connectionsThu Oct 25 17:01:11 +1000 2007: ERROR: Too many connectionsThu Oct 25 17:01:11 +1000 2007: ERROR: Too many connections
Thu Oct 25 17:01:11 +1000 2007: ERROR: Too many connections
-
8/14/2019 Rack Presentation Oct 07
28/36
yep, broke it (thats onmax-connections=100)
-
8/14/2019 Rack Presentation Oct 07
29/36
i dunno how to fix it
-
8/14/2019 Rack Presentation Oct 07
30/36
connection pooling?
-
8/14/2019 Rack Presentation Oct 07
31/36
yeah thanks for yourfeedback!
-
8/14/2019 Rack Presentation Oct 07
32/36
adding-on
use Rack::Builder to add some moresophisticated behaviour, its a DSL like thing
to construct rack applications
free logging, exception handling, urlmapping, http authentication, directory
serving...
-
8/14/2019 Rack Presentation Oct 07
33/36
app = Rack::Builder.new {use Rack::CommonLoggeruse Rack::ShowExceptionsmap "/" douse Rack::Lint
run MyCustomAwesomeApp.newend
}
-
8/14/2019 Rack Presentation Oct 07
34/36
so, these bits and bobs
can make life easier Rack::Reloader
Rack::Static Rack::ShowExceptions
Rack::CommonLogger
Theres a couple more, see docs!
-
8/14/2019 Rack Presentation Oct 07
35/36
links to stuff and etc
http://rack.rubyforge.org/ http://rack.rubyforge.org/doc/
http://www.wsgi.org/
-
8/14/2019 Rack Presentation Oct 07
36/36
end!