Apache Rivet delegates to the Multi-Processing Module (MPM) 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.
Apache Rivet is currently supporting only the prefork MPM which creates full fledged child processes as independent agents responding to network requests. Efforts are under way to extend the support to the worker MPM, a hybrid model where forked child processes in turn create threads as real network agents. If we can achieve this the goal would open the possibility of supporting also the Windows© specific winnt MPM, where a single process creates and manages a large number of thread agents.
Configuration parameters about this critical point can be read in the Apache documentation.
There are 4 stages in the lifetime of an Apache webserver that are relevant to Rivet:
Note | |
---|---|
GlobalInitScript has no effect to working interpreters when SeparateVirtualInterps is set. |
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.
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 ErrorScript 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.
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 abort_page command, which in turn fires the execution of an AbortScript to handle the abnormal condition. Starting with Rivet 2.1.0 abort_page accepts a free form parameter that can be retrieved later with the command abort_code
With the sole exception of .rvt templates, 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.
A special role in the interpreter is played by the ::request namespace. The ::request namespace is deleted and recreated at every request and Rivet templates (.rvt files) are executed within it.
Unless you're fully qualifying variable names outside the ::request 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.
Stage | Script | Namespace |
Apache Initialization | ServerInitScript | :: |
Child Initialization | GlobalInitScript | :: |
ChildInitScript | :: | |
Request Processing | BeforeScript | :: |
.rvt | ::request | |
.tcl | :: | |
AfterScript | :: | |
AbortScript | :: | |
AfterEveryScript | :: | |
Child Termination | ChildExitScript | :: |
Error Handling | ErrorScript | :: |