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

Reply via email to