Michael Granger
2007-Jul-31 16:22 UTC
[Mongrel] Patch: Allow overriding of handler dispatch in Mongrel::HttpServer
Hi Zed (and list), I first of all wanted to thank you for all the hard work you''ve done to make writing HTTP services in Ruby easier and more reliable. A friend of mine and I are developing a network filestore service (similar to S3) based on Mongrel, and we got a fairly useful set of functionality done and working in a matter of a few weeks thanks largely to your work. Mongrel has been reliable, easy to use, and has freed us from having to do any of the nasty bits of HTTP. Thanks! We''re adding a content-negotiation and filtering layer to the service now, and have run into a bit of a snag in the way Mongrel::HttpServer#process_client does its dispatching to the handlers registered for a given path: namely that we want to be able to wrap up Mongrel''s request and response objects in our own objects and send those to each handler''s #process method. We could of course override #process_client in our own subclass of Mongrel::HttpServer, but that''s a fairly large chunk of functionality to duplicate, so I was wondering if we could ask that the actual dispatch to the handlers be moved out into a method that can be specifically overridden. A proposed patch: Index: lib/mongrel.rb ==================================================================--- lib/mongrel.rb (revision 540) +++ lib/mongrel.rb (working copy) @@ -613,11 +613,7 @@ # request is good so far, continue processing the response response = HttpResponse.new(client) - # Process each handler in registered order until we run out or one finalizes the response. - handlers.each do |handler| - handler.process(request, response) - break if response.done or client.closed? - end + dispatch_to_handlers(client, handlers, request, response) # And finally, if nobody closed the response off, we finalize it. unless response.done or client.closed? @@ -658,6 +654,17 @@ end end + + # Process each handler in registered order until we run out or one finalizes the + # response. + def dispatch_to_handlers(client, handlers, request, response) + handlers.each do |handler| + handler.process(request, response) + return if response.done or client.closed? + end + end + + # Used internally to kill off any worker threads that have taken too long # to complete processing. Only called if there are too many processors # currently servicing. It returns the count of workers still active All the unit tests continue to pass with this change, and I couldn''t think of anything else within the purvue of Mongrel::HttpServer that needed additional testing, but if you''d like me to try to come up with tests for this change I can do that. We''re currently re-opening Mongrel::HttpServer and applying this patch ourselves, which of course works just fine, but I thought that perhaps someone else might want to do something similar and could benefit from this. It would also make our keeping up with future changes to Mongrel easier with (I hope) a minimum of code-fistage. Thanks for your time, -- Michael Granger <ged at FaerieMUD.org> Rubymage, Believer, Architect The FaerieMUD Consortium <http://www.FaerieMUD.org/> ruby -e "p 12383406064495388618631689469409153107.to_s(36).tr(''z'','' '')"