Forum OpenACS Development: Re: using persistent variables in a package namespace

Posted by Gustaf Neumann on
Dear Ben,

The rules of the variable cleanup are as following:
- all global variables (in the namespace "::") are cleaned up after every requests
- all other namespaced variables survive a request and are kept in the actual state in the per-thread interpreter of connection/scheduled thread until it shuts down.
- some packages perform management of the variables in "their" namespace (e.g. in the ::template:: namespace)

You are free what do do in your own namespace. If a connection thread set e.g. a variable ::x::v to 10 then another query executing in the same connection thread will see this variable and value when the query execution starts. However, be aware that when a thread sets a namespaced variable in its interpreter, the interpreters in other threads are unaffected. So, a new query might or might not be able to use this variable, since there is no built guarantee that the new query is executed in the same thread and there is no built-in synchronization for namespaced variables. Another consequence is that the namespaced variables are kept in every connection/scheduled thread, so there is some duplication.

A simple example for using namespaced variables is for caching of values from the DB, that will never change, like e.g. the package_id of acs-core. For this type of usage, namespaced variables are better than ns_cache (or nsvs), since the access does to the variable does not require a mutex lock.

If it is required to keep the variable value in sync with other threads (also, when e.g. a new connection thread starts) one approach is to do it same same way as for *-procs.tcl files. Add a file packages/mypkg/tcl/vars-procs.tcl to the source tree, set the variables there. This variables-file will be loaded at startup and can be reloaded at run-time via the reload operation in the package manager.

If an eventually consistent approach for communicating namespaced variables is fine, you could use ::xo::broadcast send {set ::x::v 123} or any other tcl command to update other interpreters (part of xotcl-core).

As for referring to variables: i would rather recommend to use absolute variable names (starting with "::"), since this is the only way to guarantee that you access this variable. For OpenACS (and other tcl packages) this is usually not an issue, since it uses a rather flat namespace, so the likelihood for a collision of a sub-namespace with a top-level namespace is little.

hope this helps

Posted by Benjamin Brink on
Thank you, Gustaf. You have answered my question as well as other questions I have about differences between various storage techniques and strategies that I was planning to investigate later this year. Truly, very helpful.