bionic (3) ns_ictl.3aolserver.gz

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

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