On Tue, 5 Dec 2006 13:08:14 -0800
"Joseph McDonald" <[EMAIL PROTECTED]> wrote:
> I understand that rails is not thread safe, but this is not using
> rails or any part of rails. It just sets up a simple handler. but
> registering that handler seems to allow only one instance of that
> handler to run at a time.
I think part of your confusion (and others) is the association of HttpHandlers
with HttpRequests and HttpResponses. Also, how they're run in the life cycle
of a Mongrel HTTP request process.
First, Mongrel accepts remote clients and creates one Thread for each request.
Mongrel also enforces a single request/response using Connect:close headers
because Ruby only supports 1024 files (so far). If Mongrel doesn't do this
then people like yourself can write a simple "trickle attack" client that hits
the Mongrel server, opens a bunch of continuous connections, and then eat up
all available files very quickly. Basically, a DDoS attack that's very simple
to do.
So, keep that in mind with your comet thing. You'll have to also keep track of
the number of active connections and start getting into old school capacity
planning to figure out how many mongrel processes are needed to service your
appropriate user load.
Second thing is that you can register multiple HttpHandler objects with a
URIClassifier at a URL path, but that each one is run in sequence and they are
run across all the threads. This means that *you* have to keep the threading
straight in your HttpHandler since that same object's state could be used by
500+ threads at once. This is also why each handler's process(req,resp) method
is given all the stuff it needs in the parameters.
For example, this is *really* bad:
class DumbAssHandler < HttpHandler
def initialize()
@afile = open("somefile.txt")
end
def process(req, response)
@afile.write(req.params["X-Someheader"])
end
end
The problem is a *single* instance of DumbAssHandler is shared amongst *ALL*
the threads that call DumbAssHandler::process(). When you start writing to
@afile it'll get all nasty and confused on you, but what's worse is Ruby's
threading isn't so clear on this so it *might* work most of the time, and then
one day you hit that magic thread or switch to Linux and all hell breaks loose.
Finally, each client processing Thread gets its very own HttpRequest and
HttpResponse object, so within the process() method you can go to town on it
without worrying about locking problems. If you need to store stuff someplace
so that it's not shared then just toss it into the req.params[] as a symbol
with a funky name. You can also use Thread.current[] to store things, but
there's a hidden danger: The GC doesn't run on Threads very often and not the
same as other stuff, so things in Thread.current[] tend to live for longer than
you expect.
Anyway, hope that helps you out.
--
Zed A. Shaw, MUDCRAP-CE Master Black Belt Sifu
http://www.zedshaw.com/
http://www.awprofessional.com/title/0321483502 -- The Mongrel Book
http://mongrel.rubyforge.org/
http://www.lingr.com/room/3yXhqKbfPy8 -- Come get help.
_______________________________________________
Mongrel-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/mongrel-users