Section 6.1. Mongrel s Architecture

6.1. Mongrel's Architecture

What makes Mongrel so extensible is its simplistic architecture that gets the job of cooking and shuttling HTTP requests around the system done. Mongrel would probably make the Enterprisey folks scream since it is obviously too simple to scale. Ironically this simplicity is exactly why Mongrel is fast and scales, but it's also your secret weapon when extending and embedding to your own crazy ideas.

Zed Sez

Simpler always wins when you are writing software. I didn't say "simplistic" but "simpler," meaning when compared to another solution. I find that too often programmers get too caught up in building grand palaces of crystal and gold with incredibly intricate inner workings. They love impressing their friends with the equivalent of the "SUV" of software architectures and the more boxes, lines, and color in the diagram the better. Even better if it has to go on multiple walls.

What we have now is a crisis where the coders of the world value complexity and intricacy over simplicity and directness. They would rather build a "Rube Goldberg Architecture"[9] full of indirect puzzles that interact in a chain to accomplish nearly nothing. They then wonder why their software is buggy, crashes, has security holes, and requires a coterie of 10 developers to gather before it works.

[9] (Pitagora Suiichi) for the Japanese readers (

I've always had a different aesthetic sense when I write my software. I value simplicity and directness and try to write software that follows this approach. I jokingly call it the Shibumi School of Soft­ware Structure. All I do is apply this rule: When given two possible designs with equal end results, pick the simpler one. I then ruthlessly strip the solution down to its finest elements, but no more.

Keep this in mind when you've got an architecture or solution designed that you feel is fantastic. Are you actually impressed with the solution or its complexity? Are you sure there's not a simpler way to do the same thing, even if it seems "ugly"? Is it possible that all the people who told you this is how software is designed are wrong?

These are the types of questions developers should be asking. Until they do, we're just going to get larger and larger architectures that don't really do anything. Rube would be proud.

Mongrel's architecture is composed of the following key players:

  • HttpServer The core center of Mongrel that processes incoming HTTP requests and coordinates all the other classes to complete them.

  • HttpRequest Created by the HttpServer after the incoming HTTP headers and body are processed, it contains all the information your HttpHandler needs to do its work.

  • HttpResponse This is crafted and then handed to the HttpHandler as the way the handler builds its response to the client.

  • HttpHandler The class responsible for processing cooked HttpRequest and HttpResponse objects in order to complete a request. This is where you put your logic.

  • URIClassifier You don't really need to use this, but it is responsible for mapping request paths to chains of HttpHandlers for processing. This is what your handler gets registered with.

That makes up the main classes being used. Yes, that's all of them. There are a few others that help setting up new handlers, help package them as plugins, etc. but you can get by with just these five, and actually you don't have to know how HttpServer and URIClassifier work.

How all of these classes work together is best illustrated in Figure 6.1.

Figure 6.1. Mongrel Request Processing

The only thing missing from this diagram is that HttpServer does this for chains of handlers that are registered at different URI paths. To make sure you understand the diagram, we'll go through a typical request.

  1. HttpServer accepts a new client and parses their headers. At this point the server will reject clients if their headers do not parse.[10]

    [10] This is the origin of the "BAD CLIENT" error message and is also the reason Mongrel can resist many attacks and still stay alive.

  2. The results of parsing are passed to a new HttpRequest, which becomes the HttpRequest#params variable used by HttpHandler to process forms and queries.

  3. HttpRequest continues processing the client in order to build up the body of the request. The body is always stored in an IO object, but it might be a temporary file or a StringIO depending on the size of the body.

  4. Once the HttpRequest is constructed, it and a HttpResponse object are passed to the first registered HttpHandler to do the processing.

  5. The HttpHandler#process does its magic and builds the response using the HttpResponse#start method call to pass back headers and the body content. Remember that you are at bare metal so you must explicitly specify most headers manually.

  6. Finally, when the HttpHandler#process method is done, the server checks the HttpRequest it passed and determines if the handler chain is done. If not, then it loads the next handler and continues until there are no more.

The only missing piece is how the HttpServer knows which handler gets which requests. As mentioned in the list of important classes, URIClassifier keeps a mapping of all paths and the HttpHandler chains that are responsible for processing them. HttpServer just looks them up in URIClassifier like a hash map and it's done. You actually won't work with this directly except for simple registration calls through Configurator#uri.

6.1.1. Documentation

Now that you understand Mongrel's deceptively simple architecture, you should take a quick break to browse through the Mongrel Web site's RDoc documentation. Much effort was put into documenting every class in Mongrel so that developers can be self-sufficient. You can find Mongrel's documentation at the Mongrel RubyForge RDoc pages (

Mongrel. Serving, Deploying, and Extending Your Ruby Applications
Mongrel. Serving, Deploying, and Extending Your Ruby Applications
ISBN: 9812836357
Year: 2006
Pages: 48 © 2008-2017.
If you may any questions please contact us: