Provided by: aolserver4-dev_4.5.1-18.1_amd64 

NAME
ns_ictl - Facility to control AOLserver multi-threaded Tcl interpreters
SYNOPSIS
ns_ictl addmodule module
ns_ictl cancel thread
ns_ictl cleanup
ns_ictl epoch
ns_ictl get
ns_ictl getmodules
ns_ictl gettraces which
ns_ictl once key script
ns_ictl oncleanup script
ns_ictl oncreate script
ns_ictl ondelete script
ns_ictl oninit script
ns_ictl package ?-exact? package ?version?
ns_ictl runtraces which
ns_ictl save script
ns_ictl threads
ns_ictl trace when script
ns_ictl update
_________________________________________________________________
DESCRIPTION
This command provides access to the internal facilities to control and configure multi-threaded Tcl
interpreters in the context of AOLserver virtual servers. It is normally used in startup initialization
scripts to define how new interpreters are initialized when created and to support cleanup and re-
initalization between transactions (e.g., HTTP connections).
ns_ictl addmodule module
Add a module to the list of modules to be initialized at startup. This command is not normally
required as each module specified in the AOLserver modules config section for the corresponding
server (e.g., ns/server/server1/modules) is automatically added to the list.
ns_ictl cancel thread
Send an asynchronous interrupt request to the specified thread, cancelling any script currently
executing on any AOLserver created interpreter (note the interrupt is not virtual-server
specific). This command utilizes the facilities of Tcl_AsyncMark to mark as ready a callback
registered with Tcl_AsyncCreate. The callback places an error message in the interpreter result
and returns TCL_ERROR to unwind the call stack. The underlying Tcl facility has limitations, e.g.,
the interrupt will only be noticed when Tcl checks via Tcl_AsyncReady calls between commands and
the interrupt can be caught with a catch command. See the man page for Tcl_AsyncCreate for
details.
ns_ictl cleanup
This command invokes any callbacks registered during a transaction via the C-level
Ns_TclRegisterDefer routine. Unlike callbacks registered with the ns_ictl trace deallocate
command or Ns_TclRegisterTrace routine, these callbacks are executed only once and there is no
Tcl-level access to the underlying Ns_TclRegisterDefer routine.
ns_ictl epoch
This command returns the unique id for the current duplication script for the virtual server. The
id starts as 0 when the virtual server is created and is incremented each time a new script is
saved via the ns_ictl save command.
ns_ictl get
Return the current duplication script for the virtual server. This command is useful to view the
duplication script created by the initialization script at startup.
ns_ictl getmodules
Return the list of modules to be initialized at startup. This list corresponds to the names of
modules specified in the virtual server modules config section, e.g., ns/server/server1/modules
unless additional modules are added via the ns_ictl addmodule command.
ns_ictl gettraces which
Return the list of traces which will be invoked at the specified time. The which argument can be
one of create, delete, allocate, deallocate, getconn, or freeconn. The traces are returned in the
order in which they will be executed. Script level traces are returns as strings to evaluate and
C-level traces are returned with strings which specify the address of the underlying C procedure
and argument.
ns_ictl once key script
Evaluate given script once in the virtual server. The given key is a string name which uniquely
identifies the corresponding script. This command is useful in a Tcl package which includes one-
time initialization routines, e.g., calls to ns_register_proc or initialization of shared
variables using nsv_set (see EXAMPLES below).
ns_ictl oncleanup script
This command is equivalent to ns_ictl trace deallocate script.
ns_ictl oncreate script
This command is equivalent to ns_ictl trace create script.
ns_ictl ondelete script
This command is equivalent to ns_ictl trace delete script.
ns_ictl oninit script
This command is equivalent to ns_ictl trace allocate script.
ns_ictl package ?-exact? package ?version?
This command is used to require a package in the calling interpreter and, if successfully loaded,
in all other interpreters for the virtual server. In addition to ensuring version consistency for
the package, it is equivalent to:
set version [package require package ?version?]
ns_ictl trace allocate [list package require package $version]
ns_ictl runtraces which
This command runs the requested traces. The which argument must be one of create, delete,
allocate, deallocate, getconn, or freeconn. Direct calls to this command are not normally
necessary as the underlying C code will invoke the callbacks at the required times. Exceptions
include calling ns_ictl runtraces or testing purposes or to mimic the normal cleanup and
initialization work performed on between transactions in a long running thread (see EXAMPLES
below).
ns_ictl save script
Save the given script as the duplication script, incrementing the virtual server epoch number.
This command is normally called by the bootstrap script after constructing the script to duplicate
the procedures defined by sourcing the various module initialization script files.
ns_ictl threads
Return a list of all threads with interpreters for the virtual server. The ids return are small
strings which represent the underlying thread ids and can be passed to the ns_ictl cancel command
to send an asynchronous cancel request.
ns_ictl trace create script
Register script to be called when an interpreter is first created. This is useful to create
procedures, require packages, or initialize other state to be used during the lifetime of the
interpreter.
ns_ictl trace delete script
Register script to be called before an interpreter is destroyed. This is useful to free any
resources which may have been allocated for the interpreter during the lifetime of the
interpreter.
ns_ictl trace allocate script
Register script to be called each time an interpreter is allocated for use by the
Ns_TclAllocateInterp routine. This is useful for reinitializing resources which may be used during
a single transaction in the interpreter.
ns_ictl trace deallocate script
Register script to be called each time an interpreter is returned after a transaction with the
Ns_TclDeAllocateInterp routine. This is useful for garbage collection, i.e., freeing any resources
which may be used during a single transaction in the interpreter.
ns_ictl trace getconn script
Register script to be called each time an interpreter is returned and associated with an HTTP
connection with the Ns_GetConnInterp routine. This could be useful to define variables relative to
the HTTP request.
ns_ictl trace freeconn script
Register script to be called each time an HTTP connection is closed. This could be used to log
information about the request, e.g., timing statistics. Note that the interpreter may still be
actively evaluating a script after the connection is closed, i.e., this is not equivalent to
ns_ictl trace deallocate for connection-related interpreters.
ns_ictl update
This command can be used to atomically compare the epoch of the current duplication script with
the epoch of the interpreter, evaluating the script and updating the epoch in the interpreter if
they do not match. This command is generally registered as a callback with ns_ictl trace allocate
by the legacy initialization code.
INTERPRETER ALLOCATION
Tcl interpreter in AOLserver are available on demand with state specific to a virtual server. These
interpreters are also expected to be reused for multiple transactions (e.g., HTTP connections, scheduled
procedures, socket callbacks).
To support reuse, AOLserver provides the C-level Ns_TclAllocateInterp routine to allocate an interpreter
from a per-thread cache (creating and initializing a new interpreter if necessary) and the
Ns_TclDeAllocateInterp routine to return an interpreter to the cache when no longer required. All
interpreters in the per-thread cache are destroyed when a thread exists.
In general, only C-level extension writers need to call the C-level API's directly; the various Tcl-level
interfaces in AOLserver (e.g., ADP pages, ns_regiseter_proc, ns_schedule_proc, ns_thread, etc.) allocate
and reuse interpreters using the C-level API's automatically before invoking the cooresponding script or
ADP page.
INTERPRETER TRACES
To ensure a consistent state of interpreters when allocated and enable cleanup and reinitialization
between transactions, each virtual server maintains a list of callbacks to be invoked at various points
in the lifetime of an interpreter. These callbacks are generally installed when the server is
initialized at startup and then called automatically by the Ns_TclAllocateInterp and
Ns_TclDeAllocateInterp API's at the appropriate times and in consistent order. The Ns_TclRegisterTrace
routine can be used to register C-level callbacks and the ns_ictl trace command can be used to register
Tcl script callbacks. The ns_ictl gettraces command can be used to list all currently registered
callbacks, both at the Tcl script and C level.
Callbacks registered via the tracing facility are invoked in a specific order depending on the type.
Initialization style callbacks including create, allocate, and getconn are invoked in FIFO order, with
all script callbacks invoked after all C-level callbacks. This enables extension writers to utilize the
facilities of previously initialized extensions. Correspondingly, cleanup style callbacks including
freeconn, deallocate, and delete are invoked in LIFO order, with all scripts callbacks invoked before C-
level callbacks. This helps avoid the possibility that a cleanup callback utilizes features of a
previously cleaned up extension.
In addition, the ns_ictl package command can be used to consistently manage the loading of a Tcl package
in all interpreters for a virtual server. This feature is mostly a convenience routine built above the
generic trace framework with additional checks to ensure version number consistency. Coupled with
ns_ictl once, the ns_ictl package command provides a clean framework to utilize Tcl packages in multi-
threaded AOLserver (see EXAMPLES).
VIRTUAL SERVER TCL INITIALIZATION
AOLserver also supports a Tcl initialization framework for virtual servers based on callbacks registered
by loadable modules and the sourcing of scripts files located in corresponding directories. Options to
ns_ictl to support this framework include save, get, epoch, and update and are used in conjunction with
the generic tracing facility by the virtual server bootstrap script (normally bin/init.tcl). The ns_eval
command also relies on this framework to support dynamic update of the state of interpreters.
This initialization framework pre-dates the Tcl package facilities and utilizes introspection of the
state of a startup interpreter at the end of initialization to construct a single script which attempts
to duplicate the state in subsequent interpreters. Steps taken during this initialization include:
1. Load all modules in the server's module config section, e.g.,
ns/server/server1/modules. Modules with Tcl C-level extensions typically call the legacy
Ns_TclInitInterps routine or the more general Ns_TclRegisterTrace routine with the
NS_TCL_TRACE_CREATE flag in their module init routine to register a callback to invoke when new
interpreters are created. The callback normally creates one or more new commands in the
interpreter with Tcl_CreateObjCommand but may perform any per-interpreter initialization required,
e.g., creating and saving private state with the Tcl_SetAssocData facility. In addition, as
modules are loaded, the string name of the module is added to the list of known modules.
2. After all C modules are loaded, AOLserver creates a new Tcl
interpreter for the virtual server, executing any trace callbacks already registered via the
loaded C modules (e.g., any Ns_TclInitInterps callbacks) and then sources the virtual server
bootstrap script, normally bin/init.tcl. This script creates a few utility procedures and then
sources all private and public script files in directories which correspond to loaded modules in
the order in which they were loaded. These directories are normally relative to the virtual
server and to the AOLserver installation directory, e.g., initialization script files for the
module mymod in the server1 virtual server would be searched for in the
servers/server1/modules/tcl/mymod/ and modules/tcl/mymod/. Any init.tcl file found in each
directory is sourced first with all remaining files sourced in alphabetical order. In addition,
any files in the public directory with identical names to files in the private directory are
skipped as a means to enable overloading of specific functionality on a per-server basis. In
practice, most modules only contain shared utility procedures defined in the public directories
and the private directories are empty or non-existant. The script files normally contain a mix of
commands to evaluate once for server configuration (e.g., a call to ns_register_proc to bind a Tcl
procedure to an HTTP request URL) with proc and namespace commands to provide additional
functionality in the interpreter.
3. After all script files have been sourced, the bootstrap script
code then uses a collection of recursive procedures to extract the definitions of all procedures
defined in all namespaces. The definitions are used to construct a script which attempts to
duplicate the state of the initialization interpreters. This scripts is then saved as the per-
virtual server duplication script with the ns_ictl save command which also increments the epoch to
1. There are limits to this approach to determine the full state, e.g., it does not attempt to
duplicate any global variables which may have been defined in the startup scripts. Typically,
startup scripts will use nsv_set or other mechanisms to store such shared state.
4. The bootstrap code then uses the ns_ictl trace allocate
command to register a callback to the ns_ictl update command each time an interpreter is allocated
for use. In practice, interpreters are created with the default epoch of 0 and the first call to
ns_ictl update determines an out-of-date condition, evaluates the duplication script, and
increments the interpreter's epoch to 1 to match the state created by the startup interp.
5. Subsequent calls the ns_eval, if any, will evaluate the
given script and then re-generate and save the duplication script as was done at startup,
incrementing the epoch once again. In this way, dynamic updates which are detected in other
interpreters on their next call to ns_ictl update can be supported in a limited fashion.
In practice, while generally successful, this duplication technique has inhibited the clean use of proper
Tcl package extensions and encouraged the use of the ns_eval command which is generally not recommended
for the non-deterministic manner in which it attempts to dynamically reconfigure a server. Also,
commands required to configure the server once (e.g., calls to ns_register_proc) are inter-mixed with
proc commands designed to extend functionality in all interpreters, complicating configuration
management.
As an alternative, the example below illustrates a means to more explicitly manage configuration through
a combination of direct calls to ns_ictl trace create and ns_ictl once. Unfortunately, the all
encompassing nature of the legacy initialization approach makes it difficult to incrementally move to
this cleaner approach because the duplication script construction code is unable to distinguish between
state created with the newer, cleaner ns_ictl commands and state created as a side effect of one or more
script files being sourced. As such, it is expected the legacy initialization framework will remain in
place until AOLserver 5.x when it will be removed entirely in a non-backwards compatible move towards the
cleaner API's.
EXAMPLES
This example illustrates the use of ns_ictl package and ns_ictl once to load an AOLserver-aware Tcl
package into a virtual server. The following code could be added to the virtual server bootstrap script,
bin/init.tcl, to load MyPkg in the virtual server:
#
# Startup code in bin/init.tcl:
#
# Load MyPkg in all interps (including this one).
#
ns_ictl package require MyPkg
This call will result in the package being loaded into the startup interpreter in the ordinary Tcl
fashion (see the package man page for details). Ordinary Tcl extension packages would need no
modifications but packages which utilize AOLserver-specific features or require garbage collection
between transactions could also use ns_ictl for finer grained control. For example, the init.tcl script
specified by the package ifneeded command in the MyPkg package's pkgIndex.tcl file could contains:
#
# Package code in lib/myPkg1.0/init.tcl:
#
#
package provide MyPkg 1.0
#
# Server init which will be executed the first time called,
# normally in the context of the startup interpreter as above.
#
ns_ictl once MyPkg {
# Register the run Tcl proc HTTP handler.
ns_register_proc /mypkg mkpkg::run
# Register a garbage collection callback.
ns_ictl trace deallocate mypkg::cleanup
}
#
# Code which will be invoked to initialize the package in
# all interpreters when required.
#
proc mypkg::run {} {
... handle /mypkg requests ...
}
proc mkpkg::cleanup {} {
... cleanup transaction resources for mypkg, e.g., db handles ...
}
SEE ALSO
Ns_TclAllocateInterp(3), Ns_TclDeAllocateInterp(3), Ns_GetConnInterp(3), Ns_FreeConnInterp(3),
Ns_TclInitInterps(3), Ns_TclRegisterTrace(3), Ns_TclRegisterDeferred(3), ns_atclose(n), ns_eval(n).
KEYWORDS
threads, interpreters, traces, initialization
AOLserver 4.5 ns_ictl(3aolserver)