| <html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Rivet Internals</title><link rel="stylesheet" type="text/css" href="rivet.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="Apache Rivet"><link rel="up" href="index.html" title="Apache Rivet"><link rel="prev" href="help.html" title="Resources - How to Get Help"><link rel="next" href="upgrading.html" title="Upgrading from mod_dtcl or NeoWebScript"></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">Rivet Internals</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="help.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="upgrading.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="internals"></a>Rivet Internals</h2></div></div></div><p style="width:90%"> |
| This section easily falls out of date, as new code is added, old |
| code is removed, and changes are made. The best place to look |
| is the source code itself. If you are interested in the changes |
| themselves, the Subversion revision control system |
| (<span style="font-family:monospace"><span class="command"><strong>svn</strong></span></span>) can provide you with information about |
| what has been happening with the code. |
| </p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="idp59151152"></a>Initialization</h3></div></div></div><p style="width:90%"> |
| When Apache is started, (or when child Apache processes are |
| started if a threaded Tcl is used), |
| <code class="function">Rivet_InitTclStuff</code> is called, which |
| creates a new interpreter, or one interpreter per virtual |
| host, depending on the configuration. It also initializes |
| various things, like the <span class="structname">RivetChan</span> |
| channel system, creates the Rivet-specific Tcl commands, and |
| executes Rivet's <code class="filename">init.tcl</code>. The caching |
| system is also set up, and if there is a |
| <span style="font-family:monospace"><span class="command"><strong>GlobalInitScript</strong></span></span>, it is run. |
| </p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="idp59137536"></a>RivetChan</h3></div></div></div><p style="width:90%"> |
| The <span class="structname">RivetChan</span> system was created in |
| order to have an actual Tcl channel that we could redirect |
| standard output to. This lets us use, for instance, the |
| regular <span style="font-family:monospace"><span class="command"><strong>puts</strong></span></span> command in .rvt pages. It |
| works by creating a channel that buffers output, and, at |
| predetermined times, passes it on to Apache's IO system. |
| Tcl's regular standard output is replaced with an instance of |
| this channel type, so that, by default, output will go to the |
| web page. |
| </p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="idp59201312"></a>The <span style="font-family:monospace"><span class="command"><strong>global</strong></span></span> Command</h3></div></div></div><p style="width:90%"> |
| Rivet aims to run standard Tcl code with as few surprises as |
| possible. At times this involves some compromises - in this |
| case regarding the <span style="font-family:monospace"><span class="command"><strong>global</strong></span></span> command. The |
| problem is that the command will create truly global |
| variables. If the user is just cut'n'pasting some Tcl code |
| into Rivet, they most likely just want to be able to share the |
| variable in question with other procs, and don't really care |
| if the variable is actually persistant between pages. The |
| solution we have created is to create a proc |
| <span style="font-family:monospace"><span class="command"><strong>::request::global</strong></span></span> that takes the place of |
| the <span style="font-family:monospace"><span class="command"><strong>global</strong></span></span> command in Rivet templates. If |
| you really need a true global variable, use either |
| <span style="font-family:monospace"><span class="command"><strong>::global</strong></span></span> or add the :: namespace qualifier |
| to variables you wish to make global. |
| </p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="idp59206752"></a>Page Parsing, Execution and Caching</h3></div></div></div><p style="width:90%"> |
| When a Rivet page is requested, it is transformed into an |
| ordinary Tcl script by parsing the file for the <? ?> |
| processing instruction tags. Everything outside these tags |
| becomes a large <span style="font-family:monospace"><span class="command"><strong>puts</strong></span></span> statement, and |
| everything inside them remains Tcl code. |
| </p><p style="width:90%"> |
| Each .rvt file is evaluated in its own |
| <code class="constant">::request</code> namespace, so that it is not |
| necessary to create and tear down interpreters after each |
| page. By running in its own namespace, though, each page will |
| not run afoul of local variables created by other scripts, |
| because they will be deleted automatically when the namespace |
| goes away after Apache finishes handling the request. |
| </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"> |
| One current problem with this system is that while |
| variables are garbage collected, file handles are not, so |
| that it is very important that Rivet script authors make |
| sure to close all the files they open. |
| </td></tr></table></div><p style="width:90%"> |
| </p><p style="width:90%"> |
| After a script has been loaded and parsed into it's "pure Tcl" |
| form, it is also cached, so that it may be used in the future |
| without having to reload it (and re-parse it) from the disk. |
| The number of scripts stored in memory is configurable. This |
| feature can significantly improve performance. |
| </p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="idp59211824"></a>Debugging Rivet and Apache</h3></div></div></div><p style="width:90%"> |
| If you are interested in hacking on Rivet, you're welcome to |
| contribute! Invariably, when working with code, things go |
| wrong, and it's necessary to do some debugging. In a server |
| environment like Apache, it can be a bit more difficult to |
| find the right way to do this. Here are some techniques to |
| try. |
| </p><p style="width:90%"> |
| The first thing you should know is that Apache can be launched |
| as a <span class="emphasis"><em>single process</em></span> with the |
| -X argument:</p><pre style="background:#ccc; margin: 2ex; margin-right: 10%; padding: 1ex; border: dashed black 1px ; white-space: pre; font-family: monospace; font-size: 90%;" class="programlisting">httpd -X</pre>. |
| <p style="width:90%"> |
| On Linux, one of the first things to try is the system call |
| tracer, <span style="font-family:monospace"><span class="command"><strong>strace</strong></span></span>. You don't even have to |
| recompile Rivet or Apache for this to work. |
| </p><pre style="background:#ccc; margin: 2ex; margin-right: 10%; padding: 1ex; border: dashed black 1px ; white-space: pre; font-family: monospace; font-size: 90%;" class="programlisting">strace -o /tmp/outputfile -S 1000 httpd -X</pre><p style="width:90%">This command will run httpd in the system call tracer, |
| which leaves its output (there is potentially a lot of it) in |
| <code class="filename">/tmp/outputfile</code>. The -S |
| option tells <span style="font-family:monospace"><span class="command"><strong></strong></span></span>strace to only record the |
| first 1000 bytes of a syscall. Some calls such as |
| <code class="function">write</code> can potentially be much longer than |
| this, so you may want to increase this number. The results |
| are a list of all the system calls made by the program. You |
| want to look at the end, where the failure presumably occured, |
| to see if you can find anything that looks like an error. If |
| you're not sure what to make of the results, you can always |
| ask on the Rivet development mailing list. |
| </p><p style="width:90%"> |
| If <span style="font-family:monospace"><span class="command"><strong>strace</strong></span></span> (or its equivalent on your |
| operating system) doesn't answer your question, it may be time |
| to debug Apache and Rivet. To do this, you will need to run |
| the <span style="font-family:monospace"><span class="command"><strong>./configure.tcl</strong></span></span> script with the |
| -enable-symbols option, and recompile. |
| </p><p style="width:90%"> |
| Since it's easier to debug a single process, we'll still run |
| Apache in single process mode with -X: |
| </p><pre style="background:#ccc; margin: 2ex; margin-right: 10%; padding: 1ex; border: dashed black 1px ; white-space: pre; font-family: monospace; font-size: 90%;" class="programlisting"> |
| @ashland [~] $ gdb /usr/sbin/apache.dbg |
| GNU gdb 5.3-debian |
| Copyright 2002 Free Software Foundation, Inc. |
| GDB is free software, covered by the GNU General Public License, and you are |
| welcome to change it and/or distribute copies of it under certain conditions. |
| Type "show copying" to see the conditions. |
| There is absolutely no warranty for GDB. Type "show warranty" for details. |
| This GDB was configured as "powerpc-linux"... |
| (gdb) run -X |
| Starting program: /usr/sbin/apache.dbg -X |
| [New Thread 16384 (LWP 13598)] |
| . |
| . |
| . |
| </pre><p style="width:90%"> |
| When your apache session is up and running, you can request a |
| web page with the browser, and see where things go wrong (if |
| you are dealing with a crash, for instance). |
| </p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="help.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="upgrading.html"><img src="images/next.png" alt="Next"></a></td></tr><tr><td width="40%" align="left" valign="top">Resources - How to Get Help </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"> Upgrading from mod_dtcl or NeoWebScript</td></tr></table></div></body></html> |