First, we start with a concept I am calling 'Server Pools'. Each pool has specific limits. These can include a maximum number of processes, or other limits based on resource usage. A root server pool can contain other pools, or sub pools.
(xxxx: perhaps 'server pools' is a bad word for this idea?)
Each sub pool could be set to specific User IDs.(ala perchild). However, you could have 0 or 100 of them currently running at any one time. Their spawning should be based on the same rules as normal httpd processes. However, they must be able to go down to 0 alive processes. This enables the realistic use of this MPM in a larger hosting environment.
Since you need the ability to spawn more processes on demand when none exist, there will be a 'controller process' that manages all server pools, killing or using fork() to spawn new pools.
A frontend will parse the incoming request, and provide other services, like input filters, output filters, and logging. This frontend will pass the request back to a server pool by asking the control process for which server pool should service this request. If no server pool currently has any processes running, the control process will spawn one or more.
I disagree with the concept of passing a client socket directly to the back-end as perchild does. I believe it would be better to write a protocol handler for AJP or another binary type protocol and therefore, hopefully, faster for passing requests to a backend server pool via Unix Daemon Sockets. By passing the socket directly to the backend, we enter a hell related to input filters, keep alive requests, and http 1.1 pipelining. I also believe that for most cases, an optimized AJP like protocol would be just as fast as directly writing to the client. (not for static content, but for a PHP script..)
Some ASCII drawing of what this might look like:
[ Client ] | | (HTTP) | [ Frontend Process ] | | | (AJP) | (Find/Found Pool) | | | [ Control Process ] | | | | (Die, Spawn) | | [ Backend Server Pool ]
What this Solves:
- Keep Alive/Pipelining/SSL decoding.. etc. These are all handled by the fontend.
- PHP Support. The backends could be process or threaded, it doesn't matter, but at the same time, the frontend could resemble the Event or Worker MPM.
Problems:
- Context Switching Sucks. This model has way too many for a single request.
Thoughts:
- Hacking a demo via mod_proxy
- Is this a better design than perchild MPM?
- What are the other design considerations to doing 'perchild' the 'right' way?
In some ways, this is just a more automated mod_proxy w/ load balancing that will auto-spawn your backend servers on demand. I believe it might be best to write this whole MPM as a hybrid MPM and mod_proxy module.
I am pretty sure this whole idea is sketchy in parts. I just scratched it all down at midnight. All comments are welcome.
-Paul Querna