<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Apache Child Processes Lifecycle and Request Processing</title><link rel="stylesheet" type="text/css" href="rivet.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><link rel="home" href="index.html" title="Apache Rivet 3.0"><link rel="up" href="index.html" title="Apache Rivet 3.0"><link rel="prev" href="processing.html" title="Apache Rivet HTTP Request Processing"><link rel="next" href="commands.html" title="Rivet Tcl Commands and Variables"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Apache Child Processes Lifecycle and Request Processing</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="processing.html"><img src="images/prev.png" alt="Prev"></a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="commands.html"><img src="images/next.png" alt="Next"></a></td></tr></table></div><div class="section"><div class="titlepage"><div><div><hr><h2 class="title" style="clear: both"><a name="request"></a>Apache Child Processes Lifecycle and Request Processing</h2></div></div></div><div class="simplesect"><div class="titlepage"><div><div><h3 class="title"><a name="idm606"></a>Apache Child Process Lifecycle</h3></div></div></div><p style="width:90%"> | |
Apache Rivet devolves to the <a class="ulink" href="" target="_top">Multi-Processing Module (MPM)</a> | |
the task of managing the agents responding to network requests. | |
An MPM is responsible for creating such agents during the start-up, | |
and is in charge for terminating existing ones and recreating new | |
agents when the workload is requiring it. | |
</p><p style="width:90%"> | |
Apache Rivet 2.0,2.1,2.2,2.3 supported only the | |
<a class="ulink" href="https://httpd.apache.org/docs/2.4/mod/prefork.html" target="_top">prefork</a> | |
MPM which creates child processes as independent agents responding to network requests. | |
Starting with 3.0 also the <a class="ulink" href="https://httpd.apache.org/docs/2.4/mod/worker.html" target="_top">worker</a> and | |
<a class="ulink" href="https://httpd.apache.org/docs/2.4/mod/event.html" target="_top">event</a> MPM are supported. The worker MPM is | |
an hybrid model where forked child processes in turn create threads as real | |
network agents. Also Apache on Windows© is now supported and tested | |
with the <a class="ulink" href="https://httpd.apache.org/docs/2.4/mod/mpm_winnt.html" target="_top">winnt</a> MPM, | |
where a single process creates and manages a large number of thread agents. | |
</p><p style="width:90%"> | |
Configuration parameters about this critical point can be read in the | |
<a class="ulink" href="https://httpd.apache.org/docs/2.4/misc/perf-tuning.html" target="_top">Apache | |
documentation</a>. | |
</p><p style="width:90%"> | |
There are 4 stages in the lifetime of an Apache webserver that are relevant | |
to Rivet: | |
</p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><h4><a name="idm620"></a>Server Initialization</h4><div style="margin-bottom:1.5ex ; padding .5ex"> | |
Apaches starts up as a single process. During this stage Apache performs | |
various preliminary tasks including reading and parsing the configuration. | |
After the configuration has been read Rivet sets up some internal resources | |
and if a Tcl script is set as argument of a <span style="font-family:monospace"><span class="command"><strong>ServerInitScript</strong></span></span> | |
directive the script is executed. | |
Variables, arrays or dictionaries created during | |
the execution of this script will be preserved and later replicated in the | |
child process intepreters if the prefork MPM is loaded (which restricts | |
this feature to the Unix systems). | |
The prefork MPM creates new child processes with a fork() | |
system call, which involves only in memory copy of sections of a | |
process address space. Tcl is careful about reproducing an environment | |
across a fork call in order to have a functional interpreter. | |
</div><div style="margin-bottom:1.5ex ; padding .5ex"> | |
Still, regardless the OS and loaded MPM <span style="font-family:monospace"><span class="command"><strong>ServerInitScript</strong></span></span> | |
is a good place to do global initialization that doesn't involve | |
creation of private data. Example of tasks that can be done | |
in this context are IPC methods that must be initialized at this stage. | |
With the prefork MPM also importing from namespaces and loading packages | |
can be done here removing the burden from the child initialization stage. | |
</div></li><li class="listitem"><h4><a name="idm626"></a>Child Process Initialization</h4><div style="margin-bottom:1.5ex ; padding .5ex"> | |
A child process calls the MPM bridge interface function to set up | |
the Tcl run time environment,either creating multiple threads each running its | |
Tcl interpreters or, in the case of the prefork MPM bridge, setting up | |
the environment within a the child process itself as a single Tcl thread. | |
</div><div style="margin-bottom:1.5ex ; padding .5ex"> | |
This is the stage where most likely you want to open I/O channels, | |
database connections or any other resource that has to be private to an | |
interpreter and has to persist over a whole thread lifespan. | |
When the option <span style="font-family:monospace"><span class="command"><strong>SeparateVirtualInterps</strong></span></span> is | |
turned off child processes will have a single interpreter regardless | |
the number of virtual hosts configured. The | |
<span style="font-family:monospace"><span class="command"><strong>GlobalInitScript</strong></span></span> is the configuration script | |
the child process will run once before getting ready to | |
serve requests | |
</div><div style="margin-bottom:1.5ex ; padding .5ex"> | |
When <span style="font-family:monospace"><span class="command"><strong>SeparateVirtualInterps</strong></span></span> is turned on | |
each configured virtual host will have its own slave interpreter which | |
can will run the <span style="font-family:monospace"><span class="command"><strong>ChildInitScript</strong></span></span> directive as | |
initialization script. The | |
<span style="font-family:monospace"><span class="command"><strong>ChildInitScript</strong></span></span> has to be | |
placed within a <VirtualHost...>...</VirtualHost ...> | |
stanza to associate a script to a specific virtual host initialization. | |
This scenario of interpreter separation is extremely useful to | |
prevent resource conflicts when different virtual hosts are | |
serving different web applications. | |
</div><div style="margin-bottom:1.5ex ; padding .5ex"> | |
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"><span style="font-family:monospace"><span class="command"><strong>GlobalInitScript</strong></span></span> has no effect to working interpreters | |
when <span style="font-family:monospace"><span class="command"><strong>SeparateVirtualInterps</strong></span></span> is set. | |
</td></tr></table></div> | |
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"> | |
The lazy MPM bridge implements a model where | |
every worker thread has exactly one interpreter and belongs to | |
a single virtual host, therefore <span style="font-family:monospace"><span class="command"><strong>SeparateVirtualInterps</strong></span></span> | |
is ignored and you can't share the same interpreter among virtual host | |
</td></tr></table></div> | |
</div></li><li class="listitem"><h4><a name="idm642"></a>Request Processing and Content Generation</h4><div style="margin-bottom:1.5ex ; padding .5ex"> | |
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"> | |
This section explain the default request handling procedure which | |
was written to let Rivet 3.0 work as a drop in replacement | |
of any 2.x module. For a in-depth understanding of | |
the new request processing mechanics please read the | |
<a class="link" href="processing.html" title="Apache Rivet HTTP Request Processing">request processing</a> section of the manual | |
</td></tr></table></div> | |
</div><div style="margin-bottom:1.5ex ; padding .5ex"> | |
After a child has been initialized it's ready to serve requests. | |
A child process' lifetime is almost entirely spent in this phase, waiting | |
for connections and responding to requests. At every request the URL | |
goes through filter processing and, in case, rewritten | |
(mod_rewrite, Alias directives, etc). | |
Parameter values encoded in the request are made available to the | |
environment and finally the script encoded in the URL is run. | |
The developer can tell Rivet if optionally the execution has to | |
be preceded by a <span style="font-family:monospace"><span class="command"><strong>BeforeScript</strong></span></span> and followed by an | |
<span style="font-family:monospace"><span class="command"><strong>AfterScript</strong></span></span>. The real script mod_rivet will | |
execute is the result of the concatenation of the | |
<span style="font-family:monospace"><span class="command"><strong>BeforeScript</strong></span></span>, | |
the script encoded in the URL and the <span style="font-family:monospace"><span class="command"><strong>AfterScript</strong></span></span>. | |
Thus the whole ensemble of code that makes up a web application might | |
be running within the same "before" and "after" scripts to which | |
the programmer can devolve tasks common to every | |
page of an application. | |
</div></li><li class="listitem"><h4><a name="idm652"></a>Child Process Exit</h4><div style="margin-bottom:1.5ex ; padding .5ex"> | |
If no error condition forces the child process to a premature exit, his | |
life is determined by the Apache configuration parameters. To reduce | |
the effects of memory leaks in buggy applications the Apache webserver | |
forces a child process to exit after a | |
certain number of requests served. A child process gets replaced | |
with a brand new one if the workload of webserver requires so. | |
Before the process quits an exit handler can be run | |
to do some housekeeping, just in case something the could have been | |
left behind has to be cleaned up. Like the initialization scripts | |
<span style="font-family:monospace"><span class="command"><strong>ChildExitScript</strong></span></span> too is a "one shot" script. | |
</div><div style="margin-bottom:1.5ex ; padding .5ex"> | |
The Tcl <span style="font-family:monospace"><span class="command"><strong>exit</strong></span></span> command forces an interpreter to | |
quit, thus removing the ability of the process embedding it | |
to run more Tcl scripts. The child process then is forced | |
to exit and be replaced by a new one when the workload demands it. | |
This operation implies the <span style="font-family:monospace"><span class="command"><strong>ChildExitScript</strong></span></span> be | |
run before the interpreter is actually deleted. | |
</div></li></ol></div></div><div class="simplesect"><div class="titlepage"><div><div><h3 class="title"><a name="idm658"></a>Apache Rivet Error and Exception Scripts Directives</h3></div></div></div><p style="width:90%"> | |
Rivet is highly configurable and each of the webserver lifecycle stages | |
can be exploited to control a web application. | |
Not only the orderly sequence of stages | |
in a child lifecycle can be controlled with Tcl scripts, but also | |
Tcl error or abnormal conditions taking place during | |
the execution can be caught and handled with specific scripts. | |
</p><p style="width:90%"> | |
Tcl errors (conditions generated when a command exits with code TCL_ERROR) | |
usually result in the printing of a backtrace of the code fragment | |
relevant to the error. | |
Rivet can set up scripts to trap these errors and run instead | |
an <span style="font-family:monospace"><span class="command"><strong>ErrorScript</strong></span></span> to handle it and conceal details | |
that usually have no interest for the end user and it | |
may show lines of code that ought to remain private. The ErrorScript | |
handler might create a polite error page where things | |
can be explained in human readable form, thus enabling the end user | |
to provide meaningful feedback information. | |
</p><p style="width:90%"> | |
In other cases an unmanageable conditions might take place in the data and | |
this could demand an immediate interruption of the content generation. These abort | |
conditions can be fired by the <a class="xref" href="abort_page.html" title="abort_page">abort_page</a> command, which | |
in turn fires the execution of an <span style="font-family:monospace"><span class="command"><strong>AbortScript</strong></span></span> to handle | |
the abnormal condition. Starting with Rivet 2.1.0 <a class="xref" href="abort_page.html" title="abort_page">abort_page</a> | |
accepts a free form parameter that can be retrieved later with the command | |
<a class="xref" href="abort_code.html" title="abort_code">abort_code</a> | |
</p></div><div class="simplesect"><div class="titlepage"><div><div><h3 class="title"><a name="idm668"></a>Tcl Namespaces in Rivet and the <span style="font-family:monospace"><span class="command"><strong>::request</strong></span></span> Namespace</h3></div></div></div><p style="width:90%"> | |
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Note"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="images/note.png"></td><th align="left">Note</th></tr><tr><td align="left" valign="top"> | |
This section explain the default request handling procedure which | |
was written to let Rivet 3.0 work as a drop in replacement | |
of any 2.x module. For a in-depth understanding of | |
the new request processing mechanics please read the | |
<a class="link" href="processing.html" title="Apache Rivet HTTP Request Processing">request processing</a> section of the manual | |
</td></tr></table></div><p style="width:90%"> | |
</p><p style="width:90%"> | |
With the sole exception of .rvt templates, mod_rivet runs pure Tcl scripts | |
at the global namespace. That means that every variable or procedure | |
created in Tcl scripts resides by default in the | |
"::" namespace (just like in traditional Tcl scripting) and they | |
are persistent across different requests until explicitly unset or | |
until the interpreter is deleted. | |
You can create your own application namespaces to store data but | |
it is important to remember that subsequent requests will in general be served | |
by different child processes. Your application can rely on the fact that | |
certain application data will be in the interpreter, but you shouldn't | |
assume the state of a transaction spanning several pages | |
can be stored in this way and be safely kept available to a | |
specific client. Sessions exist for this purpose and Rivet ships its own | |
session package with support for most of popular DBMS. Nonetheless | |
storing data in the global namespace can be useful, even though scoping | |
data in a namespace is recommended. I/O channels and | |
database connections are examples of information usually specific | |
to a process for which you don't want to pay the overhead of creating them | |
at every request, probably causing a dramatic loss in the application | |
performance. | |
</p><p style="width:90%"> | |
A special role in the interpreter is played by the <span style="font-family:monospace"><span class="command"><strong>::request</strong></span></span> | |
namespace. The <span style="font-family:monospace"><span class="command"><strong>::request</strong></span></span> namespace is deleted and recreated | |
at every request and Rivet templates (.rvt files) are executed within it. | |
</p><p style="width:90%"> | |
Unless you're fully qualifying variable names outside the <span style="font-family:monospace"><span class="command"><strong>::request</strong></span></span> | |
namespace, every variable and procedure created in .rvt files is by default placed in | |
it and deleted before any other requests gets processed. It is therefore safe to | |
create variables or object instances in template files and foresake about them: Rivet | |
will take care of cleaning the namespace up and everything created inside the namespace | |
will be destroyed. | |
</p><div class="table"><table align="center" title="Apache Rivet Scripts" class="namespaces"><thead><td>Stage</td><td>Script</td><td>Namespace</td></thead><tbody><tr class="init"><td>Apache Initialization</td><td>ServerInitScript</td><td>::</td></tr><tr class="childinit"><td rowspan="2">Child Initialization</td><td>GlobalInitScript</td><td>::</td></tr><tr class="childinit"><td>ChildInitScript</td><td>::</td></tr><tr class="processing"><td rowspan="6">Request Processing</td><td>BeforeScript</td><td>::</td></tr><tr class="processing"><td>.rvt</td><td>::request</td></tr><tr class="processing"><td>.tcl</td><td>::</td></tr><tr class="processing"><td>AfterScript</td><td>::</td></tr><tr class="processing"><td>AbortScript</td><td>::</td></tr><tr class="processing"><td>AfterEveryScript</td><td>::</td></tr><tr class="childexit"><td>Child Termination</td><td>ChildExitScript</td><td>::</td></tr><tr class="processing"><td>Error Handling</td><td>ErrorScript</td><td>::</td></tr></tbody></table></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="processing.html"><img src="images/prev.png" alt="Prev"></a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="commands.html"><img src="images/next.png" alt="Next"></a></td></tr><tr><td width="40%" align="left" valign="top">Apache Rivet HTTP Request Processing </td><td width="20%" align="center"><a accesskey="h" href="index.html"><img src="images/home.png" alt="Home"></a></td><td width="40%" align="right" valign="top"> Rivet Tcl Commands and Variables</td></tr></table></div></body></html> |