The Fork Server (sponsored by Intellisurvey) ============================================ This is a really advanced (and complex) feature developed with sponsorship from Intellisurvey.com. If you have dozens or even hundreds of applications built upon the same codebase you can setup your Emperor to fork vassals from an already running one (with the application core loaded). Currently the feature is supported only in the PSGI plugin, and requires Linux kernel >= 3.4. How it works ------------ When in `fork-server` mode, the Emperor differentiates between two kind of vassals: base vassals and adopted vassals. "base" vassals are pretty much classic vassals; generated by `fork()` + `execve()` by the Emperor. The only difference is that they are supposed to load as much of your application code as possible as soon as possible, then suspend themselves waiting for connections on a UNIX socket. A "base" vassal will be something like this .. code-block:: ini [uwsgi] ; load myapp.pl as soon as possible early-psgi = myapp.pl ; suspend and execution and bind on UNIX socket /tmp/fork_server.socket fork-server = /tmp/fork_server.socket "Adopted" vassals are the true "new thing". Once an adopted vassal is requested, the Emperor connects to the specified fork server (instead of calling `fork()` + `execve()` itself). The Emperor passes an uwsgi-serialized array of command line options of the new vassal and up to 3 file descriptors (since UNIX sockets allow passing file descriptors from one process to another). Those 3 file descriptors are: * 1 -> the communication pipe with the Emperor (required) * 2 -> the config pipe (optional) * 3 -> on_demand socket (optional) At this point, the fork server `fork()`\ s itself twice and continues the uWSGI startup using the supplied arguments array. How can the Emperor `wait()` on an external process, then? This is why a >= 3.4 kernel is required, as thanks to the `prctl(PR_SET_CHILD_SUBREAPER, 1)` call we can tell vassals to be re-parented to the Emperor when their parent dies (in fact the fork-server forks two times, so the vassal has no live parent, poor thing). Now the Emperor has a new child and a communication pipe. And that's all. Configuring the Emperor for fork-server mode --------------------------------------------- You need only two new options: ``--emperor-use-fork-serve `` and ``--vassal-fork-base `` Let's start with a slow-loading (10 seconds) Perl app: .. code-block:: pl # myapp.pl print "I am the App\n"; sleep(10); my $app = sub { return [200, ['Content-Type'=>'text/html'], ["Hello World"]]; }; Save it as myapp.pl and load it in perlbase.ini vassal file (this is a base vassal): .. code-block:: ini [uwsgi] early-psgi = myapp.pl fork-server = /var/run/fork_server.socket Now create two vassals (one.ini and two.ini) that will `fork()` from the base one: .. code-block:: ini [uwsgi] ; one.ini http-socket = :8181 processes = 4 uid = 1001 gid = 1001 .. code-block:: ini [uwsgi] ; two.ini http-socket = :8282 processes = 8 uid = 1002 gid = 1002 As you can see they are pretty different, even in privileges. Now let's spawn the Emperor in fork-server mode allowing perlbase.ini as a "base" vassal: .. code-block:: ini [uwsgi] emperor = /etc/uwsgi/vassals emperor-use-fork-server = /var/run/fork_server.socket vassal-fork-base = perlbase.ini emperor-stats = 127.0.0.1:5000 The Emperor will start running perlbase.ini as a standard vassal, while for the non-base ones it will `fork()` from the base, where the app is already loaded. You will note that instead waiting for 10 seconds, your new vassals will start immediately. Pretty cool, huh?