unbit / uwsgi

uWSGI application server container
http://projects.unbit.it/uwsgi
Other
3.45k stars 691 forks source link

Emperor + fork server #617

Closed unbit closed 10 years ago

unbit commented 10 years ago

Introduction:

The customer has hundreds of Emperor-managed PSGI applications built upon the same code base.

Those apps start pretty slow, so they could highly benefit from fork() copy on write.

The Emperor calls fork()/clone() and execve() for each vassal so they spawn with a clean setup. Execve functions clear the whole memory map of the process so inheriting the copy of an application is impossible.

The idea:

The PSGI plugin exposes a new option: --early-psgi

This option of type "IMMEDIATE" (it means the options is executed soon after parsing) initialize a perl interpreter and load the specified app in it exposing its entry point address in a global area.

Soon after the initialization, (and thanks to the --fork-socket option) the uWSGI process binds to a UNIX address looply waiting for connections.

Each connection will trigger a double fork() and will pass up to 3 file descriptors:

In addition to the file descriptors a uwsgi-serialized array is passed with the vassal command line options. Those options override the old ones, and the config parser is run again, triggering the spawn of a fully capable instance.

The Emperor side:

instead of calling fork() for each vassal, a connection to the fork server is made, passing the vassal's file descriptors. The Emperor is initialized with prctl(PR_SET_CHILD_SUBREAPER, 1) so every sub-children without a parent will be reparented to the Emperor (this explains the need of double-fork in the fork-server).

Now the Emperor can wait() for the sub-children, and can pass messages to the vassal file descriptors.

unbit commented 10 years ago

implemented in 2.1 branch