This question was sent to me in private, but (with the asker's
permission) I'm responding on the list for the benefit of others.

+---------- On Jun 8, Jeff Nichols said:
> I guess I'm wondering where I can find more info about how threads,
> interpreters and connections are used in AOLServer.  A lot of the docs
> (tcl and aolserver) refer to things being related to a thread or
> interpreter.  If I understood how these things were created, related,
> and deleted I could make educated decisions.
>
> In particular we're thinking about using packages and namespaces
> extensively but want to know the performance consequences.  From what I
> can tell, a package/namespace seems to exist for each thread.  When the
> thread times out the package/namespace info is lost and must be
> reinitialized.  The tcl package docs seem to state that packages exist
> for each interpreter so this and my observations seem to imply that each
> thread has it's own interpreter...

The following describes AOLserver 3.0 through 3.4.  I believe that some
things have changed in 4.0 (which hasn't been released yet).

Each thread has its own interpreter.

There is a pool of threads that handle HTTP connections.  There is also
a thread that runs scheduled procs.

At server startup, the server creates an interpreter.  This startup
interpreter sources the .tcl files in your shared and private tcl libraries.
The server then digs through this interpreter's symbol table and copies
out all of the commands and procedures, then destroys the interpreter.

When a thread tries to use its interpreter for the first time, the
server creates the interpreter and gives it all of the commands and
procedures from that startup interpreter.

Note that variables are not copied to the thread interpreters.

If you do a "package require" in your tcl library, then all the
procedures and commands of that package will be copied.  For many
packages, this is ok.  However, if the package expects certain
variables to be set, it is not so fine.

If you say "package require" in a thread interpreter (say, from a
registered proc or from a .tcl page), then only that thread will load
the package.  This is assuming you can get the package load path
straightened out, which is difficult.

You can put procs in namespaces.  I do it all the time.  However, you
should avoid using namespace import/export; it's not handled correctly.

After a connection thread handles its connection, it removes (almost)
all the global variables from its interpreter.  So if your .tcl page or
whatever sets a global variable, it will go away at the end of the
connection.  Note that globals are not shared between interpreters.

However, the script that deletes the globals does NOT dig through all
your namespaces.  So if you set a namespace variable, it will NOT be
removed at the end of the connection.

To demonstrate, try putting this in a .tcl page in your pageroot:

    set text ""

    # Make sure ::test namespace exists.
    namespace eval ::test {}

    if {![info exists ::test::myvar]} {
        append text "::test::myvar doesn't exist yet - creating it\n"
        set ::test::myvar 0
    } else {
        append text "::test::myvar = $::test::myvar\n"
        incr ::test::myvar
    }

    global myglobal

    if {![info exists myglobal]} {
        append text "myglobal doesn't exist yet - creating it\n"
        set myglobal 0
    } else {
        append text "myglobal = $myglobal\n"
        incr myglobal
    }

    ns_return 200 text/plain $text

Reply via email to