Provided by: aolserver4-dev_4.5.1-18.1_amd64 bug


       ns_ictl - Facility to control AOLserver multi-threaded Tcl interpreters


       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


       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

       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

       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

       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

       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


       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.


       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


       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.


       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 ...


       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).


       threads, interpreters, traces, initialization