| <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="idm45905564639648"></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="idm45905564688288"></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="idm45905564684016"></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="idm45905564606448"></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="idm45905564599984"></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="idm45905564594736"></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="idm45905564588688"></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> |