File: internals.en.html

package info (click to toggle)
rivet 0.5.0-3
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 4,664 kB
  • ctags: 1,359
  • sloc: sh: 8,342; xml: 6,622; ansic: 4,367; tcl: 2,813; makefile: 99; lisp: 78; sql: 25
file content (125 lines) | stat: -rw-r--r-- 11,606 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Rivet Internals</title><link rel="stylesheet" href="rivet.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.66.1"><link rel="start" href="index.en.html" title="Apache Rivet"><link rel="up" href="index.en.html" title="Apache Rivet"><link rel="prev" href="help.en.html" title="Resources - How to Get Help"><link rel="next" href="upgrading.en.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.en.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.en.html"><img src="images/next.png" alt="Next"></a></td></tr></table></div><div class="section" lang="en"><div class="titlepage"><div><div><hr><h2 class="title" style="clear: both"><a name="internals"></a>Rivet Internals</h2></div></div></div><div class="toc"><dl><dt><span class="section"><a href="internals.en.html#id4771253">Initialization</a></span></dt><dt><span class="section"><a href="internals.en.html#id4771292">RivetChan</a></span></dt><dt><span class="section"><a href="internals.en.html#id4771319">The <span style="font-family:monospace"><span><b class="command">global</b></span></span> Command</a></span></dt><dt><span class="section"><a href="internals.en.html#id4771370">Page Parsing, Execution and Caching</a></span></dt><dt><span class="section"><a href="internals.en.html#id4771420">Debugging Rivet and Apache</a></span></dt></dl></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, <span style="font-family:monospace"><span><b class="command">cvs</b></span></span> can provide you with
      information about what has been happening with the code.
    </p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id4771253"></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),
	<tt class="function">Rivet_InitTclStuff</tt> 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 <tt class="filename">init.tcl</tt>.  The caching
	system is also set up, and if there is a
	<span style="font-family:monospace"><span><b class="command">GlobalInitScript</b></span></span>, it is run.
      </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id4771292"></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><b class="command">puts</b></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" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id4771319"></a>The <span style="font-family:monospace"><span><b class="command">global</b></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><b class="command">global</b></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><b class="command">::request::global</b></span></span> that takes the place of
	the <span style="font-family:monospace"><span><b class="command">global</b></span></span> command in Rivet templates.  If
	you really need a true global variable, use either
	<span style="font-family:monospace"><span><b class="command">::global</b></span></span> or add the :: namespace qualifier
	to variables you wish to make global.
      </p></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id4771370"></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 &lt;? ?&gt;
	processing instruction tags.  Everything outside these tags
	becomes a large <span style="font-family:monospace"><span><b class="command">puts</b></span></span> statement, and
	everything inside them remains Tcl code.
      </p><p style="width:90%">
	Each .rvt file is evaluated in its own
	<tt class="constant">::request</tt> 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 colspan="2" 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" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id4771420"></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:#bbffbb ; width:90ex ; margin: 2ex ;      padding: 1ex; border: solid black 1px ; white-space: pre;      font-family:monospace ; " 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><b class="command">strace</b></span></span>.  You don't even have to
	recompile Rivet or Apache for this to work.
      </p><pre style="background:#bbffbb ; width:90ex ; margin: 2ex ;      padding: 1ex; border: solid black 1px ; white-space: pre;      font-family:monospace ; " 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
	<tt class="filename">/tmp/outputfile</tt>.  The -S
	option tells <span style="font-family:monospace"><span><b class="command"></b></span></span>strace to only record the
	first 1000 bytes of a syscall.  Some calls such as
	<tt class="function">write</tt> 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><b class="command">strace</b></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><b class="command">./configure.tcl</b></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:#bbffbb ; width:90ex ; margin: 2ex ;      padding: 1ex; border: solid black 1px ; white-space: pre;      font-family:monospace ; " 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).  A helpful
	<span style="font-family:monospace"><span><b class="command">gdb</b></span></span> tutorial is available here: <a href="http://www.delorie.com/gnu/docs/gdb/gdb_toc.html" target="_top">http://www.delorie.com/gnu/docs/gdb/gdb_toc.html</a>
      </p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="help.en.html"><img src="images/prev.png" alt="Prev"></a></td><td width="20%" align="center"><a accesskey="u" href="index.en.html"><img src="images/up.png" alt="Up"></a></td><td width="40%" align="right"><a accesskey="n" href="upgrading.en.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.en.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>