Rob,

Thanks for the info.  It was VERY helpful.  I did have problems with the
following:

 > If you do a "package require" in your tcl library, then all the
 > procedures and commands of that package will be copied.

This does not seem to be the case.  I created a .tcl file in modules/tcl
that is sourced at startup.  I did a "package require my_package" and
defined a proc "test_proc".  The package require worked fine and the
"test_proc" procedure is available to all threads/interpreters but the
package and package namespace are not available outside the startup
interpreter.

It appears that procedures are copied from the "startup interpreter" (no
suprise there) but packages and the related namespaces are not.  This is
disappointing.  It would be nice to have global packages/namespaces that
are available to all interpreters without them having to do a package
require.

By the way, packages and namespaces are working fine otherwise so it
really does seem to be a problem with packages/namespaces not being
copied from the startup interpreter to the interpreters that handle page
requests and .tcl scripts.

Thanks again Rob.

Jeff Nichols




Rob Mayoff wrote:

> 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